From acacd27ba25f7ebfec40bfa66d34ece543569e23 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 23:37:07 +0000 Subject: [PATCH] (merge from 3.0) auth/auth_util.c: - Fill in the 'backup' idea of a domain, if the DC didn't supply one. This doesn't seem to occour in reality, hence why we missed the typo. lib/charcnv.c: lib/smbldap.c: libads/ldap.c: libsmb/libsmbclient.c: printing/nt_printing.c: - all the callers to pull_utf8_allocate() pass a char ** as the first parammeter, so don't make them all cast it to a void ** nsswitch/winbind_util.c: - Allow for a more 'correct' view of when usernames should be qualified in winbindd. If we are a PDC, or have 'winbind trusted domains only', then for the authentication returns stip the domain portion. - Fix valgrind warning about use of free()ed name when looking up our local domain. lp_workgroup() is maniplated inside a procedure that uses it's former value. Instead, use the fact that our local domain is always the first in the list. -- Jerry rightly complained that we can't assume that the first domain is our primary domain - new domains are added to the front of the list. :-( Use a much more reliable 'flag test' instead. (note: changes winbind structures, make clean). -- Forgot to commit this for the 'get our primary domain' change. Andrew Bartlett --- source/auth/auth_util.c | 2 +- source/lib/charcnv.c | 4 +-- source/lib/smbldap.c | 2 +- source/libads/ldap.c | 2 +- source/libsmb/libsmbclient.c | 2 +- source/nsswitch/winbindd.h | 1 + source/nsswitch/winbindd_util.c | 80 +++++++++++++++++++++++++++++++++-------- source/printing/nt_printing.c | 4 +-- 8 files changed, 74 insertions(+), 23 deletions(-) diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c index c4740496172..0f945b33cb3 100644 --- a/source/auth/auth_util.c +++ b/source/auth/auth_util.c @@ -1078,7 +1078,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) { /* If the server didn't give us one, just use the one we sent them */ - domain = domain; + nt_domain = domain; } /* try to fill the SAM account.. If getpwnam() fails, then try the diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index d6eb336d311..7903dfd3f64 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -1011,11 +1011,11 @@ size_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src) * @returns The number of bytes occupied by the string in the destination **/ -size_t pull_utf8_allocate(void **dest, const char *src) +size_t pull_utf8_allocate(char **dest, const char *src) { size_t src_len = strlen(src)+1; *dest = NULL; - return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, dest); + return convert_string_allocate(NULL, CH_UTF8, CH_UNIX, src, src_len, (void **)dest); } /** diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c index e05d127d91e..2eeec156bdd 100644 --- a/source/lib/smbldap.c +++ b/source/lib/smbldap.c @@ -1196,7 +1196,7 @@ char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry) DEBUG (5, ("smbldap_get_dn: ldap_get_dn failed\n")); return NULL; } - if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) { + if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) { DEBUG (0, ("smbldap_get_dn: String conversion failure utf8 [%s]\n", utf8_dn)); return NULL; } diff --git a/source/libads/ldap.c b/source/libads/ldap.c index 6e40089b70c..9828acccba3 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -714,7 +714,7 @@ char *ads_get_dn(ADS_STRUCT *ads, void *msg) return NULL; } - if (pull_utf8_allocate((void **) &unix_dn, utf8_dn) == (size_t)-1) { + if (pull_utf8_allocate(&unix_dn, utf8_dn) == (size_t)-1) { DEBUG(0,("ads_get_dn: string conversion failure utf8 [%s]\n", utf8_dn )); return NULL; diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c index 21273ec4319..37e794478d3 100644 --- a/source/libsmb/libsmbclient.c +++ b/source/libsmb/libsmbclient.c @@ -144,7 +144,7 @@ decode_urlpart(char *segment, size_t sizeof_segment) free(new_usegment); /* realloc it with unix charset */ - pull_utf8_allocate((void**)&new_usegment, new_segment); + pull_utf8_allocate(&new_usegment, new_segment); /* this assumes (very safely) that removing %aa sequences only shortens the string */ diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h index 677afa1849f..f1a58ab4518 100644 --- a/source/nsswitch/winbindd.h +++ b/source/nsswitch/winbindd.h @@ -96,6 +96,7 @@ struct winbindd_domain { fstring alt_name; /* alt Domain name (if any) */ DOM_SID sid; /* SID for this domain */ BOOL native_mode; /* is this a win2k domain in native mode ? */ + BOOL primary; /* is this our primary domain ? */ /* Lookup methods for this domain (LDAP or RPC) */ struct winbindd_methods *methods; diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c index 6d1675752f4..318da4a63a9 100644 --- a/source/nsswitch/winbindd_util.c +++ b/source/nsswitch/winbindd_util.c @@ -52,8 +52,9 @@ struct winbindd_domain *domain_list(void) { /* Initialise list */ - if (!_domain_list) - init_domain_list(); + if (!_domain_list) + if (!init_domain_list()) + return NULL; return _domain_list; } @@ -166,9 +167,7 @@ void rescan_trusted_domains( void ) if ( (now > last_scan) && ((now-last_scan) < WINBINDD_RESCAN_FREQ) ) return; - /* get the handle for our domain */ - - if ( (mydomain = find_domain_from_name(lp_workgroup())) == NULL ) { + if ( (mydomain = find_our_domain()) == NULL ) { DEBUG(0,("rescan_trusted_domains: Can't find my own domain!\n")); return; } @@ -266,10 +265,12 @@ BOOL init_domain_list(void) /* Free existing list */ free_domain_list(); - /* Add ourselves as the first entry */ + /* Add ourselves as the first entry. It *must* be the first entry */ domain = add_trusted_domain( lp_workgroup(), lp_realm(), &cache_methods, NULL); + domain->primary = True; + /* get any alternate name for the primary domain */ cache_methods.alternate_name(domain); @@ -291,8 +292,17 @@ BOOL init_domain_list(void) return True; } -/* Given a domain name, return the struct winbindd domain info for it - if it is actually working. */ +/** + * 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 looking at the first entry in domain_list() + * directly. + * + * + * @return The domain structure for the named domain, if it is working. + */ struct winbindd_domain *find_domain_from_name(const char *domain_name) { @@ -302,8 +312,9 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name) 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))) + (domain->alt_name[0] && strequal(domain_name, domain->alt_name))) { return domain; + } } /* Not found */ @@ -329,6 +340,24 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) return NULL; } +/* Given a domain sid, return the struct winbindd domain info for it */ + +struct winbindd_domain *find_our_domain() +{ + struct winbindd_domain *domain; + + /* Search through list */ + + for (domain = domain_list(); domain != NULL; domain = domain->next) { + if (domain->primary) + return domain; + } + + /* Not found */ + + return NULL; +} + /* Lookup a sid in a domain from a name */ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, @@ -471,6 +500,20 @@ BOOL check_domain_env(char *domain_env, char *domain) return False; } +/* Is this a domain which we may assume no DOMAIN\ prefix? */ + +static BOOL assume_domain(const char *domain) { + if ((lp_winbind_use_default_domain() + || lp_winbind_trusted_domains_only()) && + strequal(lp_workgroup(), domain)) + return True; + + 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) @@ -480,10 +523,13 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) if ( !p ) { fstrcpy(user, domuser); - if ( lp_winbind_use_default_domain() ) + if ( assume_domain(lp_workgroup())) { fstrcpy(domain, lp_workgroup()); - else - fstrcpy( domain, "" ); + } else if (assume_domain(get_global_sam_name())) { + fstrcpy( domain, get_global_sam_name() ); + } else { + fstrcpy( domain, ""); + } } else { fstrcpy(user, p+1); @@ -501,13 +547,17 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) 'winbind separator' options. This means: - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is - lp_workgroup + 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 */ void fill_domain_username(fstring name, const char *domain, const char *user) { - if(lp_winbind_use_default_domain() && - !strcmp(lp_workgroup(), domain)) { + if (assume_domain(domain)) { strlcpy(name, user, sizeof(fstring)); } else { slprintf(name, sizeof(fstring) - 1, "%s%s%s", diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c index 7ba777f1311..34274d18318 100644 --- a/source/printing/nt_printing.c +++ b/source/printing/nt_printing.c @@ -2662,13 +2662,13 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer) return WERR_SERVER_UNAVAILABLE; } /* Now convert to CH_UNIX. */ - if (pull_utf8_allocate((void **) &srv_dn, srv_dn_utf8) == (size_t)-1) { + if (pull_utf8_allocate(&srv_dn, srv_dn_utf8) == (size_t)-1) { ldap_memfree(srv_dn_utf8); ldap_memfree(srv_cn_utf8); ads_destroy(&ads); return WERR_SERVER_UNAVAILABLE; } - if (pull_utf8_allocate((void **) &srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) { + if (pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) { ldap_memfree(srv_dn_utf8); ldap_memfree(srv_cn_utf8); ads_destroy(&ads); -- 2.11.4.GIT