From 14fc7fd10917d9c08ea98aa08c70a8d1e97e7e58 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 8 Oct 2001 00:34:14 +0000 Subject: More work on winbindd connection rewrite: - implemented some of the sam related connection manager routines - fill in group id and gecos fields for getpwnam/getpwuid routines - convert querydispinfo to cm - getent passwd now works Now for the group related routines... (This used to be commit 4f8ea877876e91d4762f22e78aeb1bce4c65f011) --- source3/nsswitch/winbindd.c | 10 +- source3/nsswitch/winbindd_cm.c | 226 +++++++++++++++++++++++++++++++++----- source3/nsswitch/winbindd_proto.h | 11 +- source3/nsswitch/winbindd_user.c | 149 ++++++++++--------------- source3/nsswitch/winbindd_util.c | 136 ++++++++++++++--------- 5 files changed, 353 insertions(+), 179 deletions(-) diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 9bf4935eff..21dda58aae 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -230,12 +230,12 @@ static struct dispatch_table dispatch_table[] = { { WINBINDD_GETPWNAM_FROM_USER, winbindd_getpwnam_from_user }, { WINBINDD_GETPWNAM_FROM_UID, winbindd_getpwnam_from_uid }, -#if 0 - { WINBINDD_SETPWENT, winbindd_setpwent }, { WINBINDD_ENDPWENT, winbindd_endpwent }, { WINBINDD_GETPWENT, winbindd_getpwent }, +#if 0 + { WINBINDD_GETGROUPS, winbindd_getgroups }, /* Group functions */ @@ -699,6 +699,12 @@ int main(int argc, char **argv) secrets_init(); + /* Get list of domains we look up requests for. This includes the + domain which we are a member of as well as any trusted + domains. */ + + get_domain_info(); + ZERO_STRUCT(server_state); /* Winbind daemon initialisation */ diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index ec1db826dd..df9c553b0b 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -33,15 +33,13 @@ - manage re-entrancy for when winbindd becomes able to handle multiple outstanding rpc requests - We can also throw away the CLI_POLICY_HND stuff as all this information - will be stored within this module. - Why not have connection management as part of the rpc layer like tng? Good question. This code may morph into libsmb/rpc_cache.c or something like that but at the moment it's simply staying as part of winbind. I think the TNG architecture of forcing every user of the rpc layer to use the connection caching system is a bad idea. It should be an optional - method of using the routines. + method of using the routines. We actually cache policy handles - tng + caches connections to pipes. The TNG design is quite good but I disagree with some aspects of the implementation. -tpot @@ -55,7 +53,13 @@ moved down into another function. - There needs to be a utility function in libsmb/namequery.c that does - get_any_dc_name() + cm_get_dc_name() + + - When closing down sam handles we need to close down user, group and + domain handles. + + - Take care when destroying cli_structs as they can be shared between + various sam handles. */ @@ -63,13 +67,25 @@ /* We store lists of connections here */ +enum sam_pipe_type { + SAM_PIPE_BASIC, /* A basic handle */ + SAM_PIPE_DOM, /* A domain handle */ + SAM_PIPE_USER, /* A handle on a user */ + SAM_PIPE_GROUP /* A handle on a group */ +}; + struct winbindd_cm_conn { struct winbindd_cm_conn *prev, *next; fstring domain; fstring controller; fstring pipe_name; - struct cli_state cli; + struct cli_state *cli; POLICY_HND pol; + + /* Specific pipe stuff - move into a union? */ + + enum sam_pipe_type sam_pipe_type; /* Domain, user, group etc */ + uint32 user_rid; }; /* Global list of connections. Initially a DLIST but can become a hash @@ -122,19 +138,17 @@ static BOOL cm_open_connection(char *domain, char *pipe_name, BOOL result = False; struct ntuser_creds creds; - ZERO_STRUCT(new_conn->cli); - fstrcpy(new_conn->domain, domain); fstrcpy(new_conn->pipe_name, pipe_name); /* Look for a domain controller for this domain */ - if (!cm_get_dc_name(lp_workgroup(), new_conn->controller)) + if (!cm_get_dc_name(domain, new_conn->controller)) goto done; /* Initialise SMB connection */ - if (!cli_initialise(&new_conn->cli)) + if (!(new_conn->cli = cli_initialise(NULL))) goto done; if (!resolve_srv_name(new_conn->controller, dest_host, &dest_ip)) @@ -147,21 +161,21 @@ static BOOL cm_open_connection(char *domain, char *pipe_name, ZERO_STRUCT(creds); creds.pwd.null_pwd = 1; - cli_init_creds(&new_conn->cli, &creds); + cli_init_creds(new_conn->cli, &creds); - if (!cli_establish_connection(&new_conn->cli, new_conn->controller, + if (!cli_establish_connection(new_conn->cli, new_conn->controller, &dest_ip, &calling, &called, "IPC$", "IPC", False, True)) goto done; - if (!cli_nt_session_open (&new_conn->cli, pipe_name)) + if (!cli_nt_session_open (new_conn->cli, pipe_name)) goto done; result = True; done: - if (!result) - cli_shutdown(&new_conn->cli); + if (!result && new_conn->cli) + cli_shutdown(new_conn->cli); return result; } @@ -189,13 +203,15 @@ CLI_POLICY_HND *cm_get_lsa_handle(char *domain) malloc(sizeof(struct winbindd_cm_conn)))) return NULL; + ZERO_STRUCTP(conn); + if (!cm_open_connection(domain, PIPE_LSARPC, conn)) { DEBUG(3, ("Could not connect to a dc for domain %s\n", domain)); return NULL; } - result = cli_lsa_open_policy(&conn->cli, conn->cli.mem_ctx, False, + result = cli_lsa_open_policy(conn->cli, conn->cli->mem_ctx, False, des_access, &conn->pol); if (!NT_STATUS_IS_OK(result)) @@ -207,7 +223,7 @@ CLI_POLICY_HND *cm_get_lsa_handle(char *domain) ok: hnd.pol = conn->pol; - hnd.cli = &conn->cli; + hnd.cli = conn->cli; return &hnd; } @@ -216,24 +232,184 @@ CLI_POLICY_HND *cm_get_lsa_handle(char *domain) CLI_POLICY_HND *cm_get_sam_handle(char *domain) { - DEBUG(0, ("get_sam_handle(): not implemented\n")); - return NULL; + struct winbindd_cm_conn *conn; + uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; + NTSTATUS result; + static CLI_POLICY_HND hnd; + + /* Look for existing connections */ + + for (conn = cm_conns; conn; conn = conn->next) { + if (strequal(conn->domain, domain) && + strequal(conn->pipe_name, PIPE_SAMR) && + conn->sam_pipe_type == SAM_PIPE_BASIC) + goto ok; + } + + /* Create a new one */ + + if (!(conn = (struct winbindd_cm_conn *) + malloc(sizeof(struct winbindd_cm_conn)))) + return NULL; + + ZERO_STRUCTP(conn); + + if (!cm_open_connection(domain, PIPE_SAMR, conn)) { + DEBUG(3, ("Could not connect to a dc for domain %s\n", + domain)); + return NULL; + } + + result = cli_samr_connect(conn->cli, conn->cli->mem_ctx, des_access, + &conn->pol); + + if (!NT_STATUS_IS_OK(result)) + return NULL; + + /* Add to list */ + + DLIST_ADD(cm_conns, conn); + + ok: + hnd.pol = conn->pol; + hnd.cli = conn->cli; + + return &hnd; } /* Return a SAM domain policy handle on a domain */ -CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain) +CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid) { - DEBUG(0, ("get_sam_dom_handle(): not implemented\n")); - return NULL; + struct winbindd_cm_conn *conn, *basic_conn = NULL; + static CLI_POLICY_HND hnd; + NTSTATUS result; + uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; + + /* Look for existing connections */ + + for (conn = cm_conns; conn; conn = conn->next) { + if (strequal(conn->domain, domain) && + strequal(conn->pipe_name, PIPE_SAMR) && + conn->sam_pipe_type == SAM_PIPE_DOM) + goto ok; + } + + /* Create a basic handle to open a domain handle from */ + + if (!cm_get_sam_handle(domain)) + return False; + + for (conn = cm_conns; conn; conn = conn->next) { + if (strequal(conn->domain, domain) && + strequal(conn->pipe_name, PIPE_SAMR) && + conn->sam_pipe_type == SAM_PIPE_BASIC) + basic_conn = conn; + } + + if (!basic_conn) { + DEBUG(0, ("No basic sam handle was created!\n")); + return NULL; + + } + if (!(conn = (struct winbindd_cm_conn *) + malloc(sizeof(struct winbindd_cm_conn)))) + return NULL; + + ZERO_STRUCTP(conn); + + fstrcpy(conn->domain, basic_conn->domain); + fstrcpy(conn->controller, basic_conn->controller); + fstrcpy(conn->pipe_name, basic_conn->pipe_name); + + conn->sam_pipe_type = SAM_PIPE_DOM; + conn->cli = basic_conn->cli; + + result = cli_samr_open_domain(conn->cli, conn->cli->mem_ctx, + &basic_conn->pol, des_access, + domain_sid, &conn->pol); + + if (!NT_STATUS_IS_OK(result)) + return NULL; + + /* Add to list */ + + DLIST_ADD(cm_conns, conn); + + ok: + hnd.pol = conn->pol; + hnd.cli = conn->cli; + + return &hnd; } /* Return a SAM policy handle on a domain user */ -CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, char *user) +CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid, + uint32 user_rid) { - DEBUG(0, ("get_sam_user_handle(): not implemented\n")); - return NULL; + struct winbindd_cm_conn *conn, *basic_conn = NULL; + static CLI_POLICY_HND hnd; + NTSTATUS result; + uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; + + /* Look for existing connections */ + + for (conn = cm_conns; conn; conn = conn->next) { + if (strequal(conn->domain, domain) && + strequal(conn->pipe_name, PIPE_SAMR) && + conn->sam_pipe_type == SAM_PIPE_USER && + conn->user_rid == user_rid) + goto ok; + } + + /* Create a domain handle to open a user handle from */ + + if (!cm_get_sam_dom_handle(domain, domain_sid)) + return NULL; + + for (conn = cm_conns; conn; conn = conn->next) { + if (strequal(conn->domain, domain) && + strequal(conn->pipe_name, PIPE_SAMR) && + conn->sam_pipe_type == SAM_PIPE_DOM) + basic_conn = conn; + } + + if (!basic_conn) { + DEBUG(0, ("No domain sam handle was created!\n")); + return NULL; + } + + if (!(conn = (struct winbindd_cm_conn *) + malloc(sizeof(struct winbindd_cm_conn)))) + return NULL; + + ZERO_STRUCTP(conn); + + fstrcpy(conn->domain, basic_conn->domain); + fstrcpy(conn->controller, basic_conn->controller); + fstrcpy(conn->pipe_name, basic_conn->pipe_name); + + conn->sam_pipe_type = SAM_PIPE_USER; + conn->cli = basic_conn->cli; + conn->user_rid = user_rid; + + result = cli_samr_open_user(conn->cli, conn->cli->mem_ctx, + &basic_conn->pol, des_access, user_rid, + &conn->pol); + + if (!NT_STATUS_IS_OK(result)) + return NULL; + + /* Add to list */ + + DLIST_ADD(cm_conns, conn); + + ok: + hnd.pol = conn->pol; + hnd.cli = conn->cli; + + return &hnd; } /* Return a SAM policy handle on a domain group */ diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h index 7b4e36576d..3c44b63234 100644 --- a/source3/nsswitch/winbindd_proto.h +++ b/source3/nsswitch/winbindd_proto.h @@ -50,8 +50,9 @@ void winbindd_cache_dump_status(void); BOOL cm_get_dc_name(char *domain, fstring srv_name); CLI_POLICY_HND *cm_get_lsa_handle(char *domain); CLI_POLICY_HND *cm_get_sam_handle(char *domain); -CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain); -CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, char *user); +CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid); +CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid, + uint32 user_rid); CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, char *group); /* The following definitions come from nsswitch/winbindd_group.c */ @@ -115,17 +116,17 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state); /* The following definitions come from nsswitch/winbindd_util.c */ +BOOL get_domain_info(void); BOOL domain_handles_open(struct winbindd_domain *domain); void winbindd_kill_all_connections(void); void establish_connections(BOOL force_reestablish) ; BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain); -BOOL get_domain_info(struct winbindd_domain *domain); BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *type); BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name, enum SID_NAME_USE *type); -BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain, - uint32 user_rid, SAM_USERINFO_CTR **user_info); +BOOL winbindd_lookup_userinfo(char *domain, uint32 user_rid, + SAM_USERINFO_CTR **user_info); BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain, uint32 user_rid, uint32 *num_groups, DOM_GID **user_groups); diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index bb5b1e354e..25ab38dd8c 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -145,9 +145,7 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state /* The following costs 3 packets */ -#if 0 - - if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) { + if (!winbindd_lookup_userinfo(name_domain, user_rid, &user_info)) { DEBUG(1, ("pwnam_from_user(): error getting user info for " "user '%s'\n", name_user)); return WINBINDD_ERROR; @@ -157,11 +155,6 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name, sizeof(gecos_name) - 1); -#endif - - group_rid = DOMAIN_GROUP_RID_GUESTS; - fstrcpy(gecos_name, "foo"); - /* Now take all this information and fill in a passwd structure */ if (!winbindd_fill_pwent(name_domain, state->request.data.username, @@ -236,9 +229,7 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state /* Get some user info */ -#if 0 - - if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) { + if (!winbindd_lookup_userinfo(domain->name, user_rid, &user_info)) { DEBUG(1, ("pwnam_from_uid(): error getting user info for " "user '%s'\n", user_name)); return WINBINDD_ERROR; @@ -247,10 +238,6 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state group_rid = user_info->info.id21->group_rid; unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name, sizeof(gecos_name) - 1); -#endif - - group_rid = DOMAIN_GROUP_RID_GUESTS; - fstrcpy(gecos_name, "foo"); /* Resolve gid number */ @@ -272,8 +259,6 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state return WINBINDD_OK; } -#if 0 - /* * set/get/endpwent functions */ @@ -282,68 +267,61 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state) { - struct winbindd_domain *tmp; - - DEBUG(3, ("[%5d]: setpwent\n", state->pid)); - - if (state == NULL) return WINBINDD_ERROR; - - /* Check user has enabled this */ - - if (!lp_winbind_enum_users()) { - return WINBINDD_ERROR; - } - - /* Free old static data if it exists */ - - if (state->getpwent_state != NULL) { - free_getent_state(state->getpwent_state); - state->getpwent_state = NULL; - } - - /* Create sam pipes for each domain we know about */ - - for(tmp = domain_list; tmp != NULL; tmp = tmp->next) { - struct getent_state *domain_state; - - /* Skip domains other than WINBINDD_DOMAIN environment variable */ - - if ((strcmp(state->request.domain, "") != 0) && - !check_domain_env(state->request.domain, tmp->name)) { - continue; + struct winbindd_domain *tmp; + + DEBUG(3, ("[%5d]: setpwent\n", state->pid)); + + /* Check user has enabled this */ + + if (!lp_winbind_enum_users()) + return WINBINDD_ERROR; + + /* Free old static data if it exists */ + + if (state->getpwent_state != NULL) { + free_getent_state(state->getpwent_state); + state->getpwent_state = NULL; } - - /* Create a state record for this domain */ - - if ((domain_state = (struct getent_state *) - malloc(sizeof(struct getent_state))) == NULL) { - - return WINBINDD_ERROR; + + /* Create sam pipes for each domain we know about */ + + for(tmp = domain_list; tmp != NULL; tmp = tmp->next) { + struct getent_state *domain_state; + + /* Skip domains other than WINBINDD_DOMAIN environment + variable */ + + if ((strcmp(state->request.domain, "") != 0) && + !check_domain_env(state->request.domain, tmp->name)) + continue; + + /* Create a state record for this domain */ + + if ((domain_state = (struct getent_state *) + malloc(sizeof(struct getent_state))) == NULL) + return WINBINDD_ERROR; + + ZERO_STRUCTP(domain_state); + domain_state->domain = tmp; + + /* Add to list of open domains */ + + DLIST_ADD(state->getpwent_state, domain_state); } - - ZERO_STRUCTP(domain_state); - domain_state->domain = tmp; - - /* Add to list of open domains */ - - DLIST_ADD(state->getpwent_state, domain_state) - } - - return WINBINDD_OK; + + return WINBINDD_OK; } /* Close file pointer to ntdom passwd database */ enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5d]: endpwent\n", state->pid)); - - if (state == NULL) return WINBINDD_ERROR; + DEBUG(3, ("[%5d]: endpwent\n", state->pid)); - free_getent_state(state->getpwent_state); - state->getpwent_state = NULL; - - return WINBINDD_OK; + free_getent_state(state->getpwent_state); + state->getpwent_state = NULL; + + return WINBINDD_OK; } /* Get partial list of domain users for a domain. We fill in the sam_entries, @@ -362,9 +340,8 @@ static BOOL get_sam_user_entries(struct getent_state *ent) struct getpwent_user *name_list = NULL; uint32 group_rid; - if (ent->got_all_sam_entries) { + if (ent->got_all_sam_entries) return False; - } ZERO_STRUCT(info1); ZERO_STRUCT(ctr); @@ -390,10 +367,6 @@ static BOOL get_sam_user_entries(struct getent_state *ent) group_rid = DOMAIN_GROUP_RID_USERS; - if (!domain_handles_open(ent->domain)) { - return WINBINDD_ERROR; - } - /* Free any existing user info */ SAFE_FREE(ent->sam_entries); @@ -486,22 +459,18 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) DEBUG(3, ("[%5d]: getpwent\n", state->pid)); - if (state == NULL) return WINBINDD_ERROR; - /* Check user has enabled this */ - if (!lp_winbind_enum_users()) { + if (!lp_winbind_enum_users()) return WINBINDD_ERROR; - } /* Allocate space for returning a chunk of users */ num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries); if ((state->response.extra_data = - malloc(num_users * sizeof(struct winbindd_pw))) == NULL) { + malloc(num_users * sizeof(struct winbindd_pw))) == NULL) return WINBINDD_ERROR; - } memset(state->response.extra_data, 0, num_users * sizeof(struct winbindd_pw)); @@ -509,9 +478,8 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) user_list = (struct winbindd_pw *)state->response.extra_data; sep = lp_winbind_separator(); - if (!(ent = state->getpwent_state)) { + if (!(ent = state->getpwent_state)) return WINBINDD_ERROR; - } /* Start sending back users */ @@ -540,7 +508,8 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) /* No more domains */ - if (!ent) break; + if (!ent) + break; } name_list = ent->sam_entries; @@ -579,11 +548,9 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state) state->response.length += sizeof(struct winbindd_pw); - } else { + } else DEBUG(1, ("could not lookup domain user %s\n", domain_user_name)); - } - } /* Out of domains */ @@ -620,10 +587,6 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state) continue; } - if (!domain_handles_open(domain)) { - continue; - } - /* Query display info */ do { @@ -692,5 +655,3 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state) return WINBINDD_OK; } - -#endif diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index c5b3c7585b..c257719be1 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -24,39 +24,33 @@ #include "winbindd.h" #include "sids.h" -#if 0 - -static void winbindd_kill_connections(struct winbindd_domain *domain); - /* Add a trusted domain to our list of domains */ -static struct winbindd_domain *add_trusted_domain(char *domain_name) +static struct winbindd_domain *add_trusted_domain(char *domain_name, + DOM_SID *domain_sid) { struct winbindd_domain *domain, *tmp; for (tmp = domain_list; tmp != NULL; tmp = tmp->next) { if (strcmp(domain_name, tmp->name) == 0) { - DEBUG(3, ("domain %s already in trusted list\n", + DEBUG(3, ("domain %s already in domain list\n", domain_name)); return tmp; } } - DEBUG(1, ("adding trusted domain %s\n", domain_name)); + DEBUG(1, ("adding domain %s\n", domain_name)); /* Create new domain entry */ - if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL) { + if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL) return NULL; - } /* Fill in fields */ ZERO_STRUCTP(domain); - - if (domain_name) { - fstrcpy(domain->name, domain_name); - } + fstrcpy(domain->name, domain_name); + sid_copy(&domain->sid, domain_sid); /* Link to domain list */ @@ -67,42 +61,55 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name) /* Look up global info for the winbind daemon */ -static BOOL get_trusted_domains(void) +BOOL get_domain_info(void) { uint32 enum_ctx = 0; uint32 num_doms = 0; char **domains = NULL; - DOM_SID *sids = NULL; - BOOL result; + DOM_SID *sids = NULL, domain_sid; + NTSTATUS result; + CLI_POLICY_HND *hnd; int i; + fstring level5_dom; DEBUG(1, ("getting trusted domain list\n")); /* Add our workgroup - keep handle to look up trusted domains */ - if (!add_trusted_domain(lp_workgroup())) { - DEBUG(0, ("could not add record for domain %s\n", - lp_workgroup())); - return False; - } + + if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) + return False; + + result = cli_lsa_query_info_policy(hnd->cli, hnd->cli->mem_ctx, + &hnd->pol, 0x05, level5_dom, + &domain_sid); + + if (!NT_STATUS_IS_OK(result)) + return False; + + add_trusted_domain(lp_workgroup(), &domain_sid); /* Enumerate list of trusted domains */ - result = wb_lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx, - &num_doms, &domains, &sids); + + if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) + return False; + + result = cli_lsa_enum_trust_dom(hnd->cli, hnd->cli->mem_ctx, + &hnd->pol, &enum_ctx, &num_doms, + &domains, &sids); - if (!result || !domains) return False; + if (!NT_STATUS_IS_OK(result)) + return False; /* Add each domain to the trusted domain list */ - for(i = 0; i < num_doms; i++) { - if (!add_trusted_domain(domains[i])) { - DEBUG(0, ("could not add record for domain %s\n", - domains[i])); - result = False; - } - } + + for(i = 0; i < num_doms; i++) + add_trusted_domain(domains[i], &sids[i]); return True; } +#if 0 + /* Open sam and sam domain handles */ static BOOL open_sam_handles(struct winbindd_domain *domain) @@ -408,9 +415,11 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain) return NT_STATUS_IS_OK(result); } +#if 0 + /* Lookup domain controller and sid for a domain */ -BOOL get_domain_info(struct winbindd_domain *domain) + BOOL get_domain_info(struct winbindd_domain *domain) { fstring sid_str; @@ -433,6 +442,8 @@ BOOL get_domain_info(struct winbindd_domain *domain) return True; } +#endif + /* Lookup a sid in a domain from a name */ BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, @@ -518,17 +529,31 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name, return False; } -#if 0 - /* Lookup user information from a rid */ -BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain, - uint32 user_rid, SAM_USERINFO_CTR **user_info) +BOOL winbindd_lookup_userinfo(char *domain_name, uint32 user_rid, + SAM_USERINFO_CTR **user_info) { - return wb_get_samr_query_userinfo(&domain->sam_dom_handle, 0x15, - user_rid, user_info); + CLI_POLICY_HND *hnd; + uint16 info_level = 0x15; + NTSTATUS result; + struct winbindd_domain *domain; + + if (!(domain = find_domain_from_name(domain_name))) + return False; + + if (!(hnd = cm_get_sam_user_handle(domain_name, &domain->sid, + user_rid))) + return False; + + result = cli_samr_query_userinfo(hnd->cli, hnd->cli->mem_ctx, + &hnd->pol, info_level, user_info); + + return NT_STATUS_IS_OK(result); } +#if 0 + /* Lookup groups a user is a member of. I wish Unix had a call like this! */ BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain, @@ -587,14 +612,8 @@ struct winbindd_domain *find_domain_from_name(char *domain_name) /* Search through list */ for (tmp = domain_list; tmp != NULL; tmp = tmp->next) { - if (strcmp(domain_name, tmp->name) == 0) { - - if (!tmp->got_domain_info) { - get_domain_info(tmp); - } - - return tmp->got_domain_info ? tmp : NULL; - } + if (strcmp(domain_name, tmp->name) == 0) + return tmp; } /* Not found */ @@ -609,14 +628,17 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid) struct winbindd_domain *tmp; /* Search through list */ + for (tmp = domain_list; tmp != NULL; tmp = tmp->next) { if (sid_equal(sid, &tmp->sid)) { - if (!tmp->got_domain_info) return NULL; + if (!tmp->got_domain_info) + return NULL; return tmp; } } /* Not found */ + return NULL; } @@ -704,8 +726,6 @@ BOOL winbindd_param_init(void) return True; } -#if 0 - /* Query display info for a domain. This returns enough information plus a bit extra to give an overview of domain users for the User Manager application. */ @@ -714,8 +734,20 @@ NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain, uint32 *start_ndx, uint16 info_level, uint32 *num_entries, SAM_DISPINFO_CTR *ctr) { - return wb_samr_query_dispinfo(&domain->sam_dom_handle, start_ndx, - info_level, num_entries, ctr); + CLI_POLICY_HND *hnd; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + if (!(hnd = cm_get_sam_dom_handle(domain->name, &domain->sid))) + return result; + + result = cli_samr_query_dispinfo(hnd->cli, hnd->cli->mem_ctx, + &hnd->pol, start_ndx, info_level, + num_entries, 0xffff, ctr); + + if (!NT_STATUS_IS_OK(result)) + return result; + + return NT_STATUS_OK; } /* Check if a domain is present in a comma-separated list of domains */ @@ -734,8 +766,6 @@ BOOL check_domain_env(char *domain_env, char *domain) return False; } -#endif - /* Parse a string of the form DOMAIN/user into a domain and a user */ void parse_domain_user(char *domuser, fstring domain, fstring user) -- cgit