diff options
author | Nadezhda Ivanova <nadezhda.ivanova@postpath.com> | 2010-01-04 11:24:10 +0200 |
---|---|---|
committer | Nadezhda Ivanova <nadezhda.ivanova@postpath.com> | 2010-01-04 11:24:10 +0200 |
commit | fb5383c69ee52fb5e6d066a43451dc8c806cc795 (patch) | |
tree | 45b72e03f68ab6d212755c524f8e8a60a3b4373a /source3/winbindd | |
parent | 60d8ab3b7b0bd2c9b633f0380d1fdf5bcf5e2621 (diff) | |
parent | a06e5cdb99ddf7abf16486d3837105ec4e0da9ee (diff) | |
download | samba-fb5383c69ee52fb5e6d066a43451dc8c806cc795.tar.gz samba-fb5383c69ee52fb5e6d066a43451dc8c806cc795.tar.bz2 samba-fb5383c69ee52fb5e6d066a43451dc8c806cc795.zip |
Merge branch 'master' of git://git.samba.org/samba
Diffstat (limited to 'source3/winbindd')
26 files changed, 452 insertions, 2179 deletions
diff --git a/source3/winbindd/wb_getgrsid.c b/source3/winbindd/wb_getgrsid.c index 03d71e45b9..bb93be2174 100644 --- a/source3/winbindd/wb_getgrsid.c +++ b/source3/winbindd/wb_getgrsid.c @@ -52,6 +52,17 @@ struct tevent_req *wb_getgrsid_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->max_nesting = max_nesting; + if (lp_winbind_trusted_domains_only()) { + struct winbindd_domain *our_domain = find_our_domain(); + + if (sid_compare_domain(group_sid, &our_domain->sid) == 0) { + DEBUG(7, ("winbindd_getgrsid: My domain -- rejecting " + "getgrsid() for %s\n", sid_string_tos(group_sid))); + tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); + return tevent_req_post(req, ev); + } + } + subreq = wb_lookupsid_send(state, ev, &state->sid); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); diff --git a/source3/winbindd/wb_gettoken.c b/source3/winbindd/wb_gettoken.c index 26189e5a97..ca407b2117 100644 --- a/source3/winbindd/wb_gettoken.c +++ b/source3/winbindd/wb_gettoken.c @@ -60,6 +60,13 @@ struct tevent_req *wb_gettoken_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } + if (lp_winbind_trusted_domains_only() && domain->primary) { + DEBUG(7, ("wb_gettoken: My domain -- rejecting getgroups() " + "for %s.\n", sid_string_tos(sid))); + tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); + return tevent_req_post(req, ev); + } + subreq = wb_lookupusergroups_send(state, ev, domain, &state->usersid); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); diff --git a/source3/winbindd/wb_sid2gid.c b/source3/winbindd/wb_sid2gid.c index a578746ea2..e15d563cd7 100644 --- a/source3/winbindd/wb_sid2gid.c +++ b/source3/winbindd/wb_sid2gid.c @@ -54,7 +54,7 @@ struct tevent_req *wb_sid2gid_send(TALLOC_CTX *mem_ctx, DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n", (int)state->gid, expired ? " (expired)": "")); - if (!expired || IS_DOMAIN_OFFLINE(find_our_domain())) { + if (!expired || is_domain_offline(find_our_domain())) { if (state->gid == -1) { tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); } else { diff --git a/source3/winbindd/wb_sid2uid.c b/source3/winbindd/wb_sid2uid.c index abfe257bfa..9c22b8d10b 100644 --- a/source3/winbindd/wb_sid2uid.c +++ b/source3/winbindd/wb_sid2uid.c @@ -53,7 +53,7 @@ struct tevent_req *wb_sid2uid_send(TALLOC_CTX *mem_ctx, DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n", (int)state->uid, expired ? " (expired)": "")); - if (!expired || IS_DOMAIN_OFFLINE(find_our_domain())) { + if (!expired || is_domain_offline(find_our_domain())) { if (state->uid == -1) { tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); } else { diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index e09374c5cb..f6f4a8fee7 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -532,6 +532,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = { winbindd_list_groups_send, winbindd_list_groups_recv }, { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC", winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv }, + { WINBINDD_PING_DC, "PING_DC", + winbindd_ping_dc_send, winbindd_ping_dc_recv }, { 0, NULL, NULL, NULL } }; @@ -796,10 +798,15 @@ static void winbind_client_request_read(struct tevent_req *req) ret = wb_req_read_recv(req, state, &state->request, &err); TALLOC_FREE(req); if (ret == -1) { + if (err == EPIPE) { + DEBUG(6, ("closing socket %d, client exited\n", + state->sock)); + } else { + DEBUG(2, ("Could not read client request from fd %d: " + "%s\n", state->sock, strerror(err))); + } close(state->sock); state->sock = -1; - DEBUG(2, ("Could not read client request: %s\n", - strerror(err))); remove_client(state); return; } @@ -833,10 +840,6 @@ static void remove_client(struct winbindd_cli_state *state) state->sock = -1; } - /* Free any getent state */ - - free_getent_state(state->getgrent_state); - TALLOC_FREE(state->mem_ctx); /* Remove from list and free */ @@ -855,7 +858,7 @@ static bool remove_idle_client(void) for (state = winbindd_client_list(); state; state = state->next) { if (state->response == NULL && - !state->pwent_state && !state->getgrent_state) { + !state->pwent_state && !state->grent_state) { nidle++; if (!last_access || state->last_access < last_access) { last_access = state->last_access; diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 2e7d09f442..ea791234fb 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -65,22 +65,11 @@ struct winbindd_cli_state { * initialized? */ bool getgrent_initialized; /* Has getgrent_state been * initialized? */ - struct getent_state *getgrent_state; /* State for getgrent() */ struct getpwent_state *pwent_state; /* State for getpwent() */ struct getgrent_state *grent_state; /* State for getgrent() */ }; -/* State between get{pw,gr}ent() calls */ - -struct getent_state { - struct getent_state *prev, *next; - void *sam_entries; - uint32 sam_entry_index, num_sam_entries; - bool got_sam_entries; - fstring domain_name; -}; - struct getpwent_state { struct winbindd_domain *domain; int next_user; @@ -121,8 +110,6 @@ struct winbindd_cm_conn { struct rpc_pipe_client *netlogon_pipe; }; -struct winbindd_async_request; - /* Async child */ struct winbindd_domain; @@ -326,10 +313,7 @@ struct winbindd_methods { /* enumerate trusted domains */ NTSTATUS (*trusted_domains)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids); + struct netr_DomainTrustList *trusts); }; /* Filled out by IDMAP backends */ @@ -400,9 +384,4 @@ struct WINBINDD_CCACHE_ENTRY { #define WINBINDD_PAM_AUTH_KRB5_RENEW_TIME 2592000 /* one month */ #define DOM_SEQUENCE_NONE ((uint32)-1) -#define IS_DOMAIN_OFFLINE(x) ( lp_winbind_offline_logon() && \ - ( get_global_winbindd_state_offline() \ - || !(x)->online ) ) -#define IS_DOMAIN_ONLINE(x) (!IS_DOMAIN_OFFLINE(x)) - #endif /* _WINBINDD_H */ diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 92c0272088..d15fb86d86 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -1257,33 +1257,23 @@ static NTSTATUS password_policy(struct winbindd_domain *domain, /* get a list of trusted domains */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - struct netr_DomainTrustList trusts; int i; uint32 flags; struct rpc_pipe_client *cli; - uint32 fr_flags = (NETR_TRUST_FLAG_IN_FOREST | NETR_TRUST_FLAG_TREEROOT); int ret_count; DEBUG(3,("ads: trusted_domains\n")); - *num_domains = 0; - *alt_names = NULL; - *names = NULL; - *dom_sids = NULL; + ZERO_STRUCTP(trusts); /* If this is our primary domain or a root in our forest, query for all trusts. If not, then just look for domain trusts in the target forest */ - if ( domain->primary || - ((domain->domain_flags&fr_flags) == fr_flags) ) - { + if (domain->primary || domain_is_forest_root(domain)) { flags = NETR_TRUST_FLAG_OUTBOUND | NETR_TRUST_FLAG_INBOUND | NETR_TRUST_FLAG_IN_FOREST; @@ -1303,142 +1293,121 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx, cli->desthost, flags, - &trusts, + trusts, NULL); - if ( NT_STATUS_IS_OK(result) && trusts.count) { - - /* Allocate memory for trusted domain names and sids */ - - if ( !(*names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - if ( !(*alt_names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - if ( !(*dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, trusts.count)) ) { - DEBUG(0, ("trusted_domains: out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - /* Copy across names and sids */ - - - ret_count = 0; - for (i = 0; i < trusts.count; i++) { - struct winbindd_domain d; + if (!NT_STATUS_IS_OK(result)) { + return result; + } + if (trusts->count == 0) { + return NT_STATUS_OK; + } - ZERO_STRUCT(d); + /* Copy across names and sids */ - /* drop external trusts if this is not our primary - domain. This means that the returned number of - domains may be less that the ones actually trusted - by the DC. */ + ret_count = 0; + for (i = 0; i < trusts->count; i++) { + struct netr_DomainTrust *trust = &trusts->array[i]; + struct winbindd_domain d; - if ( (trusts.array[i].trust_attributes == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && - !domain->primary ) - { - DEBUG(10,("trusted_domains: Skipping external trusted domain " - "%s because it is outside of our primary domain\n", - trusts.array[i].netbios_name)); - continue; - } + ZERO_STRUCT(d); - /* We must check that the SID of each trusted domain - * was returned to work around a bug in Windows: - * http://support.microsoft.com/kb/922832 */ + /* + * drop external trusts if this is not our primary + * domain. This means that the returned number of + * domains may be less that the ones actually trusted + * by the DC. + */ - (*names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].netbios_name); - (*alt_names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].dns_name); - if (trusts.array[i].sid) { - sid_copy(&(*dom_sids)[ret_count], trusts.array[i].sid); - } else { - sid_copy(&(*dom_sids)[ret_count], &global_sid_NULL); - } + if ((trust->trust_attributes + == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && + !domain->primary ) + { + DEBUG(10,("trusted_domains: Skipping external trusted " + "domain %s because it is outside of our " + "primary domain\n", + trust->netbios_name)); + continue; + } - /* add to the trusted domain cache */ + /* add to the trusted domain cache */ - fstrcpy( d.name, trusts.array[i].netbios_name); - fstrcpy( d.alt_name, trusts.array[i].dns_name); - if (trusts.array[i].sid) { - sid_copy( &d.sid, trusts.array[i].sid); - } else { - sid_copy(&d.sid, &global_sid_NULL); - } + fstrcpy(d.name, trust->netbios_name); + fstrcpy(d.alt_name, trust->dns_name); + if (trust->sid) { + sid_copy(&d.sid, trust->sid); + } else { + sid_copy(&d.sid, &global_sid_NULL); + } - if ( domain->primary ) { + if ( domain->primary ) { + DEBUG(10,("trusted_domains(ads): Searching " + "trusted domain list of %s and storing " + "trust flags for domain %s\n", + domain->name, d.alt_name)); + + d.domain_flags = trust->trust_flags; + d.domain_type = trust->trust_type; + d.domain_trust_attribs = trust->trust_attributes; + + wcache_tdc_add_domain( &d ); + ret_count++; + } else if (domain_is_forest_root(domain)) { + /* Check if we already have this record. If + * we are following our forest root that is not + * our primary domain, we want to keep trust + * flags from the perspective of our primary + * domain not our forest root. */ + struct winbindd_tdc_domain *exist = NULL; + + exist = wcache_tdc_fetch_domain( + talloc_tos(), trust->netbios_name); + if (!exist) { DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and storing " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - - d.domain_flags = trusts.array[i].trust_flags; - d.domain_type = trusts.array[i].trust_type; - d.domain_trust_attribs = trusts.array[i].trust_attributes; + "trusted domain list of %s and " + "storing trust flags for domain " + "%s\n", domain->name, d.alt_name)); + d.domain_flags = trust->trust_flags; + d.domain_type = trust->trust_type; + d.domain_trust_attribs = + trust->trust_attributes; wcache_tdc_add_domain( &d ); ret_count++; - } else if ( (domain->domain_flags&fr_flags) == fr_flags ) { - /* Check if we already have this record. If - * we are following our forest root that is not - * our primary domain, we want to keep trust - * flags from the perspective of our primary - * domain not our forest root. */ - struct winbindd_tdc_domain *exist = NULL; - - exist = - wcache_tdc_fetch_domain(NULL, trusts.array[i].netbios_name); - if (!exist) { - DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and storing " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - d.domain_flags = trusts.array[i].trust_flags; - d.domain_type = trusts.array[i].trust_type; - d.domain_trust_attribs = trusts.array[i].trust_attributes; - - wcache_tdc_add_domain( &d ); - ret_count++; - } - TALLOC_FREE(exist); + } + TALLOC_FREE(exist); + } else { + /* This gets a little tricky. If we are + following a transitive forest trust, then + innerit the flags, type, and attribs from + the domain we queried to make sure we don't + record the view of the trust from the wrong + side. Always view it from the side of our + primary domain. --jerry */ + struct winbindd_tdc_domain *parent = NULL; + + DEBUG(10,("trusted_domains(ads): Searching " + "trusted domain list of %s and inheriting " + "trust flags for domain %s\n", + domain->name, d.alt_name)); + + parent = wcache_tdc_fetch_domain(talloc_tos(), + domain->name); + if (parent) { + d.domain_flags = parent->trust_flags; + d.domain_type = parent->trust_type; + d.domain_trust_attribs = parent->trust_attribs; } else { - /* This gets a little tricky. If we are - following a transitive forest trust, then - innerit the flags, type, and attribs from - the domain we queried to make sure we don't - record the view of the trust from the wrong - side. Always view it from the side of our - primary domain. --jerry */ - struct winbindd_tdc_domain *parent = NULL; - - DEBUG(10,("trusted_domains(ads): Searching " - "trusted domain list of %s and inheriting " - "trust flags for domain %s\n", - domain->name, d.alt_name)); - - parent = wcache_tdc_fetch_domain(NULL, domain->name); - if (parent) { - d.domain_flags = parent->trust_flags; - d.domain_type = parent->trust_type; - d.domain_trust_attribs = parent->trust_attribs; - } else { - d.domain_flags = domain->domain_flags; - d.domain_type = domain->domain_type; - d.domain_trust_attribs = domain->domain_trust_attribs; - } - TALLOC_FREE(parent); - - wcache_tdc_add_domain( &d ); - ret_count++; + d.domain_flags = domain->domain_flags; + d.domain_type = domain->domain_type; + d.domain_trust_attribs = + domain->domain_trust_attribs; } - } + TALLOC_FREE(parent); - *num_domains = ret_count; + wcache_tdc_add_domain( &d ); + ret_count++; + } } - return result; } diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c index 6c5d92e71b..5a350b99bc 100644 --- a/source3/winbindd/winbindd_async.c +++ b/source3/winbindd/winbindd_async.c @@ -6,17 +6,6 @@ Copyright (C) Volker Lendecke 2005 Copyright (C) Gerald Carter 2006 - The helpers always consist of three functions: - - * A request setup function that takes the necessary parameters together - with a continuation function that is to be called upon completion - - * A private continuation function that is internal only. This is to be - called by the lower-level functions in do_async(). Its only task is to - properly call the continuation function named above. - - * A worker function that is called inside the appropriate child process. - 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 @@ -37,423 +26,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -struct do_async_state { - TALLOC_CTX *mem_ctx; - struct winbindd_request request; - struct winbindd_response response; - void (*cont)(TALLOC_CTX *mem_ctx, - bool success, - struct winbindd_response *response, - void *c, void *private_data); - void *c, *private_data; -}; - -static void do_async_recv(void *private_data, bool success) -{ - struct do_async_state *state = - talloc_get_type_abort(private_data, struct do_async_state); - - state->cont(state->mem_ctx, success, &state->response, - state->c, state->private_data); -} - -void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child, - const struct winbindd_request *request, - void (*cont)(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data), - void *c, void *private_data) -{ - struct do_async_state *state; - - state = TALLOC_ZERO_P(mem_ctx, struct do_async_state); - if (state == NULL) { - DEBUG(0, ("talloc failed\n")); - cont(mem_ctx, False, NULL, c, private_data); - return; - } - - state->mem_ctx = mem_ctx; - state->request = *request; - state->request.length = sizeof(state->request); - state->cont = cont; - state->c = c; - state->private_data = private_data; - - async_request(mem_ctx, child, &state->request, - &state->response, do_async_recv, state); -} - -static void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, - const struct winbindd_request *request, - void (*cont)(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data), - void *c, void *private_data) -{ - struct do_async_state *state; - - state = TALLOC_ZERO_P(mem_ctx, struct do_async_state); - if (state == NULL) { - DEBUG(0, ("talloc failed\n")); - cont(mem_ctx, False, NULL, c, private_data); - return; - } - - state->mem_ctx = mem_ctx; - state->request = *request; - state->request.length = sizeof(state->request); - state->cont = cont; - state->c = c; - state->private_data = private_data; - - async_domain_request(mem_ctx, domain, &state->request, - &state->response, do_async_recv, state); -} - -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) -{ - 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) { - /* 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; - sid_to_fstring(request.data.sid, &s->sid); - - do_async_domain(mem_ctx, root_domain, &request, lookupsid_recv2, - (void *)cont, s); - - return; - } - - cont(s->caller_private_data, True, response->data.name.dom_name, - response->data.name.name, - (enum lsa_SidType)response->data.name.type); -} - -void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, - const char *dom_name, - const char *name, - enum lsa_SidType type), - void *private_data) -{ - struct winbindd_domain *domain; - struct winbindd_request request; - struct lookupsid_state *s; - - domain = find_lookup_domain_from_sid(sid); - if (domain == NULL) { - DEBUG(5, ("Could not find domain for sid %s\n", - sid_string_dbg(sid))); - cont(private_data, False, NULL, NULL, SID_NAME_UNKNOWN); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_LOOKUPSID; - sid_to_fstring(request.data.sid, 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, s); -} - -enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - enum lsa_SidType type; - DOM_SID sid; - char *name; - char *dom_name; - - /* Ensure null termination */ - state->request->data.sid[sizeof(state->request->data.sid)-1]='\0'; - - DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, - state->request->data.sid)); - - /* Lookup sid from PDC using lsa_lookup_sids() */ - - if (!string_to_sid(&sid, state->request->data.sid)) { - DEBUG(5, ("%s not a SID\n", state->request->data.sid)); - return WINBINDD_ERROR; - } - - /* Lookup the sid */ - - 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; - } - - fstrcpy(state->response->data.name.dom_name, dom_name); - fstrcpy(state->response->data.name.name, name); - state->response->data.name.type = type; - - TALLOC_FREE(dom_name); - TALLOC_FREE(name); - return WINBINDD_OK; -} - -/******************************************************************** - 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) -{ - void (*cont)(void *priv, bool succ, const DOM_SID *sid, - 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(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("lookup_name returned an error\n")); - 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(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - cont(s->caller_private_data, True, &sid, - (enum lsa_SidType)response->data.sid.type); -} - -/******************************************************************** - This is the first callback after contacting our own domain -********************************************************************/ - -static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const DOM_SID *sid, - 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(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_request request; - - if ( !root_domain ) { - DEBUG(5,("lookupname_recv: unable to determine forest root\n")); - cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_LOOKUPNAME; - - 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, s); - - 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(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - cont(s->caller_private_data, True, &sid, - (enum lsa_SidType)response->data.sid.type); -} - -/******************************************************************** - The lookup name call first contacts a DC in its own domain - and fallbacks to contact a DC if the forest in our domain doesn't - know the name. -********************************************************************/ - -void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, - const char *dom_name, const char *name, - void (*cont)(void *private_data, bool success, - const DOM_SID *sid, - enum lsa_SidType type), - enum winbindd_cmd orig_cmd, - void *private_data) -{ - struct winbindd_request request; - struct winbindd_domain *domain; - struct lookupname_state *s; - - domain = find_lookup_domain_from_name(dom_name); - if (domain == NULL) { - DEBUG(5, ("Could not find domain for name '%s'\n", dom_name)); - cont(private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_LOOKUPNAME; - request.original_cmd = orig_cmd; - 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 ); - if (!s->dom_name || !s->name) { - cont(private_data, False, NULL, SID_NAME_UNKNOWN); - return; - } - - s->caller_private_data = private_data; - - do_async_domain(mem_ctx, domain, &request, lookupname_recv, - (void *)cont, s); -} - -enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - enum lsa_SidType type; - char *name_domain, *name_user; - DOM_SID sid; - char *p; - - /* Ensure null termination */ - state->request->data.name.dom_name[sizeof(state->request->data.name.dom_name)-1]='\0'; - - /* Ensure null termination */ - state->request->data.name.name[sizeof(state->request->data.name.name)-1]='\0'; - - /* cope with the name being a fully qualified name */ - p = strstr(state->request->data.name.name, lp_winbind_separator()); - if (p) { - *p = 0; - name_domain = state->request->data.name.name; - name_user = p+1; - } else { - name_domain = state->request->data.name.dom_name; - name_user = state->request->data.name.name; - } - - DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid, - name_domain, lp_winbind_separator(), name_user)); - - /* Lookup name from DC using lsa_lookup_names() */ - if (!winbindd_lookup_sid_by_name(state->mem_ctx, state->request->original_cmd, domain, name_domain, - name_user, &sid, &type)) { - return WINBINDD_ERROR; - } - - sid_to_fstring(state->response->data.sid.sid, &sid); - state->response->data.sid.type = type; - - return WINBINDD_OK; -} - bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids, size_t num_sids, char **result, ssize_t *len) { @@ -514,127 +86,6 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, return True; } -static void getsidaliases_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, - DOM_SID *aliases, size_t num_aliases) = - (void (*)(void *, bool, DOM_SID *, size_t))c; - char *aliases_str; - DOM_SID *sids = NULL; - size_t num_sids = 0; - - if (!success) { - DEBUG(5, ("Could not trigger getsidaliases\n")); - cont(private_data, success, NULL, 0); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("getsidaliases returned an error\n")); - cont(private_data, False, NULL, 0); - return; - } - - aliases_str = (char *)response->extra_data.data; - - if (aliases_str == NULL) { - DEBUG(10, ("getsidaliases return 0 SIDs\n")); - cont(private_data, True, NULL, 0); - return; - } - - if (!parse_sidlist(mem_ctx, aliases_str, &sids, &num_sids)) { - DEBUG(0, ("Could not parse sids\n")); - cont(private_data, False, NULL, 0); - return; - } - - cont(private_data, True, sids, num_sids); -} - -void winbindd_getsidaliases_async(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const DOM_SID *sids, size_t num_sids, - void (*cont)(void *private_data, - bool success, - const DOM_SID *aliases, - size_t num_aliases), - void *private_data) -{ - struct winbindd_request request; - char *sidstr = NULL; - ssize_t len; - - if (num_sids == 0) { - cont(private_data, True, NULL, 0); - return; - } - - if (!print_sidlist(mem_ctx, sids, num_sids, &sidstr, &len)) { - cont(private_data, False, NULL, 0); - return; - } - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_GETSIDALIASES; - request.extra_len = len; - request.extra_data.data = sidstr; - - do_async_domain(mem_ctx, domain, &request, getsidaliases_recv, - (void *)cont, private_data); -} - -static void query_user_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const char *acct_name, - const char *full_name, const char *homedir, - const char *shell, uint32 gid, uint32 group_rid) = - (void (*)(void *, bool, const char *, const char *, - const char *, const char *, uint32, uint32))c; - - if (!success) { - DEBUG(5, ("Could not trigger query_user\n")); - cont(private_data, False, NULL, NULL, NULL, NULL, -1, -1); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("query_user returned an error\n")); - cont(private_data, False, NULL, NULL, NULL, NULL, -1, -1); - return; - } - - cont(private_data, True, response->data.user_info.acct_name, - response->data.user_info.full_name, - response->data.user_info.homedir, - response->data.user_info.shell, - response->data.user_info.primary_gid, - response->data.user_info.group_rid); -} - -void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, - const DOM_SID *sid, - void (*cont)(void *private_data, bool success, - const char *acct_name, - const char *full_name, - const char *homedir, - const char *shell, - gid_t gid, - uint32 group_rid), - void *private_data) -{ - struct winbindd_request request; - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_USERINFO; - sid_to_fstring(request.data.sid, sid); - do_async_domain(mem_ctx, domain, &request, query_user_recv, - (void *)cont, private_data); -} - enum winbindd_result winbindd_dual_ping(struct winbindd_domain *domain, struct winbindd_cli_state *state) { diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index c4bc936a5d..ddbd9d9d5b 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -514,7 +514,7 @@ static void refresh_sequence_number(struct winbindd_domain *domain, bool force) time_t t = time(NULL); unsigned cache_time = lp_winbind_cache_time(); - if ( IS_DOMAIN_OFFLINE(domain) ) { + if (is_domain_offline(domain)) { return; } @@ -2446,62 +2446,9 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) * Guenther */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { - struct winbind_cache *cache = get_cache(domain); - struct cache_entry *centry = NULL; NTSTATUS status; - int i; - - if (!cache->tdb) - goto do_query; - - centry = wcache_fetch(cache, domain, "TRUSTDOMS/%s", domain->name); - - if (!centry) { - goto do_query; - } - - *num_domains = centry_uint32(centry); - - if (*num_domains) { - (*names) = TALLOC_ARRAY(mem_ctx, char *, *num_domains); - (*alt_names) = TALLOC_ARRAY(mem_ctx, char *, *num_domains); - (*dom_sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains); - - if (! (*dom_sids) || ! (*names) || ! (*alt_names)) { - smb_panic_fn("trusted_domains out of memory"); - } - } else { - (*names) = NULL; - (*alt_names) = NULL; - (*dom_sids) = NULL; - } - - for (i=0; i<(*num_domains); i++) { - (*names)[i] = centry_string(centry, mem_ctx); - (*alt_names)[i] = centry_string(centry, mem_ctx); - if (!centry_sid(centry, &(*dom_sids)[i])) { - sid_copy(&(*dom_sids)[i], &global_sid_NULL); - } - } - - status = centry->status; - - DEBUG(10,("trusted_domains: [Cached] - cached info for domain %s (%d trusts) status: %s\n", - domain->name, *num_domains, nt_errstr(status) )); - - centry_free(centry); - return status; - -do_query: - (*num_domains) = 0; - (*dom_sids) = NULL; - (*names) = NULL; - (*alt_names) = NULL; /* Return status value returned by seq number check */ @@ -2511,8 +2458,7 @@ do_query: DEBUG(10,("trusted_domains: [Cached] - doing backend query for info for domain %s\n", domain->name )); - status = domain->backend->trusted_domains(domain, mem_ctx, num_domains, - names, alt_names, dom_sids); + status = domain->backend->trusted_domains(domain, mem_ctx, trusts); /* no trusts gives NT_STATUS_NO_MORE_ENTRIES resetting to NT_STATUS_OK * so that the generic centry handling still applies correctly - @@ -2521,33 +2467,6 @@ do_query: if (!NT_STATUS_IS_ERR(status)) { status = NT_STATUS_OK; } - - -#if 0 /* Disabled as we want the trust dom list to be managed by - the main parent and always to make the query. --jerry */ - - /* and save it */ - refresh_sequence_number(domain, false); - - centry = centry_start(domain, status); - if (!centry) - goto skip_save; - - centry_put_uint32(centry, *num_domains); - - for (i=0; i<(*num_domains); i++) { - centry_put_string(centry, (*names)[i]); - centry_put_string(centry, (*alt_names)[i]); - centry_put_sid(centry, &(*dom_sids)[i]); - } - - centry_end(centry, "TRUSTDOMS/%s", domain->name); - - centry_free(centry); - -skip_save: -#endif - return status; } @@ -3557,34 +3476,6 @@ static int validate_nss_na(TALLOC_CTX *mem_ctx, const char *keystr, return 0; } -static int validate_trustdoms(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, - struct tdb_validation_status *state) -{ - struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); - int32 num_domains, i; - - if (!centry) { - return 1; - } - - num_domains = centry_uint32(centry); - - for (i=0; i< num_domains; i++) { - DOM_SID sid; - (void)centry_string(centry, mem_ctx); - (void)centry_string(centry, mem_ctx); - (void)centry_sid(centry, &sid); - } - - centry_free(centry); - - if (!(state->success)) { - return 1; - } - DEBUG(10,("validate_trustdoms: %s ok\n", keystr)); - return 0; -} - static int validate_trustdomcache(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, struct tdb_validation_status *state) @@ -3666,7 +3557,6 @@ struct key_val_struct { {"DR/", validate_dr}, {"DE/", validate_de}, {"NSS/PWINFO/", validate_pwinfo}, - {"TRUSTDOMS/", validate_trustdoms}, {"TRUSTDOMCACHE/", validate_trustdomcache}, {"NSS/NA/", validate_nss_na}, {"NSS/AN/", validate_nss_an}, @@ -4361,6 +4251,7 @@ static bool wcache_opnum_cacheable(uint32_t opnum) case NDR_WBINT_ALLOCATEGID: case NDR_WBINT_CHECKMACHINEACCOUNT: case NDR_WBINT_CHANGEMACHINEACCOUNT: + case NDR_WBINT_PINGDC: return false; } return true; @@ -4393,7 +4284,7 @@ bool wcache_fetch_ndr(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, goto fail; } - if (IS_DOMAIN_ONLINE(domain)) { + if (!is_domain_offline(domain)) { uint32_t entry_seqnum, dom_seqnum, last_check; if (!wcache_fetch_seqnum(domain->name, &dom_seqnum, diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index 86017e2215..921110a0be 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -6,23 +6,24 @@ Copyright (C) Robert O'Callahan 2006 Copyright (C) Jeremy Allison 2006 (minor fixes to fit into Samba and protect against integer wrap). - + 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 <http://www.gnu.org/licenses/>. */ #include "includes.h" #include "winbindd.h" +#include "ntlmssp.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -49,7 +50,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username, DATA_BLOB *auth_msg) { NTSTATUS status; - NTLMSSP_STATE *ntlmssp_state = NULL; + struct ntlmssp_state *ntlmssp_state = NULL; DATA_BLOB dummy_msg, reply; status = ntlmssp_client_start(&ntlmssp_state); @@ -77,7 +78,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username, } status = ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash); - + if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set hashes: %s\n", nt_errstr(status))); @@ -250,21 +251,15 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma goto process_result; } - initial = data_blob(state->request->extra_data.data, initial_blob_len); - challenge = data_blob(state->request->extra_data.data + initial_blob_len, - state->request->data.ccache_ntlm_auth.challenge_blob_len); - - if (!initial.data || !challenge.data) { - result = NT_STATUS_NO_MEMORY; - } else { - result = do_ntlm_auth_with_hashes(name_user, name_domain, - entry->lm_hash, entry->nt_hash, - initial, challenge, &auth); - } - - data_blob_free(&initial); - data_blob_free(&challenge); + initial = data_blob_const(state->request->extra_data.data, + initial_blob_len); + challenge = data_blob_const( + state->request->extra_data.data + initial_blob_len, + state->request->data.ccache_ntlm_auth.challenge_blob_len); + result = do_ntlm_auth_with_hashes(name_user, name_domain, + entry->lm_hash, entry->nt_hash, + initial, challenge, &auth); if (!NT_STATUS_IS_OK(result)) { goto process_result; } diff --git a/source3/winbindd/winbindd_check_machine_acct.c b/source3/winbindd/winbindd_check_machine_acct.c index 610e9edfaa..33b6d9fba4 100644 --- a/source3/winbindd/winbindd_check_machine_acct.c +++ b/source3/winbindd/winbindd_check_machine_acct.c @@ -42,7 +42,7 @@ struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx, return NULL; } - if (request->domain_name[0] == '0') { + if (request->domain_name[0] == '\0') { /* preserve old behavior, when no domain name is given */ domain = find_our_domain(); } else { diff --git a/source3/winbindd/winbindd_domain.c b/source3/winbindd/winbindd_domain.c index ad3d6d7916..45da57e132 100644 --- a/source3/winbindd/winbindd_domain.c +++ b/source3/winbindd/winbindd_domain.c @@ -31,14 +31,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .struct_cmd = WINBINDD_PING, .struct_fn = winbindd_dual_ping, },{ - .name = "LOOKUPSID", - .struct_cmd = WINBINDD_LOOKUPSID, - .struct_fn = winbindd_dual_lookupsid, - },{ - .name = "LOOKUPNAME", - .struct_cmd = WINBINDD_LOOKUPNAME, - .struct_fn = winbindd_dual_lookupname, - },{ .name = "LIST_TRUSTDOM", .struct_cmd = WINBINDD_LIST_TRUSTDOM, .struct_fn = winbindd_dual_list_trusted_domains, @@ -47,10 +39,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .struct_cmd = WINBINDD_INIT_CONNECTION, .struct_fn = winbindd_dual_init_connection, },{ - .name = "GETDCNAME", - .struct_cmd = WINBINDD_GETDCNAME, - .struct_fn = winbindd_dual_getdcname, - },{ .name = "SHOW_SEQUENCE", .struct_cmd = WINBINDD_SHOW_SEQUENCE, .struct_fn = winbindd_dual_show_sequence, @@ -75,22 +63,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .struct_cmd = WINBINDD_PAM_CHAUTHTOK, .struct_fn = winbindd_dual_pam_chauthtok, },{ - .name = "DUAL_USERINFO", - .struct_cmd = WINBINDD_DUAL_USERINFO, - .struct_fn = winbindd_dual_userinfo, - },{ - .name = "GETUSERDOMGROUPS", - .struct_cmd = WINBINDD_GETUSERDOMGROUPS, - .struct_fn = winbindd_dual_getuserdomgroups, - },{ - .name = "GETSIDALIASES", - .struct_cmd = WINBINDD_DUAL_GETSIDALIASES, - .struct_fn = winbindd_dual_getsidaliases, - },{ - .name = "GETSIDALIASES", - .struct_cmd = WINBINDD_GETSIDALIASES, - .struct_fn = winbindd_dual_getsidaliases, - },{ .name = "CCACHE_NTLM_AUTH", .struct_cmd = WINBINDD_CCACHE_NTLMAUTH, .struct_fn = winbindd_dual_ccache_ntlm_auth, @@ -108,6 +80,4 @@ void setup_domain_child(struct winbindd_domain *domain, { setup_child(domain, child, domain_dispatch_table, "log.wb", domain->name); - - child->domain = domain; } diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 376d7c7309..74b2b99b7f 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -367,85 +367,6 @@ int wb_domain_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, return 0; } -/* - * Machinery for async requests sent to children. You set up a - * winbindd_request, select a child to query, and issue a async_request - * call. When the request is completed, the callback function you specified is - * called back with the private pointer you gave to async_request. - */ - -struct winbindd_async_request { - struct winbindd_async_request *next, *prev; - TALLOC_CTX *mem_ctx; - struct winbindd_child *child; - struct winbindd_response *response; - void (*continuation)(void *private_data, bool success); - struct timed_event *reply_timeout_event; - pid_t child_pid; /* pid of the child we're waiting on. Used to detect - a restart of the child (child->pid != child_pid). */ - void *private_data; -}; - -static void async_request_done(struct tevent_req *req); - -void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, - struct winbindd_request *request, - struct winbindd_response *response, - void (*continuation)(void *private_data, bool success), - void *private_data) -{ - struct winbindd_async_request *state; - struct tevent_req *req; - - DEBUG(10, ("Sending request to child pid %d (domain=%s)\n", - (int)child->pid, - (child->domain != NULL) ? child->domain->name : "''")); - - state = talloc(mem_ctx, struct winbindd_async_request); - if (state == NULL) { - DEBUG(0, ("talloc failed\n")); - continuation(private_data, False); - return; - } - - state->mem_ctx = mem_ctx; - state->child = child; - state->reply_timeout_event = NULL; - state->response = response; - state->continuation = continuation; - state->private_data = private_data; - - request->pid = child->pid; - - req = wb_child_request_send(state, winbind_event_context(), - child, request); - if (req == NULL) { - DEBUG(0, ("wb_child_request_send failed\n")); - continuation(private_data, false); - return; - } - tevent_req_set_callback(req, async_request_done, state); -} - -static void async_request_done(struct tevent_req *req) -{ - struct winbindd_async_request *state = tevent_req_callback_data( - req, struct winbindd_async_request); - struct winbindd_response *response; - int ret, err; - - ret = wb_child_request_recv(req, state, &response, &err); - TALLOC_FREE(req); - if (ret == -1) { - DEBUG(2, ("wb_child_request_recv failed: %s\n", - strerror(err))); - state->continuation(state->private_data, false); - return; - } - *state->response = *response; - state->continuation(state->private_data, true); -} - struct domain_request_state { struct winbindd_domain *domain; struct winbindd_request *request; @@ -527,13 +448,6 @@ static void recvfrom_child(void *private_data_data, bool success) request_ok(state); } -void sendto_child(struct winbindd_cli_state *state, - struct winbindd_child *child) -{ - async_request(state->mem_ctx, child, state->request, - state->response, recvfrom_child, state); -} - void sendto_domain(struct winbindd_cli_state *state, struct winbindd_domain *domain) { @@ -588,7 +502,7 @@ void setup_child(struct winbindd_domain *domain, struct winbindd_child *child, "logname == NULL"); } - child->domain = NULL; + child->domain = domain; child->table = table; child->queue = tevent_queue_create(NULL, "winbind_child"); SMB_ASSERT(child->queue != NULL); @@ -696,7 +610,7 @@ void winbind_msg_offline(struct messaging_context *msg_ctx, } for (child = children; child != NULL; child = child->next) { - /* Don't send message to internal childs. We've already + /* Don't send message to internal children. We've already done so above. */ if (!child->domain || winbindd_internal_child(child)) { continue; @@ -830,7 +744,7 @@ void winbind_msg_onlinestatus(struct messaging_context *msg_ctx, TALLOC_CTX *mem_ctx; const char *message; struct server_id *sender; - + DEBUG(5,("winbind_msg_onlinestatus received.\n")); if (!data->data) { @@ -843,7 +757,7 @@ void winbind_msg_onlinestatus(struct messaging_context *msg_ctx, if (mem_ctx == NULL) { return; } - + message = collect_onlinestatus(mem_ctx); if (message == NULL) { talloc_destroy(mem_ctx); diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index cecbb61051..b247d5a233 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -510,6 +510,54 @@ again: return status; } +NTSTATUS _wbint_PingDc(pipes_struct *p, struct wbint_PingDc *r) +{ + NTSTATUS status; + struct winbindd_domain *domain; + struct rpc_pipe_client *netlogon_pipe; + union netr_CONTROL_QUERY_INFORMATION info; + WERROR werr; + fstring logon_server; + + domain = wb_child_domain(); + if (domain == NULL) { + return NT_STATUS_REQUEST_NOT_ACCEPTED; + } + + status = cm_connect_netlogon(domain, &netlogon_pipe); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("could not open handle to NETLOGON pipe\n")); + return status; + } + + fstr_sprintf(logon_server, "\\\\%s", domain->dcname); + + /* + * This provokes a WERR_NOT_SUPPORTED error message. This is + * documented in the wspp docs. I could not get a successful + * call to work, but the main point here is testing that the + * netlogon pipe works. + */ + status = rpccli_netr_LogonControl(netlogon_pipe, p->mem_ctx, + logon_server, NETLOGON_CONTROL_QUERY, + 2, &info, &werr); + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + DEBUG(2, ("rpccli_netr_LogonControl timed out\n")); + invalidate_cm_connection(&domain->conn); + return status; + } + + if (!NT_STATUS_EQUAL(status, NT_STATUS_CTL_FILE_NOT_SUPPORTED)) { + DEBUG(2, ("rpccli_netr_LogonControl returned %s, expected " + "NT_STATUS_CTL_FILE_NOT_SUPPORTED\n", + nt_errstr(status))); + return status; + } + + DEBUG(5, ("winbindd_dual_ping_dc succeeded\n")); + return NT_STATUS_OK; +} NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r) { diff --git a/source3/winbindd/winbindd_getgrnam.c b/source3/winbindd/winbindd_getgrnam.c index d888393399..3ca1aa6111 100644 --- a/source3/winbindd/winbindd_getgrnam.c +++ b/source3/winbindd/winbindd_getgrnam.c @@ -40,7 +40,6 @@ struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct winbindd_getgrnam_state *state; - struct winbindd_domain *domain; char *tmp; NTSTATUS nt_status; @@ -77,27 +76,7 @@ struct tevent_req *winbindd_getgrnam_send(TALLOC_CTX *mem_ctx, fstrcpy(state->name_domain, get_global_sam_name()); } - /* Get info for the domain */ - - domain = find_domain_from_name_noinit(state->name_domain); - if (domain == NULL) { - DEBUG(3, ("could not get domain sid for domain %s\n", - state->name_domain)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); - return tevent_req_post(req, ev); - } - - /* should we deal with users for our domain? */ - - if ( lp_winbind_trusted_domains_only() && domain->primary) { - DEBUG(7,("winbindd_getgrnam: My domain -- rejecting " - "getgrnam() for %s\\%s.\n", state->name_domain, - state->name_group)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); - return tevent_req_post(req, ev); - } - - subreq = wb_lookupname_send(state, ev, domain->name, state->name_group, + subreq = wb_lookupname_send(state, ev, state->name_domain, state->name_group, 0); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); diff --git a/source3/winbindd/winbindd_getgroups.c b/source3/winbindd/winbindd_getgroups.c index 3bdf762c45..736eba698a 100644 --- a/source3/winbindd/winbindd_getgroups.c +++ b/source3/winbindd/winbindd_getgroups.c @@ -45,7 +45,6 @@ struct tevent_req *winbindd_getgroups_send(TALLOC_CTX *mem_ctx, struct tevent_req *req, *subreq; struct winbindd_getgroups_state *state; char *domuser, *mapped_user; - struct winbindd_domain *domain; NTSTATUS status; req = tevent_req_create(mem_ctx, &state, @@ -76,29 +75,6 @@ struct tevent_req *winbindd_getgroups_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - domain = find_domain_from_name_noinit(state->domname); - if (domain == NULL) { - /* Retry with DNS name */ - char *p = strchr(domuser, '@'); - if (p != NULL) { - domain = find_domain_from_name_noinit(p+1); - } - } - if (domain == NULL) { - DEBUG(7, ("could not find domain entry for domain %s\n", - state->domname)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return tevent_req_post(req, ev); - } - - if (lp_winbind_trusted_domains_only() && domain->primary) { - DEBUG(7,("winbindd_getgroups: My domain -- " - "rejecting getgroups() for %s\\%s.\n", - state->domname, state->username)); - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return tevent_req_post(req, ev); - } - subreq = wb_lookupname_send(state, ev, state->domname, state->username, LOOKUP_NAME_NO_NSS); if (tevent_req_nomem(subreq, req)) { diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c index eab5c26df4..a985fa254f 100644 --- a/source3/winbindd/winbindd_group.c +++ b/source3/winbindd/winbindd_group.c @@ -66,290 +66,6 @@ bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr, return True; } -/* Get the list of domain groups and domain aliases for a domain. We fill in - the sam_entries and num_sam_entries fields with domain group information. - Return True if some groups were returned, False otherwise. */ - -bool get_sam_group_entries(struct getent_state *ent) -{ - NTSTATUS status; - uint32 num_entries; - struct acct_info *name_list = NULL; - TALLOC_CTX *mem_ctx; - bool result = False; - struct acct_info *sam_grp_entries = NULL; - struct winbindd_domain *domain; - - if (ent->got_sam_entries) - return False; - - if (!(mem_ctx = talloc_init("get_sam_group_entries(%s)", - ent->domain_name))) { - DEBUG(1, ("get_sam_group_entries: " - "could not create talloc context!\n")); - return False; - } - - /* Free any existing group info */ - - SAFE_FREE(ent->sam_entries); - ent->num_sam_entries = 0; - ent->got_sam_entries = True; - - /* Enumerate domain groups */ - - num_entries = 0; - - if (!(domain = find_domain_from_name(ent->domain_name))) { - DEBUG(3, ("no such domain %s in get_sam_group_entries\n", - ent->domain_name)); - goto done; - } - - /* always get the domain global groups */ - - status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries, - &sam_grp_entries); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("get_sam_group_entries: " - "could not enumerate domain groups! Error: %s\n", - nt_errstr(status))); - result = False; - goto done; - } - - /* Copy entries into return buffer */ - - if (num_entries) { - name_list = SMB_MALLOC_ARRAY(struct acct_info, num_entries); - if (!name_list) { - DEBUG(0,("get_sam_group_entries: Failed to malloc " - "memory for %d domain groups!\n", - num_entries)); - result = False; - goto done; - } - memcpy(name_list, sam_grp_entries, - num_entries * sizeof(struct acct_info)); - } - - ent->num_sam_entries = num_entries; - - /* get the domain local groups if we are a member of a native win2k - * domain and are not using LDAP to get the groups */ - - if ( ( lp_security() != SEC_ADS && domain->native_mode - && domain->primary) || domain->internal ) - { - DEBUG(4,("get_sam_group_entries: %s domain; " - "enumerating local groups as well\n", - domain->native_mode ? "Native Mode 2k": - "BUILTIN or local")); - - status = domain->methods->enum_local_groups(domain, mem_ctx, - &num_entries, - &sam_grp_entries); - - if ( !NT_STATUS_IS_OK(status) ) { - DEBUG(3,("get_sam_group_entries: " - "Failed to enumerate " - "domain local groups with error %s!\n", - nt_errstr(status))); - num_entries = 0; - } - else - DEBUG(4,("get_sam_group_entries: " - "Returned %d local groups\n", - num_entries)); - - /* Copy entries into return buffer */ - - if ( num_entries ) { - name_list = SMB_REALLOC_ARRAY(name_list, - struct acct_info, - ent->num_sam_entries+ - num_entries); - if (!name_list) { - DEBUG(0,("get_sam_group_entries: " - "Failed to realloc more memory " - "for %d local groups!\n", - num_entries)); - result = False; - goto done; - } - - memcpy(&name_list[ent->num_sam_entries], - sam_grp_entries, - num_entries * sizeof(struct acct_info)); - } - - ent->num_sam_entries += num_entries; - } - - - /* Fill in remaining fields */ - - ent->sam_entries = name_list; - ent->sam_entry_index = 0; - - result = (ent->num_sam_entries > 0); - - done: - talloc_destroy(mem_ctx); - - return result; -} - -/* Get user supplementary groups. This is much quicker than trying to - invert the groups database. We merge the groups from the gids and - other_sids info3 fields as trusted domain, universal group - memberships, and nested groups (win2k native mode only) are not - returned by the getgroups RPC call but are present in the info3. */ - -struct getgroups_state { - struct winbindd_cli_state *state; - struct winbindd_domain *domain; - char *domname; - char *username; - DOM_SID user_sid; - - const DOM_SID *token_sids; - size_t i, num_token_sids; - - gid_t *token_gids; - size_t num_token_gids; -}; - -enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID user_sid; - NTSTATUS status; - - char *sidstring; - ssize_t len; - DOM_SID *groups; - uint32 num_groups; - - /* Ensure null termination */ - state->request->data.sid[sizeof(state->request->data.sid)-1]='\0'; - - if (!string_to_sid(&user_sid, state->request->data.sid)) { - DEBUG(1, ("Could not get convert sid %s from string\n", - state->request->data.sid)); - return WINBINDD_ERROR; - } - - status = domain->methods->lookup_usergroups(domain, state->mem_ctx, - &user_sid, &num_groups, - &groups); - if (!NT_STATUS_IS_OK(status)) - return WINBINDD_ERROR; - - if (num_groups == 0) { - state->response->data.num_entries = 0; - state->response->extra_data.data = NULL; - return WINBINDD_OK; - } - - if (!print_sidlist(state->mem_ctx, - groups, num_groups, - &sidstring, &len)) { - DEBUG(0, ("talloc failed\n")); - return WINBINDD_ERROR; - } - - state->response->extra_data.data = sidstring; - state->response->length += len+1; - state->response->data.num_entries = num_groups; - - return WINBINDD_OK; -} - -enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID *sids = NULL; - size_t num_sids = 0; - char *sidstr = NULL; - ssize_t len; - size_t i; - uint32 num_aliases; - uint32 *alias_rids; - NTSTATUS result; - - DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid)); - - sidstr = state->request->extra_data.data; - if (sidstr == NULL) { - sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */ - if (!sidstr) { - DEBUG(0, ("Out of memory\n")); - return WINBINDD_ERROR; - } - } - - DEBUG(10, ("Sidlist: %s\n", sidstr)); - - if (!parse_sidlist(state->mem_ctx, sidstr, &sids, &num_sids)) { - DEBUG(0, ("Could not parse SID list: %s\n", sidstr)); - return WINBINDD_ERROR; - } - - num_aliases = 0; - alias_rids = NULL; - - result = domain->methods->lookup_useraliases(domain, - state->mem_ctx, - num_sids, sids, - &num_aliases, - &alias_rids); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3, ("Could not lookup_useraliases: %s\n", - nt_errstr(result))); - return WINBINDD_ERROR; - } - - num_sids = 0; - sids = NULL; - sidstr = NULL; - - DEBUG(10, ("Got %d aliases\n", num_aliases)); - - for (i=0; i<num_aliases; i++) { - DOM_SID sid; - DEBUGADD(10, (" rid %d\n", alias_rids[i])); - sid_copy(&sid, &domain->sid); - sid_append_rid(&sid, alias_rids[i]); - result = add_sid_to_array(state->mem_ctx, &sid, &sids, - &num_sids); - if (!NT_STATUS_IS_OK(result)) { - return WINBINDD_ERROR; - } - } - - - if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) { - DEBUG(0, ("Could not print_sidlist\n")); - state->response->extra_data.data = NULL; - return WINBINDD_ERROR; - } - - state->response->extra_data.data = NULL; - - if (sidstr) { - state->response->extra_data.data = sidstr; - DEBUG(10, ("aliases_list: %s\n", - (char *)state->response->extra_data.data)); - state->response->length += len+1; - state->response->data.num_entries = num_sids; - } - - return WINBINDD_OK; -} - struct getgr_countmem { int num; size_t len; diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c index 1d275014ce..028026087d 100644 --- a/source3/winbindd/winbindd_idmap.c +++ b/source3/winbindd/winbindd_idmap.c @@ -7,17 +7,6 @@ Copyright (C) Gerald Carter 2006 Copyright (C) Simo Sorce 2007 - The helpers always consist of three functions: - - * A request setup function that takes the necessary parameters together - with a continuation function that is to be called upon completion - - * A private continuation function that is internal only. This is to be - called by the lower-level functions in do_async(). Its only task is to - properly call the continuation function named above. - - * A worker function that is called inside the appropriate child process. - 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 @@ -45,322 +34,12 @@ struct winbindd_child *idmap_child(void) return &static_idmap_child; } -static void winbindd_sid2uid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, uid_t uid) = - (void (*)(void *, bool, uid_t))c; - - if (!success) { - DEBUG(5, ("Could not trigger sid2uid\n")); - cont(private_data, False, 0); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("sid2uid returned an error\n")); - cont(private_data, False, 0); - return; - } - - cont(private_data, True, response->data.uid); -} - -void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, uid_t uid), - void *private_data) -{ - struct winbindd_request request; - struct winbindd_domain *domain; - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_SID2UID; - - domain = find_domain_from_sid(sid); - - if (domain != NULL) { - DEBUG(10, ("winbindd_sid2uid_async found domain %s, " - "have_idmap_config = %d\n", domain->name, - (int)domain->have_idmap_config)); - - } - else { - DEBUG(10, ("winbindd_sid2uid_async did not find a domain for " - "%s\n", sid_string_dbg(sid))); - } - - if ((domain != NULL) && (domain->have_idmap_config)) { - fstrcpy(request.domain_name, domain->name); - } - - sid_to_fstring(request.data.dual_sid2id.sid, sid); - do_async(mem_ctx, idmap_child(), &request, winbindd_sid2uid_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - NTSTATUS result; - - DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid, - state->request->data.dual_sid2id.sid)); - - if (!string_to_sid(&sid, state->request->data.dual_sid2id.sid)) { - DEBUG(1, ("Could not get convert sid %s from string\n", - state->request->data.dual_sid2id.sid)); - return WINBINDD_ERROR; - } - - result = idmap_sid_to_uid(state->request->domain_name, &sid, - &state->response->data.uid); - - DEBUG(10, ("winbindd_dual_sid2uid: 0x%08x - %s - %u\n", - NT_STATUS_V(result), sid_string_dbg(&sid), - (unsigned int)state->response->data.uid)); - - return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; -} - -static void winbindd_sid2gid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, gid_t gid) = - (void (*)(void *, bool, gid_t))c; - - if (!success) { - DEBUG(5, ("Could not trigger sid2gid\n")); - cont(private_data, False, 0); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("sid2gid returned an error\n")); - cont(private_data, False, 0); - return; - } - - cont(private_data, True, response->data.gid); -} - -void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, gid_t gid), - void *private_data) -{ - struct winbindd_request request; - struct winbindd_domain *domain; - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_SID2GID; - - domain = find_domain_from_sid(sid); - if ((domain != NULL) && (domain->have_idmap_config)) { - fstrcpy(request.domain_name, domain->name); - } - - sid_to_fstring(request.data.dual_sid2id.sid, sid); - - DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n", - request.data.dual_sid2id.sid)); - - do_async(mem_ctx, idmap_child(), &request, winbindd_sid2gid_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - NTSTATUS result; - - DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid, - state->request->data.dual_sid2id.sid)); - - if (!string_to_sid(&sid, state->request->data.dual_sid2id.sid)) { - DEBUG(1, ("Could not get convert sid %s from string\n", - state->request->data.dual_sid2id.sid)); - return WINBINDD_ERROR; - } - - /* Find gid for this sid and return it, possibly ask the slow remote idmap */ - - result = idmap_sid_to_gid(state->request->domain_name, &sid, - &state->response->data.gid); - - DEBUG(10, ("winbindd_dual_sid2gid: 0x%08x - %s - %u\n", - NT_STATUS_V(result), sid_string_dbg(&sid), - (unsigned int)state->response->data.gid)); - - return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; -} - -/* The following uid2sid/gid2sid functions has been contributed by - * Keith Reynolds <Keith.Reynolds@centrify.com> */ - -static void winbindd_uid2sid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const char *sid) = - (void (*)(void *, bool, const char *))c; - - if (!success) { - DEBUG(5, ("Could not trigger uid2sid\n")); - cont(private_data, False, NULL); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("uid2sid returned an error\n")); - cont(private_data, False, NULL); - return; - } - - cont(private_data, True, response->data.sid.sid); -} - -void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid, - void (*cont)(void *private_data, bool success, const char *sid), - void *private_data) -{ - struct winbindd_domain *domain; - struct winbindd_request request; - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_UID2SID; - request.data.uid = uid; - - for (domain = domain_list(); domain != NULL; domain = domain->next) { - if (domain->have_idmap_config - && (uid >= domain->id_range_low) - && (uid <= domain->id_range_high)) { - fstrcpy(request.domain_name, domain->name); - } - } - - do_async(mem_ctx, idmap_child(), &request, winbindd_uid2sid_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - NTSTATUS result; - - DEBUG(3,("[%5lu]: uid to sid %lu\n", - (unsigned long)state->pid, - (unsigned long) state->request->data.uid)); - - /* Find sid for this uid and return it, possibly ask the slow remote idmap */ - result = idmap_uid_to_sid(state->request->domain_name, &sid, - state->request->data.uid); - - if (NT_STATUS_IS_OK(result)) { - sid_to_fstring(state->response->data.sid.sid, &sid); - state->response->data.sid.type = SID_NAME_USER; - return WINBINDD_OK; - } - - return WINBINDD_ERROR; -} - -static void winbindd_gid2sid_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, const char *sid) = - (void (*)(void *, bool, const char *))c; - - if (!success) { - DEBUG(5, ("Could not trigger gid2sid\n")); - cont(private_data, False, NULL); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("gid2sid returned an error\n")); - cont(private_data, False, NULL); - return; - } - - cont(private_data, True, response->data.sid.sid); -} - -void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid, - void (*cont)(void *private_data, bool success, const char *sid), - void *private_data) -{ - struct winbindd_domain *domain; - struct winbindd_request request; - - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_GID2SID; - request.data.gid = gid; - - for (domain = domain_list(); domain != NULL; domain = domain->next) { - if (domain->have_idmap_config - && (gid >= domain->id_range_low) - && (gid <= domain->id_range_high)) { - fstrcpy(request.domain_name, domain->name); - } - } - - do_async(mem_ctx, idmap_child(), &request, winbindd_gid2sid_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - NTSTATUS result; - - DEBUG(3,("[%5lu]: gid %lu to sid\n", - (unsigned long)state->pid, - (unsigned long) state->request->data.gid)); - - /* Find sid for this gid and return it, possibly ask the slow remote idmap */ - result = idmap_gid_to_sid(state->request->domain_name, &sid, - state->request->data.gid); - - if (NT_STATUS_IS_OK(result)) { - sid_to_fstring(state->response->data.sid.sid, &sid); - DEBUG(10, ("[%5lu]: retrieved sid: %s\n", - (unsigned long)state->pid, - state->response->data.sid.sid)); - state->response->data.sid.type = SID_NAME_DOM_GRP; - return WINBINDD_OK; - } - - return WINBINDD_ERROR; -} - static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = { { .name = "PING", .struct_cmd = WINBINDD_PING, .struct_fn = winbindd_dual_ping, },{ - .name = "DUAL_SID2UID", - .struct_cmd = WINBINDD_DUAL_SID2UID, - .struct_fn = winbindd_dual_sid2uid, - },{ - .name = "DUAL_SID2GID", - .struct_cmd = WINBINDD_DUAL_SID2GID, - .struct_fn = winbindd_dual_sid2gid, - },{ - .name = "DUAL_UID2SID", - .struct_cmd = WINBINDD_DUAL_UID2SID, - .struct_fn = winbindd_dual_uid2sid, - },{ - .name = "DUAL_GID2SID", - .struct_cmd = WINBINDD_DUAL_GID2SID, - .struct_fn = winbindd_dual_gid2sid, - },{ .name = "NDRCMD", .struct_cmd = WINBINDD_DUAL_NDRCMD, .struct_fn = winbindd_dual_ndrcmd, diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 3ebd9ffdbd..ac8f1a7dfd 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -5,17 +5,17 @@ Copyright (C) Tim Potter 2000 Copyright (C) Andrew Bartlett 2002 - + 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 <http://www.gnu.org/licenses/>. */ @@ -93,7 +93,7 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) int extra_data_len = 0; char *extra_data = NULL; int i = 0; - + DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); @@ -102,6 +102,12 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) goto done; } + extra_data = talloc_strdup(state->mem_ctx, ""); + if (extra_data == NULL) { + request_error(state); + goto done; + } + for ( i = 0; i < num_domains; i++ ) { struct winbindd_domain *domain; bool is_online = true; @@ -111,41 +117,27 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) if (domain) { is_online = domain->online; } - - if ( !extra_data ) { - extra_data = talloc_asprintf(state->mem_ctx, - "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s", - d->domain_name, - d->dns_name ? d->dns_name : d->domain_name, - sid_string_talloc(state->mem_ctx, &d->sid), - get_trust_type_string(d), - trust_is_transitive(d) ? "Yes" : "No", - trust_is_inbound(d) ? "Yes" : "No", - trust_is_outbound(d) ? "Yes" : "No", - is_online ? "Online" : "Offline" ); - } else { - extra_data = talloc_asprintf(state->mem_ctx, - "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s", - extra_data, - d->domain_name, - d->dns_name ? d->dns_name : d->domain_name, - sid_string_talloc(state->mem_ctx, &d->sid), - get_trust_type_string(d), - trust_is_transitive(d) ? "Yes" : "No", - trust_is_inbound(d) ? "Yes" : "No", - trust_is_outbound(d) ? "Yes" : "No", - is_online ? "Online" : "Offline" ); - } - } - - extra_data_len = 0; - if (extra_data != NULL) { - extra_data_len = strlen(extra_data); + extra_data = talloc_asprintf_append_buffer( + extra_data, + "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s\n", + d->domain_name, + d->dns_name ? d->dns_name : d->domain_name, + sid_string_talloc(state->mem_ctx, &d->sid), + get_trust_type_string(d), + trust_is_transitive(d) ? "Yes" : "No", + trust_is_inbound(d) ? "Yes" : "No", + trust_is_outbound(d) ? "Yes" : "No", + is_online ? "Online" : "Offline" ); } + extra_data_len = strlen(extra_data); if (extra_data_len > 0) { + + /* Strip the last \n */ + extra_data[extra_data_len-1] = '\0'; + state->response->extra_data.data = extra_data; - state->response->length += extra_data_len+1; + state->response->length += extra_data_len; } request_ok(state); @@ -156,20 +148,18 @@ done: enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain, struct winbindd_cli_state *state) { - uint32 i, num_domains; - char **names, **alt_names; - DOM_SID *sids; + int i; int extra_data_len = 0; char *extra_data; NTSTATUS result; bool have_own_domain = False; + struct netr_DomainTrustList trusts; DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); result = domain->methods->trusted_domains(domain, state->mem_ctx, - &num_domains, &names, - &alt_names, &sids); + &trusts); if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("winbindd_dual_list_trusted_domains: trusted_domains returned %s\n", @@ -179,45 +169,37 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * extra_data = talloc_strdup(state->mem_ctx, ""); - if (num_domains > 0) - extra_data = talloc_asprintf( - state->mem_ctx, "%s\\%s\\%s", - names[0], alt_names[0] ? alt_names[0] : names[0], - sid_string_talloc(state->mem_ctx, &sids[0])); - - for (i=1; i<num_domains; i++) - extra_data = talloc_asprintf( - state->mem_ctx, "%s\n%s\\%s\\%s", - extra_data, names[i], - alt_names[i] ? alt_names[i] : names[i], - sid_string_talloc(state->mem_ctx, &sids[i])); + for (i=0; i<trusts.count; i++) { + extra_data = talloc_asprintf_append_buffer( + extra_data, "%s\\%s\\%s\n", + trusts.array[i].netbios_name, + trusts.array[i].dns_name, + sid_string_talloc(state->mem_ctx, + trusts.array[i].sid)); + } /* add our primary domain */ - - for (i=0; i<num_domains; i++) { - if (strequal(names[i], domain->name)) { + + for (i=0; i<trusts.count; i++) { + if (strequal(trusts.array[i].netbios_name, domain->name)) { have_own_domain = True; break; } } if (state->request->data.list_all_domains && !have_own_domain) { - extra_data = talloc_asprintf( - state->mem_ctx, "%s\n%s\\%s\\%s", - extra_data, domain->name, + extra_data = talloc_asprintf_append_buffer( + extra_data, "%s\\%s\\%s\n", domain->name, domain->alt_name ? domain->alt_name : domain->name, sid_string_talloc(state->mem_ctx, &domain->sid)); } - /* This is a bit excessive, but the extra data sooner or later will be - talloc'ed */ + extra_data_len = strlen(extra_data); + if (extra_data_len > 0) { - extra_data_len = 0; - if (extra_data != NULL) { - extra_data_len = strlen(extra_data); - } + /* Strip the last \n */ + extra_data[extra_data_len-1] = '\0'; - if (extra_data_len > 0) { state->response->extra_data.data = extra_data; state->response->length += extra_data_len+1; } @@ -225,78 +207,6 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * return WINBINDD_OK; } -enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - const char *dcname_slash = NULL; - const char *p; - struct rpc_pipe_client *netlogon_pipe; - NTSTATUS result; - WERROR werr; - unsigned int orig_timeout; - struct winbindd_domain *req_domain; - - state->request->domain_name - [sizeof(state->request->domain_name)-1] = '\0'; - - DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid, - state->request->domain_name)); - - result = cm_connect_netlogon(domain, &netlogon_pipe); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1, ("Can't contact the NETLOGON pipe\n")); - return WINBINDD_ERROR; - } - - /* This call can take a long time - allow the server to time out. - 35 seconds should do it. */ - - orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000); - - req_domain = find_domain_from_name_noinit(state->request->domain_name); - if (req_domain == domain) { - result = rpccli_netr_GetDcName(netlogon_pipe, - state->mem_ctx, - domain->dcname, - state->request->domain_name, - &dcname_slash, - &werr); - } else { - result = rpccli_netr_GetAnyDCName(netlogon_pipe, - state->mem_ctx, - domain->dcname, - state->request->domain_name, - &dcname_slash, - &werr); - } - /* And restore our original timeout. */ - rpccli_set_timeout(netlogon_pipe, orig_timeout); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(5,("Error requesting DCname for domain %s: %s\n", - state->request->domain_name, nt_errstr(result))); - return WINBINDD_ERROR; - } - - if (!W_ERROR_IS_OK(werr)) { - DEBUG(5, ("Error requesting DCname for domain %s: %s\n", - state->request->domain_name, win_errstr(werr))); - return WINBINDD_ERROR; - } - - p = dcname_slash; - if (*p == '\\') { - p+=1; - } - if (*p == '\\') { - p+=1; - } - - fstrcpy(state->response->data.dc_name, p); - return WINBINDD_OK; -} - /* This is the child-only version of --sequence. It only allows for a single * domain (ie "our" one) to be displayed. */ @@ -440,7 +350,7 @@ void winbindd_interface_version(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: request interface version\n", (unsigned long)state->pid)); - + state->response->data.interface_version = WINBIND_INTERFACE_VERSION; request_ok(state); } @@ -450,7 +360,7 @@ void winbindd_interface_version(struct winbindd_cli_state *state) void winbindd_domain_name(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid)); - + fstrcpy(state->response->data.domain_name, lp_workgroup()); request_ok(state); } @@ -461,7 +371,7 @@ void winbindd_netbios_name(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: request netbios name\n", (unsigned long)state->pid)); - + fstrcpy(state->response->data.netbios_name, global_myname()); request_ok(state); } @@ -473,7 +383,7 @@ void winbindd_priv_pipe_dir(struct winbindd_cli_state *state) char *priv_dir; DEBUG(3, ("[%5lu]: request location of privileged pipe\n", (unsigned long)state->pid)); - + priv_dir = get_winbind_priv_pipe_dir(); state->response->extra_data.data = talloc_move(state->mem_ctx, &priv_dir); diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c index c23f87dcd5..34b5990a3f 100644 --- a/source3/winbindd/winbindd_passdb.c +++ b/source3/winbindd/winbindd_passdb.c @@ -398,16 +398,10 @@ static NTSTATUS builtin_query_user(struct winbindd_domain *domain, /* get a list of trusted domains - builtin domain */ static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + TALLOC_CTX *mem_ctx, + struct netr_DomainTrustList *trusts) { - *num_domains = 0; - *names = NULL; - *alt_names = NULL; - *dom_sids = NULL; + ZERO_STRUCTP(trusts); return NT_STATUS_OK; } @@ -649,58 +643,44 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, /* get a list of trusted domains */ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + TALLOC_CTX *mem_ctx, + struct netr_DomainTrustList *trusts) { NTSTATUS nt_status; struct trustdom_info **domains; int i; - TALLOC_CTX *tmp_ctx; - - *num_domains = 0; - *names = NULL; - *alt_names = NULL; - *dom_sids = NULL; - - if (!(tmp_ctx = talloc_init("trusted_domains"))) { - return NT_STATUS_NO_MEMORY; - } - nt_status = pdb_enum_trusteddoms(tmp_ctx, num_domains, &domains); + nt_status = pdb_enum_trusteddoms(talloc_tos(), &trusts->count, + &domains); if (!NT_STATUS_IS_OK(nt_status)) { - TALLOC_FREE(tmp_ctx); return nt_status; } - if (*num_domains) { - *names = TALLOC_ARRAY(mem_ctx, char *, *num_domains); - *alt_names = TALLOC_ARRAY(mem_ctx, char *, *num_domains); - *dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains); + if (trusts->count == 0) { + trusts->array = NULL; + return NT_STATUS_OK; + } - if ((*alt_names == NULL) || (*names == NULL) || (*dom_sids == NULL)) { - TALLOC_FREE(tmp_ctx); - return NT_STATUS_NO_MEMORY; - } - } else { - *names = NULL; - *alt_names = NULL; - *dom_sids = NULL; + trusts->array = talloc_zero_array( + mem_ctx, struct netr_DomainTrust, trusts->count); + if (trusts->array == NULL) { + return NT_STATUS_NO_MEMORY; } - for (i=0; i<*num_domains; i++) { - (*alt_names)[i] = NULL; - if (!((*names)[i] = talloc_strdup((*names), - domains[i]->name))) { - TALLOC_FREE(tmp_ctx); + for (i=0; i<trusts->count; i++) { + struct dom_sid *sid; + + trusts->array[i].netbios_name = talloc_move( + trusts->array, &domains[i]->name); + trusts->array[i].dns_name = NULL; + + sid = talloc(trusts->array, struct dom_sid); + if (sid == NULL) { return NT_STATUS_NO_MEMORY; } - sid_copy(&(*dom_sids)[i], &domains[i]->sid); + sid_copy(sid, &domains[i]->sid); + trusts->array[i].sid = sid; } - - TALLOC_FREE(tmp_ctx); return NT_STATUS_OK; } diff --git a/source3/winbindd/winbindd_ping_dc.c b/source3/winbindd/winbindd_ping_dc.c new file mode 100644 index 0000000000..e06e5896c2 --- /dev/null +++ b/source3/winbindd/winbindd_ping_dc.c @@ -0,0 +1,96 @@ +/* + Unix SMB/CIFS implementation. + async implementation of WINBINDD_PING_DC + Copyright (C) Volker Lendecke 2009 + + 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 <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "winbindd.h" +#include "librpc/gen_ndr/cli_wbint.h" + +struct winbindd_ping_dc_state { + uint8_t dummy; +}; + +static void winbindd_ping_dc_done(struct tevent_req *subreq); + +struct tevent_req *winbindd_ping_dc_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct winbindd_cli_state *cli, + struct winbindd_request *request) +{ + struct tevent_req *req, *subreq; + struct winbindd_ping_dc_state *state; + struct winbindd_domain *domain; + + req = tevent_req_create(mem_ctx, &state, + struct winbindd_ping_dc_state); + if (req == NULL) { + return NULL; + } + + if (request->domain_name[0] == '\0') { + /* preserve old behavior, when no domain name is given */ + domain = find_our_domain(); + } else { + domain = find_domain_from_name(request->domain_name); + } + if (domain == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN); + return tevent_req_post(req, ev); + } + if (domain->internal) { + /* + * Internal domains are passdb based, we can always + * contact them. + */ + tevent_req_done(req); + return tevent_req_post(req, ev); + } + + subreq = rpccli_wbint_PingDc_send(state, ev, domain->child.rpccli); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, winbindd_ping_dc_done, req); + return req; +} + +static void winbindd_ping_dc_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct winbindd_ping_dc_state *state = tevent_req_data( + req, struct winbindd_ping_dc_state); + NTSTATUS status, result; + + status = rpccli_wbint_PingDc_recv(subreq, state, &result); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + if (!NT_STATUS_IS_OK(result)) { + tevent_req_nterror(req, result); + return; + } + tevent_req_done(req); +} + +NTSTATUS winbindd_ping_dc_recv(struct tevent_req *req, + struct winbindd_response *presp) +{ + return tevent_req_simple_recv_ntstatus(req); +} diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 6e232c9db8..93d5748c49 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -82,62 +82,10 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, /* The following definitions come from winbindd/winbindd_async.c */ -void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child, - const struct winbindd_request *request, - void (*cont)(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data), - void *c, void *private_data); -void winbindd_lookupsid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, - const char *dom_name, - const char *name, - enum lsa_SidType type), - void *private_data); -enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, - const char *dom_name, const char *name, - void (*cont)(void *private_data, bool success, - const DOM_SID *sid, - enum lsa_SidType type), - enum winbindd_cmd orig_cmd, - void *private_data); -enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_listent_async(TALLOC_CTX *mem_ctx, - struct winbindd_domain *domain, - void (*cont)(void *private_data, bool success, - fstring dom_name, char* extra_data), - void *private_data, enum ent_type type); -enum winbindd_result winbindd_dual_list_users(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_list_groups(struct winbindd_domain *domain, - struct winbindd_cli_state *state); bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids, size_t num_sids, char **result, ssize_t *len); bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, DOM_SID **sids, size_t *num_sids); -void winbindd_getsidaliases_async(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const DOM_SID *sids, size_t num_sids, - void (*cont)(void *private_data, - bool success, - const DOM_SID *aliases, - size_t num_aliases), - void *private_data); -enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, - const DOM_SID *sid, - void (*cont)(void *private_data, bool success, - const char *acct_name, - const char *full_name, - const char *homedir, - const char *shell, - gid_t gid, - uint32 group_rid), - void *private_data); /* The following definitions come from winbindd/winbindd_cache.c */ @@ -328,19 +276,12 @@ struct tevent_req *wb_domain_request_send(TALLOC_CTX *mem_ctx, int wb_domain_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presponse, int *err); -void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child, - struct winbindd_request *request, - struct winbindd_response *response, - void (*continuation)(void *private_data, bool success), - void *private_data); void async_domain_request(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, struct winbindd_request *request, struct winbindd_response *response, void (*continuation)(void *private_data_data, bool success), void *private_data_data); -void sendto_child(struct winbindd_cli_state *state, - struct winbindd_child *child); void sendto_domain(struct winbindd_cli_state *state, struct winbindd_domain *domain); void setup_child(struct winbindd_domain *domain, struct winbindd_child *child, @@ -394,9 +335,6 @@ void winbindd_getgroups(struct winbindd_cli_state *state); void winbindd_getusersids(struct winbindd_cli_state *state); void winbindd_getuserdomgroups(struct winbindd_cli_state *state); void winbindd_getsidaliases(struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -bool get_sam_group_entries(struct getent_state *ent); bool fill_grent(TALLOC_CTX *mem_ctx, struct winbindd_gr *gr, const char *dom_name, const char *gr_name, gid_t unix_gid); NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members, @@ -408,64 +346,17 @@ NTSTATUS winbindd_print_groupmembers(struct talloc_dict *members, void init_idmap_child(void); struct winbindd_child *idmap_child(void); -void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map, - void (*cont)(void *private_data, bool success), - void *private_data); -enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_remove_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map, - void (*cont)(void *private_data, bool success), - void *private_data); -enum winbindd_result winbindd_dual_remove_mapping(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid, - void (*cont)(void *private_data, bool success), - void *private_data); -enum winbindd_result winbindd_dual_set_hwm(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_sids2xids_async(TALLOC_CTX *mem_ctx, void *sids, int size, - void (*cont)(void *private_data, bool success, void *data, int len), - void *private_data); -enum winbindd_result winbindd_dual_sids2xids(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, uid_t uid), - void *private_data); -enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - void (*cont)(void *private_data, bool success, gid_t gid), - void *private_data); -enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid, - void (*cont)(void *private_data, bool success, const char *sid), - void *private_data); -enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid, - void (*cont)(void *private_data, bool success, const char *sid), - void *private_data); -enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); /* The following definitions come from winbindd/winbindd_locator.c */ void init_locator_child(void); struct winbindd_child *locator_child(void); -void winbindd_dsgetdcname(struct winbindd_cli_state *state); /* The following definitions come from winbindd/winbindd_misc.c */ -void winbindd_check_machine_acct(struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_list_ent(struct winbindd_cli_state *state, enum ent_type type); void winbindd_list_trusted_domains(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain, struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, - struct winbindd_cli_state *state); void winbindd_show_sequence(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain, struct winbindd_cli_state *state); @@ -518,47 +409,10 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state); -/* The following definitions come from winbindd/winbindd_passdb.c */ - - -/* The following definitions come from winbindd/winbindd_reconnect.c */ - - -/* The following definitions come from winbindd/winbindd_sid.c */ - -void winbindd_lookupsid(struct winbindd_cli_state *state); -void winbindd_lookupname(struct winbindd_cli_state *state); -void winbindd_lookuprids(struct winbindd_cli_state *state); -void winbindd_sid_to_uid(struct winbindd_cli_state *state); -void winbindd_sid_to_gid(struct winbindd_cli_state *state); -void winbindd_set_mapping(struct winbindd_cli_state *state); -void winbindd_remove_mapping(struct winbindd_cli_state *state); -void winbindd_set_hwm(struct winbindd_cli_state *state); -void winbindd_uid_to_sid(struct winbindd_cli_state *state); -void winbindd_gid_to_sid(struct winbindd_cli_state *state); -void winbindd_allocate_uid(struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_allocate_uid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_allocate_gid(struct winbindd_cli_state *state); -enum winbindd_result winbindd_dual_allocate_gid(struct winbindd_domain *domain, - struct winbindd_cli_state *state); - -/* The following definitions come from winbindd/winbindd_user.c */ - -enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, - struct winbindd_cli_state *state); -void winbindd_getpwnam(struct winbindd_cli_state *state); -void winbindd_getpwuid(struct winbindd_cli_state *state); -void winbindd_getpwsid(struct winbindd_cli_state *state); -void winbindd_setpwent(struct winbindd_cli_state *state); -void winbindd_endpwent(struct winbindd_cli_state *state); -void winbindd_getpwent(struct winbindd_cli_state *state); -void winbindd_list_users(struct winbindd_cli_state *state); - /* The following definitions come from winbindd/winbindd_util.c */ struct winbindd_domain *domain_list(void); -void free_domain_list(void); +bool domain_is_forest_root(const struct winbindd_domain *domain); void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te, struct timeval now, void *private_data); enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain, @@ -574,19 +428,6 @@ struct winbindd_domain *find_root_domain(void); struct winbindd_domain *find_builtin_domain(void); struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid); struct winbindd_domain *find_lookup_domain_from_name(const char *domain_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); -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); -void free_getent_state(struct getent_state *state); bool parse_domain_user(const char *domuser, fstring domain, fstring user); bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, char **domain, char **user); @@ -633,6 +474,7 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain); void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain); void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain); void set_auth_errors(struct winbindd_response *resp, NTSTATUS result); +bool is_domain_offline(const struct winbindd_domain *domain); /* The following definitions come from winbindd/winbindd_wins.c */ @@ -987,6 +829,13 @@ struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx, NTSTATUS winbindd_check_machine_acct_recv(struct tevent_req *req, struct winbindd_response *presp); +struct tevent_req *winbindd_ping_dc_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct winbindd_cli_state *cli, + struct winbindd_request *request); +NTSTATUS winbindd_ping_dc_recv(struct tevent_req *req, + struct winbindd_response *presp); + struct tevent_req *winbindd_change_machine_acct_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct winbindd_cli_state *cli, diff --git a/source3/winbindd/winbindd_reconnect.c b/source3/winbindd/winbindd_reconnect.c index 3efd4a9428..bf6e577f29 100644 --- a/source3/winbindd/winbindd_reconnect.c +++ b/source3/winbindd/winbindd_reconnect.c @@ -279,21 +279,15 @@ static NTSTATUS password_policy(struct winbindd_domain *domain, /* get a list of trusted domains */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { NTSTATUS result; - result = msrpc_methods.trusted_domains(domain, mem_ctx, - num_domains, names, - alt_names, dom_sids); + result = msrpc_methods.trusted_domains(domain, mem_ctx, trusts); if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) result = msrpc_methods.trusted_domains(domain, mem_ctx, - num_domains, names, - alt_names, dom_sids); + trusts); return result; } diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index 1018a2952b..e7003766d8 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -787,16 +787,16 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, if (!NT_STATUS_IS_OK(result)) return result; - *num_names = rids->count; - rid_mem = rids->rids; - - if (!*num_names) { + if (!rids || !rids->count) { names = NULL; name_types = NULL; sid_mem = NULL; return NT_STATUS_OK; } + *num_names = rids->count; + rid_mem = rids->rids; + /* 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 @@ -1032,10 +1032,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) /* get a list of trusted domains */ static NTSTATUS trusted_domains(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *num_domains, - char ***names, - char ***alt_names, - DOM_SID **dom_sids) + struct netr_DomainTrustList *trusts) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 enum_ctx = 0; @@ -1044,10 +1041,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, DEBUG(3,("rpc: trusted_domains\n")); - *num_domains = 0; - *names = NULL; - *alt_names = NULL; - *dom_sids = NULL; + ZERO_STRUCTP(trusts); result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); if (!NT_STATUS_IS_OK(result)) @@ -1070,22 +1064,33 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; - start_idx = *num_domains; - *num_domains += dom_list.count; - *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names, - char *, *num_domains); - *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids, - DOM_SID, *num_domains); - *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names, - char *, *num_domains); - if ((*names == NULL) || (*dom_sids == NULL) || - (*alt_names == NULL)) + start_idx = trusts->count; + trusts->count += dom_list.count; + + trusts->array = talloc_realloc( + mem_ctx, trusts->array, struct netr_DomainTrust, + trusts->count); + if (trusts->array == NULL) { return NT_STATUS_NO_MEMORY; + } for (i=0; i<dom_list.count; i++) { - (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string); - (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid; - (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, ""); + struct netr_DomainTrust *trust = &trusts->array[i]; + struct dom_sid *sid; + + ZERO_STRUCTP(trust); + + trust->netbios_name = talloc_move( + trusts->array, + &dom_list.domains[i].name.string); + trust->dns_name = NULL; + + sid = talloc(trusts->array, struct dom_sid); + if (sid == NULL) { + return NT_STATUS_NO_MEMORY; + } + sid_copy(sid, dom_list.domains[i].sid); + trust->sid = sid; } } return result; @@ -1258,7 +1263,7 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, NTSTATUS status; struct rpc_pipe_client *cli = NULL; struct policy_handle lsa_policy; - unsigned int orig_timeout; + unsigned int orig_timeout = 0; lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names; if (domain->can_do_ncacn_ip_tcp) { diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c deleted file mode 100644 index 6afa941b7f..0000000000 --- a/source3/winbindd/winbindd_user.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind daemon - user related functions - - Copyright (C) Tim Potter 2000 - Copyright (C) Jeremy Allison 2001. - Copyright (C) Gerald (Jerry) Carter 2003. - - 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 <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "winbindd.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_WINBIND - -/* Wrapper for domain->methods->query_user, only on the parent->child pipe */ - -enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID sid; - struct wbint_userinfo user_info; - NTSTATUS status; - - /* Ensure null termination */ - state->request->data.sid[sizeof(state->request->data.sid)-1]='\0'; - - DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, - state->request->data.sid)); - - if (!string_to_sid(&sid, state->request->data.sid)) { - DEBUG(5, ("%s not a SID\n", state->request->data.sid)); - return WINBINDD_ERROR; - } - - status = domain->methods->query_user(domain, state->mem_ctx, - &sid, &user_info); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("error getting user info for sid %s\n", - sid_string_dbg(&sid))); - return WINBINDD_ERROR; - } - - fstrcpy(state->response->data.user_info.acct_name, - user_info.acct_name); - fstrcpy(state->response->data.user_info.full_name, - user_info.full_name); - fstrcpy(state->response->data.user_info.homedir, user_info.homedir); - fstrcpy(state->response->data.user_info.shell, user_info.shell); - state->response->data.user_info.primary_gid = user_info.primary_gid; - if (!sid_peek_check_rid(&domain->sid, &user_info.group_sid, - &state->response->data.user_info.group_rid)) { - DEBUG(1, ("Could not extract group rid out of %s\n", - sid_string_dbg(&sid))); - return WINBINDD_ERROR; - } - - return WINBINDD_OK; -} diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index ff8c101b37..3e03f4091c 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -58,7 +58,7 @@ struct winbindd_domain *domain_list(void) /* Free all entries in the trusted domain list */ -void free_domain_list(void) +static void free_domain_list(void) { struct winbindd_domain *domain = _domain_list; @@ -143,13 +143,14 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const } } - /* 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 ) ) + if (domain != NULL) { + /* + * We found a match. Possibly update the SID + */ + if ((sid != NULL) + && sid_equal(&domain->sid, &global_sid_NULL)) { sid_copy( &domain->sid, sid ); - + } return domain; } @@ -223,6 +224,14 @@ done: return domain; } +bool domain_is_forest_root(const struct winbindd_domain *domain) +{ + const uint32_t fr_flags = + (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST); + + return ((domain->domain_flags & fr_flags) == fr_flags); +} + /******************************************************************** rescan our domains looking for new trusted domains ********************************************************************/ @@ -243,8 +252,6 @@ static void add_trusted_domains( struct winbindd_domain *domain ) TALLOC_CTX *mem_ctx; struct winbindd_request *request; struct winbindd_response *response; - uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST); - struct trustdom_state *state; mem_ctx = talloc_init("add_trusted_domains"); @@ -269,7 +276,7 @@ static void add_trusted_domains( struct winbindd_domain *domain ) /* 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 ); + state->forest_root = domain_is_forest_root(domain); request->length = sizeof(*request); request->cmd = WINBINDD_LIST_TRUSTDOM; @@ -792,23 +799,18 @@ struct winbindd_domain *find_root_domain(void) { struct winbindd_domain *ours = find_our_domain(); - if ( !ours ) - return NULL; - - if ( strlen(ours->forest_name) == 0 ) + if (ours->forest_name[0] == '\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); - + domain = find_domain_from_sid(&global_sid_Builtin); if (domain == NULL) { smb_panic("Could not find BUILTIN domain"); } @@ -868,95 +870,6 @@ struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name) 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; - - /* - * For all but LOOKUPNAME we have to avoid nss calls to avoid - * recursion - */ - result = domain->methods->name_to_sid( - domain, mem_ctx, domain_name, name, - orig_cmd == WINBINDD_LOOKUPNAME ? 0 : LOOKUP_NAME_NO_NSS, - 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 = temp->next; - - /* Free sam entries then list entry */ - - SAFE_FREE(state->sam_entries); - DLIST_REMOVE(state, state); - - SAFE_FREE(temp); - temp = next; - } -} - /* Is this a domain which we may assume no DOMAIN\ prefix? */ static bool assume_domain(const char *domain) @@ -1550,3 +1463,14 @@ void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) get_friendly_nt_error_msg(result)); resp->data.auth.pam_error = nt_status_to_pam(result); } + +bool is_domain_offline(const struct winbindd_domain *domain) +{ + if (!lp_winbind_offline_logon()) { + return false; + } + if (get_global_winbindd_state_offline()) { + return true; + } + return !domain->online; +} |