diff options
author | Jeremy Allison <jra@samba.org> | 2002-04-30 13:28:41 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2002-04-30 13:28:41 +0000 |
commit | d04b55f2186fb8af998cf61c576771a5f72f4892 (patch) | |
tree | 9ff8c3a7cf34cefc0ee9a550a3bb1236a9e77595 /source/nsswitch/winbindd_util.c | |
parent | 73267ca42d9eddabb71b31b4c5068ebbe7bc9f7c (diff) | |
download | samba-d04b55f2186fb8af998cf61c576771a5f72f4892.tar.gz samba-d04b55f2186fb8af998cf61c576771a5f72f4892.tar.xz samba-d04b55f2186fb8af998cf61c576771a5f72f4892.zip |
Start of merge to 2_2_RELEASE branch for release.
Jeremy.
Diffstat (limited to 'source/nsswitch/winbindd_util.c')
-rw-r--r-- | source/nsswitch/winbindd_util.c | 850 |
1 files changed, 163 insertions, 687 deletions
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c index c0c7b6ae0dd..06804b3b43f 100644 --- a/source/nsswitch/winbindd_util.c +++ b/source/nsswitch/winbindd_util.c @@ -1,5 +1,5 @@ /* - Unix SMB/Netbios implementation. + Unix SMB/CIFS implementation. Winbind daemon for ntdom nss module @@ -36,418 +36,204 @@ * * Correct code should never look at a field that has this value. **/ -static const fstring name_deadbeef = "<deadbeef>"; - -/* Globals for domain list stuff */ +static const fstring name_deadbeef = "<deadbeef>"; -struct winbindd_domain *domain_list = NULL; +/* 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. */ -/* Given a domain name, return the struct winbindd domain info for it - if it is actually working. */ +static struct winbindd_domain *_domain_list; -struct winbindd_domain *find_domain_from_name(char *domain_name) +struct winbindd_domain *domain_list(void) { - struct winbindd_domain *tmp; - - if (domain_list == NULL) - get_domain_info(); - - /* Search through list */ - - for (tmp = domain_list; tmp != NULL; tmp = tmp->next) { - if (strcmp(domain_name, tmp->name) == 0) - return tmp; - } + /* Initialise list */ - /* Not found */ + if (!_domain_list) + init_domain_list(); - return NULL; + return _domain_list; } -/* Given a domain name, return the struct winbindd domain info for it */ +/* Free all entries in the trusted domain list */ -struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) +void free_domain_list(void) { - struct winbindd_domain *tmp; - - if (domain_list == NULL) - get_domain_info(); - - /* Search through list */ - - for (tmp = domain_list; tmp != NULL; tmp = tmp->next) { - if (sid_equal(sid, &tmp->sid)) - return tmp; + struct winbindd_domain *domain = _domain_list; + + while(domain) { + struct winbindd_domain *next = domain->next; + + DLIST_REMOVE(_domain_list, domain); + SAFE_FREE(domain); + domain = next; } - - /* Not found */ - - return NULL; } /* Add a trusted domain to our list of domains */ static struct winbindd_domain *add_trusted_domain(char *domain_name, - DOM_SID *domain_sid) + struct winbindd_methods *methods) { - struct winbindd_domain *domain, *tmp; + struct winbindd_domain *domain; - for (tmp = domain_list; tmp != NULL; tmp = tmp->next) { - if (strcmp(domain_name, tmp->name) == 0) { - DEBUG(3, ("domain %s already in domain list\n", domain_name)); - return tmp; + /* 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 (strcmp(domain_name, domain->name) == 0) { + DEBUG(3, ("domain %s already in domain list\n", + domain_name)); + return domain; } } - DEBUG(1, ("adding domain %s\n", domain_name)); - /* Create new domain entry */ - - if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL) + + if ((domain = (struct winbindd_domain *) + malloc(sizeof(*domain))) == NULL) return NULL; /* Fill in fields */ ZERO_STRUCTP(domain); + fstrcpy(domain->name, domain_name); - sid_copy(&domain->sid, domain_sid); - + domain->methods = methods; + domain->sequence_number = DOM_SEQUENCE_NONE; + domain->last_seq_check = 0; + /* Link to domain list */ - DLIST_ADD(domain_list, domain); + DLIST_ADD(_domain_list, domain); return domain; } /* Look up global info for the winbind daemon */ -BOOL get_domain_info(void) +BOOL init_domain_list(void) { - uint32 enum_ctx = 0, num_doms = 0; - char **domains = NULL; - DOM_SID *sids = NULL, domain_sid; NTSTATUS result; - CLI_POLICY_HND *hnd; - int i; - fstring level5_dom; - BOOL rv = False; TALLOC_CTX *mem_ctx; - - DEBUG(1, ("getting trusted domain list\n")); + extern struct winbindd_methods cache_methods; + struct winbindd_domain *domain; + DOM_SID *dom_sids; + char **names; + int num_domains = 0; - if (!(mem_ctx = talloc_init())) + if (!(mem_ctx = talloc_init_named("init_domain_list"))) return False; - /* Add our workgroup - keep handle to look up trusted domains */ + /* Free existing list */ - if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) - goto done; + free_domain_list(); - result = cli_lsa_query_info_policy(hnd->cli, mem_ctx, - &hnd->pol, 0x05, level5_dom, &domain_sid); + /* Add ourselves as the first entry */ - if (!NT_STATUS_IS_OK(result)) - goto done; - - add_trusted_domain(lp_workgroup(), &domain_sid); - - /* Enumerate list of trusted domains */ + domain = add_trusted_domain(lp_workgroup(), &cache_methods); - if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) - goto done; + /* Now we *must* get the domain sid for our primary domain. Go into + a holding pattern until that is available */ - result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, - &hnd->pol, &enum_ctx, &num_doms, &domains, &sids); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - /* Add each domain to the trusted domain list */ - - for(i = 0; i < num_doms; i++) - add_trusted_domain(domains[i], &sids[i]); - - rv = True; - - done: - - talloc_destroy(mem_ctx); - - return rv; -} - -/* Free global domain info */ - -void free_domain_info(void) -{ - struct winbindd_domain *domain; - - /* Free list of domains */ - - if (domain_list) { - struct winbindd_domain *next_domain; - - domain = domain_list; - - while(domain) { - next_domain = domain->next; - SAFE_FREE(domain); - domain = next_domain; - } + result = cache_methods.domain_sid(domain, &domain->sid); + while (!NT_STATUS_IS_OK(result)) { + sleep(10); + DEBUG(1,("Retrying startup domain sid fetch for %s\n", + domain->name)); + result = cache_methods.domain_sid(domain, &domain->sid); } -} + + DEBUG(1,("Added domain %s (%s)\n", + domain->name, + sid_string_static(&domain->sid))); -/* Connect to a domain controller using get_any_dc_name() to discover - the domain name and sid */ + DEBUG(1, ("getting trusted domain list\n")); -BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain) -{ - fstring level5_dom; - uint32 enum_ctx = 0, num_doms = 0; - char **domains = NULL; - DOM_SID *sids = NULL; - CLI_POLICY_HND *hnd; - NTSTATUS result; - BOOL rv = False; - TALLOC_CTX *mem_ctx; - - DEBUG(1, ("looking up sid for domain %s\n", domain_name)); - - if (!(mem_ctx = talloc_init())) - return False; - - if (!(hnd = cm_get_lsa_handle(domain_name))) - goto done; - - /* Do a level 5 query info policy if we are looking up the SID for - our own domain. */ - - if (strequal(domain_name, lp_workgroup())) { - - result = cli_lsa_query_info_policy(hnd->cli, mem_ctx, - &hnd->pol, 0x05, level5_dom, - &domain->sid); - - rv = NT_STATUS_IS_OK(result); - goto done; - } - - /* Use lsaenumdomains to get sid for this domain */ - - result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, &hnd->pol, - &enum_ctx, &num_doms, &domains, &sids); - - /* Look for domain name */ - - if (NT_STATUS_IS_OK(result) && domains && sids) { - BOOL found = False; + result = cache_methods.trusted_domains(domain, mem_ctx, &num_domains, + &names, &dom_sids); + + /* Add each domain to the trusted domain list */ + if (NT_STATUS_IS_OK(result)) { int i; - - for(i = 0; i < num_doms; i++) { - if (strequal(domain_name, domains[i])) { - sid_copy(&domain->sid, &sids[i]); - found = True; - break; - } + for(i = 0; i < num_domains; i++) { + domain = add_trusted_domain(names[i], &cache_methods); + if (!domain) continue; + sid_copy(&domain->sid, &dom_sids[i]); + DEBUG(1,("Added domain %s (%s)\n", + domain->name, + sid_string_static(&domain->sid))); + + /* this primes the connection */ + cache_methods.domain_sid(domain, &domain->sid); } - - rv = found; - goto done; } - - rv = False; /* An error occured with a trusted domain */ - - done: talloc_destroy(mem_ctx); - - return rv; -} - -/* Store a SID in a domain indexed by name in the cache. */ - -static void store_sid_by_name_in_cache(fstring name, DOM_SID *sid, enum SID_NAME_USE type) -{ - fstring domain_str; - char *p; - struct winbindd_sid sid_val; - struct winbindd_domain *domain; - - /* Get name from domain. */ - fstrcpy( domain_str, name); - p = strchr(domain_str, '\\'); - if (p) - *p = '\0'; - - if ((domain = find_domain_from_name(domain_str)) == NULL) - return; - - sid_to_string(sid_val.sid, sid); - sid_val.type = (int)type; - - DEBUG(10,("store_sid_by_name_in_cache: storing cache entry %s -> SID %s\n", - name, sid_val.sid )); - - winbindd_store_sid_cache_entry(domain, name, &sid_val); -} - -/* Lookup a SID in a domain indexed by name in the cache. */ - -static BOOL winbindd_lookup_sid_by_name_in_cache(fstring name, DOM_SID *sid, enum SID_NAME_USE *type) -{ - fstring domain_str; - char *p; - struct winbindd_sid sid_ret; - struct winbindd_domain *domain; - - /* Get name from domain. */ - fstrcpy( domain_str, name); - p = strchr(domain_str, '\\'); - if (p) - *p = '\0'; - - if ((domain = find_domain_from_name(domain_str)) == NULL) - return False; - - if (!winbindd_fetch_sid_cache_entry(domain, name, &sid_ret)) - return False; - - string_to_sid( sid, sid_ret.sid); - *type = (enum SID_NAME_USE)sid_ret.type; - - DEBUG(10,("winbindd_lookup_sid_by_name_in_cache: Cache hit for name %s. SID = %s\n", - name, sid_ret.sid )); - return True; } -/* Store a name in a domain indexed by SID in the cache. */ +/* Given a domain name, return the struct winbindd domain info for it + if it is actually working. */ -static void store_name_by_sid_in_cache(DOM_SID *sid, fstring name, enum SID_NAME_USE type) +struct winbindd_domain *find_domain_from_name(const char *domain_name) { - fstring sid_str; - uint32 rid; - DOM_SID domain_sid; - struct winbindd_name name_val; struct winbindd_domain *domain; - /* Split sid into domain sid and user rid */ - sid_copy(&domain_sid, sid); - sid_split_rid(&domain_sid, &rid); - - if ((domain = find_domain_from_sid(&domain_sid)) == NULL) - return; + /* Search through list */ - sid_to_string(sid_str, sid); - fstrcpy( name_val.name, name ); - name_val.type = (int)type; + for (domain = domain_list(); domain != NULL; domain = domain->next) { + if (strequal(domain_name, domain->name) || + strequal(domain_name, domain->full_name)) + return domain; + } - DEBUG(10,("store_name_by_sid_in_cache: storing cache entry SID %s -> %s\n", - sid_str, name_val.name )); + /* Not found */ - winbindd_store_name_cache_entry(domain, sid_str, &name_val); + return NULL; } -/* Lookup a name in a domain indexed by SID in the cache. */ +/* Given a domain sid, return the struct winbindd domain info for it */ -static BOOL winbindd_lookup_name_by_sid_in_cache(DOM_SID *sid, fstring name, enum SID_NAME_USE *type) +struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) { - fstring sid_str; - uint32 rid; - DOM_SID domain_sid; - struct winbindd_name name_ret; struct winbindd_domain *domain; - /* Split sid into domain sid and user rid */ - sid_copy(&domain_sid, sid); - sid_split_rid(&domain_sid, &rid); - - if ((domain = find_domain_from_sid(&domain_sid)) == NULL) - return False; - - sid_to_string(sid_str, sid); - - if (!winbindd_fetch_name_cache_entry(domain, sid_str, &name_ret)) - return False; + /* Search through list */ - fstrcpy( name, name_ret.name ); - *type = (enum SID_NAME_USE)name_ret.type; + for (domain = domain_list(); domain != NULL; domain = domain->next) { + if (sid_compare_domain(sid, &domain->sid) == 0) + return domain; + } - DEBUG(10,("winbindd_lookup_name_by_sid_in_cache: Cache hit for SID = %s, name %s\n", - sid_str, name )); + /* Not found */ - return True; + return NULL; } /* Lookup a sid in a domain from a name */ -BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *type) +BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, + const char *name, DOM_SID *sid, + enum SID_NAME_USE *type) { - int num_sids = 0, num_names = 1; - DOM_SID *sids = NULL; - uint32 *types = NULL; - CLI_POLICY_HND *hnd; NTSTATUS result; - TALLOC_CTX *mem_ctx; - BOOL rv = False; /* Don't bother with machine accounts */ if (name[strlen(name) - 1] == '$') return False; - /* First check cache. */ - if (winbindd_lookup_sid_by_name_in_cache(name, sid, type)) { - if (*type == SID_NAME_USE_NONE) - return False; /* Negative cache hit. */ - return True; - } - /* Lookup name */ - - if (!(mem_ctx = talloc_init())) - return False; - - if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) - goto done; - - result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, - num_names, (char **)&name, &sids, - &types, &num_sids); + result = domain->methods->name_to_sid(domain, name, sid, type); /* Return rid and type if lookup successful */ - - if (NT_STATUS_IS_OK(result)) { - - /* Return sid */ - - if ((sid != NULL) && (sids != NULL)) - sid_copy(sid, &sids[0]); - - /* Return name type */ - - if ((type != NULL) && (types != NULL)) - *type = types[0]; - - /* Store the forward and reverse map of this lookup in the cache. */ - store_sid_by_name_in_cache(name, &sids[0], types[0]); - store_name_by_sid_in_cache(&sids[0], name, types[0]); - } else { - /* JRA. Here's where we add the -ve cache store with a name type of SID_NAME_USE_NONE. */ - DOM_SID nullsid; - - ZERO_STRUCT(nullsid); - store_sid_by_name_in_cache(name, &nullsid, SID_NAME_USE_NONE); + if (!NT_STATUS_IS_OK(result)) { *type = SID_NAME_UNKNOWN; } - rv = NT_STATUS_IS_OK(result); - - done: - talloc_destroy(mem_ctx); - - return rv; + return NT_STATUS_IS_OK(result); } /** @@ -457,6 +243,8 @@ BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *ty * * @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. * @@ -464,335 +252,45 @@ BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *ty * are set, otherwise False. **/ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, + fstring dom_name, fstring name, enum SID_NAME_USE *type) { - int num_sids = 1, num_names = 0; - uint32 *types = NULL; - char **names; - CLI_POLICY_HND *hnd; + char *names; NTSTATUS result; TALLOC_CTX *mem_ctx; BOOL rv = False; + struct winbindd_domain *domain; - /* First check cache. */ - if (winbindd_lookup_name_by_sid_in_cache(sid, name, type)) { - if (*type == SID_NAME_USE_NONE) { - fstrcpy(name, name_deadbeef); - *type = SID_NAME_UNKNOWN; - return False; /* Negative cache hit. */ - } else - return True; + domain = find_domain_from_sid(sid); + + if (!domain) { + DEBUG(1,("Can't find domain from sid\n")); + return False; } /* Lookup name */ - if (!(mem_ctx = talloc_init())) + if (!(mem_ctx = talloc_init_named("winbindd_lookup_name_by_sid"))) return False; - if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) - goto done; - - result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol, - num_sids, sid, &names, &types, - &num_names); + result = domain->methods->sid_to_name(domain, mem_ctx, sid, &names, type); /* Return name and type if successful */ if ((rv = NT_STATUS_IS_OK(result))) { - - /* Return name */ - - if ((names != NULL) && (name != NULL)) - fstrcpy(name, names[0]); - - /* Return name type */ - - if ((type != NULL) && (types != NULL)) - *type = types[0]; - - store_sid_by_name_in_cache(names[0], sid, types[0]); - store_name_by_sid_in_cache(sid, names[0], types[0]); + fstrcpy(dom_name, domain->name); + fstrcpy(name, names); } else { - /* OK, so we tried to look up a name in this sid, and - * didn't find it. Therefore add a negative cache - * entry. */ - store_name_by_sid_in_cache(sid, "", SID_NAME_USE_NONE); *type = SID_NAME_UNKNOWN; fstrcpy(name, name_deadbeef); } - - done: talloc_destroy(mem_ctx); return rv; } -/* Lookup user information from a rid */ - -BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, uint32 user_rid, - SAM_USERINFO_CTR **user_info) -{ - CLI_POLICY_HND *hnd; - uint16 info_level = 0x15; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - POLICY_HND dom_pol, user_pol; - BOOL got_dom_pol = False, got_user_pol = False; - - /* Get sam handle */ - - if (!(hnd = cm_get_sam_handle(domain->name))) - goto done; - - /* Get domain handle */ - - result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, - des_access, &domain->sid, &dom_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - got_dom_pol = True; - - /* Get user handle */ - - result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol, - des_access, user_rid, &user_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - /* Get user info */ - - result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol, - info_level, user_info); - - cli_samr_close(hnd->cli, mem_ctx, &user_pol); - - done: - /* Clean up policy handles */ - - if (got_user_pol) - cli_samr_close(hnd->cli, mem_ctx, &user_pol); - - if (got_dom_pol) - cli_samr_close(hnd->cli, mem_ctx, &dom_pol); - - return NT_STATUS_IS_OK(result); -} - -/* Lookup groups a user is a member of. I wish Unix had a call like this! */ - -BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 user_rid, uint32 *num_groups, - DOM_GID **user_groups) -{ - CLI_POLICY_HND *hnd; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND dom_pol, user_pol; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - BOOL got_dom_pol = False, got_user_pol = False; - - /* Get sam handle */ - - if (!(hnd = cm_get_sam_handle(domain->name))) - goto done; - - /* Get domain handle */ - - result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, - des_access, &domain->sid, &dom_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - got_dom_pol = True; - - /* Get user handle */ - - result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol, - des_access, user_rid, &user_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - got_user_pol = True; - - /* Query user rids */ - - result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol, - num_groups, user_groups); - - done: - - /* Clean up policy handles */ - - if (got_user_pol) - cli_samr_close(hnd->cli, mem_ctx, &user_pol); - - if (got_dom_pol) - cli_samr_close(hnd->cli, mem_ctx, &dom_pol); - - return NT_STATUS_IS_OK(result); -} - -/* Lookup group membership given a rid. */ - -BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 group_rid, uint32 *num_names, - uint32 **rid_mem, char ***names, - uint32 **name_types) -{ - CLI_POLICY_HND *hnd; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i, total_names = 0; - POLICY_HND dom_pol, group_pol; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - BOOL got_dom_pol = False, got_group_pol = False; - - /* Get sam handle */ - - if (!(hnd = cm_get_sam_handle(domain->name))) - goto done; - - /* Get domain handle */ - - result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, - des_access, &domain->sid, &dom_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - got_dom_pol = True; - - /* Get group handle */ - - result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol, - des_access, group_rid, &group_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - got_group_pol = True; - - /* Step #1: Get a list of user rids that are the members of the - group. */ - - result = cli_samr_query_groupmem(hnd->cli, mem_ctx, - &group_pol, num_names, rid_mem, - name_types); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - /* Step #2: Convert list of rids into list of usernames. Do this - in bunches of ~1000 to avoid crashing NT4. It looks like there - is a buffer overflow or something like that lurking around - somewhere. */ - -#define MAX_LOOKUP_RIDS 900 - - *names = talloc(mem_ctx, *num_names * sizeof(char *)); - *name_types = talloc(mem_ctx, *num_names * sizeof(uint32)); - - for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) { - int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS); - uint32 tmp_num_names = 0; - char **tmp_names = NULL; - uint32 *tmp_types = NULL; - - /* Lookup a chunk of rids */ - - result = cli_samr_lookup_rids(hnd->cli, mem_ctx, - &dom_pol, 1000, /* flags */ - num_lookup_rids, - &(*rid_mem)[i], - &tmp_num_names, - &tmp_names, &tmp_types); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - /* Copy result into array. The talloc system will take - care of freeing the temporary arrays later on. */ - - memcpy(&(*names)[i], tmp_names, sizeof(char *) * - tmp_num_names); - - memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) * - tmp_num_names); - - total_names += tmp_num_names; - } - - *num_names = total_names; - - done: - if (got_group_pol) - cli_samr_close(hnd->cli, mem_ctx, &group_pol); - - if (got_dom_pol) - cli_samr_close(hnd->cli, mem_ctx, &dom_pol); - - return NT_STATUS_IS_OK(result); -} - -BOOL create_samr_domain_handle(struct winbindd_domain *domain, POLICY_HND *pdom_pol) -{ - CLI_POLICY_HND *hnd; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - TALLOC_CTX *mem_ctx = talloc_init(); - - ZERO_STRUCTP(pdom_pol); - - if (!mem_ctx) - return False; - - /* Get sam handle */ - - if (!(hnd = cm_get_sam_handle(domain->name))) { - talloc_destroy(mem_ctx); - return False; - } - /* Get domain handle */ - result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, - des_access, &domain->sid, pdom_pol); - - talloc_destroy(mem_ctx); - if (!NT_STATUS_IS_OK(result)) - return False; - - return True; -} - -void close_samr_domain_handle(struct winbindd_domain *domain, POLICY_HND *pdom_pol) -{ - static POLICY_HND zero_pol; - CLI_POLICY_HND *hnd; - TALLOC_CTX *mem_ctx = talloc_init(); - - if (!mem_ctx) - return; - - if (memcmp(pdom_pol, &zero_pol, sizeof(zero_pol)) == 0) - return; - - if (!(hnd = cm_get_sam_handle(domain->name))) { - talloc_destroy(mem_ctx); - return; - } - - cli_samr_close(hnd->cli, mem_ctx, pdom_pol); - ZERO_STRUCTP(pdom_pol); - - talloc_destroy(mem_ctx); -} /* Free state information held for {set,get,end}{pw,gr}ent() functions */ @@ -807,9 +305,6 @@ void free_getent_state(struct getent_state *state) while(temp != NULL) { struct getent_state *next; - /* Close SAMR cache handle. */ - close_samr_domain_handle(temp->domain, &temp->dom_pol); - /* Free sam entries then list entry */ SAFE_FREE(state->sam_entries); @@ -821,68 +316,23 @@ void free_getent_state(struct getent_state *state) } } -struct getent_state *create_getent_state(struct winbindd_domain *domain) -{ - struct getent_state *state = (struct getent_state *)malloc(sizeof(struct getent_state)); - - if (state == NULL) - return NULL; - - ZERO_STRUCTP(state); - state->domain = domain; - - /* Create and cache a SAMR domain handle. */ - if (!create_samr_domain_handle(state->domain, &state->dom_pol)) { - free_getent_state(state); - return NULL; - } - - return state; -} - /* Initialise trusted domain info */ BOOL winbindd_param_init(void) { - /* Parse winbind uid and winbind_gid parameters */ - - if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) { - DEBUG(0, ("winbind uid range missing or invalid\n")); - return False; - } - - if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) { - DEBUG(0, ("winbind gid range missing or invalid\n")); - return False; - } - - return True; -} - -/* Query display info for a domain. This returns enough information plus a - bit extra to give an overview of domain users for the User Manager - application. */ - -NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, POLICY_HND *pdom_pol, - uint32 *start_ndx, uint16 info_level, - uint32 *num_entries, SAM_DISPINFO_CTR *ctr) -{ - CLI_POLICY_HND *hnd; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - /* Get sam handle */ - - if (!(hnd = cm_get_sam_handle(domain->name))) - return NT_STATUS_UNSUCCESSFUL; + /* Parse winbind uid and winbind_gid parameters */ - /* Query display info */ - - result = cli_samr_query_dispinfo(hnd->cli, mem_ctx, - pdom_pol, start_ndx, info_level, - num_entries, 0xffff, ctr); - - return result; + if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) { + DEBUG(0, ("winbind uid range missing or invalid\n")); + return False; + } + + if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) { + DEBUG(0, ("winbind gid range missing or invalid\n")); + return False; + } + + return True; } /* Check if a domain is present in a comma-separated list of domains */ @@ -901,17 +351,43 @@ BOOL check_domain_env(char *domain_env, char *domain) } /* Parse a string of the form DOMAIN/user into a domain and a user */ +extern fstring global_myworkgroup; -BOOL parse_domain_user(char *domuser, fstring domain, fstring user) +BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) { char *p = strchr(domuser,*lp_winbind_separator()); - if (!p) + if (!(p || lp_winbind_use_default_domain())) return False; - fstrcpy(user, p+1); - fstrcpy(domain, domuser); - domain[PTR_DIFF(p, domuser)] = 0; + if(!p && lp_winbind_use_default_domain()) { + fstrcpy(user, domuser); + fstrcpy(domain, global_myworkgroup); + } else { + fstrcpy(user, p+1); + fstrcpy(domain, domuser); + domain[PTR_DIFF(p, domuser)] = 0; + } strupper(domain); 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 + global_myworkgroup + +*/ +void fill_domain_username(fstring name, const char *domain, const char *user) +{ + if(lp_winbind_use_default_domain() && + !strcmp(global_myworkgroup, domain)) { + strlcpy(name, user, sizeof(fstring)); + } else { + slprintf(name, sizeof(fstring) - 1, "%s%s%s", + domain, lp_winbind_separator(), + user); + } +} |