diff options
author | Andreas Schneider <asn@samba.org> | 2012-06-22 15:25:14 +0200 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2012-07-03 21:56:48 +0200 |
commit | e0e55ca166365783b88911db3affc4f97e5f4b56 (patch) | |
tree | e88186450b965723ab25aa5210d2c2e12c3f16d5 /source3/winbindd/idmap_adex | |
parent | a8acaeebb6336f608c5104122f79cea90c706a4b (diff) | |
download | samba-e0e55ca166365783b88911db3affc4f97e5f4b56.tar.gz samba-e0e55ca166365783b88911db3affc4f97e5f4b56.tar.bz2 samba-e0e55ca166365783b88911db3affc4f97e5f4b56.zip |
s3-winbind: Remove obsolte idmap_adex.
Diffstat (limited to 'source3/winbindd/idmap_adex')
-rw-r--r-- | source3/winbindd/idmap_adex/cell_util.c | 295 | ||||
-rw-r--r-- | source3/winbindd/idmap_adex/domain_util.c | 288 | ||||
-rw-r--r-- | source3/winbindd/idmap_adex/gc_util.c | 862 | ||||
-rw-r--r-- | source3/winbindd/idmap_adex/idmap_adex.c | 407 | ||||
-rw-r--r-- | source3/winbindd/idmap_adex/idmap_adex.h | 254 | ||||
-rw-r--r-- | source3/winbindd/idmap_adex/likewise_cell.c | 447 | ||||
-rw-r--r-- | source3/winbindd/idmap_adex/provider_unified.c | 1198 |
7 files changed, 0 insertions, 3751 deletions
diff --git a/source3/winbindd/idmap_adex/cell_util.c b/source3/winbindd/idmap_adex/cell_util.c deleted file mode 100644 index 194544086b..0000000000 --- a/source3/winbindd/idmap_adex/cell_util.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * idmap_adex: Support for 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 "../libds/common/flags.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_IDMAP - -/********************************************************************** -**********************************************************************/ - - char *find_attr_string(char **list, size_t num_lines, const char *substr) -{ - int i; - int cmplen = strlen(substr); - - for (i = 0; i < num_lines; i++) { - /* make sure to avoid substring matches like uid - and uidNumber */ - if ((strncasecmp_m(list[i], substr, cmplen) == 0) && - (list[i][cmplen] == '=')) { - /* Don't return an empty string */ - if (list[i][cmplen + 1] != '\0') - return &(list[i][cmplen + 1]); - - return NULL; - } - } - - return NULL; -} - -/********************************************************************** -**********************************************************************/ - - bool is_object_class(char **list, size_t num_lines, const char *substr) -{ - int i; - - for (i = 0; i < num_lines; i++) { - if (strequal(list[i], substr)) { - return true; - } - } - - return false; -} - -/********************************************************************** - Find out about the cell (e.g. use2307Attrs, etc...) -**********************************************************************/ - - NTSTATUS cell_lookup_settings(struct likewise_cell * cell) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - /* Parameter check */ - - if (!cell) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Only supporting Forest-wide, schema based searches */ - - cell_set_flags(cell, LWCELL_FLAG_USE_RFC2307_ATTRS); - cell_set_flags(cell, LWCELL_FLAG_SEARCH_FOREST); - - cell->provider = &ccp_unified; - - nt_status = NT_STATUS_OK; - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(1,("LWI: Failed to obtain cell settings (%s)\n", - nt_errstr(nt_status))); - } - - return nt_status; -} - - -static NTSTATUS cell_lookup_forest(struct likewise_cell *c) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct gc_info *gc = NULL; - - if (!c) { - return NT_STATUS_INVALID_PARAMETER; - } - - if ((gc = talloc_zero(NULL, struct gc_info)) == NULL) { - nt_status = NT_STATUS_NO_MEMORY; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Query the rootDSE for the forest root naming conect first. - Check that the a GC server for the forest has not already - been added */ - - nt_status = gc_find_forest_root(gc, cell_dns_domain(c)); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - c->forest_name = talloc_strdup(c, gc->forest_name); - BAIL_ON_PTR_ERROR(c->forest_name, nt_status); - -done: - if (gc) { - talloc_free(gc); - } - - return nt_status; -} - -/********************************************************************** -**********************************************************************/ - - NTSTATUS cell_locate_membership(ADS_STRUCT * ads) -{ - ADS_STATUS status; - char *domain_dn = ads_build_dn(lp_realm()); - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct dom_sid sid; - struct likewise_cell *cell = NULL; - - /* In the Likewise plugin, I had to support the concept of cells - based on the machine's membership in an OU. However, now I'll - just assume our membership in the forest cell */ - - DEBUG(2, ("locate_cell_membership: Located membership " - "in cell \"%s\"\n", domain_dn)); - - if ((cell = cell_new()) == NULL) { - nt_status = NT_STATUS_NO_MEMORY; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - status = ads_domain_sid(ads, &sid); - if (!ADS_ERR_OK(status)) { - DEBUG(3,("locate_cell_membership: Failed to find " - "domain SID for %s\n", domain_dn)); - } - - /* save the SID and search base for our domain */ - - cell_set_dns_domain(cell, lp_realm()); - cell_set_connection(cell, ads); - cell_set_dn(cell, domain_dn); - cell_set_domain_sid(cell, &sid); - - /* Now save our forest root */ - - cell_lookup_forest(cell); - - /* Add the cell to the list */ - - if (!cell_list_add(cell)) { - nt_status = NT_STATUS_INSUFFICIENT_RESOURCES; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Done! */ - nt_status = NT_STATUS_OK; - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("LWI: Failed to locate cell membership (%s)\n", - nt_errstr(nt_status))); - } - - SAFE_FREE(domain_dn); - - return nt_status; -} - -/********************************************************************* - ********************************************************************/ - - int min_id_value(void) -{ - int id_val; - - id_val = lp_parm_int(-1, "lwidentity", "min_id_value", MIN_ID_VALUE); - - /* Still don't let it go below 50 */ - - return MAX(50, id_val); -} - -/******************************************************************** - *******************************************************************/ - - char *cell_dn_to_dns(const char *dn) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - char *domain = NULL; - char *dns_name = NULL; - const char *tmp_dn; - char *buffer = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!dn || !*dn) { - goto done; - } - - tmp_dn = talloc_strdup(frame, dn); - BAIL_ON_PTR_ERROR(tmp_dn, nt_status); - - while (next_token_talloc(frame, &tmp_dn, &buffer, ",")) { - - /* skip everything up the where DC=... begins */ - if (strncasecmp_m(buffer, "DC=", 3) != 0) - continue; - - if (!domain) { - domain = talloc_strdup(frame, &buffer[3]); - } else { - domain = talloc_asprintf_append(domain, ".%s", - &buffer[3]); - } - BAIL_ON_PTR_ERROR(domain, nt_status); - } - - dns_name = SMB_STRDUP(domain); - BAIL_ON_PTR_ERROR(dns_name, nt_status); - - nt_status = NT_STATUS_OK; - -done: - PRINT_NTSTATUS_ERROR(nt_status, "cell_dn_to_dns", 1); - - talloc_destroy(frame); - - return dns_name; -} - -/********************************************************************* - ********************************************************************/ - - NTSTATUS get_sid_type(ADS_STRUCT *ads, - LDAPMessage *msg, - enum lsa_SidType *type) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32_t atype; - - if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) { - nt_status = NT_STATUS_INVALID_USER_BUFFER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - switch (atype &0xF0000000) { - case ATYPE_SECURITY_GLOBAL_GROUP: - *type = SID_NAME_DOM_GRP; - break; - case ATYPE_SECURITY_LOCAL_GROUP: - *type = SID_NAME_ALIAS; - break; - case ATYPE_NORMAL_ACCOUNT: - case ATYPE_WORKSTATION_TRUST: - case ATYPE_INTERDOMAIN_TRUST: - *type = SID_NAME_USER; - break; - default: - *type = SID_NAME_USE_NONE; - nt_status = NT_STATUS_INVALID_ACCOUNT_NAME; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - nt_status = NT_STATUS_OK; - -done: - return nt_status; -} diff --git a/source3/winbindd/idmap_adex/domain_util.c b/source3/winbindd/idmap_adex/domain_util.c deleted file mode 100644 index 99dc0cca65..0000000000 --- a/source3/winbindd/idmap_adex/domain_util.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * idmap_adex: Domain search interface - * - * Copyright (C) Gerald (Jerry) Carter 2007-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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_IDMAP - -struct dc_info { - struct dc_info *prev, *next; - char *dns_name; - struct likewise_cell *domain_cell; -}; - -static struct dc_info *_dc_server_list = NULL; - - -/********************************************************************** - *********************************************************************/ - -static struct dc_info *dc_list_head(void) -{ - return _dc_server_list; -} - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS dc_add_domain(const char *domain) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct dc_info *dc = NULL; - - if (!domain) { - return NT_STATUS_INVALID_PARAMETER; - } - - DEBUG(10,("dc_add_domain: Attempting to add domain %s\n", domain)); - - /* Check for duplicates */ - - dc = dc_list_head(); - while (dc) { - if (strequal (dc->dns_name, domain)) - break; - dc = dc->next; - } - - if (dc) { - DEBUG(10,("dc_add_domain: %s already in list\n", domain)); - return NT_STATUS_OK; - } - - dc = talloc_zero(NULL, struct dc_info); - BAIL_ON_PTR_ERROR(dc, nt_status); - - dc->dns_name = talloc_strdup(dc, domain); - BAIL_ON_PTR_ERROR(dc->dns_name, nt_status); - - DLIST_ADD_END(_dc_server_list, dc, struct dc_info*); - - nt_status = NT_STATUS_OK; - - DEBUG(5,("dc_add_domain: Successfully added %s\n", domain)); - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_destroy(dc); - DEBUG(0,("LWI: Failed to add new DC connection for %s (%s)\n", - domain, nt_errstr(nt_status))); - } - - return nt_status; -} - -/********************************************************************** - *********************************************************************/ - -static void dc_server_list_destroy(void) -{ - struct dc_info *dc = dc_list_head(); - - while (dc) { - struct dc_info *p = dc->next; - - cell_destroy(dc->domain_cell); - talloc_destroy(dc); - - dc = p; - } - - return; -} - - -/********************************************************************** - *********************************************************************/ - - NTSTATUS domain_init_list(void) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct winbindd_tdc_domain *domains = NULL; - size_t num_domains = 0; - int i; - - if (_dc_server_list != NULL) { - dc_server_list_destroy(); - } - - /* Add our domain */ - - nt_status = dc_add_domain(lp_realm()); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - if (!wcache_tdc_fetch_list(&domains, &num_domains)) { - nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Add all domains with an incoming trust path */ - - for (i=0; i<num_domains; i++) { - uint32_t flags = (NETR_TRUST_FLAG_INBOUND|NETR_TRUST_FLAG_IN_FOREST); - - /* We just require one of the flags to be set here */ - - if (domains[i].trust_flags & flags) { - nt_status = dc_add_domain(domains[i].dns_name); - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - } - - nt_status = NT_STATUS_OK; - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2,("LWI: Failed to initialize DC list (%s)\n", - nt_errstr(nt_status))); - } - - TALLOC_FREE(domains); - - return nt_status; -} - -/******************************************************************** - *******************************************************************/ - -static NTSTATUS dc_do_search(struct dc_info *dc, - const char *search_base, - int scope, - const char *expr, - const char **attrs, - LDAPMessage ** msg) -{ - ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - status = cell_do_search(dc->domain_cell, search_base, - scope, expr, attrs, msg); - nt_status = ads_ntstatus(status); - - return nt_status; -} - -/********************************************************************** - *********************************************************************/ - -static struct dc_info *dc_find_domain(const char *dns_domain) -{ - struct dc_info *dc = dc_list_head(); - - if (!dc) - return NULL; - - while (dc) { - if (strequal(dc->dns_name, dns_domain)) { - return dc; - } - - dc = dc->next; - } - - return NULL; -} - -/********************************************************************** - *********************************************************************/ - - NTSTATUS dc_search_domains(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(); - char *dns_domain; - const char *attrs[] = { "*", NULL }; - struct dc_info *dc = NULL; - const char *base = NULL; - - if (!dn || !*dn) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - dns_domain = cell_dn_to_dns(dn); - BAIL_ON_PTR_ERROR(dns_domain, nt_status); - - if ((dc = dc_find_domain(dns_domain)) == NULL) { - nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Reparse the cell settings for the domain if necessary */ - - if (!dc->domain_cell) { - char *base_dn; - - base_dn = ads_build_dn(dc->dns_name); - BAIL_ON_PTR_ERROR(base_dn, nt_status); - - nt_status = cell_connect_dn(&dc->domain_cell, base_dn); - SAFE_FREE(base_dn); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - nt_status = cell_lookup_settings(dc->domain_cell); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - /* By definition this is already part of a larger - forest-wide search scope */ - - cell_set_flags(dc->domain_cell, LWCELL_FLAG_SEARCH_FOREST); - } - - /* Check whether we are operating in non-schema or RFC2307 - mode */ - - if (cell_flags(dc->domain_cell) & LWCELL_FLAG_USE_RFC2307_ATTRS) { - nt_status = dc_do_search(dc, dn, LDAP_SCOPE_BASE, - "(objectclass=*)", attrs, msg); - } else { - const char *sid_str = NULL; - char *filter = NULL; - - sid_str = sid_string_talloc(frame, sid); - BAIL_ON_PTR_ERROR(sid_str, nt_status); - - filter = talloc_asprintf(frame, "(keywords=backLink=%s)", - sid_str); - BAIL_ON_PTR_ERROR(filter, nt_status); - - base = cell_search_base(dc->domain_cell); - BAIL_ON_PTR_ERROR(base, nt_status); - - nt_status = dc_do_search(dc, base, LDAP_SCOPE_SUBTREE, - filter, attrs, msg); - } - BAIL_ON_NTSTATUS_ERROR(nt_status); - - *cell = dc->domain_cell; - -done: - talloc_destroy(discard_const_p(char, base)); - talloc_destroy(frame); - - return nt_status; -} diff --git a/source3/winbindd/idmap_adex/gc_util.c b/source3/winbindd/idmap_adex/gc_util.c deleted file mode 100644 index 461a2e679b..0000000000 --- a/source3/winbindd/idmap_adex/gc_util.c +++ /dev/null @@ -1,862 +0,0 @@ -/* - * idmap_adex: Global Catalog search interface - * - * Copyright (C) Gerald (Jerry) Carter 2007-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 "libads/cldap.h" -#include "../libcli/ldap/ldap_ndr.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_IDMAP - -static struct gc_info *_gc_server_list = NULL; - - -/********************************************************************** - *********************************************************************/ - -static struct gc_info *gc_list_head(void) -{ - return _gc_server_list; -} - -/********************************************************************** - Checks if either of the domains is a subdomain of the other - *********************************************************************/ - -static bool is_subdomain(const char* a, const char *b) -{ - char *s; - TALLOC_CTX *frame = talloc_stackframe(); - char *x, *y; - bool ret = false; - - /* Trivial cases */ - - if (!a && !b) - return true; - - if (!a || !b) - return false; - - /* Normalize the case */ - - x = talloc_strdup(frame, a); - y = talloc_strdup(frame, b); - if (!x || !y) { - ret = false; - goto done; - } - - strupper_m(x); - strupper_m(y); - - /* Exact match */ - - if (strcmp(x, y) == 0) { - ret = true; - goto done; - } - - /* Check for trailing substrings */ - - s = strstr_m(x, y); - if (s && (strlen(s) == strlen(y))) { - ret = true; - goto done; - } - - s = strstr_m(y, x); - if (s && (strlen(s) == strlen(x))) { - ret = true; - goto done; - } - -done: - talloc_destroy(frame); - - return ret; -} - -/********************************************************************** - *********************************************************************/ - - NTSTATUS gc_find_forest_root(struct gc_info *gc, const char *domain) -{ - ADS_STRUCT *ads = NULL; - ADS_STATUS ads_status; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply; - TALLOC_CTX *frame = talloc_stackframe(); - struct sockaddr_storage ss; - - if (!gc || !domain) { - return NT_STATUS_INVALID_PARAMETER; - } - - ZERO_STRUCT(cldap_reply); - - ads = ads_init(domain, NULL, NULL); - BAIL_ON_PTR_ERROR(ads, nt_status); - - ads->auth.flags = ADS_AUTH_NO_BIND; - ads_status = ads_connect(ads); - if (!ADS_ERR_OK(ads_status)) { - DEBUG(4, ("find_forest_root: ads_connect(%s) failed! (%s)\n", - domain, ads_errstr(ads_status))); - } - nt_status = ads_ntstatus(ads_status); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - if (!resolve_name(ads->config.ldap_server_name, &ss, 0x20, true)) { - DEBUG(5,("gc_find_forest_root: unable to resolve name %s\n", - ads->config.ldap_server_name)); - nt_status = NT_STATUS_IO_TIMEOUT; - /* This matches the old code which did the resolve in - * ads_cldap_netlogon_5 */ - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - if (!ads_cldap_netlogon_5(frame, - &ss, - ads->config.realm, - &cldap_reply)) - { - DEBUG(4,("find_forest_root: Failed to get a CLDAP reply from %s!\n", - ads->server.ldap_server)); - nt_status = NT_STATUS_IO_TIMEOUT; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - gc->forest_name = talloc_strdup(gc, cldap_reply.forest); - BAIL_ON_PTR_ERROR(gc->forest_name, nt_status); - -done: - if (ads) { - ads_destroy(&ads); - } - - return nt_status; -} - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS gc_add_forest(const char *domain) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct gc_info *gc = NULL; - struct gc_info *find_gc = NULL; - char *dn; - ADS_STRUCT *ads = NULL; - struct likewise_cell *primary_cell = NULL; - - primary_cell = cell_list_head(); - if (!primary_cell) { - nt_status = NT_STATUS_INVALID_SERVER_STATE; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Check for duplicates based on domain name first as this - requires no connection */ - - find_gc = gc_list_head(); - while (find_gc) { - if (strequal (find_gc->forest_name, domain)) - break; - find_gc = find_gc->next; - } - - if (find_gc) { - DEBUG(10,("gc_add_forest: %s already in list\n", find_gc->forest_name)); - return NT_STATUS_OK; - } - - if ((gc = talloc_zero(NULL, struct gc_info)) == NULL) { - nt_status = NT_STATUS_NO_MEMORY; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Query the rootDSE for the forest root naming conect first. - Check that the a GC server for the forest has not already - been added */ - - nt_status = gc_find_forest_root(gc, domain); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - find_gc = gc_list_head(); - while (find_gc) { - if (strequal (find_gc->forest_name, gc->forest_name)) - break; - find_gc = find_gc->next; - } - - if (find_gc) { - DEBUG(10,("gc_add_forest: Forest %s already in list\n", - find_gc->forest_name)); - return NT_STATUS_OK; - } - - /* Not found, so add it here. Make sure we connect to - a DC in _this_ domain and not the forest root. */ - - dn = ads_build_dn(gc->forest_name); - BAIL_ON_PTR_ERROR(dn, nt_status); - - gc->search_base = talloc_strdup(gc, dn); - SAFE_FREE(dn); - BAIL_ON_PTR_ERROR(gc->search_base, nt_status); - -#if 0 - /* Can't use cell_connect_dn() here as there is no way to - specifiy the LWCELL_FLAG_GC_CELL flag setting for cell_connect() */ - - nt_status = cell_connect_dn(&gc->forest_cell, gc->search_base); - BAIL_ON_NTSTATUS_ERROR(nt_status); -#else - - gc->forest_cell = cell_new(); - BAIL_ON_PTR_ERROR(gc->forest_cell, nt_status); - - /* Set the DNS domain, dn, etc ... and add it to the list */ - - cell_set_dns_domain(gc->forest_cell, gc->forest_name); - cell_set_dn(gc->forest_cell, gc->search_base); - cell_set_flags(gc->forest_cell, LWCELL_FLAG_GC_CELL); -#endif - - /* It is possible to belong to a non-forest cell and a - non-provisioned forest (at our domain levele). In that - case, we should just inherit the flags from our primary - cell since the GC searches will match our own schema - model. */ - - if (strequal(primary_cell->forest_name, gc->forest_name) - || is_subdomain(primary_cell->dns_domain, gc->forest_name)) - { - cell_set_flags(gc->forest_cell, cell_flags(primary_cell)); - } else { - /* outside of our domain */ - - nt_status = cell_connect(gc->forest_cell); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - nt_status = cell_lookup_settings(gc->forest_cell); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - /* Drop the connection now that we have the settings */ - - ads = cell_connection(gc->forest_cell); - ads_destroy(&ads); - cell_set_connection(gc->forest_cell, NULL); - } - - DLIST_ADD_END(_gc_server_list, gc, struct gc_info*); - - DEBUG(10,("gc_add_forest: Added %s to Global Catalog list of servers\n", - gc->forest_name)); - - nt_status = NT_STATUS_OK; - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_destroy(gc); - DEBUG(3,("LWI: Failed to add new GC connection for %s (%s)\n", - domain, nt_errstr(nt_status))); - } - - return nt_status; -} - -/********************************************************************** - *********************************************************************/ - -static void gc_server_list_destroy(void) -{ - struct gc_info *gc = gc_list_head(); - - while (gc) { - struct gc_info *p = gc->next; - - cell_destroy(gc->forest_cell); - talloc_destroy(gc); - - gc = p; - } - - _gc_server_list = NULL; - - return; -} - -/********************************************************************** - Setup the initial list of forests and initial the forest cell - settings for each. FIXME!!! - *********************************************************************/ - - NTSTATUS gc_init_list(void) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct winbindd_tdc_domain *domains = NULL; - size_t num_domains = 0; - int i; - - if (_gc_server_list != NULL) { - gc_server_list_destroy(); - } - - if (!wcache_tdc_fetch_list(&domains, &num_domains)) { - nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Find our forest first. Have to try all domains here starting - with our own. gc_add_forest() filters duplicates */ - - nt_status = gc_add_forest(lp_realm()); - WARN_ON_NTSTATUS_ERROR(nt_status); - - for (i=0; i<num_domains; i++) { - uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST); - - /* I think we should be able to break out of loop once - we add a GC for our forest and not have to test every one. - In fact, this entire loop is probably irrelevant since - the GC location code should always find a GC given lp_realm(). - Will have to spend time testing before making the change. - --jerry */ - - if ((domains[i].trust_flags & flags) == flags) { - nt_status = gc_add_forest(domains[i].dns_name); - WARN_ON_NTSTATUS_ERROR(nt_status); - /* Don't BAIL here since not every domain may - have a GC server */ - } - } - - /* Now add trusted forests. gc_add_forest() will filter out - duplicates. Check everything with an incoming trust path - that is not in our own forest. */ - - for (i=0; i<num_domains; i++) { - uint32_t flags = domains[i].trust_flags; - uint32_t attribs = domains[i].trust_attribs; - - /* Skip non_AD domains */ - - if (strlen(domains[i].dns_name) == 0) { - continue; - } - - /* Only add a GC for a forest outside of our own. - Ignore QUARANTINED/EXTERNAL trusts */ - - if ((flags & NETR_TRUST_FLAG_INBOUND) - && !(flags & NETR_TRUST_FLAG_IN_FOREST) - && (attribs & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) - { - nt_status = gc_add_forest(domains[i].dns_name); - WARN_ON_NTSTATUS_ERROR(nt_status); - } - } - - nt_status = NT_STATUS_OK; - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2,("LWI: Failed to initialized GC list (%s)\n", - nt_errstr(nt_status))); - } - - TALLOC_FREE(domains); - - return nt_status; -} - - -/********************************************************************** - *********************************************************************/ - - struct gc_info *gc_search_start(void) -{ - NTSTATUS nt_status = NT_STATUS_OK; - struct gc_info *gc = gc_list_head(); - - if (!gc) { - nt_status = gc_init_list(); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - gc = gc_list_head(); - } - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2,("LWI: Failed to initialize GC list (%s)\n", - nt_errstr(nt_status))); - } - - return gc; -} - -/********************************************************************** - Search Global Catalog. Always search our own forest. The flags set - controls whether or not we search cross forest. Assume that the - resulting set is always returned from one GC so that we don't have to - both combining the LDAPMessage * results - *********************************************************************/ - - NTSTATUS gc_search_forest(struct gc_info *gc, - LDAPMessage **msg, - const char *filter) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); - const char *attrs[] = {"*", NULL}; - LDAPMessage *m = NULL; - - if (!gc || !msg || !filter) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* When you have multiple domain trees in a forest, the - GC will search all naming contexts when you send it - and empty ("") base search suffix. Tested against - Windows 2003. */ - - ads_status = cell_do_search(gc->forest_cell, "", - LDAP_SCOPE_SUBTREE, filter, attrs, &m); - nt_status = ads_ntstatus(ads_status); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - *msg = m; - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2,("LWI: Forest wide search %s failed (%s)\n", - filter, nt_errstr(nt_status))); - } - - return nt_status; -} - -/********************************************************************** - Search all forests via GC and return the results in an array of - ADS_STRUCT/LDAPMessage pairs. - *********************************************************************/ - - NTSTATUS gc_search_all_forests(const char *filter, - ADS_STRUCT ***ads_list, - LDAPMessage ***msg_list, - int *num_resp, uint32_t flags) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct gc_info *gc = NULL; - uint32_t test_flags = ADEX_GC_SEARCH_CHECK_UNIQUE; - - *ads_list = NULL; - *msg_list = NULL; - *num_resp = 0; - - if ((gc = gc_search_start()) == NULL) { - nt_status = NT_STATUS_INVALID_DOMAIN_STATE; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - while (gc) { - LDAPMessage *m = NULL; - - 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); - - /* If there can only be one match, then we are done */ - - if ((*num_resp > 0) && ((flags & test_flags) == test_flags)) { - break; - } - - gc = gc->next; - } - - if (*num_resp == 0) { - nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - nt_status = NT_STATUS_OK; - -done: - return nt_status; -} - -/********************************************************************** - Search all forests via GC and return the results in an array of - ADS_STRUCT/LDAPMessage pairs. - *********************************************************************/ - - NTSTATUS gc_search_all_forests_unique(const char *filter, - ADS_STRUCT **ads, - LDAPMessage **msg) -{ - ADS_STRUCT **ads_list = NULL; - LDAPMessage **msg_list = NULL; - int num_resp; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - nt_status = gc_search_all_forests(filter, &ads_list, - &msg_list, &num_resp, - ADEX_GC_SEARCH_CHECK_UNIQUE); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - nt_status = check_result_unique(ads_list[0], msg_list[0]); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - *ads = ads_list[0]; - *msg = msg_list[0]; - -done: - /* Be care that we don't free the msg result being returned */ - - if (!NT_STATUS_IS_OK(nt_status)) { - free_result_array(ads_list, msg_list, num_resp); - } else { - talloc_destroy(ads_list); - talloc_destroy(msg_list); - } - - return nt_status; -} - -/********************************************************************* - ********************************************************************/ - - NTSTATUS gc_name_to_sid(const char *domain, - const char *name, - struct dom_sid *sid, - enum lsa_SidType *sid_type) -{ - TALLOC_CTX *frame = talloc_stackframe(); - char *p, *name_user; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - char *name_filter; - ADS_STRUCT *ads = NULL; - LDAPMessage *msg = NULL; - LDAPMessage *e = NULL; - char *dn = NULL; - char *dns_domain = NULL; - ADS_STRUCT **ads_list = NULL; - LDAPMessage **msg_list = NULL; - int num_resp = 0; - int i; - - /* Strip the "DOMAIN\" prefix if necessary and search for - a matching sAMAccountName in the forest */ - - if ((p = strchr_m( name, '\\' )) == NULL) - name_user = talloc_strdup( frame, name ); - else - name_user = talloc_strdup( frame, p+1 ); - BAIL_ON_PTR_ERROR(name_user, nt_status); - - name_filter = talloc_asprintf(frame, "(sAMAccountName=%s)", name_user); - BAIL_ON_PTR_ERROR(name_filter, nt_status); - - nt_status = gc_search_all_forests(name_filter, &ads_list, - &msg_list, &num_resp, 0); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - /* Assume failure until we know otherwise*/ - - nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - - /* Match the domain name from the DN */ - - for (i=0; i<num_resp; i++) { - ads = ads_list[i]; - msg = msg_list[i]; - - e = ads_first_entry(ads, msg); - while (e) { - struct winbindd_tdc_domain *domain_rec; - - dn = ads_get_dn(ads, frame, e); - BAIL_ON_PTR_ERROR(dn, nt_status); - - dns_domain = cell_dn_to_dns(dn); - TALLOC_FREE(dn); - BAIL_ON_PTR_ERROR(dns_domain, nt_status); - - domain_rec = wcache_tdc_fetch_domain(frame, dns_domain); - SAFE_FREE(dns_domain); - - /* Ignore failures and continue the search */ - - if (!domain_rec) { - e = ads_next_entry(ads, e); - continue; - } - - /* Check for a match on the domain name */ - - if (strequal(domain, domain_rec->domain_name)) { - if (!ads_pull_sid(ads, e, "objectSid", sid)) { - nt_status = NT_STATUS_INVALID_SID; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - talloc_destroy(domain_rec); - - nt_status = get_sid_type(ads, msg, sid_type); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - /* We're done! */ - nt_status = NT_STATUS_OK; - break; - } - - /* once more around thew merry-go-round */ - - talloc_destroy(domain_rec); - e = ads_next_entry(ads, e); - } - } - -done: - free_result_array(ads_list, msg_list, num_resp); - talloc_destroy(frame); - - return nt_status; -} - -/******************************************************************** - Pull an attribute string value - *******************************************************************/ - -static NTSTATUS get_object_account_name(ADS_STRUCT *ads, - LDAPMessage *msg, - char **name) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - char *sam_name = NULL; - struct winbindd_tdc_domain *domain_rec = NULL; - char *dns_domain = NULL; - char *dn = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - int len; - - /* Check parameters */ - - if (!ads || !msg || !name) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* get the name and domain */ - - dn = ads_get_dn(ads, frame, msg); - BAIL_ON_PTR_ERROR(dn, nt_status); - - DEBUG(10,("get_object_account_name: dn = \"%s\"\n", dn)); - - dns_domain = cell_dn_to_dns(dn); - TALLOC_FREE(dn); - BAIL_ON_PTR_ERROR(dns_domain, nt_status); - - domain_rec = wcache_tdc_fetch_domain(frame, dns_domain); - SAFE_FREE(dns_domain); - - if (!domain_rec) { - nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - sam_name = ads_pull_string(ads, frame, msg, "sAMAccountName"); - BAIL_ON_PTR_ERROR(sam_name, nt_status); - - len = asprintf(name, "%s\\%s", domain_rec->domain_name, sam_name); - if (len == -1) { - *name = NULL; - BAIL_ON_PTR_ERROR((*name), nt_status); - } - - nt_status = NT_STATUS_OK; - -done: - talloc_destroy(frame); - - return nt_status; -} - -/********************************************************************* - ********************************************************************/ - - NTSTATUS gc_sid_to_name(const struct dom_sid *sid, - char **name, - enum lsa_SidType *sid_type) -{ - TALLOC_CTX *frame = talloc_stackframe(); - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - char *filter; - ADS_STRUCT *ads = NULL; - LDAPMessage *msg = NULL; - char *sid_string; - - *name = NULL; - - sid_string = ldap_encode_ndr_dom_sid(frame, sid); - BAIL_ON_PTR_ERROR(sid_string, nt_status); - - filter = talloc_asprintf(frame, "(objectSid=%s)", sid_string); - TALLOC_FREE(sid_string); - BAIL_ON_PTR_ERROR(filter, nt_status); - - nt_status = gc_search_all_forests_unique(filter, &ads, &msg); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - nt_status = get_object_account_name(ads, msg, name); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - nt_status = get_sid_type(ads, msg, sid_type); - BAIL_ON_NTSTATUS_ERROR(nt_status); - -done: - ads_msgfree(ads, msg); - talloc_destroy(frame); - - return nt_status; -} - -/********************************************************************** - *********************************************************************/ - - NTSTATUS add_ads_result_to_array(ADS_STRUCT *ads, - LDAPMessage *msg, - ADS_STRUCT ***ads_list, - LDAPMessage ***msg_list, - int *size) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - ADS_STRUCT **ads_tmp = NULL; - LDAPMessage **msg_tmp = NULL; - int count = *size; - - if (!ads || !msg) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - -#if 0 - /* Don't add a response with no entries */ - - if (ads_count_replies(ads, msg) == 0) { - return NT_STATUS_OK; - } -#endif - - if (count == 0) { - ads_tmp = talloc_array(NULL, ADS_STRUCT*, 1); - BAIL_ON_PTR_ERROR(ads_tmp, nt_status); - - msg_tmp = talloc_array(NULL, LDAPMessage*, 1); - BAIL_ON_PTR_ERROR(msg_tmp, nt_status); - } else { - ads_tmp = talloc_realloc(*ads_list, *ads_list, ADS_STRUCT*, - count+1); - BAIL_ON_PTR_ERROR(ads_tmp, nt_status); - - msg_tmp = talloc_realloc(*msg_list, *msg_list, LDAPMessage*, - count+1); - BAIL_ON_PTR_ERROR(msg_tmp, nt_status); - } - - ads_tmp[count] = ads; - msg_tmp[count] = msg; - count++; - - *ads_list = ads_tmp; - *msg_list = msg_tmp; - *size = count; - - nt_status = NT_STATUS_OK; - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - talloc_destroy(ads_tmp); - talloc_destroy(msg_tmp); - } - - return nt_status; -} - -/********************************************************************** - Frees search results. Do not free the ads_list as these are - references back to the GC search structures. - *********************************************************************/ - - void free_result_array(ADS_STRUCT **ads_list, - LDAPMessage **msg_list, - int num_resp) -{ - int i; - - for (i=0; i<num_resp; i++) { - ads_msgfree(ads_list[i], msg_list[i]); - } - - talloc_destroy(ads_list); - talloc_destroy(msg_list); -} - -/********************************************************************** - Check that we have exactly one entry from the search - *********************************************************************/ - - NTSTATUS check_result_unique(ADS_STRUCT *ads, LDAPMessage *msg) -{ - NTSTATUS nt_status; - int count; - - count = ads_count_replies(ads, msg); - - if (count <= 0) { - 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); - } - - nt_status = NT_STATUS_OK; - -done: - return nt_status; -} diff --git a/source3/winbindd/idmap_adex/idmap_adex.c b/source3/winbindd/idmap_adex/idmap_adex.c deleted file mode 100644 index d64487a2d6..0000000000 --- a/source3/winbindd/idmap_adex/idmap_adex.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * idmap_adex: Support for D 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 "nss_info.h" -#include "secrets.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_IDMAP - -#define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache" - -/* - * IdMap backend - */ - -/******************************************************************** - Basic init function responsible for determining our current mode - (standalone or using Centeris Cells). This must return success or - it will be dropped from the idmap backend list. - *******************************************************************/ - -static NTSTATUS _idmap_adex_init(struct idmap_domain *dom) -{ - ADS_STRUCT *ads = NULL; - ADS_STATUS status; - static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - struct dom_sid domain_sid; - fstring dcname; - struct sockaddr_storage ip; - struct likewise_cell *lwcell; - - if (NT_STATUS_IS_OK(init_status)) - return NT_STATUS_OK; - - /* Silently fail if we are not a member server in security = ads */ - - if ((lp_server_role() != ROLE_DOMAIN_MEMBER) || - (lp_security() != SEC_ADS)) { - init_status = NT_STATUS_INVALID_SERVER_STATE; - BAIL_ON_NTSTATUS_ERROR(init_status); - } - - /* fetch our domain SID first */ - - if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { - init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - BAIL_ON_NTSTATUS_ERROR(init_status); - } - - /* reuse the same ticket cache as winbindd */ - - setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); - - /* Establish a connection to a DC */ - - if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) { - init_status = NT_STATUS_NO_MEMORY; - BAIL_ON_NTSTATUS_ERROR(init_status); - } - - ads->auth.password = - secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - ads->auth.realm = SMB_STRDUP(lp_realm()); - - /* get the DC name here to setup the server affinity cache and - local krb5.conf */ - - get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip); - - status = ads_connect(ads); - if (!ADS_ERR_OK(status)) { - DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n", - ads_errstr(status))); - } - init_status = ads_ntstatus(status); - BAIL_ON_NTSTATUS_ERROR(init_status); - - - /* Find out cell membership */ - - init_status = cell_locate_membership(ads); - if (!NT_STATUS_IS_OK(init_status)) { - DEBUG(0,("LWI: Fail to locate cell membership (%s).", - nt_errstr(init_status))); - goto done; - } - - /* Fill in the cell information */ - - lwcell = cell_list_head(); - - init_status = cell_lookup_settings(lwcell); - BAIL_ON_NTSTATUS_ERROR(init_status); - - /* Miscellaneous setup. E.g. set up the list of GC - servers and domain list for our forest (does not actually - connect). */ - - init_status = gc_init_list(); - BAIL_ON_NTSTATUS_ERROR(init_status); - - init_status = domain_init_list(); - BAIL_ON_NTSTATUS_ERROR(init_status); - -done: - if (!NT_STATUS_IS_OK(init_status)) { - DEBUG(1,("Likewise initialization failed (%s)\n", - nt_errstr(init_status))); - } - - /* cleanup */ - - if (!NT_STATUS_IS_OK(init_status)) { - cell_list_destroy(); - - /* init_status stores the failure reason but we need to - return success or else idmap_init() will drop us from the - backend list */ - return NT_STATUS_OK; - } - - init_status = NT_STATUS_OK; - - return init_status; -} - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS _idmap_adex_get_sid_from_id(struct - idmap_domain - *dom, struct - id_map - **ids) -{ - int i; - NTSTATUS nt_status; - struct likewise_cell *cell; - - /* initialize the status to avoid suprise */ - for (i = 0; ids[i]; i++) { - ids[i]->status = ID_UNKNOWN; - } - - nt_status = _idmap_adex_init(dom); - if (!NT_STATUS_IS_OK(nt_status)) - return nt_status; - - if ((cell = cell_list_head()) == NULL) { - return NT_STATUS_INVALID_SERVER_STATE; - } - - /* have to work through these one by one */ - for (i = 0; ids[i]; i++) { - NTSTATUS status; - status = cell->provider->get_sid_from_id(ids[i]->sid, - ids[i]->xid.id, - ids[i]->xid.type); - /* Fail if we cannot find any DC */ - if (NT_STATUS_EQUAL - (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { - return status; - } - - if (!NT_STATUS_IS_OK(status)) { - ids[i]->status = ID_UNMAPPED; - continue; - } - - ids[i]->status = ID_MAPPED; - } - - return NT_STATUS_OK; -} - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS _idmap_adex_get_id_from_sid(struct - idmap_domain - *dom, struct - id_map - **ids) -{ - int i; - NTSTATUS nt_status; - struct likewise_cell *cell; - - /* initialize the status to avoid suprise */ - for (i = 0; ids[i]; i++) { - ids[i]->status = ID_UNKNOWN; - } - - nt_status = _idmap_adex_init(dom); - if (!NT_STATUS_IS_OK(nt_status)) - return nt_status; - - if ((cell = cell_list_head()) == NULL) { - return NT_STATUS_INVALID_SERVER_STATE; - } - - /* have to work through these one by one */ - for (i = 0; ids[i]; i++) { - NTSTATUS status; - status = cell->provider->get_id_from_sid(&ids[i]->xid.id, - &ids[i]->xid. - type, ids[i]->sid); - /* Fail if we cannot find any DC */ - if (NT_STATUS_EQUAL - (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { - return status; - } - - if (!NT_STATUS_IS_OK(status)) { - ids[i]->status = ID_UNMAPPED; - continue; - } - - ids[i]->status = ID_MAPPED; - } - - return NT_STATUS_OK; -} - -/* - * IdMap NSS plugin - */ - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS _nss_adex_init(struct nss_domain_entry - *e) -{ - return _idmap_adex_init(NULL); -} - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS _nss_adex_get_info(struct - nss_domain_entry *e, - const struct dom_sid * sid, - TALLOC_CTX * ctx, - const char **homedir, - const char **shell, - const char **gecos, gid_t * p_gid) -{ - NTSTATUS nt_status; - struct likewise_cell *cell; - - nt_status = _idmap_adex_init(NULL); - if (!NT_STATUS_IS_OK(nt_status)) - return nt_status; - - if ((cell = cell_list_head()) == NULL) { - return NT_STATUS_INVALID_SERVER_STATE; - } - - return cell->provider->get_nss_info(sid, ctx, homedir, - shell, gecos, p_gid); -} - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx, - struct nss_domain_entry *e, - const char *name, char **alias) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct likewise_cell *cell = NULL; - - nt_status = _idmap_adex_init(NULL); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - if ((cell = cell_list_head()) == NULL) { - nt_status = NT_STATUS_INVALID_SERVER_STATE; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - nt_status = cell->provider->map_to_alias(mem_ctx, e->domain, - name, alias); - - /* go ahead and allow the cache mgr to mark this in - negative cache */ - - if (!NT_STATUS_IS_OK(nt_status)) - nt_status = NT_STATUS_NONE_MAPPED; - -done: - return nt_status; -} - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, - struct nss_domain_entry *e, - const char *alias, char **name) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct likewise_cell *cell = NULL; - - nt_status = _idmap_adex_init(NULL); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - if ((cell = cell_list_head()) == NULL) { - nt_status = NT_STATUS_INVALID_SERVER_STATE; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - - nt_status = cell->provider->map_from_alias(mem_ctx, e->domain, - alias, name); - - /* go ahead and allow the cache mgr to mark this in - negative cache */ - - if (!NT_STATUS_IS_OK(nt_status)) - nt_status = NT_STATUS_NONE_MAPPED; - -done: - return nt_status; -} - -/********************************************************************** - *********************************************************************/ - -static NTSTATUS _nss_adex_close(void) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -/********************************************************************** - *********************************************************************/ - -static struct idmap_methods adex_idmap_methods = { - - .init = _idmap_adex_init, - .unixids_to_sids = _idmap_adex_get_sid_from_id, - .sids_to_unixids = _idmap_adex_get_id_from_sid, -}; -static struct nss_info_methods adex_nss_methods = { - .init = _nss_adex_init, - .get_nss_info = _nss_adex_get_info, - .map_to_alias = _nss_adex_map_to_alias, - .map_from_alias = _nss_adex_map_from_alias, - .close_fn = _nss_adex_close -}; - -/********************************************************************** - Register with the idmap and idmap_nss subsystems. We have to protect - against the idmap and nss_info interfaces being in a half-registered - state. - **********************************************************************/ -NTSTATUS samba_init_module(void) -{ - static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL; - static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL; - if (!NT_STATUS_IS_OK(idmap_status)) { - idmap_status = - smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, - "adex", &adex_idmap_methods); - if (!NT_STATUS_IS_OK(idmap_status)) { - DEBUG(0, - ("idmap_centeris_init: Failed to register the adex" - "idmap plugin.\n")); - return idmap_status; - } - } - - if (!NT_STATUS_IS_OK(nss_status)) { - nss_status = - smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION, - "adex", &adex_nss_methods); - if (!NT_STATUS_IS_OK(nss_status)) { - DEBUG(0, - ("idmap_adex_init: Failed to register the adex" - "nss plugin.\n")); - return nss_status; - } - } - - return NT_STATUS_OK; -} diff --git a/source3/winbindd/idmap_adex/idmap_adex.h b/source3/winbindd/idmap_adex/idmap_adex.h deleted file mode 100644 index 18edf2fad9..0000000000 --- a/source3/winbindd/idmap_adex/idmap_adex.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * idmap_centeris: Support for Local IDs and Centeris Cell Structure - * - * 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. - */ - -#ifndef _IDMAP_ADEX_H -#define _IDMAP_ADEX_H - -#include "winbindd/winbindd.h" - -#define ADEX_CELL_RDN "$LikewiseIdentityCell" - -#define ADEX_OC_USER "centerisLikewiseUser" -#define ADEX_OC_GROUP "centerisLikewiseGroup" - -#define AD_USER "User" -#define AD_GROUP "Group" - -#define ADEX_OC_POSIX_USER "posixAccount" -#define ADEX_OC_POSIX_GROUP "posixGroup" - -#define ADEX_ATTR_UIDNUM "uidNumber" -#define ADEX_ATTR_GIDNUM "gidNUmber" -#define ADEX_ATTR_HOMEDIR "unixHomeDirectory" -#define ADEX_ATTR_USERPW "unixUserPassword" -#define ADEX_ATTR_GROUPALIAS "groupAlias" /* Not part of RFC2307 */ -#define ADEX_ATTR_SHELL "loginShell" -#define ADEX_ATTR_GECOS "gecos" -#define ADEX_ATTR_UID "uid" -#define ADEX_ATTR_DISPLAYNAME "displayName" - -#define MIN_ID_VALUE 100 - -#define BAIL_ON_NTSTATUS_ERROR(x) \ - do { \ - if (!NT_STATUS_IS_OK(x)) { \ - DEBUG(10,("Failed! (%s)\n", nt_errstr(x))); \ - goto done; \ - } \ - } \ - while (0); \ - -#define WARN_ON_NTSTATUS_ERROR(x) \ - do { \ - if (!NT_STATUS_IS_OK(x)) { \ - DEBUG(10,("Failure ignored! (%s)\n", nt_errstr(x))); \ - } \ - } \ - while (0); \ - -#define BAIL_ON_ADS_ERROR(x) \ - do { \ - if (!ADS_ERR_OK(x)) { \ - goto done; \ - } \ - } \ - while (0); - -#define BAIL_ON_PTR_ERROR(p, x) \ - do { \ - if ((p) == NULL ) { \ - DEBUG(10,("NULL pointer!\n")); \ - x = NT_STATUS_NO_MEMORY; \ - goto done; \ - } \ - } while (0); - -#define PRINT_NTSTATUS_ERROR(x, hdr, level) \ - do { \ - if (!NT_STATUS_IS_OK(x)) { \ - DEBUG(level,("LWI ("hdr"): %s\n", nt_errstr(x))); \ - } \ - } while(0); -/* - * Cell Provider API - */ - -struct cell_provider_api { - NTSTATUS(*get_sid_from_id) (struct dom_sid * sid, - uint32_t id, enum id_type type); - NTSTATUS(*get_id_from_sid) (uint32_t * id, - enum id_type * type, const struct dom_sid * sid); - NTSTATUS(*get_nss_info) (const struct dom_sid * sid, - TALLOC_CTX * ctx, - const char **homedir, - const char **shell, - const char **gecos, gid_t * p_gid); - NTSTATUS(*map_to_alias) (TALLOC_CTX * mem_ctx, - const char *domain, - const char *name, char **alias); - NTSTATUS(*map_from_alias) (TALLOC_CTX * mem_ctx, - const char *domain, - const char *alias, char **name); -}; - -/* registered providers */ - -extern struct cell_provider_api ccp_unified; -extern struct cell_provider_api ccp_local; - -#define LWCELL_FLAG_USE_RFC2307_ATTRS 0x00000001 -#define LWCELL_FLAG_SEARCH_FOREST 0x00000002 -#define LWCELL_FLAG_GC_CELL 0x00000004 -#define LWCELL_FLAG_LOCAL_MODE 0x00000008 - -struct likewise_cell { - struct likewise_cell *prev, *next; - ADS_STRUCT *conn; - struct likewise_cell *gc_search_cell; - struct dom_sid domain_sid; - char *dns_domain; - char *forest_name; - char *dn; - struct GUID *links; /* only held by owning cell */ - size_t num_links; - uint32_t flags; - struct cell_provider_api *provider; -}; - -/* Search flags used for Global Catalog API */ - -#define ADEX_GC_SEARCH_CHECK_UNIQUE 0x00000001 - -struct gc_info { - struct gc_info *prev, *next; - char *forest_name; - char *search_base; - struct likewise_cell *forest_cell; -}; - -/* Available functions outside of idmap_lwidentity.c */ - -/* cell_util.c */ - -char *find_attr_string(char **list, size_t num_lines, const char *substr); -bool is_object_class(char **list, size_t num_lines, const char *substr); -int min_id_value(void); -char *cell_dn_to_dns(const char *dn); -NTSTATUS get_sid_type(ADS_STRUCT *ads, - LDAPMessage *msg, - enum lsa_SidType *type); - -NTSTATUS cell_locate_membership(ADS_STRUCT * ads); -NTSTATUS cell_lookup_settings(struct likewise_cell * cell); - -/* likewise_cell.c */ - -struct likewise_cell *cell_new(void); -struct likewise_cell *cell_list_head(void); - -bool cell_list_add(struct likewise_cell *cell); -bool cell_list_remove(struct likewise_cell * cell); - -void cell_list_destroy(void); -void cell_destroy(struct likewise_cell *c); -void cell_set_dns_domain(struct likewise_cell *c, - const char *dns_domain); -void cell_set_connection(struct likewise_cell *c, - ADS_STRUCT *ads); -void cell_set_dn(struct likewise_cell *c, - const char *dn); -void cell_set_domain_sid(struct likewise_cell *c, - struct dom_sid *sid); -void cell_set_flags(struct likewise_cell *c, uint32_t flags); -void cell_clear_flags(struct likewise_cell *c, uint32_t flags); - -const char* cell_search_base(struct likewise_cell *c); -const char *cell_dns_domain(struct likewise_cell *c); -ADS_STRUCT *cell_connection(struct likewise_cell *c); -bool cell_search_forest(struct likewise_cell *c); -ADS_STATUS cell_do_search(struct likewise_cell *c, - const char *search_base, - int scope, - const char *expr, - const char **attrs, - LDAPMessage ** msg); -uint32_t cell_flags(struct likewise_cell *c); - -NTSTATUS cell_connect_dn(struct likewise_cell **c, - const char *dn); -NTSTATUS cell_connect(struct likewise_cell *c); - - -/* gc_util.c */ - -NTSTATUS gc_init_list(void); - -NTSTATUS gc_find_forest_root(struct gc_info *gc, - const char *domain); - -struct gc_info *gc_search_start(void); - -NTSTATUS gc_search_forest(struct gc_info *gc, - LDAPMessage **msg, - const char *filter); - -NTSTATUS gc_search_all_forests(const char *filter, - ADS_STRUCT ***ads_list, - LDAPMessage ***msg_list, - int *num_resp, uint32_t flags); - -NTSTATUS gc_search_all_forests_unique(const char *filter, - ADS_STRUCT **ads, - LDAPMessage **msg); - -NTSTATUS gc_name_to_sid(const char *domain, - const char *name, - struct dom_sid *sid, - enum lsa_SidType *sid_type); - -NTSTATUS gc_sid_to_name(const struct dom_sid *sid, - char **name, - enum lsa_SidType *sid_type); - -NTSTATUS add_ads_result_to_array(ADS_STRUCT *ads, - LDAPMessage *msg, - ADS_STRUCT ***ads_list, - LDAPMessage ***msg_list, - int *size); - -void free_result_array(ADS_STRUCT **ads_list, - LDAPMessage **msg_list, - int num_resp); - -NTSTATUS check_result_unique(ADS_STRUCT *ads, - LDAPMessage *msg); - - -/* domain_util.c */ - -NTSTATUS domain_init_list(void); - -NTSTATUS dc_search_domains(struct likewise_cell **cell, - LDAPMessage **msg, - const char *dn, - const struct dom_sid *user_sid); - - -#endif /* _IDMAP_ADEX_H */ diff --git a/source3/winbindd/idmap_adex/likewise_cell.c b/source3/winbindd/idmap_adex/likewise_cell.c deleted file mode 100644 index 0e544e90f7..0000000000 --- a/source3/winbindd/idmap_adex/likewise_cell.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * idmap_adex: Support for 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 "secrets.h" -#include "../libcli/security/dom_sid.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_IDMAP - -static struct likewise_cell *_lw_cell_list = NULL; - -/********************************************************************** - Return the current HEAD of the list - *********************************************************************/ - - struct likewise_cell *cell_list_head(void) -{ - return _lw_cell_list; -} - - -/********************************************************************** - *********************************************************************/ - - void cell_destroy(struct likewise_cell *c) -{ - if (!c) - return; - - if (c->conn) - ads_destroy(&c->conn); - - talloc_destroy(c); -} - -/********************************************************************** - Free all cell entries and reset the list head to NULL - *********************************************************************/ - - void cell_list_destroy(void) -{ - struct likewise_cell *p = _lw_cell_list; - - while (p) { - struct likewise_cell *q = p->next; - - cell_destroy(p); - - p = q; - } - - _lw_cell_list = NULL; - - return; -} - -/********************************************************************** - Add a new cell structure to the list - *********************************************************************/ - - struct likewise_cell* cell_new(void) -{ - struct likewise_cell *c; - - /* Each cell struct is a TALLOC_CTX* */ - - c = talloc_zero(NULL, struct likewise_cell); - if (!c) { - DEBUG(0,("cell_new: memory allocation failure!\n")); - return NULL; - } - - return c; -} - -/********************************************************************** - Add a new cell structure to the list - *********************************************************************/ - - bool cell_list_add(struct likewise_cell * cell) -{ - if (!cell) { - return false; - } - - /* Always add to the end */ - - DLIST_ADD_END(_lw_cell_list, cell, struct likewise_cell *); - - return true; -} - -/********************************************************************** - Add a new cell structure to the list - *********************************************************************/ - - bool cell_list_remove(struct likewise_cell * cell) -{ - if (!cell) { - return false; - } - - /* Remove and drop the cell structure */ - - DLIST_REMOVE(_lw_cell_list, cell); - talloc_destroy(cell); - - return true; -} - -/********************************************************************** - Set the containing DNS domain for a cell - *********************************************************************/ - - void cell_set_dns_domain(struct likewise_cell *c, const char *dns_domain) -{ - c->dns_domain = talloc_strdup(c, dns_domain); -} - -/********************************************************************** - Set ADS connection for a cell - *********************************************************************/ - - void cell_set_connection(struct likewise_cell *c, ADS_STRUCT *ads) -{ - c->conn = ads; -} - -/********************************************************************** - *********************************************************************/ - - void cell_set_flags(struct likewise_cell *c, uint32_t flags) -{ - c->flags |= flags; -} - -/********************************************************************** - *********************************************************************/ - - void cell_clear_flags(struct likewise_cell *c, uint32_t flags) -{ - c->flags &= ~flags; -} - -/********************************************************************** - Set the Cell's DN - *********************************************************************/ - - void cell_set_dn(struct likewise_cell *c, const char *dn) -{ - if ( c->dn) { - talloc_free(c->dn); - c->dn = NULL; - } - - c->dn = talloc_strdup(c, dn); -} - -/********************************************************************** - *********************************************************************/ - - void cell_set_domain_sid(struct likewise_cell *c, struct dom_sid *sid) -{ - sid_copy(&c->domain_sid, sid); -} - -/* - * Query Routines - */ - -/********************************************************************** - *********************************************************************/ - - const char* cell_search_base(struct likewise_cell *c) -{ - if (!c) - return NULL; - - return talloc_asprintf(c, "cn=%s,%s", ADEX_CELL_RDN, c->dn); -} - -/********************************************************************** - *********************************************************************/ - - bool cell_search_forest(struct likewise_cell *c) -{ - uint32_t test_flags = LWCELL_FLAG_SEARCH_FOREST; - - return ((c->flags & test_flags) == test_flags); -} - -/********************************************************************** - *********************************************************************/ - - uint32_t cell_flags(struct likewise_cell *c) -{ - if (!c) - return 0; - - return c->flags; -} - -/********************************************************************** - *********************************************************************/ - - const char *cell_dns_domain(struct likewise_cell *c) -{ - if (!c) - return NULL; - - return c->dns_domain; -} - -/********************************************************************** - *********************************************************************/ - - ADS_STRUCT *cell_connection(struct likewise_cell *c) -{ - if (!c) - return NULL; - - return c->conn; -} - -/* - * Connection functions - */ - -/******************************************************************** - *******************************************************************/ - - NTSTATUS cell_connect(struct likewise_cell *c) -{ - ADS_STRUCT *ads = NULL; - ADS_STATUS ads_status; - fstring dc_name; - struct sockaddr_storage dcip; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - /* have to at least have the AD domain name */ - - if (!c->dns_domain) { - nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* clear out any old information */ - - if (c->conn) { - ads_destroy(&c->conn); - c->conn = NULL; - } - - /* now setup the new connection */ - - ads = ads_init(c->dns_domain, NULL, NULL); - BAIL_ON_PTR_ERROR(ads, nt_status); - - ads->auth.password = - secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - ads->auth.realm = SMB_STRDUP(lp_realm()); - - /* Make the connection. We should already have an initial - TGT using the machine creds */ - - if (cell_flags(c) & LWCELL_FLAG_GC_CELL) { - ads_status = ads_connect_gc(ads); - } else { - /* Set up server affinity for normal cells and the client - site name cache */ - - if (!get_dc_name("", c->dns_domain, dc_name, &dcip)) { - nt_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - ads_status = ads_connect(ads); - } - - - c->conn = ads; - - nt_status = ads_ntstatus(ads_status); - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - ads_destroy(&ads); - c->conn = NULL; - } - - return nt_status; -} - -/******************************************************************** - *******************************************************************/ - - NTSTATUS cell_connect_dn(struct likewise_cell **c, const char *dn) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct likewise_cell *new_cell = NULL; - char *dns_domain = NULL; - - if (*c || !dn) { - nt_status = NT_STATUS_INVALID_PARAMETER; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - if ((new_cell = cell_new()) == NULL) { - nt_status = NT_STATUS_NO_MEMORY; - BAIL_ON_NTSTATUS_ERROR(nt_status); - } - - /* Set the DNS domain, dn, etc ... and add it to the list */ - - dns_domain = cell_dn_to_dns(dn); - cell_set_dns_domain(new_cell, dns_domain); - SAFE_FREE(dns_domain); - - cell_set_dn(new_cell, dn); - - nt_status = cell_connect(new_cell); - BAIL_ON_NTSTATUS_ERROR(nt_status); - - *c = new_cell; - -done: - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(1,("LWI: Failled to connect to cell \"%s\" (%s)\n", - dn ? dn : "NULL", nt_errstr(nt_status))); - talloc_destroy(new_cell); - } - - return nt_status; -} - - -/******************************************************************** - *******************************************************************/ - -#define MAX_SEARCH_COUNT 2 - - ADS_STATUS cell_do_search(struct likewise_cell *c, - const char *search_base, - int scope, - const char *expr, - const char **attrs, - LDAPMessage ** msg) -{ - int search_count = 0; - ADS_STATUS status; - NTSTATUS nt_status; - - /* check for a NULL connection */ - - if (!c->conn) { - nt_status = cell_connect(c); - if (!NT_STATUS_IS_OK(nt_status)) { - status = ADS_ERROR_NT(nt_status); - return status; - } - } - - DEBUG(10, ("cell_do_search: Base = %s, Filter = %s, Scope = %d, GC = %s\n", - search_base, expr, scope, - c->conn->server.gc ? "yes" : "no")); - - /* we try multiple times in case the ADS_STRUCT is bad - and we need to reconnect */ - - while (search_count < MAX_SEARCH_COUNT) { - *msg = NULL; - status = ads_do_search(c->conn, search_base, - scope, expr, attrs, msg); - if (ADS_ERR_OK(status)) { - if (DEBUGLEVEL >= 10) { - LDAPMessage *e = NULL; - - int n = ads_count_replies(c->conn, *msg); - - DEBUG(10,("cell_do_search: Located %d entries\n", n)); - - for (e=ads_first_entry(c->conn, *msg); - e!=NULL; - e = ads_next_entry(c->conn, e)) - { - char *dn = ads_get_dn(c->conn, talloc_tos(), e); - - DEBUGADD(10,(" dn: %s\n", dn ? dn : "<NULL>")); - TALLOC_FREE(dn); - } - } - - return status; - } - - - DEBUG(5, ("cell_do_search: search[%d] failed (%s)\n", - search_count, ads_errstr(status))); - - search_count++; - - /* Houston, we have a problem */ - - if (status.error_type == ENUM_ADS_ERROR_LDAP) { - switch (status.err.rc) { - case LDAP_TIMELIMIT_EXCEEDED: - case LDAP_TIMEOUT: - case -1: /* we get this error if we cannot contact - the LDAP server */ - nt_status = cell_connect(c); - if (!NT_STATUS_IS_OK(nt_status)) { - status = ADS_ERROR_NT(nt_status); - return status; - } - break; - default: - /* we're all done here */ - return status; - } - } - } - - DEBUG(5, ("cell_do_search: exceeded maximum search count!\n")); - - return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); -} 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 -}; |