From 28aa4bff8d6be031c6089fe5c7ab010f1cc48340 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Sep 2007 12:03:58 +0000 Subject: r25154: move winbindd code into winbindd/ metze (This used to be commit 3ac7566ae14c48ff9b0f6b232e0ec4b2f73df558) --- source3/winbindd/winbindd_util.c | 1460 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1460 insertions(+) create mode 100644 source3/winbindd/winbindd_util.c (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c new file mode 100644 index 0000000000..37d29e1765 --- /dev/null +++ b/source3/winbindd/winbindd_util.c @@ -0,0 +1,1460 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon for ntdom nss module + + Copyright (C) Tim Potter 2000-2001 + Copyright (C) 2001 by Martin Pool + + 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 3 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, see . +*/ + +#include "includes.h" +#include "winbindd.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_WINBIND + +extern struct winbindd_methods cache_methods; +extern struct winbindd_methods passdb_methods; + +/** + * @file winbindd_util.c + * + * Winbind daemon for NT domain authentication nss module. + **/ + +/* The list of trusted domains. Note that the list can be deleted and + recreated using the init_domain_list() function so pointers to + individual winbindd_domain structures cannot be made. Keep a copy of + the domain name instead. */ + +static struct winbindd_domain *_domain_list; + +/** + When was the last scan of trusted domains done? + + 0 == not ever +*/ + +static time_t last_trustdom_scan; + +struct winbindd_domain *domain_list(void) +{ + /* Initialise list */ + + if ((!_domain_list) && (!init_domain_list())) { + smb_panic("Init_domain_list failed"); + } + + return _domain_list; +} + +/* Free all entries in the trusted domain list */ + +void free_domain_list(void) +{ + struct winbindd_domain *domain = _domain_list; + + while(domain) { + struct winbindd_domain *next = domain->next; + + DLIST_REMOVE(_domain_list, domain); + SAFE_FREE(domain); + domain = next; + } +} + +static BOOL is_internal_domain(const DOM_SID *sid) +{ + if (sid == NULL) + return False; + + if ( IS_DC ) + return sid_check_is_builtin(sid); + + return (sid_check_is_domain(sid) || sid_check_is_builtin(sid)); +} + +static BOOL is_in_internal_domain(const DOM_SID *sid) +{ + if (sid == NULL) + return False; + + if ( IS_DC ) + return sid_check_is_in_builtin(sid); + + return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid)); +} + + +/* Add a trusted domain to our list of domains */ +static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name, + struct winbindd_methods *methods, + const DOM_SID *sid) +{ + struct winbindd_domain *domain; + const char *alternative_name = NULL; + + /* ignore alt_name if we are not in an AD domain */ + + if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) { + alternative_name = alt_name; + } + + /* We can't call domain_list() as this function is called from + init_domain_list() and we'll get stuck in a loop. */ + for (domain = _domain_list; domain; domain = domain->next) { + if (strequal(domain_name, domain->name) || + strequal(domain_name, domain->alt_name)) + { + break; + } + + if (alternative_name && *alternative_name) + { + if (strequal(alternative_name, domain->name) || + strequal(alternative_name, domain->alt_name)) + { + break; + } + } + + if (sid) + { + if (is_null_sid(sid)) { + continue; + } + + if (sid_equal(sid, &domain->sid)) { + break; + } + } + } + + /* See if we found a match. Check if we need to update the + SID. */ + + if ( domain && sid) { + if ( sid_equal( &domain->sid, &global_sid_NULL ) ) + sid_copy( &domain->sid, sid ); + + return domain; + } + + /* Create new domain entry */ + + if ((domain = SMB_MALLOC_P(struct winbindd_domain)) == NULL) + return NULL; + + /* Fill in fields */ + + ZERO_STRUCTP(domain); + + /* prioritise the short name */ + if (strchr_m(domain_name, '.') && alternative_name && *alternative_name) { + fstrcpy(domain->name, alternative_name); + fstrcpy(domain->alt_name, domain_name); + } else { + fstrcpy(domain->name, domain_name); + if (alternative_name) { + fstrcpy(domain->alt_name, alternative_name); + } + } + + domain->methods = methods; + domain->backend = NULL; + domain->internal = is_internal_domain(sid); + domain->sequence_number = DOM_SEQUENCE_NONE; + domain->last_seq_check = 0; + domain->initialized = False; + domain->online = is_internal_domain(sid); + domain->check_online_timeout = 0; + if (sid) { + sid_copy(&domain->sid, sid); + } + + /* Link to domain list */ + DLIST_ADD(_domain_list, domain); + + wcache_tdc_add_domain( domain ); + + DEBUG(2,("Added domain %s %s %s\n", + domain->name, domain->alt_name, + &domain->sid?sid_string_static(&domain->sid):"")); + + return domain; +} + +/******************************************************************** + rescan our domains looking for new trusted domains +********************************************************************/ + +struct trustdom_state { + TALLOC_CTX *mem_ctx; + BOOL primary; + BOOL forest_root; + struct winbindd_response *response; +}; + +static void trustdom_recv(void *private_data, BOOL success); +static void rescan_forest_root_trusts( void ); +static void rescan_forest_trusts( void ); + +static void add_trusted_domains( struct winbindd_domain *domain ) +{ + TALLOC_CTX *mem_ctx; + struct winbindd_request *request; + struct winbindd_response *response; + uint32 fr_flags = (DS_DOMAIN_TREE_ROOT|DS_DOMAIN_IN_FOREST); + + struct trustdom_state *state; + + mem_ctx = talloc_init("add_trusted_domains"); + if (mem_ctx == NULL) { + DEBUG(0, ("talloc_init failed\n")); + return; + } + + request = TALLOC_ZERO_P(mem_ctx, struct winbindd_request); + response = TALLOC_P(mem_ctx, struct winbindd_response); + state = TALLOC_P(mem_ctx, struct trustdom_state); + + if ((request == NULL) || (response == NULL) || (state == NULL)) { + DEBUG(0, ("talloc failed\n")); + talloc_destroy(mem_ctx); + return; + } + + state->mem_ctx = mem_ctx; + state->response = response; + + /* Flags used to know how to continue the forest trust search */ + + state->primary = domain->primary; + state->forest_root = ((domain->domain_flags & fr_flags) == fr_flags ); + + request->length = sizeof(*request); + request->cmd = WINBINDD_LIST_TRUSTDOM; + + async_domain_request(mem_ctx, domain, request, response, + trustdom_recv, state); +} + +static void trustdom_recv(void *private_data, BOOL success) +{ + struct trustdom_state *state = + talloc_get_type_abort(private_data, struct trustdom_state); + struct winbindd_response *response = state->response; + char *p; + + if ((!success) || (response->result != WINBINDD_OK)) { + DEBUG(1, ("Could not receive trustdoms\n")); + talloc_destroy(state->mem_ctx); + return; + } + + p = (char *)response->extra_data.data; + + while ((p != NULL) && (*p != '\0')) { + char *q, *sidstr, *alt_name; + DOM_SID sid; + struct winbindd_domain *domain; + char *alternate_name = NULL; + + alt_name = strchr(p, '\\'); + if (alt_name == NULL) { + DEBUG(0, ("Got invalid trustdom response\n")); + break; + } + + *alt_name = '\0'; + alt_name += 1; + + sidstr = strchr(alt_name, '\\'); + if (sidstr == NULL) { + DEBUG(0, ("Got invalid trustdom response\n")); + break; + } + + *sidstr = '\0'; + sidstr += 1; + + q = strchr(sidstr, '\n'); + if (q != NULL) + *q = '\0'; + + if (!string_to_sid(&sid, sidstr)) { + /* Allow NULL sid for sibling domains */ + if ( strcmp(sidstr,"S-0-0") == 0) { + sid_copy( &sid, &global_sid_NULL); + } else { + DEBUG(0, ("Got invalid trustdom response\n")); + break; + } + } + + /* use the real alt_name if we have one, else pass in NULL */ + + if ( !strequal( alt_name, "(null)" ) ) + alternate_name = alt_name; + + /* If we have an existing domain structure, calling + add_trusted_domain() will update the SID if + necessary. This is important because we need the + SID for sibling domains */ + + if ( find_domain_from_name_noinit(p) != NULL ) { + domain = add_trusted_domain(p, alternate_name, + &cache_methods, + &sid); + } else { + domain = add_trusted_domain(p, alternate_name, + &cache_methods, + &sid); + if (domain) { + setup_domain_child(domain, &domain->child, NULL); + } + } + p=q; + if (p != NULL) + p += 1; + } + + SAFE_FREE(response->extra_data.data); + + /* + Cases to consider when scanning trusts: + (a) we are calling from a child domain (primary && !forest_root) + (b) we are calling from the root of the forest (primary && forest_root) + (c) we are calling from a trusted forest domain (!primary + && !forest_root) + */ + + if ( state->primary ) { + /* If this is our primary domain and we are not the in the + forest root, we have to scan the root trusts first */ + + if ( !state->forest_root ) + rescan_forest_root_trusts(); + else + rescan_forest_trusts(); + + } else if ( state->forest_root ) { + /* Once we have done root forest trust search, we can + go on to search thing trusted forests */ + + rescan_forest_trusts(); + } + + talloc_destroy(state->mem_ctx); + + return; +} + +/******************************************************************** + Scan the trusts of our forest root +********************************************************************/ + +static void rescan_forest_root_trusts( void ) +{ + struct winbindd_tdc_domain *dom_list = NULL; + size_t num_trusts = 0; + int i; + + /* The only transitive trusts supported by Windows 2003 AD are + (a) Parent-Child, (b) Tree-Root, and (c) Forest. The + first two are handled in forest and listed by + DsEnumerateDomainTrusts(). Forest trusts are not so we + have to do that ourselves. */ + + if ( !wcache_tdc_fetch_list( &dom_list, &num_trusts ) ) + return; + + for ( i=0; iname, d->alt_name )); + + d->domain_flags = dom_list[i].trust_flags; + d->domain_type = dom_list[i].trust_type; + d->domain_trust_attribs = dom_list[i].trust_attribs; + + add_trusted_domains( d ); + + break; + } + + TALLOC_FREE( dom_list ); + + return; +} + +/******************************************************************** + scan the transitive forest trists (not our own) +********************************************************************/ + + +static void rescan_forest_trusts( void ) +{ + struct winbindd_domain *d = NULL; + struct winbindd_tdc_domain *dom_list = NULL; + size_t num_trusts = 0; + int i; + + /* The only transitive trusts supported by Windows 2003 AD are + (a) Parent-Child, (b) Tree-Root, and (c) Forest. The + first two are handled in forest and listed by + DsEnumerateDomainTrusts(). Forest trusts are not so we + have to do that ourselves. */ + + if ( !wcache_tdc_fetch_list( &dom_list, &num_trusts ) ) + return; + + for ( i=0; iinternal || d->primary ) ) + continue; + + if ( (flags & DS_DOMAIN_DIRECT_INBOUND) && + (type == DS_DOMAIN_TRUST_TYPE_UPLEVEL) && + (attribs == DS_DOMAIN_TRUST_ATTRIB_FOREST_TRANSITIVE) ) + { + /* add the trusted domain if we don't know + about it */ + + if ( !d ) { + d = add_trusted_domain( dom_list[i].domain_name, + dom_list[i].dns_name, + &cache_methods, + &dom_list[i].sid ); + } + + DEBUG(10,("Following trust path for domain %s (%s)\n", + d->name, d->alt_name )); + add_trusted_domains( d ); + } + } + + TALLOC_FREE( dom_list ); + + return; +} + +/********************************************************************* + The process of updating the trusted domain list is a three step + async process: + (a) ask our domain + (b) ask the root domain in our forest + (c) ask the a DC in any Win2003 trusted forests +*********************************************************************/ + +void rescan_trusted_domains( void ) +{ + time_t now = time(NULL); + + /* see if the time has come... */ + + if ((now >= last_trustdom_scan) && + ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) ) + return; + + /* clear the TRUSTDOM cache first */ + + wcache_tdc_clear(); + + /* this will only add new domains we didn't already know about + in the domain_list()*/ + + add_trusted_domains( find_our_domain() ); + + last_trustdom_scan = now; + + return; +} + +struct init_child_state { + TALLOC_CTX *mem_ctx; + struct winbindd_domain *domain; + struct winbindd_request *request; + struct winbindd_response *response; + void (*continuation)(void *private_data, BOOL success); + void *private_data; +}; + +static void init_child_recv(void *private_data, BOOL success); +static void init_child_getdc_recv(void *private_data, BOOL success); + +enum winbindd_result init_child_connection(struct winbindd_domain *domain, + void (*continuation)(void *private_data, + BOOL success), + void *private_data) +{ + TALLOC_CTX *mem_ctx; + struct winbindd_request *request; + struct winbindd_response *response; + struct init_child_state *state; + struct winbindd_domain *request_domain; + + mem_ctx = talloc_init("init_child_connection"); + if (mem_ctx == NULL) { + DEBUG(0, ("talloc_init failed\n")); + return WINBINDD_ERROR; + } + + request = TALLOC_ZERO_P(mem_ctx, struct winbindd_request); + response = TALLOC_P(mem_ctx, struct winbindd_response); + state = TALLOC_P(mem_ctx, struct init_child_state); + + if ((request == NULL) || (response == NULL) || (state == NULL)) { + DEBUG(0, ("talloc failed\n")); + TALLOC_FREE(mem_ctx); + continuation(private_data, False); + return WINBINDD_ERROR; + } + + request->length = sizeof(*request); + + state->mem_ctx = mem_ctx; + state->domain = domain; + state->request = request; + state->response = response; + state->continuation = continuation; + state->private_data = private_data; + + if (IS_DC || domain->primary || domain->internal ) { + /* The primary domain has to find the DC name itself */ + request->cmd = WINBINDD_INIT_CONNECTION; + fstrcpy(request->domain_name, domain->name); + request->data.init_conn.is_primary = domain->internal ? False : True; + fstrcpy(request->data.init_conn.dcname, ""); + async_request(mem_ctx, &domain->child, request, response, + init_child_recv, state); + return WINBINDD_PENDING; + } + + /* This is *not* the primary domain, let's ask our DC about a DC + * name */ + + request->cmd = WINBINDD_GETDCNAME; + fstrcpy(request->domain_name, domain->name); + + request_domain = find_our_domain(); + async_domain_request(mem_ctx, request_domain, request, response, + init_child_getdc_recv, state); + return WINBINDD_PENDING; +} + +static void init_child_getdc_recv(void *private_data, BOOL success) +{ + struct init_child_state *state = + talloc_get_type_abort(private_data, struct init_child_state); + const char *dcname = ""; + + DEBUG(10, ("Received getdcname response\n")); + + if (success && (state->response->result == WINBINDD_OK)) { + dcname = state->response->data.dc_name; + } + + state->request->cmd = WINBINDD_INIT_CONNECTION; + fstrcpy(state->request->domain_name, state->domain->name); + state->request->data.init_conn.is_primary = False; + fstrcpy(state->request->data.init_conn.dcname, dcname); + + async_request(state->mem_ctx, &state->domain->child, + state->request, state->response, + init_child_recv, state); +} + +static void init_child_recv(void *private_data, BOOL success) +{ + struct init_child_state *state = + talloc_get_type_abort(private_data, struct init_child_state); + + DEBUG(5, ("Received child initialization response for domain %s\n", + state->domain->name)); + + if ((!success) || (state->response->result != WINBINDD_OK)) { + DEBUG(3, ("Could not init child\n")); + state->continuation(state->private_data, False); + talloc_destroy(state->mem_ctx); + return; + } + + fstrcpy(state->domain->name, + state->response->data.domain_info.name); + fstrcpy(state->domain->alt_name, + state->response->data.domain_info.alt_name); + string_to_sid(&state->domain->sid, + state->response->data.domain_info.sid); + state->domain->native_mode = + state->response->data.domain_info.native_mode; + state->domain->active_directory = + state->response->data.domain_info.active_directory; + state->domain->sequence_number = + state->response->data.domain_info.sequence_number; + + init_dc_connection(state->domain); + + if (state->continuation != NULL) + state->continuation(state->private_data, True); + talloc_destroy(state->mem_ctx); +} + +enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + /* Ensure null termination */ + state->request.domain_name + [sizeof(state->request.domain_name)-1]='\0'; + state->request.data.init_conn.dcname + [sizeof(state->request.data.init_conn.dcname)-1]='\0'; + + if (strlen(state->request.data.init_conn.dcname) > 0) { + fstrcpy(domain->dcname, state->request.data.init_conn.dcname); + } + + init_dc_connection(domain); + + if (!domain->initialized) { + /* If we return error here we can't do any cached authentication, + but we may be in disconnected mode and can't initialize correctly. + Do what the previous code did and just return without initialization, + once we go online we'll re-initialize. + */ + DEBUG(5, ("winbindd_dual_init_connection: %s returning without initialization " + "online = %d\n", domain->name, (int)domain->online )); + } + + fstrcpy(state->response.data.domain_info.name, domain->name); + fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name); + fstrcpy(state->response.data.domain_info.sid, + sid_string_static(&domain->sid)); + + state->response.data.domain_info.native_mode + = domain->native_mode; + state->response.data.domain_info.active_directory + = domain->active_directory; + state->response.data.domain_info.primary + = domain->primary; + state->response.data.domain_info.sequence_number = + domain->sequence_number; + + return WINBINDD_OK; +} + +/* Look up global info for the winbind daemon */ +BOOL init_domain_list(void) +{ + struct winbindd_domain *domain; + int role = lp_server_role(); + + /* Free existing list */ + free_domain_list(); + + /* Add ourselves as the first entry. */ + + if ( role == ROLE_DOMAIN_MEMBER ) { + DOM_SID our_sid; + + if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) { + DEBUG(0, ("Could not fetch our SID - did we join?\n")); + return False; + } + + domain = add_trusted_domain( lp_workgroup(), lp_realm(), + &cache_methods, &our_sid); + if (domain) { + domain->primary = True; + setup_domain_child(domain, &domain->child, NULL); + + /* Even in the parent winbindd we'll need to + talk to the DC, so try and see if we can + contact it. Theoretically this isn't neccessary + as the init_dc_connection() in init_child_recv() + will do this, but we can start detecting the DC + early here. */ + set_domain_online_request(domain); + } + } + + /* Local SAM */ + + domain = add_trusted_domain(get_global_sam_name(), NULL, + &passdb_methods, get_global_sam_sid()); + if (domain) { + if ( role != ROLE_DOMAIN_MEMBER ) { + domain->primary = True; + } + setup_domain_child(domain, &domain->child, NULL); + } + + /* BUILTIN domain */ + + domain = add_trusted_domain("BUILTIN", NULL, &passdb_methods, + &global_sid_Builtin); + if (domain) { + setup_domain_child(domain, &domain->child, NULL); + } + + return True; +} + +void check_domain_trusted( const char *name, const DOM_SID *user_sid ) +{ + struct winbindd_domain *domain; + DOM_SID dom_sid; + uint32 rid; + + domain = find_domain_from_name_noinit( name ); + if ( domain ) + return; + + sid_copy( &dom_sid, user_sid ); + if ( !sid_split_rid( &dom_sid, &rid ) ) + return; + + /* add the newly discovered trusted domain */ + + domain = add_trusted_domain( name, NULL, &cache_methods, + &dom_sid); + + if ( !domain ) + return; + + /* assume this is a trust from a one-way transitive + forest trust */ + + domain->active_directory = True; + domain->domain_flags = DS_DOMAIN_DIRECT_OUTBOUND; + domain->domain_type = DS_DOMAIN_TRUST_TYPE_UPLEVEL; + domain->internal = False; + domain->online = True; + + setup_domain_child(domain, &domain->child, NULL); + + wcache_tdc_add_domain( domain ); + + return; +} + +/** + * Given a domain name, return the struct winbindd domain info for it + * + * @note Do *not* pass lp_workgroup() to this function. domain_list + * may modify it's value, and free that pointer. Instead, our local + * domain may be found by calling find_our_domain(). + * directly. + * + * + * @return The domain structure for the named domain, if it is working. + */ + +struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name) +{ + struct winbindd_domain *domain; + + /* Search through list */ + + for (domain = domain_list(); domain != NULL; domain = domain->next) { + if (strequal(domain_name, domain->name) || + (domain->alt_name[0] && + strequal(domain_name, domain->alt_name))) { + return domain; + } + } + + /* Not found */ + + return NULL; +} + +struct winbindd_domain *find_domain_from_name(const char *domain_name) +{ + struct winbindd_domain *domain; + + domain = find_domain_from_name_noinit(domain_name); + + if (domain == NULL) + return NULL; + + if (!domain->initialized) + init_dc_connection(domain); + + return domain; +} + +/* Given a domain sid, return the struct winbindd domain info for it */ + +struct winbindd_domain *find_domain_from_sid_noinit(const DOM_SID *sid) +{ + struct winbindd_domain *domain; + + /* Search through list */ + + for (domain = domain_list(); domain != NULL; domain = domain->next) { + if (sid_compare_domain(sid, &domain->sid) == 0) + return domain; + } + + /* Not found */ + + return NULL; +} + +/* Given a domain sid, return the struct winbindd domain info for it */ + +struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid) +{ + struct winbindd_domain *domain; + + domain = find_domain_from_sid_noinit(sid); + + if (domain == NULL) + return NULL; + + if (!domain->initialized) + init_dc_connection(domain); + + return domain; +} + +struct winbindd_domain *find_our_domain(void) +{ + struct winbindd_domain *domain; + + /* Search through list */ + + for (domain = domain_list(); domain != NULL; domain = domain->next) { + if (domain->primary) + return domain; + } + + smb_panic("Could not find our domain"); + return NULL; +} + +struct winbindd_domain *find_root_domain(void) +{ + struct winbindd_domain *ours = find_our_domain(); + + if ( !ours ) + return NULL; + + if ( strlen(ours->forest_name) == 0 ) + return NULL; + + return find_domain_from_name( ours->forest_name ); +} + +struct winbindd_domain *find_builtin_domain(void) +{ + DOM_SID sid; + struct winbindd_domain *domain; + + string_to_sid(&sid, "S-1-5-32"); + domain = find_domain_from_sid(&sid); + + if (domain == NULL) { + smb_panic("Could not find BUILTIN domain"); + } + + return domain; +} + +/* Find the appropriate domain to lookup a name or SID */ + +struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid) +{ + /* SIDs in the S-1-22-{1,2} domain should be handled by our passdb */ + + if ( sid_check_is_in_unix_groups(sid) || + sid_check_is_unix_groups(sid) || + sid_check_is_in_unix_users(sid) || + sid_check_is_unix_users(sid) ) + { + return find_domain_from_sid(get_global_sam_sid()); + } + + /* A DC can't ask the local smbd for remote SIDs, here winbindd is the + * one to contact the external DC's. On member servers the internal + * domains are different: These are part of the local SAM. */ + + DEBUG(10, ("find_lookup_domain_from_sid(%s)\n", + sid_string_static(sid))); + + if (IS_DC || is_internal_domain(sid) || is_in_internal_domain(sid)) { + DEBUG(10, ("calling find_domain_from_sid\n")); + return find_domain_from_sid(sid); + } + + /* On a member server a query for SID or name can always go to our + * primary DC. */ + + DEBUG(10, ("calling find_our_domain\n")); + return find_our_domain(); +} + +struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name) +{ + if ( strequal(domain_name, unix_users_domain_name() ) || + strequal(domain_name, unix_groups_domain_name() ) ) + { + return find_domain_from_name_noinit( get_global_sam_name() ); + } + + if (IS_DC || strequal(domain_name, "BUILTIN") || + strequal(domain_name, get_global_sam_name())) + return find_domain_from_name_noinit(domain_name); + + /* The "Unix User" and "Unix Group" domain our handled by passdb */ + + return find_our_domain(); +} + +/* Lookup a sid in a domain from a name */ + +BOOL winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx, + enum winbindd_cmd orig_cmd, + struct winbindd_domain *domain, + const char *domain_name, + const char *name, DOM_SID *sid, + enum lsa_SidType *type) +{ + NTSTATUS result; + + /* Lookup name */ + result = domain->methods->name_to_sid(domain, mem_ctx, orig_cmd, + domain_name, name, sid, type); + + /* Return sid and type if lookup successful */ + if (!NT_STATUS_IS_OK(result)) { + *type = SID_NAME_UNKNOWN; + } + + return NT_STATUS_IS_OK(result); +} + +/** + * @brief Lookup a name in a domain from a sid. + * + * @param sid Security ID you want to look up. + * @param name On success, set to the name corresponding to @p sid. + * @param dom_name On success, set to the 'domain name' corresponding to @p sid. + * @param type On success, contains the type of name: alias, group or + * user. + * @retval True if the name exists, in which case @p name and @p type + * are set, otherwise False. + **/ +BOOL winbindd_lookup_name_by_sid(TALLOC_CTX *mem_ctx, + struct winbindd_domain *domain, + DOM_SID *sid, + char **dom_name, + char **name, + enum lsa_SidType *type) +{ + NTSTATUS result; + + *dom_name = NULL; + *name = NULL; + + /* Lookup name */ + + result = domain->methods->sid_to_name(domain, mem_ctx, sid, dom_name, name, type); + + /* Return name and type if successful */ + + if (NT_STATUS_IS_OK(result)) { + return True; + } + + *type = SID_NAME_UNKNOWN; + + return False; +} + +/* Free state information held for {set,get,end}{pw,gr}ent() functions */ + +void free_getent_state(struct getent_state *state) +{ + struct getent_state *temp; + + /* Iterate over state list */ + + temp = state; + + while(temp != NULL) { + struct getent_state *next; + + /* Free sam entries then list entry */ + + SAFE_FREE(state->sam_entries); + DLIST_REMOVE(state, state); + next = temp->next; + + SAFE_FREE(temp); + temp = next; + } +} + +/* Is this a domain which we may assume no DOMAIN\ prefix? */ + +static BOOL assume_domain(const char *domain) +{ + /* never assume the domain on a standalone server */ + + if ( lp_server_role() == ROLE_STANDALONE ) + return False; + + /* domain member servers may possibly assume for the domain name */ + + if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) { + if ( !strequal(lp_workgroup(), domain) ) + return False; + + if ( lp_winbind_use_default_domain() || lp_winbind_trusted_domains_only() ) + return True; + } + + /* only left with a domain controller */ + + if ( strequal(get_global_sam_name(), domain) ) { + return True; + } + + return False; +} + +/* Parse a string of the form DOMAIN\user into a domain and a user */ + +BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) +{ + char *p = strchr(domuser,*lp_winbind_separator()); + + if ( !p ) { + fstrcpy(user, domuser); + + if ( assume_domain(lp_workgroup())) { + fstrcpy(domain, lp_workgroup()); + } else if ((p = strchr(domuser, '@')) != NULL) { + fstrcpy(domain, ""); + } else { + return False; + } + } else { + fstrcpy(user, p+1); + fstrcpy(domain, domuser); + domain[PTR_DIFF(p, domuser)] = 0; + } + + strupper_m(domain); + + return True; +} + +BOOL parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, + char **domain, char **user) +{ + fstring fstr_domain, fstr_user; + if (!parse_domain_user(domuser, fstr_domain, fstr_user)) { + return False; + } + *domain = talloc_strdup(mem_ctx, fstr_domain); + *user = talloc_strdup(mem_ctx, fstr_user); + return ((*domain != NULL) && (*user != NULL)); +} + +/* Ensure an incoming username from NSS is fully qualified. Replace the + incoming fstring with DOMAIN user. Returns the same + values as parse_domain_user() but also replaces the incoming username. + Used to ensure all names are fully qualified within winbindd. + Used by the NSS protocols of auth, chauthtok, logoff and ccache_ntlm_auth. + The protocol definitions of auth_crap, chng_pswd_auth_crap + really should be changed to use this instead of doing things + by hand. JRA. */ + +BOOL canonicalize_username(fstring username_inout, fstring domain, fstring user) +{ + if (!parse_domain_user(username_inout, domain, user)) { + return False; + } + slprintf(username_inout, sizeof(fstring) - 1, "%s%c%s", + domain, *lp_winbind_separator(), + user); + return True; +} + +/* + Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and + 'winbind separator' options. + This means: + - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is + lp_workgroup() + + If we are a PDC or BDC, and this is for our domain, do likewise. + + Also, if omit DOMAIN if 'winbind trusted domains only = true', as the + username is then unqualified in unix + + We always canonicalize as UPPERCASE DOMAIN, lowercase username. +*/ +void fill_domain_username(fstring name, const char *domain, const char *user, BOOL can_assume) +{ + fstring tmp_user; + + fstrcpy(tmp_user, user); + strlower_m(tmp_user); + + if (can_assume && assume_domain(domain)) { + strlcpy(name, tmp_user, sizeof(fstring)); + } else { + slprintf(name, sizeof(fstring) - 1, "%s%c%s", + domain, *lp_winbind_separator(), + tmp_user); + } +} + +/* + * Winbindd socket accessor functions + */ + +char *get_winbind_priv_pipe_dir(void) +{ + return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR); +} + +/* + * Client list accessor functions + */ + +static struct winbindd_cli_state *_client_list; +static int _num_clients; + +/* Return list of all connected clients */ + +struct winbindd_cli_state *winbindd_client_list(void) +{ + return _client_list; +} + +/* Add a connection to the list */ + +void winbindd_add_client(struct winbindd_cli_state *cli) +{ + DLIST_ADD(_client_list, cli); + _num_clients++; +} + +/* Remove a client from the list */ + +void winbindd_remove_client(struct winbindd_cli_state *cli) +{ + DLIST_REMOVE(_client_list, cli); + _num_clients--; +} + +/* Close all open clients */ + +void winbindd_kill_all_clients(void) +{ + struct winbindd_cli_state *cl = winbindd_client_list(); + + DEBUG(10, ("winbindd_kill_all_clients: going postal\n")); + + while (cl) { + struct winbindd_cli_state *next; + + next = cl->next; + winbindd_remove_client(cl); + cl = next; + } +} + +/* Return number of open clients */ + +int winbindd_num_clients(void) +{ + return _num_clients; +} + +NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const DOM_SID *user_sid, + uint32 *p_num_groups, DOM_SID **user_sids) +{ + NET_USER_INFO_3 *info3 = NULL; + NTSTATUS status = NT_STATUS_NO_MEMORY; + int i; + size_t num_groups = 0; + DOM_SID group_sid, primary_group; + + DEBUG(3,(": lookup_usergroups_cached\n")); + + *user_sids = NULL; + num_groups = 0; + *p_num_groups = 0; + + info3 = netsamlogon_cache_get(mem_ctx, user_sid); + + if (info3 == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (info3->num_groups == 0) { + TALLOC_FREE(info3); + return NT_STATUS_UNSUCCESSFUL; + } + + /* always add the primary group to the sid array */ + sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid); + + if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) { + TALLOC_FREE(info3); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; inum_groups; i++) { + sid_copy(&group_sid, &info3->dom_sid.sid); + sid_append_rid(&group_sid, info3->gids[i].g_rid); + + if (!add_sid_to_array(mem_ctx, &group_sid, user_sids, + &num_groups)) { + TALLOC_FREE(info3); + return NT_STATUS_NO_MEMORY; + } + } + + /* Add any Universal groups in the other_sids list */ + + for (i=0; inum_other_sids; i++) { + /* Skip Domain local groups outside our domain. + We'll get these from the getsidaliases() RPC call. */ + if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE) + continue; + + if (!add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, + user_sids, &num_groups)) + { + TALLOC_FREE(info3); + return NT_STATUS_NO_MEMORY; + } + } + + + TALLOC_FREE(info3); + *p_num_groups = num_groups; + status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; + + DEBUG(3,(": lookup_usergroups_cached succeeded\n")); + + return status; +} + +/********************************************************************* + We use this to remove spaces from user and group names +********************************************************************/ + +void ws_name_replace( char *name, char replace ) +{ + char replace_char[2] = { 0x0, 0x0 }; + + if ( !lp_winbind_normalize_names() || (replace == '\0') ) + return; + + replace_char[0] = replace; + all_string_sub( name, " ", replace_char, 0 ); + + return; +} + +/********************************************************************* + We use this to do the inverse of ws_name_replace() +********************************************************************/ + +void ws_name_return( char *name, char replace ) +{ + char replace_char[2] = { 0x0, 0x0 }; + + if ( !lp_winbind_normalize_names() || (replace == '\0') ) + return; + + replace_char[0] = replace; + all_string_sub( name, replace_char, " ", 0 ); + + return; +} + +/********************************************************************* + ********************************************************************/ + +BOOL winbindd_can_contact_domain( struct winbindd_domain *domain ) +{ + /* We can contact the domain if it is our primary domain */ + + if ( domain->primary ) + return True; + + /* Can always contact a domain that is in out forest */ + + if ( domain->domain_flags & DS_DOMAIN_IN_FOREST ) + return True; + + /* We cannot contact the domain if it is running AD and + we have no inbound trust */ + + if ( domain->active_directory && + ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) ) + { + return False; + } + + /* Assume everything else is ok (probably not true but what + can you do?) */ + + return True; +} + +/********************************************************************* + ********************************************************************/ + +BOOL winbindd_internal_child(struct winbindd_child *child) +{ + if ((child == idmap_child()) || (child == locator_child())) { + return True; + } + + return False; +} + +#ifdef HAVE_KRB5_LOCATE_PLUGIN_H + +/********************************************************************* + ********************************************************************/ + +static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain) +{ + char *var = NULL; + const char *kdc = NULL; + int lvl = 11; + + if (!domain || !domain->alt_name || !*domain->alt_name) { + return; + } + + if (domain->initialized && !domain->active_directory) { + DEBUG(lvl,("winbindd_set_locator_kdc_env: %s not AD\n", + domain->alt_name)); + return; + } + + kdc = inet_ntoa(domain->dcaddr.sin_addr); + if (!kdc) { + DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC IP\n", + domain->alt_name)); + kdc = domain->dcname; + } + + if (!kdc || !*kdc) { + DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC at all\n", + domain->alt_name)); + return; + } + + if (asprintf(&var, "%s_%s", WINBINDD_LOCATOR_KDC_ADDRESS, + strupper_static(domain->alt_name)) == -1) { + return; + } + + DEBUG(lvl,("winbindd_set_locator_kdc_env: setting var: %s to: %s\n", + var, kdc)); + + setenv(var, kdc, 1); + free(var); +} + +/********************************************************************* + ********************************************************************/ + +void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain) +{ + struct winbindd_domain *our_dom = find_our_domain(); + + winbindd_set_locator_kdc_env(domain); + + if (domain != our_dom) { + winbindd_set_locator_kdc_env(our_dom); + } +} + +/********************************************************************* + ********************************************************************/ + +void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain) +{ + char *var = NULL; + + if (!domain || !domain->alt_name || !*domain->alt_name) { + return; + } + + if (asprintf(&var, "%s_%s", WINBINDD_LOCATOR_KDC_ADDRESS, + strupper_static(domain->alt_name)) == -1) { + return; + } + + unsetenv(var); + free(var); +} +#else + +void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain) +{ + return; +} + +void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain) +{ + return; +} + +#endif /* HAVE_KRB5_LOCATE_PLUGIN_H */ -- cgit From 0805a4bc715f055fd68c5e27bd46eadfb101e1b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Sep 2007 17:19:57 +0000 Subject: r25236: make it possible to alter WINBINDD_SOCKET_DIR via "winbindd:socket dir=/path/to/dir" for usage in make test metze (This used to be commit 5566cf01e827edf60c0235a661d95dd376210108) --- source3/winbindd/winbindd_util.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 37d29e1765..c1600823fc 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1158,6 +1158,11 @@ void fill_domain_username(fstring name, const char *domain, const char *user, BO * Winbindd socket accessor functions */ +const char *get_winbind_pipe_dir(void) +{ + return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR); +} + char *get_winbind_priv_pipe_dir(void) { return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR); -- cgit From 1edf050ad8682f2cd0781babf9b9db132e1e7493 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Sep 2007 19:05:54 +0000 Subject: r25241: remove sequence_number out of WINBINDD_DOMAIN_INFO call as this is always answered by the winbindd parent and will most times return old sequence number values. metze (This used to be commit 9caf54c868e8c0109730860e772c9cc404e2f899) --- source3/winbindd/winbindd_util.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index c1600823fc..0175990f0c 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -631,8 +631,6 @@ static void init_child_recv(void *private_data, BOOL success) state->response->data.domain_info.native_mode; state->domain->active_directory = state->response->data.domain_info.active_directory; - state->domain->sequence_number = - state->response->data.domain_info.sequence_number; init_dc_connection(state->domain); @@ -677,8 +675,6 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai = domain->active_directory; state->response.data.domain_info.primary = domain->primary; - state->response.data.domain_info.sequence_number = - domain->sequence_number; return WINBINDD_OK; } -- cgit From 8ad224663576b32a4bcd43f808851d2cdde34656 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 20 Sep 2007 18:37:34 +0000 Subject: r25260: add trusted domains always to the end of the list. Now BUILTIN is always the first domain followed by the domain of our own SAM DB and the primary domain (in member server mode). metze (This used to be commit b8d67b78aa1c35e4e7e61050c1fccbb6d76d9fd7) --- source3/winbindd/winbindd_util.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 0175990f0c..0e6ba1c043 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -186,7 +186,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const } /* Link to domain list */ - DLIST_ADD(_domain_list, domain); + DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *); wcache_tdc_add_domain( domain ); @@ -688,6 +688,25 @@ BOOL init_domain_list(void) /* Free existing list */ free_domain_list(); + /* BUILTIN domain */ + + domain = add_trusted_domain("BUILTIN", NULL, &passdb_methods, + &global_sid_Builtin); + if (domain) { + setup_domain_child(domain, &domain->child, NULL); + } + + /* Local SAM */ + + domain = add_trusted_domain(get_global_sam_name(), NULL, + &passdb_methods, get_global_sam_sid()); + if (domain) { + if ( role != ROLE_DOMAIN_MEMBER ) { + domain->primary = True; + } + setup_domain_child(domain, &domain->child, NULL); + } + /* Add ourselves as the first entry. */ if ( role == ROLE_DOMAIN_MEMBER ) { @@ -714,25 +733,6 @@ BOOL init_domain_list(void) } } - /* Local SAM */ - - domain = add_trusted_domain(get_global_sam_name(), NULL, - &passdb_methods, get_global_sam_sid()); - if (domain) { - if ( role != ROLE_DOMAIN_MEMBER ) { - domain->primary = True; - } - setup_domain_child(domain, &domain->child, NULL); - } - - /* BUILTIN domain */ - - domain = add_trusted_domain("BUILTIN", NULL, &passdb_methods, - &global_sid_Builtin); - if (domain) { - setup_domain_child(domain, &domain->child, NULL); - } - return True; } -- cgit From 3c3b9afe7f229a69d051db8a08ece6ec9349e0a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Oct 2007 12:25:57 +0000 Subject: r25571: split up child_dispatch_table into domain, idmap and locator tables metze (This used to be commit abbb36a37c1dba2218a6c7ec31739eba5f250127) --- source3/winbindd/winbindd_util.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 0e6ba1c043..49d20c527e 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -324,7 +324,10 @@ static void trustdom_recv(void *private_data, BOOL success) &cache_methods, &sid); if (domain) { - setup_domain_child(domain, &domain->child, NULL); + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); } } p=q; @@ -693,7 +696,10 @@ BOOL init_domain_list(void) domain = add_trusted_domain("BUILTIN", NULL, &passdb_methods, &global_sid_Builtin); if (domain) { - setup_domain_child(domain, &domain->child, NULL); + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); } /* Local SAM */ @@ -704,7 +710,10 @@ BOOL init_domain_list(void) if ( role != ROLE_DOMAIN_MEMBER ) { domain->primary = True; } - setup_domain_child(domain, &domain->child, NULL); + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); } /* Add ourselves as the first entry. */ @@ -721,8 +730,11 @@ BOOL init_domain_list(void) &cache_methods, &our_sid); if (domain) { domain->primary = True; - setup_domain_child(domain, &domain->child, NULL); - + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); + /* Even in the parent winbindd we'll need to talk to the DC, so try and see if we can contact it. Theoretically this isn't neccessary @@ -767,7 +779,10 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid ) domain->internal = False; domain->online = True; - setup_domain_child(domain, &domain->child, NULL); + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); wcache_tdc_add_domain( domain ); -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/winbindd/winbindd_util.c | 75 +++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 21 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 49d20c527e..c2fe09eead 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -35,6 +35,7 @@ extern struct winbindd_methods passdb_methods; * Winbind daemon for NT domain authentication nss module. **/ + /* The list of trusted domains. Note that the list can be deleted and recreated using the init_domain_list() function so pointers to individual winbindd_domain structures cannot be made. Keep a copy of @@ -324,10 +325,7 @@ static void trustdom_recv(void *private_data, BOOL success) &cache_methods, &sid); if (domain) { - setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + setup_domain_child(domain, &domain->child, NULL); } } p=q; @@ -696,10 +694,7 @@ BOOL init_domain_list(void) domain = add_trusted_domain("BUILTIN", NULL, &passdb_methods, &global_sid_Builtin); if (domain) { - setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + setup_domain_child(domain, &domain->child, NULL); } /* Local SAM */ @@ -710,10 +705,7 @@ BOOL init_domain_list(void) if ( role != ROLE_DOMAIN_MEMBER ) { domain->primary = True; } - setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + setup_domain_child(domain, &domain->child, NULL); } /* Add ourselves as the first entry. */ @@ -730,11 +722,8 @@ BOOL init_domain_list(void) &cache_methods, &our_sid); if (domain) { domain->primary = True; - setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); - + setup_domain_child(domain, &domain->child, NULL); + /* Even in the parent winbindd we'll need to talk to the DC, so try and see if we can contact it. Theoretically this isn't neccessary @@ -779,10 +768,7 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid ) domain->internal = False; domain->online = True; - setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + setup_domain_child(domain, &domain->child, NULL); wcache_tdc_add_domain( domain ); @@ -1179,6 +1165,53 @@ char *get_winbind_priv_pipe_dir(void) return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR); } +/* Open the winbindd socket */ + +static int _winbindd_socket = -1; +static int _winbindd_priv_socket = -1; + +int open_winbindd_socket(void) +{ + if (_winbindd_socket == -1) { + _winbindd_socket = create_pipe_sock( + get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755); + DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n", + _winbindd_socket)); + } + + return _winbindd_socket; +} + +int open_winbindd_priv_socket(void) +{ + if (_winbindd_priv_socket == -1) { + _winbindd_priv_socket = create_pipe_sock( + get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750); + DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n", + _winbindd_priv_socket)); + } + + return _winbindd_priv_socket; +} + +/* Close the winbindd socket */ + +void close_winbindd_socket(void) +{ + if (_winbindd_socket != -1) { + DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n", + _winbindd_socket)); + close(_winbindd_socket); + _winbindd_socket = -1; + } + if (_winbindd_priv_socket != -1) { + DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n", + _winbindd_priv_socket)); + close(_winbindd_priv_socket); + _winbindd_priv_socket = -1; + } +} + /* * Client list accessor functions */ -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/winbindd/winbindd_util.c | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index c2fe09eead..54bb5a24b7 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -77,7 +77,7 @@ void free_domain_list(void) } } -static BOOL is_internal_domain(const DOM_SID *sid) +static bool is_internal_domain(const DOM_SID *sid) { if (sid == NULL) return False; @@ -88,7 +88,7 @@ static BOOL is_internal_domain(const DOM_SID *sid) return (sid_check_is_domain(sid) || sid_check_is_builtin(sid)); } -static BOOL is_in_internal_domain(const DOM_SID *sid) +static bool is_in_internal_domain(const DOM_SID *sid) { if (sid == NULL) return False; @@ -204,12 +204,12 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const struct trustdom_state { TALLOC_CTX *mem_ctx; - BOOL primary; - BOOL forest_root; + bool primary; + bool forest_root; struct winbindd_response *response; }; -static void trustdom_recv(void *private_data, BOOL success); +static void trustdom_recv(void *private_data, bool success); static void rescan_forest_root_trusts( void ); static void rescan_forest_trusts( void ); @@ -253,7 +253,7 @@ static void add_trusted_domains( struct winbindd_domain *domain ) trustdom_recv, state); } -static void trustdom_recv(void *private_data, BOOL success) +static void trustdom_recv(void *private_data, bool success) { struct trustdom_state *state = talloc_get_type_abort(private_data, struct trustdom_state); @@ -518,16 +518,16 @@ struct init_child_state { struct winbindd_domain *domain; struct winbindd_request *request; struct winbindd_response *response; - void (*continuation)(void *private_data, BOOL success); + void (*continuation)(void *private_data, bool success); void *private_data; }; -static void init_child_recv(void *private_data, BOOL success); -static void init_child_getdc_recv(void *private_data, BOOL success); +static void init_child_recv(void *private_data, bool success); +static void init_child_getdc_recv(void *private_data, bool success); enum winbindd_result init_child_connection(struct winbindd_domain *domain, void (*continuation)(void *private_data, - BOOL success), + bool success), void *private_data) { TALLOC_CTX *mem_ctx; @@ -585,7 +585,7 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain, return WINBINDD_PENDING; } -static void init_child_getdc_recv(void *private_data, BOOL success) +static void init_child_getdc_recv(void *private_data, bool success) { struct init_child_state *state = talloc_get_type_abort(private_data, struct init_child_state); @@ -607,7 +607,7 @@ static void init_child_getdc_recv(void *private_data, BOOL success) init_child_recv, state); } -static void init_child_recv(void *private_data, BOOL success) +static void init_child_recv(void *private_data, bool success) { struct init_child_state *state = talloc_get_type_abort(private_data, struct init_child_state); @@ -681,7 +681,7 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai } /* Look up global info for the winbind daemon */ -BOOL init_domain_list(void) +bool init_domain_list(void) { struct winbindd_domain *domain; int role = lp_server_role(); @@ -951,7 +951,7 @@ struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name) /* Lookup a sid in a domain from a name */ -BOOL winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx, +bool winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx, enum winbindd_cmd orig_cmd, struct winbindd_domain *domain, const char *domain_name, @@ -983,7 +983,7 @@ BOOL winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx, * @retval True if the name exists, in which case @p name and @p type * are set, otherwise False. **/ -BOOL winbindd_lookup_name_by_sid(TALLOC_CTX *mem_ctx, +bool winbindd_lookup_name_by_sid(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, DOM_SID *sid, char **dom_name, @@ -1036,7 +1036,7 @@ void free_getent_state(struct getent_state *state) /* Is this a domain which we may assume no DOMAIN\ prefix? */ -static BOOL assume_domain(const char *domain) +static bool assume_domain(const char *domain) { /* never assume the domain on a standalone server */ @@ -1064,7 +1064,7 @@ static BOOL assume_domain(const char *domain) /* Parse a string of the form DOMAIN\user into a domain and a user */ -BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) +bool parse_domain_user(const char *domuser, fstring domain, fstring user) { char *p = strchr(domuser,*lp_winbind_separator()); @@ -1089,7 +1089,7 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) return True; } -BOOL parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, +bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, char **domain, char **user) { fstring fstr_domain, fstr_user; @@ -1110,7 +1110,7 @@ BOOL parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, really should be changed to use this instead of doing things by hand. JRA. */ -BOOL canonicalize_username(fstring username_inout, fstring domain, fstring user) +bool canonicalize_username(fstring username_inout, fstring domain, fstring user) { if (!parse_domain_user(username_inout, domain, user)) { return False; @@ -1135,7 +1135,7 @@ BOOL canonicalize_username(fstring username_inout, fstring domain, fstring user) We always canonicalize as UPPERCASE DOMAIN, lowercase username. */ -void fill_domain_username(fstring name, const char *domain, const char *user, BOOL can_assume) +void fill_domain_username(fstring name, const char *domain, const char *user, bool can_assume) { fstring tmp_user; @@ -1376,7 +1376,7 @@ void ws_name_return( char *name, char replace ) /********************************************************************* ********************************************************************/ -BOOL winbindd_can_contact_domain( struct winbindd_domain *domain ) +bool winbindd_can_contact_domain( struct winbindd_domain *domain ) { /* We can contact the domain if it is our primary domain */ @@ -1406,7 +1406,7 @@ BOOL winbindd_can_contact_domain( struct winbindd_domain *domain ) /********************************************************************* ********************************************************************/ -BOOL winbindd_internal_child(struct winbindd_child *child) +bool winbindd_internal_child(struct winbindd_child *child) { if ((child == idmap_child()) || (child == locator_child())) { return True; -- cgit From 3d9a578064d46e595a51af5896a51db47bd2da4e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Oct 2007 12:25:57 +0000 Subject: r25571: split up child_dispatch_table into domain, idmap and locator tables metze (cherry picked from commit abbb36a37c1dba2218a6c7ec31739eba5f250127) (This used to be commit 5af1b45ed31043f952ec141d0f5f2973aec69d1a) --- source3/winbindd/winbindd_util.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 54bb5a24b7..8970c1faf9 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -325,7 +325,10 @@ static void trustdom_recv(void *private_data, bool success) &cache_methods, &sid); if (domain) { - setup_domain_child(domain, &domain->child, NULL); + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); } } p=q; @@ -694,7 +697,10 @@ bool init_domain_list(void) domain = add_trusted_domain("BUILTIN", NULL, &passdb_methods, &global_sid_Builtin); if (domain) { - setup_domain_child(domain, &domain->child, NULL); + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); } /* Local SAM */ @@ -705,7 +711,10 @@ bool init_domain_list(void) if ( role != ROLE_DOMAIN_MEMBER ) { domain->primary = True; } - setup_domain_child(domain, &domain->child, NULL); + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); } /* Add ourselves as the first entry. */ @@ -722,8 +731,11 @@ bool init_domain_list(void) &cache_methods, &our_sid); if (domain) { domain->primary = True; - setup_domain_child(domain, &domain->child, NULL); - + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); + /* Even in the parent winbindd we'll need to talk to the DC, so try and see if we can contact it. Theoretically this isn't neccessary @@ -768,7 +780,10 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid ) domain->internal = False; domain->online = True; - setup_domain_child(domain, &domain->child, NULL); + setup_domain_child(domain, + &domain->child, + domain_dispatch_table, + NULL); wcache_tdc_add_domain( domain ); -- cgit From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: This is a large patch (sorry). Migrate from struct in_addr to struct sockaddr_storage in most places that matter (ie. not the nmbd and NetBIOS lookups). This passes make test on an IPv4 box, but I'll have to do more work/testing on IPv6 enabled boxes. This should now give us a framework for testing and finishing the IPv6 migration. It's at the state where someone with a working IPv6 setup should (theorecically) be able to type : smbclient //ipv6-address/share and have it work. Jeremy. (This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/winbindd/winbindd_util.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 8970c1faf9..5c8c8ea13d 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1438,6 +1438,7 @@ bool winbindd_internal_child(struct winbindd_child *child) static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain) { char *var = NULL; + char addr[INET6_ADDRSTRLEN]; const char *kdc = NULL; int lvl = 11; @@ -1451,8 +1452,9 @@ static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain) return; } - kdc = inet_ntoa(domain->dcaddr.sin_addr); - if (!kdc) { + print_sockaddr(addr, sizeof(addr), &domain->dcaddr); + kdc = addr; + if (!*kdc) { DEBUG(lvl,("winbindd_set_locator_kdc_env: %s no DC IP\n", domain->alt_name)); kdc = domain->dcname; -- cgit From 78c6ee0090f4122bc25baaacb5546517ad4b7bc6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 24 Nov 2007 17:27:54 +0100 Subject: Remove some globals (This used to be commit 31d0a846db08d845e6cdfd85def4ac1c34031e02) --- source3/winbindd/winbindd_util.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 5c8c8ea13d..56ae4f27bb 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1466,8 +1466,8 @@ static void winbindd_set_locator_kdc_env(const struct winbindd_domain *domain) return; } - if (asprintf(&var, "%s_%s", WINBINDD_LOCATOR_KDC_ADDRESS, - strupper_static(domain->alt_name)) == -1) { + if (asprintf_strupper_m(&var, "%s_%s", WINBINDD_LOCATOR_KDC_ADDRESS, + domain->alt_name) == -1) { return; } @@ -1503,8 +1503,8 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain) return; } - if (asprintf(&var, "%s_%s", WINBINDD_LOCATOR_KDC_ADDRESS, - strupper_static(domain->alt_name)) == -1) { + if (asprintf_strupper_m(&var, "%s_%s", WINBINDD_LOCATOR_KDC_ADDRESS, + domain->alt_name) == -1) { return; } -- cgit From 873f14ae408d5fa151f8e4f83c3dfe0c9b8a4d2d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Dec 2007 12:27:57 +0100 Subject: winbindd: move domain child specific stuff into its own file metze (This used to be commit 075d315e0f72d506b70040da10940e4af131b4e2) --- source3/winbindd/winbindd_util.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 56ae4f27bb..2389a4be13 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -326,9 +326,7 @@ static void trustdom_recv(void *private_data, bool success) &sid); if (domain) { setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + &domain->child); } } p=q; @@ -698,9 +696,7 @@ bool init_domain_list(void) &global_sid_Builtin); if (domain) { setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + &domain->child); } /* Local SAM */ @@ -712,9 +708,7 @@ bool init_domain_list(void) domain->primary = True; } setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + &domain->child); } /* Add ourselves as the first entry. */ @@ -732,9 +726,7 @@ bool init_domain_list(void) if (domain) { domain->primary = True; setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + &domain->child); /* Even in the parent winbindd we'll need to talk to the DC, so try and see if we can @@ -781,9 +773,7 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid ) domain->online = True; setup_domain_child(domain, - &domain->child, - domain_dispatch_table, - NULL); + &domain->child); wcache_tdc_add_domain( domain ); -- cgit From 900288a2b86abd247f9eb4cd15dc5617a17cfef1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:11:36 +0100 Subject: Replace sid_string_static by sid_string_dbg in DEBUGs (This used to be commit bb35e794ec129805e874ceba882bcc1e84791a09) --- source3/winbindd/winbindd_util.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 2389a4be13..b552aac709 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -193,7 +193,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const DEBUG(2,("Added domain %s %s %s\n", domain->name, domain->alt_name, - &domain->sid?sid_string_static(&domain->sid):"")); + &domain->sid?sid_string_dbg(&domain->sid):"")); return domain; } @@ -922,8 +922,7 @@ struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid) * one to contact the external DC's. On member servers the internal * domains are different: These are part of the local SAM. */ - DEBUG(10, ("find_lookup_domain_from_sid(%s)\n", - sid_string_static(sid))); + DEBUG(10, ("find_lookup_domain_from_sid(%s)\n", sid_string_dbg(sid))); if (IS_DC || is_internal_domain(sid) || is_in_internal_domain(sid)) { DEBUG(10, ("calling find_domain_from_sid\n")); -- cgit From d899b8c56ad6556baf2d2374704cc8cd1b15d5ad Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:58:28 +0100 Subject: Use sid_to_string directly It seems a bit pointless to do a fstrcpy(dst, sid_string_static(src)) (This used to be commit c221c246b10e2dbbd54a9af2dc45de2eae237380) --- source3/winbindd/winbindd_util.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index b552aac709..5ac1eb64da 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -668,8 +668,7 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai fstrcpy(state->response.data.domain_info.name, domain->name); fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name); - fstrcpy(state->response.data.domain_info.sid, - sid_string_static(&domain->sid)); + sid_to_string(state->response.data.domain_info.sid, &domain->sid); state->response.data.domain_info.native_mode = domain->native_mode; -- cgit From 2e07c2ade89f4ff281c61f74cb88e09990cf5f46 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 22:47:30 +0100 Subject: s/sid_to_string/sid_to_fstring/ least surprise for callers (This used to be commit eb523ba77697346a365589101aac379febecd546) --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 5ac1eb64da..70468b6bcd 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -668,7 +668,7 @@ enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domai fstrcpy(state->response.data.domain_info.name, domain->name); fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name); - sid_to_string(state->response.data.domain_info.sid, &domain->sid); + sid_to_fstring(state->response.data.domain_info.sid, &domain->sid); state->response.data.domain_info.native_mode = domain->native_mode; -- cgit From 84a50e21541e4c3a0bfb70d5d501dc4b7e6f9714 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Fri, 4 Jan 2008 13:35:41 -0600 Subject: Fix the inherited trust flags when spidering the trust heirarchy. Also *do not* clear the trust list when rescanning or else it is possible to suffer from a race condition where no trusted domains can be found. (This used to be commit e7164a252bf213a74d6eeac5aa04645eed5be241) --- source3/winbindd/winbindd_util.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 70468b6bcd..cc12d4b7ea 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -500,9 +500,13 @@ void rescan_trusted_domains( void ) ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) ) return; - /* clear the TRUSTDOM cache first */ - - wcache_tdc_clear(); + /* I use to clear the cache here and start over but that + caused problems in child processes that needed the + trust dom list early on. Removing it means we + could have some trusted domains listed that have been + removed from our primary domain's DC until a full + restart. This should be ok since I think this is what + Windows does as well. */ /* this will only add new domains we didn't already know about in the domain_list()*/ -- cgit From f3603d5a5ab878d45b67bf0f33e2beca50d0af2d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Jan 2008 00:11:31 +0100 Subject: Convert add_sid_to_array() add_sid_to_array_unique() to return NTSTATUS. Michael (This used to be commit 6b2b9a60ef857ec31da5fea631535205fbdede4a) --- source3/winbindd/winbindd_util.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index cc12d4b7ea..dc48fdef8b 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1304,19 +1304,22 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, /* always add the primary group to the sid array */ sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid); - if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) { + status = add_sid_to_array(mem_ctx, &primary_group, user_sids, + &num_groups); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); - return NT_STATUS_NO_MEMORY; + return status; } for (i=0; inum_groups; i++) { sid_copy(&group_sid, &info3->dom_sid.sid); sid_append_rid(&group_sid, info3->gids[i].g_rid); - if (!add_sid_to_array(mem_ctx, &group_sid, user_sids, - &num_groups)) { + status = add_sid_to_array(mem_ctx, &group_sid, user_sids, + &num_groups); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); - return NT_STATUS_NO_MEMORY; + return status; } } @@ -1328,11 +1331,11 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE) continue; - if (!add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, - user_sids, &num_groups)) - { + status = add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, + user_sids, &num_groups); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); - return NT_STATUS_NO_MEMORY; + return status; } } -- cgit From 3b83f4915885edfe8f01f4f68daad6b909fe473d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 23 Jan 2008 13:52:42 +0100 Subject: Initialize _domain_list to NULL. Just to be sure the "if (!_domain_list)" in domain_list() test always works. Michael (This used to be commit 1f49065d44dd7570d5a9928359751bd36f287952) --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index dc48fdef8b..0381053331 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -41,7 +41,7 @@ extern struct winbindd_methods passdb_methods; individual winbindd_domain structures cannot be made. Keep a copy of the domain name instead. */ -static struct winbindd_domain *_domain_list; +static struct winbindd_domain *_domain_list = NULL; /** When was the last scan of trusted domains done? -- cgit From 614ba32b221aee268b86033ee10da4dbdb087365 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 24 Jan 2008 22:47:49 +0100 Subject: Fix assignment to request->data.init_conn.is_primary in init_child_connection(). The present assignment "request->data.init_conn.is_primary = domain->internal ? False : True" simply feels wrong. This seems to be the thing right to do: "request->data.init_conn.is_primary = domain->primary ? true : false". The question is: Does this have any purpose at all? data.init_conn.is_primary seems to be used nowhere in the whole code at all. Is it (still) needed? Michael (This used to be commit 8bb21b8b3802e7b093a3c4fb41b8550033388878) --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 0381053331..724cce2512 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -571,7 +571,7 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain, /* The primary domain has to find the DC name itself */ request->cmd = WINBINDD_INIT_CONNECTION; fstrcpy(request->domain_name, domain->name); - request->data.init_conn.is_primary = domain->internal ? False : True; + request->data.init_conn.is_primary = domain->primary ? true : false; fstrcpy(request->data.init_conn.dcname, ""); async_request(mem_ctx, &domain->child, request, response, init_child_recv, state); -- cgit From 2a542ce7727cf3eb7f64d855c70d974f02185a2a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 24 Jan 2008 22:15:33 +0100 Subject: Add a debug message winbindd_can_contact_domain() explaining the reason for failure. Michael (This used to be commit ba5373ed7f74d560a9de8620039b596b8938d1dc) --- source3/winbindd/winbindd_util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 724cce2512..3d9ede3cdf 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1404,6 +1404,8 @@ bool winbindd_can_contact_domain( struct winbindd_domain *domain ) if ( domain->active_directory && ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) ) { + DEBUG(10, ("Domain is an AD domain and we have no inbound " + "trust.\n")); return False; } -- cgit From 3ca606731b99754493ab5a8d761225c637bc82dd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 25 Jan 2008 16:40:17 +0100 Subject: Fix winbindd_can_contact_domain() on a samba DC. The check for inbound trusts is invalid when samba is a DC and has a trust with an active directory domain. This effectively prevented tusts with an AD domain on a samba DC from working (unless using "winbindd rpc only"), because an ads_connect() was never performed. Only the rpc-based winbindd methods were working properly. Jerry: Please check! Michael (This used to be commit dcd42a1e0642c69348adfaeecef7f7f2f074ac30) --- source3/winbindd/winbindd_util.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 3d9ede3cdf..d16b7423a1 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1398,10 +1398,13 @@ bool winbindd_can_contact_domain( struct winbindd_domain *domain ) if ( domain->domain_flags & DS_DOMAIN_IN_FOREST ) return True; - /* We cannot contact the domain if it is running AD and - we have no inbound trust */ + /* + * On a _member_ server, we cannot contact the domain if it + * is running AD and we have no inbound trust. + */ - if ( domain->active_directory && + if ( !IS_DC && + domain->active_directory && ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) ) { DEBUG(10, ("Domain is an AD domain and we have no inbound " -- cgit From 235deb1b66ccfb4a264010e8ffe11a3a3682ac0d Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Fri, 25 Jan 2008 12:21:14 -0600 Subject: Always trust the domain flags in the wcache trusted domain cache. Use the flags stored in the tdb when determining if a domain can be contacted. The tdb should be considered authoratative anyways unless you know the flags in the winbindd_domain are correct (such as when first enumerating trusts). Original suggestion and patch from Steven Danneman . Manually rewritten by me for 3.2. (This used to be commit f53658a20de07a29abbe2e90917b328d00fc0024) --- source3/winbindd/winbindd_util.c | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index d16b7423a1..f6bb5750ea 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1386,36 +1386,56 @@ void ws_name_return( char *name, char replace ) /********************************************************************* ********************************************************************/ -bool winbindd_can_contact_domain( struct winbindd_domain *domain ) +bool winbindd_can_contact_domain(struct winbindd_domain *domain) { + struct winbindd_tdc_domain *tdc = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + bool ret = false; + /* We can contact the domain if it is our primary domain */ - if ( domain->primary ) - return True; + if (domain->primary) { + return true; + } - /* Can always contact a domain that is in out forest */ + /* Trust the TDC cache and not the winbindd_domain flags */ - if ( domain->domain_flags & DS_DOMAIN_IN_FOREST ) - return True; + if ((tdc = wcache_tdc_fetch_domain(frame, domain->name)) == NULL) { + DEBUG(10,("winbindd_can_contact_domain: %s not found in cache\n", + domain->name)); + return false; + } + + /* Can always contact a domain that is in out forest */ + if (tdc->trust_flags & DS_DOMAIN_IN_FOREST) { + ret = true; + goto done; + } + /* * On a _member_ server, we cannot contact the domain if it * is running AD and we have no inbound trust. */ - if ( !IS_DC && + if (!IS_DC && domain->active_directory && - ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) ) + ((tdc->trust_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND)) { - DEBUG(10, ("Domain is an AD domain and we have no inbound " - "trust.\n")); - return False; + DEBUG(10, ("winbindd_can_contact_domain: %s is an AD domain " + "and we have no inbound trust.\n", domain->name)); + goto done; } - + /* Assume everything else is ok (probably not true but what can you do?) */ + + ret = true; + +done: + talloc_destroy(frame); - return True; + return ret; } /********************************************************************* -- cgit From 80b2e330f939d9877352f8fbdbec3a4e0e395c7b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 29 Jan 2008 17:49:38 +0100 Subject: Remove include/rpc_ds.h and all references to it completly. Jerry, please have a look if you're fine with that. Guenther (This used to be commit beae25c808a3a03d645f247e9befcd05e3ecca2c) --- source3/winbindd/winbindd_util.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index f6bb5750ea..10779cd60a 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -218,7 +218,7 @@ static void add_trusted_domains( struct winbindd_domain *domain ) TALLOC_CTX *mem_ctx; struct winbindd_request *request; struct winbindd_response *response; - uint32 fr_flags = (DS_DOMAIN_TREE_ROOT|DS_DOMAIN_IN_FOREST); + uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST); struct trustdom_state *state; @@ -391,8 +391,8 @@ static void rescan_forest_root_trusts( void ) the domain_list() as our primary domain may not have been initialized. */ - if ( !(dom_list[i].trust_flags & DS_DOMAIN_TREE_ROOT) ) { - continue; + if ( !(dom_list[i].trust_flags & NETR_TRUST_FLAG_TREEROOT) ) { + continue; } /* Here's the forest root */ @@ -456,10 +456,10 @@ static void rescan_forest_trusts( void ) if ( d && (d->internal || d->primary ) ) continue; - - if ( (flags & DS_DOMAIN_DIRECT_INBOUND) && - (type == DS_DOMAIN_TRUST_TYPE_UPLEVEL) && - (attribs == DS_DOMAIN_TRUST_ATTRIB_FOREST_TRANSITIVE) ) + + if ( (flags & NETR_TRUST_FLAG_INBOUND) && + (type == NETR_TRUST_TYPE_UPLEVEL) && + (attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) ) { /* add the trusted domain if we don't know about it */ @@ -770,8 +770,8 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid ) forest trust */ domain->active_directory = True; - domain->domain_flags = DS_DOMAIN_DIRECT_OUTBOUND; - domain->domain_type = DS_DOMAIN_TRUST_TYPE_UPLEVEL; + domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND; + domain->domain_type = NETR_TRUST_TYPE_UPLEVEL; domain->internal = False; domain->online = True; @@ -1408,7 +1408,7 @@ bool winbindd_can_contact_domain(struct winbindd_domain *domain) /* Can always contact a domain that is in out forest */ - if (tdc->trust_flags & DS_DOMAIN_IN_FOREST) { + if (tdc->trust_flags & NETR_TRUST_FLAG_IN_FOREST) { ret = true; goto done; } @@ -1420,7 +1420,7 @@ bool winbindd_can_contact_domain(struct winbindd_domain *domain) if (!IS_DC && domain->active_directory && - ((tdc->trust_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND)) + ((tdc->trust_flags & NETR_TRUST_FLAG_INBOUND) != NETR_TRUST_FLAG_INBOUND)) { DEBUG(10, ("winbindd_can_contact_domain: %s is an AD domain " "and we have no inbound trust.\n", domain->name)); -- cgit From 93a3c5b3f9927973b4ad1496f593ea147052d1e1 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 1 Feb 2008 13:50:04 -0500 Subject: Fix winbindd running on a Samba DC, This patch make sure we do not try to contact smbd in the main dameon to avoid deadlocks. All the operations that require connecting to smbd are performed in the domain child anyway. (This used to be commit 9347d34b502bef70cdae8f3e8acd9796dba49581) --- source3/winbindd/winbindd_util.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 70468b6bcd..795209619c 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -82,9 +82,6 @@ static bool is_internal_domain(const DOM_SID *sid) if (sid == NULL) return False; - if ( IS_DC ) - return sid_check_is_builtin(sid); - return (sid_check_is_domain(sid) || sid_check_is_builtin(sid)); } @@ -93,9 +90,6 @@ static bool is_in_internal_domain(const DOM_SID *sid) if (sid == NULL) return False; - if ( IS_DC ) - return sid_check_is_in_builtin(sid); - return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid)); } -- cgit From c25958a046bbcfc13db200430e505ac4ee9b3f27 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 17 Feb 2008 02:08:12 +0100 Subject: Use netr_SamInfo3 everywhere in winbindd. Guenther (This used to be commit d9502eb75395131d5a8130ff2c4ebace106cb974) --- source3/winbindd/winbindd_util.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 7933ecf63e..038bafbe4e 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1272,7 +1272,7 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, const DOM_SID *user_sid, uint32 *p_num_groups, DOM_SID **user_sids) { - NET_USER_INFO_3 *info3 = NULL; + struct netr_SamInfo3 *info3 = NULL; NTSTATUS status = NT_STATUS_NO_MEMORY; int i; size_t num_groups = 0; @@ -1290,13 +1290,13 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - if (info3->num_groups == 0) { + if (info3->base.groups.count == 0) { TALLOC_FREE(info3); return NT_STATUS_UNSUCCESSFUL; } /* always add the primary group to the sid array */ - sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid); + sid_compose(&primary_group, info3->base.domain_sid, info3->base.rid); status = add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups); @@ -1305,9 +1305,9 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, return status; } - for (i=0; inum_groups; i++) { - sid_copy(&group_sid, &info3->dom_sid.sid); - sid_append_rid(&group_sid, info3->gids[i].g_rid); + for (i=0; i < info3->base.groups.count; i++) { + sid_copy(&group_sid, info3->base.domain_sid); + sid_append_rid(&group_sid, info3->base.groups.rids[i].rid); status = add_sid_to_array(mem_ctx, &group_sid, user_sids, &num_groups); @@ -1319,13 +1319,13 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, /* Add any Universal groups in the other_sids list */ - for (i=0; inum_other_sids; i++) { + for (i=0; i < info3->sidcount; i++) { /* Skip Domain local groups outside our domain. We'll get these from the getsidaliases() RPC call. */ - if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE) + if (info3->sids[i].attributes & SE_GROUP_RESOURCE) continue; - status = add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, + status = add_sid_to_array(mem_ctx, info3->sids[i].sid, user_sids, &num_groups); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); -- cgit From 223071f01de8d85b594bab7c1f8514386da11281 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Tue, 25 Mar 2008 16:50:58 -0700 Subject: Forest root trust flags won't overwrite child trust flags * changed the behavior of winbind_ads.c:trusted_domains() to not overwrite existing trust information if we're joined to a child domain, and querying the forest root domain. Previously if we were joined to a child domain, we'd request all known trust information from this child domain (our primary domain) and store it in the tdc. We'd then request all trust information from our tree root (to get the forests we transitively trust) and overwrite the existing trust information we already had from the perspective of the tree root. * updated several comments and fixed typos (This used to be commit 6aac972d790ad5ca65096cb2e85e6819b60a5413) --- source3/winbindd/winbindd_util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 038bafbe4e..641fd5a9f5 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -339,7 +339,7 @@ static void trustdom_recv(void *private_data, bool success) */ if ( state->primary ) { - /* If this is our primary domain and we are not the in the + /* If this is our primary domain and we are not in the forest root, we have to scan the root trusts first */ if ( !state->forest_root ) @@ -349,7 +349,7 @@ static void trustdom_recv(void *private_data, bool success) } else if ( state->forest_root ) { /* Once we have done root forest trust search, we can - go on to search thing trusted forests */ + go on to search the trusted forests */ rescan_forest_trusts(); } @@ -419,7 +419,7 @@ static void rescan_forest_root_trusts( void ) } /******************************************************************** - scan the transitive forest trists (not our own) + scan the transitive forest trusts (not our own) ********************************************************************/ -- cgit From bea4541e11f0664aaa8b62d525e0a02b14fc3afa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Apr 2008 02:53:40 +0200 Subject: Use sid_array_from_info3 in lookup_usergroups_cached(). Guenther (This used to be commit 65b4cb20ea3fb806cfd50281e08f32bea70fafce) --- source3/winbindd/winbindd_util.c | 50 ++++++++-------------------------------- 1 file changed, 10 insertions(+), 40 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 641fd5a9f5..ec97b49428 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1274,14 +1274,11 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, { struct netr_SamInfo3 *info3 = NULL; NTSTATUS status = NT_STATUS_NO_MEMORY; - int i; size_t num_groups = 0; - DOM_SID group_sid, primary_group; - + DEBUG(3,(": lookup_usergroups_cached\n")); - + *user_sids = NULL; - num_groups = 0; *p_num_groups = 0; info3 = netsamlogon_cache_get(mem_ctx, user_sid); @@ -1294,46 +1291,19 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, TALLOC_FREE(info3); return NT_STATUS_UNSUCCESSFUL; } - - /* always add the primary group to the sid array */ - sid_compose(&primary_group, info3->base.domain_sid, info3->base.rid); - - status = add_sid_to_array(mem_ctx, &primary_group, user_sids, - &num_groups); + + /* Skip Domain local groups outside our domain. + We'll get these from the getsidaliases() RPC call. */ + status = sid_array_from_info3(mem_ctx, info3, + user_sids, + &num_groups, + true, true); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); return status; } - for (i=0; i < info3->base.groups.count; i++) { - sid_copy(&group_sid, info3->base.domain_sid); - sid_append_rid(&group_sid, info3->base.groups.rids[i].rid); - - status = add_sid_to_array(mem_ctx, &group_sid, user_sids, - &num_groups); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(info3); - return status; - } - } - - /* Add any Universal groups in the other_sids list */ - - for (i=0; i < info3->sidcount; i++) { - /* Skip Domain local groups outside our domain. - We'll get these from the getsidaliases() RPC call. */ - if (info3->sids[i].attributes & SE_GROUP_RESOURCE) - continue; - - status = add_sid_to_array(mem_ctx, info3->sids[i].sid, - user_sids, &num_groups); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(info3); - return status; - } - } - - TALLOC_FREE(info3); *p_num_groups = num_groups; status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; -- cgit From 433a05c1abfa4f67bbbb4633db69ba7e01921800 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 May 2008 10:37:52 -0700 Subject: Fix winbindd on a PDC by reverting : 83b04c60fac76ccd2d5aecb14f8896a07d488b1f..6e66512d5beb256a44c6703cdb8c7fa7e0fd8537. We still need to address https://bugzilla.redhat.com/show_bug.cgi?id=429024, but this will come later. Jeremy. (This used to be commit 41e20becf3b976656f60aaec9175df329803b012) --- source3/winbindd/winbindd_util.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index ec97b49428..9008cf8122 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -82,6 +82,9 @@ static bool is_internal_domain(const DOM_SID *sid) if (sid == NULL) return False; + if ( IS_DC ) + return sid_check_is_builtin(sid); + return (sid_check_is_domain(sid) || sid_check_is_builtin(sid)); } @@ -90,6 +93,9 @@ static bool is_in_internal_domain(const DOM_SID *sid) if (sid == NULL) return False; + if ( IS_DC ) + return sid_check_is_in_builtin(sid); + return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid)); } -- cgit From 346dbc62b826dd126d147107396154c31919da1b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 May 2008 23:49:36 -0700 Subject: Split the winbindd_passdb backend into a 'builtin' and a 'sam' backend. This allows winbindd when running on a Samba PDC to correctly answer wbinfo -u lists and other queries. Jeremy. (This used to be commit e61ad0c1586733ae1d3518ce56d95094d1ac5ef9) --- source3/winbindd/winbindd_util.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 9008cf8122..6a96070f42 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -27,7 +27,9 @@ #define DBGC_CLASS DBGC_WINBIND extern struct winbindd_methods cache_methods; -extern struct winbindd_methods passdb_methods; +extern struct winbindd_methods builtin_passdb_methods; +extern struct winbindd_methods sam_passdb_methods; + /** * @file winbindd_util.c @@ -695,7 +697,7 @@ bool init_domain_list(void) /* BUILTIN domain */ - domain = add_trusted_domain("BUILTIN", NULL, &passdb_methods, + domain = add_trusted_domain("BUILTIN", NULL, &builtin_passdb_methods, &global_sid_Builtin); if (domain) { setup_domain_child(domain, @@ -705,7 +707,7 @@ bool init_domain_list(void) /* Local SAM */ domain = add_trusted_domain(get_global_sam_name(), NULL, - &passdb_methods, get_global_sam_sid()); + &sam_passdb_methods, get_global_sam_sid()); if (domain) { if ( role != ROLE_DOMAIN_MEMBER ) { domain->primary = True; -- cgit From 2a4b8fa6642204acb538cfb9d5e481538d9b53c0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Jun 2008 12:49:14 -0700 Subject: Fix bug #5533. Winbindd fails to cope correctly with a workgroup name containing a '.'. Jeremy. (This used to be commit 96325ff44dc404a68d4ebd423cf78210ec3ff902) --- source3/winbindd/winbindd_util.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 6a96070f42..a35ba7bc06 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -165,15 +165,9 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const ZERO_STRUCTP(domain); - /* prioritise the short name */ - if (strchr_m(domain_name, '.') && alternative_name && *alternative_name) { - fstrcpy(domain->name, alternative_name); - fstrcpy(domain->alt_name, domain_name); - } else { - fstrcpy(domain->name, domain_name); - if (alternative_name) { - fstrcpy(domain->alt_name, alternative_name); - } + fstrcpy(domain->name, domain_name); + if (alternative_name) { + fstrcpy(domain->alt_name, alternative_name); } domain->methods = methods; -- cgit From 340ab6a256802a22c11b7f707748397249075b65 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 13 Jul 2008 12:07:40 +0200 Subject: idmap rewrite (This used to be commit 30a180f2fce8cf6a3e5548f6bba453272ba70b33) --- source3/winbindd/winbindd_util.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index a35ba7bc06..f1da5780aa 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -109,6 +109,8 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const { struct winbindd_domain *domain; const char *alternative_name = NULL; + char *idmap_config_option; + const char *param; /* ignore alt_name if we are not in an AD domain */ @@ -181,12 +183,44 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const if (sid) { sid_copy(&domain->sid, sid); } + /* Link to domain list */ DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *); wcache_tdc_add_domain( domain ); + idmap_config_option = talloc_asprintf(talloc_tos(), "idmap config %s", + domain->name); + if (idmap_config_option == NULL) { + DEBUG(0, ("talloc failed, not looking for idmap config\n")); + goto done; + } + + param = lp_parm_const_string(-1, idmap_config_option, "range", NULL); + + DEBUG(10, ("%s : range = %s\n", idmap_config_option, + param ? param : "not defined")); + + if (param != NULL) { + unsigned low_id, high_id; + if (sscanf(param, "%u - %u", &low_id, &high_id) != 2) { + DEBUG(1, ("invalid range syntax in %s: %s\n", + idmap_config_option, param)); + goto done; + } + if (low_id > high_id) { + DEBUG(1, ("invalid range in %s: %s\n", + idmap_config_option, param)); + goto done; + } + domain->have_idmap_config = true; + domain->id_range_low = low_id; + domain->id_range_high = high_id; + } + +done: + DEBUG(2,("Added domain %s %s %s\n", domain->name, domain->alt_name, &domain->sid?sid_string_dbg(&domain->sid):"")); -- cgit From 63ff9e008147b105316dcb0ea2df9b4304a8851e Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2008 15:28:23 -0700 Subject: I think the problem with these functions is that lookup_usergroups should never include the user SID. The comment for the function in winbindd/winbindd_ads.c says /* Lookup groups a user is a member of. */ The following patch makes the wbinfo calls return the correct data before and after a login. wbinfo --user-domgroups and --user-sids (This used to be commit 7849938906a9c859805cbaeca66fae9d3c515aad) --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index f1da5780aa..77b17787c9 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1333,7 +1333,7 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, status = sid_array_from_info3(mem_ctx, info3, user_sids, &num_groups, - true, true); + false, true); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); -- cgit From 79150da70bbfddea3dc4013212fc7314b1004534 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Aug 2008 16:24:22 -0700 Subject: Here is a re-working of the winbindd reconnect code to cope with rebooting a DC. This replaces the code I asked Volker to revert. The logic is pretty simple. It adds a new parameter, "winbind reconnect delay", set to 30 seconds by default, which determines how long to wait between connection attempts. To avoid overwhelming the box with DC-probe forked children, the code now keeps track of the DC probe child per winbindd_domain struct and only starts a new one if the existing one has died. I also added a little logic to make sure the dc probe child always sends a message whatever the reason for exit so we will always reschedule another connect attempt. Also added documentation. Jeremy. (This used to be commit 8027197635b988b3dcf9d3d00126a024e768fa62) --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 77b17787c9..4668d3725d 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -180,11 +180,11 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const domain->initialized = False; domain->online = is_internal_domain(sid); domain->check_online_timeout = 0; + domain->dc_probe_pid = (pid_t)-1; if (sid) { sid_copy(&domain->sid, sid); } - /* Link to domain list */ DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *); -- cgit From 66fa77ba9ed50b114131b0c071dbe1fcb658b755 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 25 Aug 2008 13:15:41 +0200 Subject: winbindd: move set_auth_errors to util functions. Guenther (This used to be commit ae3fa60c4546c7420722d8f422c22bbfd623ff5b) --- source3/winbindd/winbindd_util.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 4668d3725d..83c5053f78 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1544,3 +1544,15 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain) } #endif /* HAVE_KRB5_LOCATE_PLUGIN_H */ + +void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) +{ + resp->data.auth.nt_status = NT_STATUS_V(result); + fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result)); + + /* we might have given a more useful error above */ + if (*resp->data.auth.error_string == '\0') + fstrcpy(resp->data.auth.error_string, + get_friendly_nt_error_msg(result)); + resp->data.auth.pam_error = nt_status_to_pam(result); +} -- cgit From f25863e04cf3264575545701cb257bac8f0aee82 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 11 Sep 2008 09:51:39 -0400 Subject: Fix for bug 5571 Make sure that usernames are parsed using the correct separator. Otherwise group memeberships in winbind may be result broken. (This used to be commit 20b9c0aa7b4e6d6be5bb6e4e96bd8a1cbb6edd37) --- source3/winbindd/winbindd_util.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 83c5053f78..132c96f1ee 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1138,6 +1138,31 @@ bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, return ((*domain != NULL) && (*user != NULL)); } +/* add a domain user name to a buffer */ +void parse_add_domuser(void *buf, char *domuser, int *len) +{ + fstring domain; + char *p, *user; + + user = domuser; + p = strchr(domuser, *lp_winbind_separator()); + + if (p) { + + fstrcpy(domain, domuser); + domain[PTR_DIFF(p, domuser)] = 0; + p++; + + if (assume_domain(domain)) { + + user = p; + *len -= (PTR_DIFF(p, domuser)); + } + } + + safe_strcpy(buf, user, *len); +} + /* Ensure an incoming username from NSS is fully qualified. Replace the incoming fstring with DOMAIN user. Returns the same values as parse_domain_user() but also replaces the incoming username. -- cgit