summaryrefslogtreecommitdiff
path: root/source3/winbindd/idmap_adex/provider_unified.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/winbindd/idmap_adex/provider_unified.c')
-rw-r--r--source3/winbindd/idmap_adex/provider_unified.c1198
1 files changed, 0 insertions, 1198 deletions
diff --git a/source3/winbindd/idmap_adex/provider_unified.c b/source3/winbindd/idmap_adex/provider_unified.c
deleted file mode 100644
index 438fb7c978..0000000000
--- a/source3/winbindd/idmap_adex/provider_unified.c
+++ /dev/null
@@ -1,1198 +0,0 @@
-/*
- * idmap_adex
- *
- * Provider for RFC2307 and SFU AD Forests
- *
- * Copyright (C) Gerald (Jerry) Carter 2006-2008
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-#include "ads.h"
-#include "idmap.h"
-#include "idmap_adex.h"
-#include "../libcli/ldap/ldap_ndr.h"
-#include "../libcli/security/dom_sid.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_IDMAP
-
-/* Information needed by the LDAP search filters */
-
-enum filterType { SidFilter, IdFilter, AliasFilter };
-
-struct lwcell_filter
-{
- enum filterType ftype;
- bool use2307;
- union {
- struct dom_sid sid;
- struct {
- uint32_t id;
- enum id_type type;
- } id;
- fstring alias;
- } filter;
-};
-
-/********************************************************************
- *******************************************************************/
-
-static char* build_id_filter(TALLOC_CTX *mem_ctx,
- uint32_t id,
- enum id_type type,
- uint32_t search_flags)
-{
- char *filter = NULL;
- char *oc_filter, *attr_filter;
- NTSTATUS nt_status;
- TALLOC_CTX *frame = talloc_stackframe();
- bool use2307 = ((search_flags & LWCELL_FLAG_USE_RFC2307_ATTRS)
- == LWCELL_FLAG_USE_RFC2307_ATTRS);
- bool use_gc = ((search_flags & LWCELL_FLAG_SEARCH_FOREST)
- == LWCELL_FLAG_SEARCH_FOREST);
- const char *oc;
-
- /* Construct search filter for objectclass and attributes */
-
- switch (type) {
- case ID_TYPE_UID:
- oc = ADEX_OC_USER;
- if (use2307) {
- oc = ADEX_OC_POSIX_USER;
- if (use_gc) {
- oc = AD_USER;
- }
- }
- oc_filter = talloc_asprintf(frame, "objectclass=%s", oc);
- attr_filter = talloc_asprintf(frame, "%s=%u",
- ADEX_ATTR_UIDNUM, id);
- break;
-
- case ID_TYPE_GID:
- oc = ADEX_OC_GROUP;
- if (use2307) {
- oc = ADEX_OC_POSIX_GROUP;
- if (use_gc) {
- oc = AD_GROUP;
- }
- }
- oc_filter = talloc_asprintf(frame, "objectclass=%s", oc);
- attr_filter = talloc_asprintf(frame, "%s=%u",
- ADEX_ATTR_GIDNUM, id);
- break;
- default:
- return NULL;
- }
-
- if (oc_filter == NULL) {
- goto done;
- }
- if (attr_filter == NULL) {
- goto done;
- }
-
- /* Use "keywords=%s" for non-schema cells */
-
- if (use2307) {
- filter = talloc_asprintf(mem_ctx,
- "(&(%s)(%s))",
- oc_filter,
- attr_filter);
- } else {
- filter = talloc_asprintf(mem_ctx,
- "(&(keywords=%s)(keywords=%s))",
- oc_filter,
- attr_filter);
- }
-
-done:
- talloc_destroy(frame);
-
- return filter;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static char* build_alias_filter(TALLOC_CTX *mem_ctx,
- const char *alias,
- uint32_t search_flags)
-{
- char *filter = NULL;
- char *user_attr_filter, *group_attr_filter;
- TALLOC_CTX *frame = talloc_stackframe();
- bool use2307 = ((search_flags & LWCELL_FLAG_USE_RFC2307_ATTRS)
- == LWCELL_FLAG_USE_RFC2307_ATTRS);
- bool search_forest = ((search_flags & LWCELL_FLAG_SEARCH_FOREST)
- == LWCELL_FLAG_SEARCH_FOREST);
-
- /* Construct search filter for objectclass and attributes */
-
- user_attr_filter = talloc_asprintf(frame, "%s=%s",
- ADEX_ATTR_UID, alias);
- group_attr_filter = talloc_asprintf(frame, "%s=%s",
- ADEX_ATTR_DISPLAYNAME, alias);
- if (user_attr_filter == NULL) {
- goto done;
- }
- if (group_attr_filter == NULL) {
- goto done;
- }
-
- /* Use "keywords=%s" for non-schema cells */
-
- if (use2307) {
- filter = talloc_asprintf(mem_ctx,
- "(|(&(%s)(objectclass=%s))(&(%s)(objectclass=%s)))",
- user_attr_filter,
- search_forest ? AD_USER : ADEX_OC_POSIX_USER,
- group_attr_filter,
- search_forest ? AD_GROUP : ADEX_OC_POSIX_GROUP);
- } else {
- filter = talloc_asprintf(mem_ctx,
- "(|(keywords=%s)(keywords=%s))",
- user_attr_filter,
- group_attr_filter);
- }
-
-done:
- talloc_destroy(frame);
-
- return filter;
-}
-
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS search_cell(struct likewise_cell *c,
- LDAPMessage **msg,
- const struct lwcell_filter *fdata)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX* frame = talloc_stackframe();
- char *filter = NULL;
- const char *base = NULL;
- ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
- const char *attrs[] = { "*", NULL };
- int count;
- char *sid_str;
-
- /* get the filter and other search parameters */
-
- switch (fdata->ftype) {
- case SidFilter:
- sid_str = sid_string_talloc(frame, &fdata->filter.sid);
- BAIL_ON_PTR_ERROR(sid_str, nt_status);
-
- filter = talloc_asprintf(frame, "(keywords=backLink=%s)",
- sid_str);
- break;
- case IdFilter:
- filter = build_id_filter(frame,
- fdata->filter.id.id,
- fdata->filter.id.type,
- cell_flags(c));
- break;
- case AliasFilter:
- filter = build_alias_filter(frame,
- fdata->filter.alias,
- cell_flags(c));
- break;
- default:
- nt_status = NT_STATUS_INVALID_PARAMETER;
- break;
- }
- BAIL_ON_PTR_ERROR(filter, nt_status);
-
- base = cell_search_base(c);
- BAIL_ON_PTR_ERROR(base, nt_status);
-
- ads_status = cell_do_search(c, base, LDAP_SCOPE_SUBTREE,
- filter, attrs, msg);
-
- nt_status = ads_ntstatus(ads_status);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Now check that we got only one reply */
-
- count = ads_count_replies(c->conn, *msg);
- if (count < 1) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if ( count > 1) {
- nt_status = NT_STATUS_DUPLICATE_NAME;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "search_cell", 4);
-
- talloc_destroy(discard_const_p(char, base));
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS search_domain(struct likewise_cell **cell,
- LDAPMessage **msg,
- const char *dn,
- const struct dom_sid *sid)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX* frame = talloc_stackframe();
- int count;
-
- nt_status = dc_search_domains(cell, msg, dn, sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Now check that we got only one reply */
-
- count = ads_count_replies(cell_connection(*cell), *msg);
- if (count < 1) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if ( count > 1) {
- nt_status = NT_STATUS_DUPLICATE_NAME;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "search_domain", 4);
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-
-/********************************************************************
- Check that a DN is within the forest scope.
- *******************************************************************/
-
-static bool check_forest_scope(const char *dn)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *frame = talloc_stackframe();
- char *p = NULL;
- char *q = NULL;
- char *dns_domain = NULL;
- struct winbindd_tdc_domain *domain;
-
- /* If the DN does *not* contain "$LikewiseIdentityCell",
- assume this is a schema mode forest and it is in the
- forest scope by definition. */
-
- if ((p = strstr_m(dn, ADEX_CELL_RDN)) == NULL) {
- nt_status = NT_STATUS_OK;
- goto done;
- }
-
- /* If this is a non-schema forest, then make sure that the DN
- is in the form "...,cn=$LikewiseIdentityCell,DC=..." */
-
- if ((q = strchr_m(p, ',')) == NULL) {
- nt_status = NT_STATUS_OBJECT_NAME_INVALID;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- q++;
- if (strncasecmp_m(q, "dc=", 3) != 0) {
- nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-
- dns_domain = cell_dn_to_dns(q);
- BAIL_ON_PTR_ERROR(dns_domain, nt_status);
-
- domain = wcache_tdc_fetch_domain(frame, dns_domain);
- if (!domain) {
- nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
- SAFE_FREE(dns_domain);
-
- return NT_STATUS_IS_OK(nt_status);
-}
-
-
-
-/********************************************************************
- Check that only one result was returned within the forest cell
- scope.
- *******************************************************************/
-
-static NTSTATUS check_result_unique_scoped(ADS_STRUCT **ads_list,
- LDAPMessage **msg_list,
- int num_resp,
- char **dn,
- struct dom_sid *user_sid)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- int i;
- ADS_STRUCT *ads = NULL;
- LDAPMessage *msg = NULL;
- int count = 0;
- char *entry_dn = NULL;
- TALLOC_CTX *frame = talloc_stackframe();
-
- if (!dn || !user_sid) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- *dn = NULL;
-
- if (!ads_list || !msg_list || (num_resp == 0)) {
- nt_status = NT_STATUS_NO_SUCH_FILE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Loop over all msgs */
-
- for (i=0; i<num_resp; i++) {
- LDAPMessage *e = ads_first_entry(ads_list[i], msg_list[i]);
-
- while (e) {
- entry_dn = ads_get_dn(ads_list[i], talloc_tos(), e);
- BAIL_ON_PTR_ERROR(entry_dn, nt_status);
-
- if (check_forest_scope(entry_dn)) {
- count++;
-
- /* If we've already broken the condition, no
- need to continue */
-
- if (count > 1) {
- nt_status = NT_STATUS_DUPLICATE_NAME;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- ads = ads_list[i];
- msg = e;
- *dn = SMB_STRDUP(entry_dn);
- BAIL_ON_PTR_ERROR((*dn), nt_status);
- }
-
- e = ads_next_entry(ads_list[i], e);
- TALLOC_FREE(entry_dn);
- }
- }
-
- if (!ads || !msg) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* If we made is through the loop, then grab the user_sid and
- run home to base */
-
- /*
- Try and get the SID from either objectSid or keywords.
- We cannot use pull_sid() here since we want to try
- both methods and not only one or the other (and we
- have no full likewise_cell struct.
-
- Fail if both are unavailable
- */
-
- if (!ads_pull_sid(ads, msg, "objectSid", user_sid)) {
- char **keywords;
- char *s;
- size_t num_lines = 0;
-
- keywords = ads_pull_strings(ads, frame, msg, "keywords",
- &num_lines);
- BAIL_ON_PTR_ERROR(keywords, nt_status);
-
- s = find_attr_string(keywords, num_lines, "backLink");
- if (!s) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if (!string_to_sid(user_sid, s)) {
- nt_status = NT_STATUS_INVALID_SID;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- if (!NT_STATUS_IS_OK(nt_status)) {
- SAFE_FREE(*dn);
- }
-
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- Search all forests. Each forest can have it's own forest-cell
- settings so we have to generate the filter for each search.
- We don't use gc_search_all_forests() since we may have a different
- schema model in each forest and need to construct the search
- filter for each GC search.
- *******************************************************************/
-
-static NTSTATUS search_forest(struct likewise_cell *forest_cell,
- LDAPMessage **msg,
- const struct lwcell_filter *fdata)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *frame = talloc_stackframe();
- char *filter = NULL;
- char *dn = NULL;
- struct gc_info *gc = NULL;
- ADS_STRUCT **ads_list = NULL;
- LDAPMessage **msg_list = NULL;
- int num_resp = 0;
- LDAPMessage *m;
- struct dom_sid user_sid;
- struct likewise_cell *domain_cell = NULL;
-
- if ((gc = gc_search_start()) == NULL) {
- nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- while (gc) {
- char *sid_binstr = NULL;
- uint32_t flags = LWCELL_FLAG_SEARCH_FOREST;
-
- m = NULL;
-
- flags |= cell_flags(gc->forest_cell);
-
- switch (fdata->ftype) {
- case SidFilter:
- sid_binstr = ldap_encode_ndr_dom_sid(frame, &fdata->filter.sid);
- BAIL_ON_PTR_ERROR(sid_binstr, nt_status);
-
- filter = talloc_asprintf(frame, "(objectSid=%s)", sid_binstr);
- TALLOC_FREE(sid_binstr);
- break;
- case IdFilter:
- filter = build_id_filter(frame,
- fdata->filter.id.id,
- fdata->filter.id.type, flags);
- break;
- case AliasFilter:
- filter = build_alias_filter(frame,
- fdata->filter.alias,
- flags);
- break;
- }
-
- /* First find the sparse object in GC */
- nt_status = gc_search_forest(gc, &m, filter);
- if (!NT_STATUS_IS_OK(nt_status)) {
- gc = gc->next;
- continue;
- }
-
- nt_status = add_ads_result_to_array(cell_connection(gc->forest_cell),
- m, &ads_list, &msg_list,
- &num_resp);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- gc = gc->next;
- }
-
- /* Uniqueness check across forests */
-
- nt_status = check_result_unique_scoped(ads_list, msg_list, num_resp,
- &dn, &user_sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = search_domain(&domain_cell, &m, dn, &user_sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Save the connection and results in the return parameters */
-
- forest_cell->gc_search_cell = domain_cell;
- *msg = m;
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "search_forest", 4);
-
- SAFE_FREE(dn);
-
- free_result_array(ads_list, msg_list, num_resp);
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS search_cell_list(struct likewise_cell **c,
- LDAPMessage **m,
- const struct lwcell_filter *fdata)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- struct likewise_cell *result_cell = NULL;
-
- if ((cell = cell_list_head()) == NULL) {
- nt_status = NT_STATUS_INVALID_SERVER_STATE;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- while (cell) {
- /* Clear any previous GC search results */
-
- cell->gc_search_cell = NULL;
-
- if (cell_search_forest(cell)) {
- nt_status = search_forest(cell, &msg, fdata);
- } else {
- nt_status = search_cell(cell, &msg, fdata);
- }
-
- /* Always point to the search result cell.
- In forests this might be for another domain
- which means the schema model may be different */
-
- result_cell = cell->gc_search_cell ?
- cell->gc_search_cell : cell;
-
- /* Check if we are done */
-
- if (NT_STATUS_IS_OK(nt_status)) {
- break;
- }
-
- /* No luck. Free memory and hit the next cell.
- Forest searches always set the gc_search_cell
- so give preference to that connection if possible. */
-
- ads_msgfree(cell_connection(result_cell), msg);
- msg = NULL;
-
- cell = cell->next;
- }
-
- /* This might be assigning NULL but that is ok as long as we
- give back the proper error code */
-
- *c = result_cell;
- *m = msg;
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "search_cell_list", 3);
-
- return nt_status;
-}
-
-/********************************************************************
- Pull the SID from an object which is always stored in the keywords
- attribute as "backLink=S-1-5-21-..."
- *******************************************************************/
-
-static NTSTATUS pull_sid(struct likewise_cell *c,
- LDAPMessage *msg,
- struct dom_sid *sid)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- TALLOC_CTX *frame = talloc_stackframe();
- ADS_STRUCT *ads = NULL;
-
- ads = cell_connection(c);
-
- /*
- We have two ways of getting the sid:
- (a) from the objectSID in case of a GC search,
- (b) from backLink in the case of a cell search.
- Pull the keywords attributes and grab the backLink.
- */
-
- if (!ads_pull_sid(ads, msg, "objectSid", sid)) {
- char **keywords;
- char *s;
- size_t num_lines = 0;
-
- keywords = ads_pull_strings(ads, frame, msg,
- "keywords", &num_lines);
- BAIL_ON_PTR_ERROR(keywords, nt_status);
-
- s = find_attr_string(keywords, num_lines, "backLink");
- if (!s) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- if (!string_to_sid(sid, s)) {
- nt_status = NT_STATUS_INVALID_SID;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS get_object_type(struct likewise_cell *c,
- LDAPMessage *msg,
- enum id_type *type)
-{
- TALLOC_CTX *ctx = talloc_stackframe();
- char **oc_list = NULL;
- NTSTATUS nt_status = NT_STATUS_OK;
- size_t list_size = 0;
- char *s = NULL;
- ADS_STRUCT *ads = NULL;
-
- ads = cell_connection(c);
-
- /* Deal with RFC 2307 support first */
-
- if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
- oc_list = ads_pull_strings(ads, ctx, msg,
- "objectClass", &list_size);
- if (!oc_list) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- goto done;
- }
-
- /* Check for posix classes and AD classes */
-
- if (is_object_class(oc_list, list_size, ADEX_OC_POSIX_USER)
- || is_object_class(oc_list, list_size, AD_USER)) {
- *type = ID_TYPE_UID;
- } else if (is_object_class(oc_list, list_size, ADEX_OC_POSIX_GROUP)
- || is_object_class(oc_list, list_size, AD_GROUP)) {
- *type = ID_TYPE_GID;
- } else {
- *type = ID_TYPE_NOT_SPECIFIED;
- nt_status = NT_STATUS_INVALID_PARAMETER;
- }
- } else {
- /* Default to non-schema mode */
-
- oc_list = ads_pull_strings(ads, ctx, msg,
- "keywords", &list_size);
- if (!oc_list) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- goto done;
- }
-
- s = find_attr_string(oc_list, list_size, "objectClass");
- if (!s) {
- nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- goto done;
- }
-
- if (strequal(s, ADEX_OC_USER)) {
- *type = ID_TYPE_UID;
- } else if (strequal(s, ADEX_OC_GROUP)) {
- *type = ID_TYPE_GID;
- } else {
- *type = ID_TYPE_NOT_SPECIFIED;
- nt_status = NT_STATUS_INVALID_PARAMETER;
- }
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(ctx);
-
- return nt_status;
-}
-
-/********************************************************************
- Pull an attribute uint32_t value
- *******************************************************************/
-
-static NTSTATUS get_object_uint32(struct likewise_cell *c,
- LDAPMessage *msg,
- const char *attrib,
- uint32_t *x)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char **keywords = NULL;
- size_t list_size = 0;
- TALLOC_CTX *frame = talloc_stackframe();
- ADS_STRUCT *ads = NULL;
-
- ads = cell_connection(c);
-
- /* Deal with RFC2307 schema */
-
- if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
- if (!ads_pull_uint32(ads, msg, attrib, x)) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- } else {
- /* Non-schema mode */
- char *s = NULL;
- uint32_t num;
-
- keywords = ads_pull_strings(ads, frame, msg, "keywords",
- &list_size);
- BAIL_ON_PTR_ERROR(keywords, nt_status);
-
- s = find_attr_string(keywords, list_size, attrib);
- if (!s) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- num = strtoll(s, NULL, 10);
- if (errno == ERANGE) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- *x = num;
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS get_object_id(struct likewise_cell *c,
- LDAPMessage *msg,
- enum id_type type,
- uint32_t *id)
-{
- NTSTATUS nt_status = NT_STATUS_OK;
- const char *id_attr;
-
- /* Figure out which attribute we need to pull */
-
- switch (type) {
- case ID_TYPE_UID:
- id_attr = ADEX_ATTR_UIDNUM;
- break;
- case ID_TYPE_GID:
- id_attr = ADEX_ATTR_GIDNUM;
- break;
- default:
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- break;
- }
-
- nt_status = get_object_uint32(c, msg, id_attr, id);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/********************************************************************
- Pull the uid/gid and type from an object. This differs depending on
- the cell flags.
- *******************************************************************/
-
-static NTSTATUS pull_id(struct likewise_cell *c,
- LDAPMessage *msg,
- uint32_t *id,
- enum id_type *type)
-{
- NTSTATUS nt_status;
-
- nt_status = get_object_type(c, msg, type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = get_object_id(c, msg, *type, id);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/********************************************************************
- Pull an attribute string value
- *******************************************************************/
-
-static NTSTATUS get_object_string(struct likewise_cell *c,
- LDAPMessage *msg,
- TALLOC_CTX *ctx,
- const char *attrib,
- char **string)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- char **keywords = NULL;
- size_t list_size = 0;
- TALLOC_CTX *frame = talloc_stackframe();
- ADS_STRUCT *ads = NULL;
-
- *string = NULL;
-
- ads = cell_connection(c);
-
- /* Deal with RFC2307 schema */
-
- if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
- *string = ads_pull_string(ads, ctx, msg, attrib);
- } else {
- /* Non-schema mode */
-
- char *s = NULL;
-
- keywords = ads_pull_strings(ads, frame, msg,
- "keywords", &list_size);
- if (!keywords) {
- nt_status = NT_STATUS_NO_MEMORY;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
- s = find_attr_string(keywords, list_size, attrib);
- if (s) {
- *string = talloc_strdup(ctx, s);
- }
- }
-
- if (!*string) {
- nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = NT_STATUS_OK;
-
-done:
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- Pull the struct passwd fields for a user
- *******************************************************************/
-
-static NTSTATUS pull_nss_info(struct likewise_cell *c,
- LDAPMessage *msg,
- TALLOC_CTX *ctx,
- const char **homedir,
- const char **shell,
- const char **gecos,
- gid_t *p_gid)
-{
- NTSTATUS nt_status;
- char *tmp;
-
- nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_HOMEDIR, &tmp);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- *homedir = tmp;
-
- nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_SHELL, &tmp);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- *shell = tmp;
-
- nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_GECOS, &tmp);
- /* Gecos is often not set so ignore failures */
- *gecos = tmp;
-
- nt_status = get_object_uint32(c, msg, ADEX_ATTR_GIDNUM, p_gid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/********************************************************************
- Pull the struct passwd fields for a user
- *******************************************************************/
-
-static NTSTATUS pull_alias(struct likewise_cell *c,
- LDAPMessage *msg,
- TALLOC_CTX *ctx,
- char **alias)
-{
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- enum id_type type;
- const char *attr = NULL;
-
- /* Figure out if this is a user or a group */
-
- nt_status = get_object_type(c, msg, &type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- switch (type) {
- case ID_TYPE_UID:
- attr = ADEX_ATTR_UID;
- break;
- case ID_TYPE_GID:
- /* What is the group attr for RFC2307 Forests? */
- attr = ADEX_ATTR_DISPLAYNAME;
- break;
- default:
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- break;
- }
-
- nt_status = get_object_string(c, msg, ctx, attr, alias);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS _ccp_get_sid_from_id(struct dom_sid * sid,
- uint32_t id, enum id_type type)
-{
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- NTSTATUS nt_status;
- struct lwcell_filter filter;
-
- filter.ftype = IdFilter;
- filter.filter.id.id = id;
- filter.filter.id.type = type;
-
- nt_status = search_cell_list(&cell, &msg, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = pull_sid(cell, msg, sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- ads_msgfree(cell->conn, msg);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS _ccp_get_id_from_sid(uint32_t * id,
- enum id_type *type,
- const struct dom_sid * sid)
-{
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- NTSTATUS nt_status;
- struct lwcell_filter filter;
-
- filter.ftype = SidFilter;
- sid_copy(&filter.filter.sid, sid);
-
- nt_status = search_cell_list(&cell, &msg, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = pull_id(cell, msg, id, type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (*id < min_id_value()) {
- nt_status = NT_STATUS_INVALID_PARAMETER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
-done:
- ads_msgfree(cell->conn, msg);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-static NTSTATUS _ccp_nss_get_info(const struct dom_sid * sid,
- TALLOC_CTX * ctx,
- const char **homedir,
- const char **shell,
- const char **gecos, gid_t * p_gid)
-{
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- NTSTATUS nt_status;
- struct lwcell_filter filter;
- enum id_type type;
-
- filter.ftype = SidFilter;
- sid_copy(&filter.filter.sid, sid);
-
- nt_status = search_cell_list(&cell, &msg, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = get_object_type(cell, msg, &type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (type != ID_TYPE_UID) {
- nt_status = NT_STATUS_NO_SUCH_USER;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- nt_status = pull_nss_info(cell, msg, ctx, homedir, shell, gecos,
- (uint32_t*) p_gid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- ads_msgfree(cell->conn, msg);
-
- return nt_status;
-}
-
-/**********************************************************************
- *********************************************************************/
-
-static NTSTATUS _ccp_map_to_alias(TALLOC_CTX *ctx,
- const char *domain,
- const char *name, char **alias)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct dom_sid sid;
- struct likewise_cell *cell = NULL;
- LDAPMessage *msg = NULL;
- struct lwcell_filter filter;
- enum lsa_SidType sid_type;
-
- /* Convert the name to a SID */
-
- nt_status = gc_name_to_sid(domain, name, &sid, &sid_type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Find the user/group */
-
- filter.ftype = SidFilter;
- sid_copy(&filter.filter.sid, &sid);
-
- nt_status = search_cell_list(&cell, &msg, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Pull the alias and return */
-
- nt_status = pull_alias(cell, msg, ctx, alias);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "map_to_alias", 3);
-
- talloc_destroy(frame);
- ads_msgfree(cell_connection(cell), msg);
-
- return nt_status;
-}
-
-/**********************************************************************
- Map from an alias name to the canonical, qualified name.
- Ensure that the alias is only pull from the closest in which
- the user or gorup is enabled in
- *********************************************************************/
-
-static NTSTATUS _ccp_map_from_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
- const char *alias, char **name)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- struct dom_sid sid;
- struct likewise_cell *cell_alias = NULL;
- LDAPMessage *msg_alias = NULL;
- struct likewise_cell *cell_sid = NULL;
- LDAPMessage *msg_sid = NULL;
- struct lwcell_filter filter;
- char *canonical_name = NULL;
- enum lsa_SidType type;
-
- /* Find the user/group */
-
- filter.ftype = AliasFilter;
- fstrcpy(filter.filter.alias, alias);
-
- nt_status = search_cell_list(&cell_alias, &msg_alias, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- nt_status = pull_sid(cell_alias, msg_alias, &sid);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- /* Now search again for the SID according to the cell list.
- Verify that the cell of both search results is the same
- so that we only match an alias from the closest cell
- in which a user/group has been instantied. */
-
- filter.ftype = SidFilter;
- sid_copy(&filter.filter.sid, &sid);
-
- nt_status = search_cell_list(&cell_sid, &msg_sid, &filter);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- if (cell_alias != cell_sid) {
- nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
- BAIL_ON_NTSTATUS_ERROR(nt_status);
- }
-
- /* Finally do the GC sid/name conversion */
-
- nt_status = gc_sid_to_name(&sid, &canonical_name, &type);
- BAIL_ON_NTSTATUS_ERROR(nt_status);
-
- *name = talloc_strdup(mem_ctx, canonical_name);
- BAIL_ON_PTR_ERROR((*name), nt_status);
-
- nt_status = NT_STATUS_OK;
-
-done:
- PRINT_NTSTATUS_ERROR(nt_status, "map_from_alias", 3);
-
- ads_msgfree(cell_connection(cell_alias), msg_alias);
- ads_msgfree(cell_connection(cell_sid), msg_sid);
-
- SAFE_FREE(canonical_name);
-
- talloc_destroy(frame);
-
- return nt_status;
-}
-
-/********************************************************************
- *******************************************************************/
-
-struct cell_provider_api ccp_unified = {
- .get_sid_from_id = _ccp_get_sid_from_id,
- .get_id_from_sid = _ccp_get_id_from_sid,
- .get_nss_info = _ccp_nss_get_info,
- .map_to_alias = _ccp_map_to_alias,
- .map_from_alias = _ccp_map_from_alias
-};