From 6ef504d71fee47fe6fbc930f488c96dfc7e6aaf8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sun, 6 May 2007 19:01:54 +0000 Subject: r22702: Convert both lookup name and lookup sid to follow the same heuristic. First try our DC and then try a DC in the root of our forest. Use a temporary state since winbindd_lookupXXX_async() is called from various winbindd API entry points. Note this will break the compile. That will be fixed in the next commit. (This used to be commit b442644bac2a7d5853440254257ca34a8e7c25de) --- source3/nsswitch/winbindd_async.c | 127 +++++++++++++++++++++++++++++++------- source3/nsswitch/winbindd_util.c | 9 +-- 2 files changed, 105 insertions(+), 31 deletions(-) (limited to 'source3') diff --git a/source3/nsswitch/winbindd_async.c b/source3/nsswitch/winbindd_async.c index eb8631ab86..2ac40ccf3d 100644 --- a/source3/nsswitch/winbindd_async.c +++ b/source3/nsswitch/winbindd_async.c @@ -687,6 +687,40 @@ static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success, } #endif /* not used */ +struct lookupsid_state { + DOM_SID sid; + void *caller_private_data; +}; + + +static void lookupsid_recv2(TALLOC_CTX *mem_ctx, BOOL success, + struct winbindd_response *response, + void *c, void *private_data) +{ + void (*cont)(void *priv, BOOL succ, const char *dom_name, + const char *name, enum lsa_SidType type) = + (void (*)(void *, BOOL, const char *, const char *, + enum lsa_SidType))c; + struct lookupsid_state *s = talloc_get_type_abort(private_data, + struct lookupsid_state); + + if (!success) { + DEBUG(5, ("Could not trigger lookupsid\n")); + cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN); + return; + } + + if (response->result != WINBINDD_OK) { + DEBUG(5, ("lookupsid (forest root) returned an error\n")); + cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN); + return; + } + + cont(s->caller_private_data, True, response->data.name.dom_name, + response->data.name.name, + (enum lsa_SidType)response->data.name.type); +} + static void lookupsid_recv(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) @@ -695,20 +729,37 @@ static void lookupsid_recv(TALLOC_CTX *mem_ctx, BOOL success, const char *name, enum lsa_SidType type) = (void (*)(void *, BOOL, const char *, const char *, enum lsa_SidType))c; + struct lookupsid_state *s = talloc_get_type_abort(private_data, + struct lookupsid_state); if (!success) { DEBUG(5, ("Could not trigger lookupsid\n")); - cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); + cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN); return; } if (response->result != WINBINDD_OK) { - DEBUG(5, ("lookupsid returned an error\n")); - cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); + /* Try again using the forest root */ + struct winbindd_domain *root_domain = find_root_domain(); + struct winbindd_request request; + + if ( !root_domain ) { + DEBUG(5,("lookupsid_recv: unable to determine forest root\n")); + cont(s->caller_private_data, False, NULL, NULL, SID_NAME_UNKNOWN); + return; + } + + ZERO_STRUCT(request); + request.cmd = WINBINDD_LOOKUPSID; + fstrcpy(request.data.sid, sid_string_static(&s->sid)); + + do_async_domain(mem_ctx, root_domain, &request, lookupsid_recv2, + (void *)cont, s); + return; } - cont(private_data, True, response->data.name.dom_name, + cont(s->caller_private_data, True, response->data.name.dom_name, response->data.name.name, (enum lsa_SidType)response->data.name.type); } @@ -722,6 +773,7 @@ void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, { struct winbindd_domain *domain; struct winbindd_request request; + struct lookupsid_state *s; domain = find_lookup_domain_from_sid(sid); if (domain == NULL) { @@ -735,6 +787,15 @@ void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, request.cmd = WINBINDD_LOOKUPSID; fstrcpy(request.data.sid, sid_string_static(sid)); + if ( (s = TALLOC_ZERO_P(mem_ctx, struct lookupsid_state)) == NULL ) { + DEBUG(0, ("winbindd_lookupsid_async: talloc failed\n")); + cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); + return; + } + + sid_copy( &s->sid, sid ); + s->caller_private_data = private_data; + do_async_domain(mem_ctx, domain, &request, lookupsid_recv, (void *)cont, private_data); } @@ -762,8 +823,9 @@ enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, /* Lookup the sid */ - if (!winbindd_lookup_name_by_sid(state->mem_ctx, &sid, &dom_name, &name, - &type)) { + if (!winbindd_lookup_name_by_sid(state->mem_ctx, domain, &sid, + &dom_name, &name, &type)) + { TALLOC_FREE(dom_name); TALLOC_FREE(name); return WINBINDD_ERROR; @@ -782,6 +844,13 @@ enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, This is the second callback after contacting the forest root ********************************************************************/ +struct lookupname_state { + char *dom_name; + char *name; + void *caller_private_data; +}; + + static void lookupname_recv2(TALLOC_CTX *mem_ctx, BOOL success, struct winbindd_response *response, void *c, void *private_data) @@ -790,27 +859,30 @@ static void lookupname_recv2(TALLOC_CTX *mem_ctx, BOOL success, enum lsa_SidType type) = (void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c; DOM_SID sid; + struct lookupname_state *s = talloc_get_type_abort( private_data, + struct lookupname_state ); + if (!success) { DEBUG(5, ("Could not trigger lookup_name\n")); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); + cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); return; } if (response->result != WINBINDD_OK) { DEBUG(5, ("lookup_name returned an error\n")); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); + cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); return; } if (!string_to_sid(&sid, response->data.sid.sid)) { DEBUG(0, ("Could not convert string %s to sid\n", response->data.sid.sid)); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); + cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); return; } - cont(private_data, True, &sid, + cont(s->caller_private_data, True, &sid, (enum lsa_SidType)response->data.sid.type); } @@ -826,36 +898,34 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success, enum lsa_SidType type) = (void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c; DOM_SID sid; + struct lookupname_state *s = talloc_get_type_abort( private_data, + struct lookupname_state ); if (!success) { DEBUG(5, ("lookupname_recv: lookup_name() failed!\n")); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); + cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); return; } if (response->result != WINBINDD_OK) { /* Try again using the forest root */ struct winbindd_domain *root_domain = find_root_domain(); - struct winbindd_cli_state *state = (struct winbindd_cli_state*)private_data; struct winbindd_request request; - char *name_domain, *name_account; if ( !root_domain ) { DEBUG(5,("lookupname_recv: unable to determine forest root\n")); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); + cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); return; } - name_domain = state->request.data.name.dom_name; - name_account = state->request.data.name.name; - ZERO_STRUCT(request); request.cmd = WINBINDD_LOOKUPNAME; - fstrcpy(request.data.name.dom_name, name_domain); - fstrcpy(request.data.name.name, name_account); + + fstrcpy( request.data.name.dom_name, s->dom_name ); + fstrcpy( request.data.name.name, s->name ); do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2, - (void *)cont, private_data); + (void *)cont, s); return; } @@ -863,11 +933,11 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success, if (!string_to_sid(&sid, response->data.sid.sid)) { DEBUG(0, ("Could not convert string %s to sid\n", response->data.sid.sid)); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); + cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); return; } - cont(private_data, True, &sid, + cont(s->caller_private_data, True, &sid, (enum lsa_SidType)response->data.sid.type); } @@ -886,6 +956,7 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, { struct winbindd_request request; struct winbindd_domain *domain; + struct lookupname_state *s; if ( (domain = find_lookup_domain_from_name(dom_name)) == NULL ) { DEBUG(5, ("Could not find domain for name %s\n", dom_name)); @@ -898,8 +969,18 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, fstrcpy(request.data.name.dom_name, dom_name); fstrcpy(request.data.name.name, name); + if ( (s = TALLOC_ZERO_P(mem_ctx, struct lookupname_state)) == NULL ) { + DEBUG(0, ("winbindd_lookupname_async: talloc failed\n")); + cont(private_data, False, NULL, SID_NAME_UNKNOWN); + return; + } + + s->dom_name = talloc_strdup( s, dom_name ); + s->name = talloc_strdup( s, name ); + s->caller_private_data = private_data; + do_async_domain(mem_ctx, domain, &request, lookupname_recv, - (void *)cont, private_data); + (void *)cont, s); } enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain, diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index d8d7249c2d..49d381913a 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -725,24 +725,17 @@ BOOL winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx, * 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; - struct winbindd_domain *domain; *dom_name = NULL; *name = NULL; - domain = find_lookup_domain_from_sid(sid); - - if (!domain) { - DEBUG(1,("Can't find domain from sid\n")); - return False; - } - /* Lookup name */ result = domain->methods->sid_to_name(domain, mem_ctx, sid, dom_name, name, type); -- cgit