diff options
author | Tim Potter <tpot@samba.org> | 2001-05-07 04:32:40 +0000 |
---|---|---|
committer | Tim Potter <tpot@samba.org> | 2001-05-07 04:32:40 +0000 |
commit | a36f9250e7c9446f3eece6d8db29fcbde99256fb (patch) | |
tree | 5b981dc1171e92f4a28232c3cc7b6d619054ea75 /source3/nsswitch/winbindd_util.c | |
parent | c2887d57b5ff6da52aefac4657c23c142977ee2e (diff) | |
download | samba-a36f9250e7c9446f3eece6d8db29fcbde99256fb.tar.gz samba-a36f9250e7c9446f3eece6d8db29fcbde99256fb.tar.bz2 samba-a36f9250e7c9446f3eece6d8db29fcbde99256fb.zip |
Preliminary merge of winbind into HEAD. Note that this compiles and links
but I haven't actually run it yet so it probably doesn't work. (-:
(This used to be commit 59f95416b66db6df05289bde224de29c721978e5)
Diffstat (limited to 'source3/nsswitch/winbindd_util.c')
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 638 |
1 files changed, 431 insertions, 207 deletions
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 80d6955e6c..0661586376 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -22,36 +22,40 @@ */ #include "winbindd.h" +#include "sids.h" -BOOL domain_handles_open(struct winbindd_domain *domain) -{ - return domain->sam_handle_open && - domain->sam_dom_handle_open && - rpc_hnd_ok(&domain->sam_handle) && - rpc_hnd_ok(&domain->sam_dom_handle); -} +/* Debug connection state */ -static BOOL resolve_dc_name(char *domain_name, fstring domain_controller) +void debug_conn_state(void) { - struct in_addr ip; - extern pstring global_myname; - - /* if its our primary domain and password server is not '*' then use the - password server parameter */ - if (strcmp(domain_name,lp_workgroup()) == 0 && !lp_wildcard_dc()) { - fstrcpy(domain_controller, lp_passwordserver()); - return True; - } + struct winbindd_domain *domain; - if (!resolve_name(domain_name, &ip, 0x1B)) return False; + DEBUG(3, ("server: dc=%s, pwdb_init=%d, lsa_hnd=%d\n", + server_state.controller, + server_state.pwdb_initialised, + server_state.lsa_handle_open)); - return lookup_pdc_name(global_myname, domain_name, &ip, - domain_controller); + for (domain = domain_list; domain; domain = domain->next) { + DEBUG(3, ("%s: dc=%s, got_sid=%d, sam_hnd=%d sam_dom_hnd=%d\n", + domain->name, domain->controller, + domain->got_domain_info, domain->sam_handle_open, + domain->sam_dom_handle_open)); + } } +/* Add a trusted domain to our list of domains */ + static struct winbindd_domain *add_trusted_domain(char *domain_name) { - struct winbindd_domain *domain; + 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", + domain_name)); + return tmp; + } + } DEBUG(1, ("adding trusted domain %s\n", domain_name)); @@ -77,12 +81,13 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name) } /* Look up global info for the winbind daemon */ + static BOOL get_trusted_domains(void) { uint32 enum_ctx = 0; uint32 num_doms = 0; char **domains = NULL; - DOM_SID **sids = NULL; + DOM_SID *sids = NULL; BOOL result; int i; @@ -110,100 +115,184 @@ static BOOL get_trusted_domains(void) } } - /* Free memory */ - free_char_array(num_doms, domains); - free_sid_array(num_doms, sids); - return True; } +/* Open sam and sam domain handles */ -/* Open sam and sam domain handles to a domain and cache the results */ static BOOL open_sam_handles(struct winbindd_domain *domain) { - /* Get domain info */ + /* Get domain info (sid and controller name) */ + if (!domain->got_domain_info) { domain->got_domain_info = get_domain_info(domain); if (!domain->got_domain_info) return False; } - if ((domain->sam_handle_open && !rpc_hnd_ok(&domain->sam_handle)) || - (domain->sam_dom_handle_open && - !rpc_hnd_ok(&domain->sam_dom_handle))) { + /* Shut down existing sam handles */ - domain->got_domain_info = get_domain_info(domain); - if (domain->sam_dom_handle_open) { - samr_close(&domain->sam_dom_handle); - domain->sam_dom_handle_open = False; - } - if (domain->sam_handle_open) { - samr_close(&domain->sam_handle); - domain->sam_handle_open = False; - } + if (domain->sam_dom_handle_open) { + samr_close(&domain->sam_dom_handle); + domain->sam_dom_handle_open = False; } - /* Open sam handle if it isn't already open */ + if (domain->sam_handle_open) { + samr_close(&domain->sam_handle); + domain->sam_handle_open = False; + } - if (!domain->sam_handle_open) { + /* Open sam handle */ - domain->sam_handle_open = - samr_connect(domain->controller, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &domain->sam_handle); + domain->sam_handle_open = + samr_connect(domain->controller, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &domain->sam_handle); - if (!domain->sam_handle_open) return False; - } + if (!domain->sam_handle_open) return False; + + /* Open sam domain handle */ + + domain->sam_dom_handle_open = + samr_open_domain(&domain->sam_handle, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &domain->sid, + &domain->sam_dom_handle); + + if (!domain->sam_dom_handle_open) return False; + + return True; +} + +static BOOL rpc_hnd_ok(CLI_POLICY_HND *hnd) +{ + return hnd->cli->fd != -1; +} - /* Open sam domain handle if it isn't already open */ +/* Return true if the SAM domain handles are open and responding. */ - if (!domain->sam_dom_handle_open) { +BOOL domain_handles_open(struct winbindd_domain *domain) +{ + time_t t; + BOOL result; - domain->sam_dom_handle_open = - samr_open_domain(&domain->sam_handle, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &domain->sid, &domain->sam_dom_handle); + /* Check we haven't checked too recently */ - if (!domain->sam_dom_handle_open) return False; + t = time(NULL); + + if ((t - domain->last_check) < WINBINDD_ESTABLISH_LOOP) { + return domain->sam_handle_open && + domain->sam_dom_handle_open; } - return True; + DEBUG(3, ("checking domain handles for domain %s\n", domain->name)); + debug_conn_state(); + + domain->last_check = t; + + /* Open sam handles if they are marked as closed */ + + if (!domain->sam_handle_open || !domain->sam_dom_handle_open) { + reopen: + DEBUG(3, ("opening sam handles\n")); + return open_sam_handles(domain); + } + + /* Check sam handles are ok - the domain controller may have failed + and we need to move to a BDC. */ + + if (!rpc_hnd_ok(&domain->sam_handle) || + !rpc_hnd_ok(&domain->sam_dom_handle)) { + + /* We want to close the current connection but attempt + to open a new set, possibly to a new dc. If this + doesn't work then return False as we have no dc + to talk to. */ + + DEBUG(3, ("sam handles not responding\n")); + + winbindd_kill_connections(domain); + goto reopen; + } + + result = domain->sam_handle_open && domain->sam_dom_handle_open; + + return result; } -/* Close all LSA and SAM connections */ +/* Shut down connections to all domain controllers */ -static void winbindd_kill_connections(void) +void winbindd_kill_connections(struct winbindd_domain *domain) { - struct winbindd_cli_state *cli; - struct winbindd_domain *domain; + BOOL is_server = False; + struct winbindd_domain *server_domain; + + /* Find pointer to domain of pdc */ + + server_domain = find_domain_from_name(lp_workgroup()); + if (!server_domain) return; + + /* If NULL passed, use pdc */ + + if (!domain) { + domain = server_domain; + } + + if (domain == server_domain || + strequal(domain->name, lp_workgroup())) { + is_server = True; + } - DEBUG(1,("killing winbindd connections\n")); + /* Log a level 0 message - this is probably a domain controller + failure */ - /* Close LSA connection */ + DEBUG(0, ("killing connections to domain %s with controller %s\n", + domain->name, domain->controller)); - server_state.pwdb_initialised = False; - server_state.lsa_handle_open = False; - lsa_close(&server_state.lsa_handle); + debug_conn_state(); + + if (is_server) { + server_state.pwdb_initialised = False; + server_state.lsa_handle_open = False; + lsa_close(&server_state.lsa_handle); + } + + /* Close domain sam handles but don't free them as this + severely traumatises the getent state. The connections + will be reopened later. */ + + if (domain->sam_dom_handle_open) { + samr_close(&domain->sam_dom_handle); + domain->sam_dom_handle_open = False; + } + + if (domain->sam_handle_open) { + samr_close(&domain->sam_handle); + domain->sam_handle_open = False; + } + + /* Re-lookup domain info which includes domain controller name */ - /* Close SAM connections */ + domain->got_domain_info = False; +} + +/* Kill connections to all servers */ + +void winbindd_kill_all_connections(void) +{ + struct winbindd_domain *domain; + + /* Iterate over domain list */ domain = domain_list; - while(domain) { + while (domain) { struct winbindd_domain *next; - /* Close SAM handles */ + /* Kill conections */ - if (domain->sam_dom_handle_open) { - samr_close(&domain->sam_dom_handle); - domain->sam_dom_handle_open = False; - } - - if (domain->sam_handle_open) { - samr_close(&domain->sam_handle); - domain->sam_handle_open = False; - } + winbindd_kill_connections(domain); - /* Remove from list */ + /* Remove domain from list */ next = domain->next; DLIST_REMOVE(domain_list, domain); @@ -211,68 +300,106 @@ static void winbindd_kill_connections(void) domain = next; } +} - /* We also need to go through and trash any pointers to domains in - get{pw,gr}ent state records */ +static BOOL get_any_dc_name(char *domain, fstring srv_name) +{ + struct in_addr *ip_list, dc_ip; + extern pstring global_myname; + int count, i; - for (cli = client_list; cli; cli = cli->next) { - free_getent_state(cli->getpwent_state); - free_getent_state(cli->getgrent_state); + /* Lookup domain controller name */ + + if (!get_dc_list(False, lp_workgroup(), &ip_list, &count)) + return False; + + /* Firstly choose a PDC/BDC who has the same network address as any + of our interfaces. */ + + for (i = 0; i < count; i++) { + if(!is_local_net(ip_list[i])) + goto got_ip; } + + i = (sys_random() % count); + + got_ip: + dc_ip = ip_list[i]; + free(ip_list); + + if (!lookup_pdc_name(global_myname, lp_workgroup(), + &dc_ip, server_state.controller)) + return False; + + return True; } -/* Try to establish connections to NT servers */ +/* Attempt to connect to all domain controllers we know about */ -void establish_connections(void) +void establish_connections(BOOL force_reestablish) { - struct winbindd_domain *domain; static time_t lastt; time_t t; + /* Check we haven't checked too recently */ + t = time(NULL); - if (t - lastt < WINBINDD_ESTABLISH_LOOP) return; + if ((t - lastt < WINBINDD_ESTABLISH_LOOP) && !force_reestablish) { + return; + } lastt = t; - /* maybe the connection died - if so then close up and restart */ + DEBUG(3, ("establishing connections\n")); + debug_conn_state(); + + /* Maybe the connection died - if so then close up and restart */ + if (server_state.pwdb_initialised && server_state.lsa_handle_open && !rpc_hnd_ok(&server_state.lsa_handle)) { - winbindd_kill_connections(); + winbindd_kill_connections(NULL); } if (!server_state.pwdb_initialised) { - fstrcpy(server_state.controller, lp_passwordserver()); - if (lp_wildcard_dc()) { - if (!resolve_dc_name(lp_workgroup(), server_state.controller)) { - return; - } + + /* Lookup domain controller name */ + + if (!get_any_dc_name(lp_workgroup(), + server_state.controller)) { + return; } - server_state.pwdb_initialised = pwdb_initialise(False); - if (!server_state.pwdb_initialised) return; + /* Initialise password database and sids */ + +// server_state.pwdb_initialised = pwdb_initialise(False); + server_state.pwdb_initialised = True; + + if (!server_state.pwdb_initialised) + return; } /* Open lsa handle if it isn't already open */ + if (!server_state.lsa_handle_open) { + server_state.lsa_handle_open = - lsa_open_policy(server_state.controller, &server_state.lsa_handle, - False, SEC_RIGHTS_MAXIMUM_ALLOWED); + lsa_open_policy(server_state.controller, + False, SEC_RIGHTS_MAXIMUM_ALLOWED, + &server_state.lsa_handle); + if (!server_state.lsa_handle_open) return; - /* now we can talk to the server we can get some info */ + /* Now we can talk to the server we can get some info */ + get_trusted_domains(); } - for (domain=domain_list; domain; domain=domain->next) { - if (!domain_handles_open(domain)) { - open_sam_handles(domain); - } - } + debug_conn_state(); } - /* Connect to a domain controller using get_any_dc_name() to discover the domain name and sid */ + BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain) { fstring level5_dom; @@ -280,7 +407,7 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain) uint32 enum_ctx = 0; uint32 num_doms = 0; char **domains = NULL; - DOM_SID **sids = NULL; + DOM_SID *sids = NULL; if (domain == NULL) { return False; @@ -289,7 +416,10 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain) DEBUG(1, ("looking up sid for domain %s\n", domain_name)); /* Get controller name for domain */ - if (!resolve_dc_name(domain_name, domain->controller)) { + + if (!get_any_dc_name(domain_name, domain->controller)) { + DEBUG(0, ("Could not resolve domain controller for domain %s\n", + domain_name)); return False; } @@ -312,7 +442,7 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain) for(i = 0; i < num_doms; i++) { if (strequal(domain_name, domains[i])) { - sid_copy(&domain->sid, sids[i]); + sid_copy(&domain->sid, &sids[i]); found = True; break; } @@ -321,15 +451,9 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain) res = found; } - /* Free memory */ - - free_char_array(num_doms, domains); - free_sid_array(num_doms, sids); - return res; } - /* Lookup domain controller and sid for a domain */ BOOL get_domain_info(struct winbindd_domain *domain) @@ -339,8 +463,14 @@ BOOL get_domain_info(struct winbindd_domain *domain) DEBUG(1, ("Getting domain info for domain %s\n", domain->name)); /* Lookup domain sid */ + if (!lookup_domain_sid(domain->name, domain)) { DEBUG(0, ("could not find sid for domain %s\n", domain->name)); + + /* Could be a DC failure - shut down connections to this domain */ + + winbindd_kill_connections(domain); + return False; } @@ -356,8 +486,7 @@ BOOL get_domain_info(struct winbindd_domain *domain) /* Lookup a sid in a domain from a name */ -BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, - char *name, DOM_SID *sid, +BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *type) { int num_sids = 0, num_names = 1; @@ -403,8 +532,7 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, /* Lookup a name in a domain from a sid */ -BOOL winbindd_lookup_name_by_sid(struct winbindd_domain *domain, - DOM_SID *sid, char *name, +BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name, enum SID_NAME_USE *type) { int num_sids = 1, num_names = 0; @@ -413,8 +541,9 @@ BOOL winbindd_lookup_name_by_sid(struct winbindd_domain *domain, BOOL res; /* Lookup name */ - res = lsa_lookup_sids(&server_state.lsa_handle, num_sids, &sid, &names, - &types, &num_names); + + res = lsa_lookup_sids(&server_state.lsa_handle, num_sids, sid, + &names, &types, &num_names); /* Return name and type if successful */ @@ -446,19 +575,49 @@ BOOL winbindd_lookup_name_by_sid(struct winbindd_domain *domain, BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain, uint32 user_rid, SAM_USERINFO_CTR *user_info) { - if (!domain_handles_open(domain)) return False; - - return get_samr_query_userinfo(&domain->sam_dom_handle, 0x15, user_rid, user_info); + return get_samr_query_userinfo(&domain->sam_dom_handle, 0x15, + user_rid, user_info); } +/* Lookup groups a user is a member of. I wish Unix had a call like this! */ + +BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain, + uint32 user_rid, uint32 *num_groups, + DOM_GID **user_groups) +{ + POLICY_HND user_pol; + BOOL result; + + if (!samr_open_user(&domain->sam_dom_handle, + SEC_RIGHTS_MAXIMUM_ALLOWED, + user_rid, &user_pol)) { + return False; + } + + if (cli_samr_query_usergroups(domain->sam_dom_handle.cli, + domain->sam_dom_handle.mem_ctx, + &user_pol, num_groups, user_groups) + != NT_STATUS_NOPROBLEMO) { + result = False; + goto done; + } + + result = True; + +done: + cli_samr_close(domain->sam_dom_handle.cli, + domain->sam_dom_handle.mem_ctx, &user_pol); + + return True; +} + /* Lookup group information from a rid */ BOOL winbindd_lookup_groupinfo(struct winbindd_domain *domain, uint32 group_rid, GROUP_INFO_CTR *info) { - if (!domain_handles_open(domain)) return False; - - return get_samr_query_groupinfo(&domain->sam_dom_handle, 1, group_rid, info); + return get_samr_query_groupinfo(&domain->sam_dom_handle, 1, + group_rid, info); } /* Lookup group membership given a rid */ @@ -468,40 +627,48 @@ BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain, uint32 **rid_mem, char ***names, enum SID_NAME_USE **name_types) { - if (!domain_handles_open(domain)) return False; - - return sam_query_groupmem(&domain->sam_dom_handle, group_rid, num_names, - rid_mem, names, name_types); + return sam_query_groupmem(&domain->sam_dom_handle, group_rid, + num_names, rid_mem, names, name_types); } -/* Lookup alias membership given a rid */ +/* Globals for domain list stuff */ + +struct winbindd_domain *domain_list = NULL; -int winbindd_lookup_aliasmem(struct winbindd_domain *domain, - uint32 alias_rid, uint32 *num_names, - DOM_SID ***sids, char ***names, - enum SID_NAME_USE **name_types) +/* Given a domain name, return the struct winbindd domain info for it + if it is actually working. */ + +struct winbindd_domain *find_domain_from_name(char *domain_name) { - /* Open sam handles */ - if (!domain_handles_open(domain)) return False; + struct winbindd_domain *tmp; - return sam_query_aliasmem(domain->controller, - &domain->sam_dom_handle, alias_rid, num_names, - sids, names, name_types); -} + /* Search through list */ -/* Globals for domain list stuff */ + for (tmp = domain_list; tmp != NULL; tmp = tmp->next) { + if (strcmp(domain_name, tmp->name) == 0) { -struct winbindd_domain *domain_list = NULL; + if (!tmp->got_domain_info) { + get_domain_info(tmp); + } + + return tmp->got_domain_info ? tmp : NULL; + } + } + + /* Not found */ + + return NULL; +} /* Given a domain name, return the struct winbindd domain info for it */ -struct winbindd_domain *find_domain_from_name(char *domain_name) +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 (strcmp(domain_name, tmp->name) == 0) { + if (sid_equal(sid, &tmp->sid)) { if (!tmp->got_domain_info) return NULL; return tmp; } @@ -544,14 +711,14 @@ static BOOL parse_id_list(char *paramstr, BOOL is_user) /* Give a nicer error message if no parameters specified */ if (strequal(paramstr, "")) { - DEBUG(0, ("winbid %s parameter missing\n", is_user ? "uid" : "gid")); + DEBUG(0, ("winbind %s parameter missing\n", is_user ? "uid" : "gid")); return False; } /* Parse entry */ if (sscanf(paramstr, "%u-%u", &id_low, &id_high) != 2) { - DEBUG(0, ("winbid %s parameter invalid\n", + DEBUG(0, ("winbind %s parameter invalid\n", is_user ? "uid" : "gid")); return False; } @@ -588,7 +755,7 @@ BOOL winbindd_param_init(void) } if (server_state.gid_low > server_state.gid_high) { - DEBUG(0, ("gid range for invalid\n")); + DEBUG(0, ("gid range invalid\n")); return False; } @@ -597,85 +764,83 @@ BOOL winbindd_param_init(void) /* Convert a enum winbindd_cmd to a string */ -char *winbindd_cmd_to_string(enum winbindd_cmd cmd) -{ - char *result; +struct cmdstr_table { + enum winbindd_cmd cmd; + char *desc; +}; - switch (cmd) { +static struct cmdstr_table cmdstr_table[] = { + + /* User functions */ - case WINBINDD_GETPWNAM_FROM_USER: - result = "getpwnam from user"; - break; - - case WINBINDD_GETPWNAM_FROM_UID: - result = "getpwnam from uid"; - break; + { WINBINDD_GETPWNAM_FROM_USER, "getpwnam from user" }, + { WINBINDD_GETPWNAM_FROM_UID, "getpwnam from uid" }, + { WINBINDD_SETPWENT, "setpwent" }, + { WINBINDD_ENDPWENT, "endpwent" }, + { WINBINDD_GETPWENT, "getpwent" }, + { WINBINDD_GETGROUPS, "getgroups" }, - case WINBINDD_GETGRNAM_FROM_GROUP: - result = "getgrnam from group"; - break; + /* Group functions */ - case WINBINDD_GETGRNAM_FROM_GID: - result = "getgrnam from gid"; - break; + { WINBINDD_GETGRNAM_FROM_GROUP, "getgrnam from group" }, + { WINBINDD_GETGRNAM_FROM_GID, "getgrnam from gid" }, + { WINBINDD_SETGRENT, "setgrent" }, + { WINBINDD_ENDGRENT, "endgrent" }, + { WINBINDD_GETGRENT, "getgrent" }, - case WINBINDD_SETPWENT: - result = "setpwent"; - break; + /* PAM auth functions */ - case WINBINDD_ENDPWENT: - result = "endpwent"; - break; + { WINBINDD_PAM_AUTH, "pam auth" }, + { WINBINDD_PAM_CHAUTHTOK, "pam chauthtok" }, - case WINBINDD_GETPWENT: - result = "getpwent"; - break; + /* List things */ - case WINBINDD_SETGRENT: - result = "setgrent"; - break; + { WINBINDD_LIST_USERS, "list users" }, + { WINBINDD_LIST_GROUPS, "list groups" }, + { WINBINDD_LIST_TRUSTDOM, "list trusted domains" }, - case WINBINDD_ENDGRENT: - result = "endgrent"; - break; + /* SID related functions */ - case WINBINDD_GETGRENT: - result = "getgrent"; - break; + { WINBINDD_LOOKUPSID, "lookup sid" }, + { WINBINDD_LOOKUPNAME, "lookup name" }, - case WINBINDD_PAM_AUTH: - result = "pam_auth"; - break; + /* S*RS related functions */ - default: - result = "invalid command"; - break; - } + { WINBINDD_SID_TO_UID, "sid to uid" }, + { WINBINDD_SID_TO_GID, "sid to gid " }, + { WINBINDD_GID_TO_SID, "gid to sid" }, + { WINBINDD_UID_TO_SID, "uid to sid" }, - return result; -}; + /* Miscellaneous other stuff */ + { WINBINDD_CHECK_MACHACC, "check machine acct pw" }, -/* parse a string of the form DOMAIN/user into a domain and a user */ -void parse_domain_user(char *domuser, fstring domain, fstring user) + /* End of list */ + + { WINBINDD_NUM_CMDS, NULL } +}; + +char *winbindd_cmd_to_string(enum winbindd_cmd cmd) { - char *p; - char *sep = lp_winbind_separator(); - if (!sep) sep = "\\"; - p = strchr(domuser,*sep); - if (!p) p = strchr(domuser,'\\'); - if (!p) { - fstrcpy(domain,""); - fstrcpy(user, domuser); - return; + struct cmdstr_table *table = cmdstr_table; + char *result = NULL; + + for(table = cmdstr_table; table->desc; table++) { + if (cmd == table->cmd) { + result = table->desc; + break; + } } - fstrcpy(user, p+1); - fstrcpy(domain, domuser); - domain[PTR_DIFF(p, domuser)] = 0; -} + if (result == NULL) { + result = "invalid command"; + } + + return result; +}; /* find the sequence number for a domain */ + uint32 domain_sequence_number(char *domain_name) { struct winbindd_domain *domain; @@ -685,6 +850,11 @@ uint32 domain_sequence_number(char *domain_name) if (!domain) return DOM_SEQUENCE_NONE; if (!samr_query_dom_info(&domain->sam_dom_handle, 2, &ctr)) { + + /* If this fails, something bad has gone wrong */ + + winbindd_kill_connections(domain); + DEBUG(2,("domain sequence query failed\n")); return DOM_SEQUENCE_NONE; } @@ -694,3 +864,57 @@ uint32 domain_sequence_number(char *domain_name) return ctr.info.inf2.seq_num; } + +/* 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. */ + +uint32 winbindd_query_dispinfo(struct winbindd_domain *domain, + uint32 *start_ndx, uint16 info_level, + uint32 *num_entries, SAM_DISPINFO_CTR *ctr) +{ + uint32 status; + + status = samr_query_dispinfo(&domain->sam_dom_handle, start_ndx, + info_level, num_entries, ctr); + + return status; +} + +/* Check if a domain is present in a comma-separated list of domains */ + +BOOL check_domain_env(char *domain_env, char *domain) +{ + fstring name; + char *tmp = domain_env; + + while(next_token(&tmp, name, ",", sizeof(fstring))) { + if (strequal(name, domain)) { + return True; + } + } + + return False; +} + + +/* Parse a string of the form DOMAIN/user into a domain and a user */ + +void parse_domain_user(char *domuser, fstring domain, fstring user) +{ + char *p; + char *sep = lp_winbind_separator(); + if (!sep) sep = "\\"; + p = strchr(domuser,*sep); + if (!p) p = strchr(domuser,'\\'); + if (!p) { + fstrcpy(domain,""); + fstrcpy(user, domuser); + return; + } + + fstrcpy(user, p+1); + fstrcpy(domain, domuser); + domain[PTR_DIFF(p, domuser)] = 0; + strupper(domain); +} |