From 28aa4bff8d6be031c6089fe5c7ab010f1cc48340 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Sep 2007 12:03:58 +0000 Subject: r25154: move winbindd code into winbindd/ metze (This used to be commit 3ac7566ae14c48ff9b0f6b232e0ec4b2f73df558) --- source3/winbindd/winbindd_user.c | 875 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 875 insertions(+) create mode 100644 source3/winbindd/winbindd_user.c (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c new file mode 100644 index 0000000000..fac2832f56 --- /dev/null +++ b/source3/winbindd/winbindd_user.c @@ -0,0 +1,875 @@ +/* + 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 . +*/ + +#include "includes.h" +#include "winbindd.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_WINBIND + +static BOOL fillup_pw_field(const char *lp_template, + const char *username, + const char *domname, + uid_t uid, + gid_t gid, + const char *in, + fstring out) +{ + char *templ; + + if (out == NULL) + return False; + + /* The substitution of %U and %D in the 'template + homedir' is done by talloc_sub_specified() below. + If we have an in string (which means the value has already + been set in the nss_info backend), then use that. + Otherwise use the template value passed in. */ + + if ( in && !strequal(in,"") && lp_security() == SEC_ADS ) { + templ = talloc_sub_specified(NULL, in, + username, domname, + uid, gid); + } else { + templ = talloc_sub_specified(NULL, lp_template, + username, domname, + uid, gid); + } + + if (!templ) + return False; + + safe_strcpy(out, templ, sizeof(fstring) - 1); + TALLOC_FREE(templ); + + return True; + +} +/* Fill a pwent structure with information we have obtained */ + +static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, + DOM_SID *user_sid, DOM_SID *group_sid, + char *full_name, char *homedir, char *shell, + struct winbindd_pw *pw) +{ + fstring output_username; + fstring sid_string; + + if (!pw || !dom_name || !user_name) + return False; + + /* Resolve the uid number */ + + if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid))) { + DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid))); + return False; + } + + /* Resolve the gid number */ + + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid))) { + DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid))); + return False; + } + + strlower_m(user_name); + + /* Username */ + + fill_domain_username(output_username, dom_name, user_name, True); + + safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); + + /* Full name (gecos) */ + + safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1); + + /* Home directory and shell */ + + if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name, + pw->pw_uid, pw->pw_gid, homedir, pw->pw_dir)) + return False; + + if (!fillup_pw_field(lp_template_shell(), user_name, dom_name, + pw->pw_uid, pw->pw_gid, shell, pw->pw_shell)) + return False; + + /* Password - set to "*" as we can't generate anything useful here. + Authentication can be done using the pam_winbind module. */ + + safe_strcpy(pw->pw_passwd, "*", sizeof(pw->pw_passwd) - 1); + + return True; +} + +/* 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; + WINBIND_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_static(&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_static(&sid))); + return WINBINDD_ERROR; + } + + return WINBINDD_OK; +} + +struct getpwsid_state { + struct winbindd_cli_state *state; + struct winbindd_domain *domain; + char *username; + char *fullname; + char *homedir; + char *shell; + DOM_SID user_sid; + uid_t uid; + DOM_SID group_sid; + gid_t gid; +}; + +static void getpwsid_queryuser_recv(void *private_data, BOOL success, + const char *acct_name, + const char *full_name, + const char *homedir, + const char *shell, + uint32 gid, + uint32 group_rid); +static void getpwsid_sid2uid_recv(void *private_data, BOOL success, uid_t uid); +static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid); + +static void winbindd_getpwsid(struct winbindd_cli_state *state, + const DOM_SID *sid) +{ + struct getpwsid_state *s; + + s = TALLOC_ZERO_P(state->mem_ctx, struct getpwsid_state); + if (s == NULL) { + DEBUG(0, ("talloc failed\n")); + goto error; + } + + s->state = state; + s->domain = find_domain_from_sid_noinit(sid); + if (s->domain == NULL) { + DEBUG(3, ("Could not find domain for sid %s\n", + sid_string_static(sid))); + goto error; + } + + sid_copy(&s->user_sid, sid); + + query_user_async(s->state->mem_ctx, s->domain, sid, + getpwsid_queryuser_recv, s); + return; + + error: + request_error(state); +} + +static void getpwsid_queryuser_recv(void *private_data, BOOL success, + const char *acct_name, + const char *full_name, + const char *homedir, + const char *shell, + uint32 gid, + uint32 group_rid) +{ + fstring username; + struct getpwsid_state *s = + talloc_get_type_abort(private_data, struct getpwsid_state); + + if (!success) { + DEBUG(5, ("Could not query domain %s SID %s\n", s->domain->name, + sid_string_static(&s->user_sid))); + request_error(s->state); + return; + } + + if ( acct_name && *acct_name ) { + fstrcpy( username, acct_name ); + } else { + char *domain_name = NULL; + enum lsa_SidType type; + char *user_name = NULL; + struct winbindd_domain *domain = NULL; + + domain = find_lookup_domain_from_sid(&s->user_sid); + if (domain == NULL) { + DEBUG(5, ("find_lookup_domain_from_sid(%s) failed\n", + sid_string_static(&s->user_sid))); + request_error(s->state); + return; + } + winbindd_lookup_name_by_sid(s->state->mem_ctx, domain, + &s->user_sid, &domain_name, + &user_name, &type ); + + /* If this still fails we ar4e done. Just error out */ + if ( !user_name ) { + DEBUG(5,("Could not obtain a name for SID %s\n", + sid_string_static(&s->user_sid))); + request_error(s->state); + return; + } + + fstrcpy( username, user_name ); + } + + strlower_m( username ); + s->username = talloc_strdup(s->state->mem_ctx, username); + + ws_name_replace( s->username, WB_REPLACE_CHAR ); + + s->fullname = talloc_strdup(s->state->mem_ctx, full_name); + s->homedir = talloc_strdup(s->state->mem_ctx, homedir); + s->shell = talloc_strdup(s->state->mem_ctx, shell); + s->gid = gid; + sid_copy(&s->group_sid, &s->domain->sid); + sid_append_rid(&s->group_sid, group_rid); + + winbindd_sid2uid_async(s->state->mem_ctx, &s->user_sid, + getpwsid_sid2uid_recv, s); +} + +static void getpwsid_sid2uid_recv(void *private_data, BOOL success, uid_t uid) +{ + struct getpwsid_state *s = + talloc_get_type_abort(private_data, struct getpwsid_state); + + if (!success) { + DEBUG(5, ("Could not query uid for user %s\\%s\n", + s->domain->name, s->username)); + request_error(s->state); + return; + } + + s->uid = uid; + winbindd_sid2gid_async(s->state->mem_ctx, &s->group_sid, + getpwsid_sid2gid_recv, s); +} + +static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid) +{ + struct getpwsid_state *s = + talloc_get_type_abort(private_data, struct getpwsid_state); + struct winbindd_pw *pw; + fstring output_username; + + /* allow the nss backend to override the primary group ID. + If the gid has already been set, then keep it. + This makes me feel dirty. If the nss backend already + gave us a gid, we don't really care whether the sid2gid() + call worked or not. --jerry */ + + if ( s->gid == (gid_t)-1 ) { + + if (!success) { + DEBUG(5, ("Could not query gid for user %s\\%s\n", + s->domain->name, s->username)); + goto failed; + } + + /* take what the sid2gid() call gave us */ + s->gid = gid; + } + + pw = &s->state->response.data.pw; + pw->pw_uid = s->uid; + pw->pw_gid = s->gid; + fill_domain_username(output_username, s->domain->name, s->username, True); + safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); + safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1); + + if (!fillup_pw_field(lp_template_homedir(), s->username, s->domain->name, + pw->pw_uid, pw->pw_gid, s->homedir, pw->pw_dir)) { + DEBUG(5, ("Could not compose homedir\n")); + goto failed; + } + + if (!fillup_pw_field(lp_template_shell(), s->username, s->domain->name, + pw->pw_uid, pw->pw_gid, s->shell, pw->pw_shell)) { + DEBUG(5, ("Could not compose shell\n")); + goto failed; + } + + /* Password - set to "*" as we can't generate anything useful here. + Authentication can be done using the pam_winbind module. */ + + safe_strcpy(pw->pw_passwd, "*", sizeof(pw->pw_passwd) - 1); + + request_ok(s->state); + return; + + failed: + request_error(s->state); +} + +/* Return a password structure from a username. */ + +static void getpwnam_name2sid_recv(void *private_data, BOOL success, + const DOM_SID *sid, enum lsa_SidType type); + +void winbindd_getpwnam(struct winbindd_cli_state *state) +{ + struct winbindd_domain *domain; + fstring domname, username; + + /* Ensure null termination */ + state->request.data.username[sizeof(state->request.data.username)-1]='\0'; + + DEBUG(3, ("[%5lu]: getpwnam %s\n", (unsigned long)state->pid, + state->request.data.username)); + + ws_name_return( state->request.data.username, WB_REPLACE_CHAR ); + + if (!parse_domain_user(state->request.data.username, domname, + username)) { + DEBUG(5, ("Could not parse domain user: %s\n", + state->request.data.username)); + request_error(state); + return; + } + + /* Get info for the domain */ + + domain = find_domain_from_name(domname); + + if (domain == NULL) { + DEBUG(7, ("could not find domain entry for domain %s. " + "Using primary domain\n", domname)); + if ( (domain = find_our_domain()) == NULL ) { + DEBUG(0,("Cannot find my primary domain structure!\n")); + request_error(state); + return; + } + } + + if ( strequal(domname, lp_workgroup()) && lp_winbind_trusted_domains_only() ) { + DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n", + domname, username)); + request_error(state); + return; + } + + /* Get rid and name type from name. The following costs 1 packet */ + + winbindd_lookupname_async(state->mem_ctx, domname, username, + getpwnam_name2sid_recv, WINBINDD_GETPWNAM, + state); +} + +static void getpwnam_name2sid_recv(void *private_data, BOOL success, + const DOM_SID *sid, enum lsa_SidType type) +{ + struct winbindd_cli_state *state = + (struct winbindd_cli_state *)private_data; + fstring domname, username; + + if (!success) { + DEBUG(5, ("Could not lookup name for user %s\n", + state->request.data.username)); + request_error(state); + return; + } + + if ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER)) { + DEBUG(5, ("%s is not a user\n", state->request.data.username)); + request_error(state); + return; + } + + if ( parse_domain_user(state->request.data.username, domname, username) ) { + check_domain_trusted( domname, sid ); + } + + + + winbindd_getpwsid(state, sid); +} + +static void getpwuid_recv(void *private_data, BOOL success, const char *sid) +{ + struct winbindd_cli_state *state = + (struct winbindd_cli_state *)private_data; + DOM_SID user_sid; + + if (!success) { + DEBUG(10,("uid2sid_recv: uid [%lu] to sid mapping failed\n.", + (unsigned long)(state->request.data.uid))); + request_error(state); + return; + } + + DEBUG(10,("uid2sid_recv: uid %lu has sid %s\n", + (unsigned long)(state->request.data.uid), sid)); + + string_to_sid(&user_sid, sid); + winbindd_getpwsid(state, &user_sid); +} + +/* Return a password structure given a uid number */ +void winbindd_getpwuid(struct winbindd_cli_state *state) +{ + DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid, + (unsigned long)state->request.data.uid)); + + /* always query idmap via the async interface */ + /* if this turns to be too slow we will add here a direct query to the cache */ + winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, getpwuid_recv, state); +} + +/* + * set/get/endpwent functions + */ + +/* Rewind file pointer for ntdom passwd database */ + +static BOOL winbindd_setpwent_internal(struct winbindd_cli_state *state) +{ + struct winbindd_domain *domain; + + DEBUG(3, ("[%5lu]: setpwent\n", (unsigned long)state->pid)); + + /* Check user has enabled this */ + + if (!lp_winbind_enum_users()) { + return False; + } + + /* Free old static data if it exists */ + + if (state->getpwent_state != NULL) { + free_getent_state(state->getpwent_state); + state->getpwent_state = NULL; + } + +#if 0 /* JERRY */ + /* add any local users we have */ + + if ( (domain_state = (struct getent_state *)malloc(sizeof(struct getent_state))) == NULL ) + return False; + + ZERO_STRUCTP(domain_state); + + /* Add to list of open domains */ + + DLIST_ADD(state->getpwent_state, domain_state); +#endif + + /* Create sam pipes for each domain we know about */ + + for(domain = domain_list(); domain != NULL; domain = domain->next) { + struct getent_state *domain_state; + + + /* don't add our domaina if we are a PDC or if we + are a member of a Samba domain */ + + if ( (IS_DC || lp_winbind_trusted_domains_only()) + && strequal(domain->name, lp_workgroup()) ) + { + continue; + } + + /* Create a state record for this domain */ + + if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) { + DEBUG(0, ("malloc failed\n")); + return False; + } + + ZERO_STRUCTP(domain_state); + + fstrcpy(domain_state->domain_name, domain->name); + + /* Add to list of open domains */ + + DLIST_ADD(state->getpwent_state, domain_state); + } + + state->getpwent_initialized = True; + return True; +} + +void winbindd_setpwent(struct winbindd_cli_state *state) +{ + if (winbindd_setpwent_internal(state)) { + request_ok(state); + } else { + request_error(state); + } +} + +/* Close file pointer to ntdom passwd database */ + +void winbindd_endpwent(struct winbindd_cli_state *state) +{ + DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid)); + + free_getent_state(state->getpwent_state); + state->getpwent_initialized = False; + state->getpwent_state = NULL; + request_ok(state); +} + +/* Get partial list of domain users for a domain. We fill in the sam_entries, + and num_sam_entries fields with domain user information. The dispinfo_ndx + field is incremented to the index of the next user to fetch. Return True if + some users were returned, False otherwise. */ + +static BOOL get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + uint32 num_entries; + WINBIND_USERINFO *info; + struct getpwent_user *name_list = NULL; + struct winbindd_domain *domain; + struct winbindd_methods *methods; + unsigned int i; + + if (ent->num_sam_entries) + return False; + + if (!(domain = find_domain_from_name(ent->domain_name))) { + DEBUG(3, ("no such domain %s in get_sam_user_entries\n", + ent->domain_name)); + return False; + } + + methods = domain->methods; + + /* Free any existing user info */ + + SAFE_FREE(ent->sam_entries); + ent->num_sam_entries = 0; + + /* Call query_user_list to get a list of usernames and user rids */ + + num_entries = 0; + + status = methods->query_user_list(domain, mem_ctx, &num_entries, + &info); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("get_sam_user_entries: query_user_list failed with %s\n", + nt_errstr(status) )); + return False; + } + + if (num_entries) { + name_list = SMB_REALLOC_ARRAY(name_list, struct getpwent_user, ent->num_sam_entries + num_entries); + + if (!name_list) { + DEBUG(0,("get_sam_user_entries realloc failed.\n")); + return False; + } + } + + for (i = 0; i < num_entries; i++) { + /* Store account name and gecos */ + if (!info[i].acct_name) { + fstrcpy(name_list[ent->num_sam_entries + i].name, ""); + } else { + fstrcpy(name_list[ent->num_sam_entries + i].name, + info[i].acct_name); + } + if (!info[i].full_name) { + fstrcpy(name_list[ent->num_sam_entries + i].gecos, ""); + } else { + fstrcpy(name_list[ent->num_sam_entries + i].gecos, + info[i].full_name); + } + if (!info[i].homedir) { + fstrcpy(name_list[ent->num_sam_entries + i].homedir, ""); + } else { + fstrcpy(name_list[ent->num_sam_entries + i].homedir, + info[i].homedir); + } + if (!info[i].shell) { + fstrcpy(name_list[ent->num_sam_entries + i].shell, ""); + } else { + fstrcpy(name_list[ent->num_sam_entries + i].shell, + info[i].shell); + } + + + /* User and group ids */ + sid_copy(&name_list[ent->num_sam_entries+i].user_sid, + &info[i].user_sid); + sid_copy(&name_list[ent->num_sam_entries+i].group_sid, + &info[i].group_sid); + } + + ent->num_sam_entries += num_entries; + + /* Fill in remaining fields */ + + ent->sam_entries = name_list; + ent->sam_entry_index = 0; + return ent->num_sam_entries > 0; +} + +/* Fetch next passwd entry from ntdom database */ + +#define MAX_GETPWENT_USERS 500 + +void winbindd_getpwent(struct winbindd_cli_state *state) +{ + struct getent_state *ent; + struct winbindd_pw *user_list; + int num_users, user_list_ndx; + + DEBUG(3, ("[%5lu]: getpwent\n", (unsigned long)state->pid)); + + /* Check user has enabled this */ + + if (!lp_winbind_enum_users()) { + request_error(state); + return; + } + + /* Allocate space for returning a chunk of users */ + + num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries); + + if (num_users == 0) { + request_error(state); + return; + } + + if ((state->response.extra_data.data = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users)) == NULL) { + request_error(state); + return; + } + + memset(state->response.extra_data.data, 0, num_users * + sizeof(struct winbindd_pw)); + + user_list = (struct winbindd_pw *)state->response.extra_data.data; + + if (!state->getpwent_initialized) + winbindd_setpwent_internal(state); + + if (!(ent = state->getpwent_state)) { + request_error(state); + return; + } + + /* Start sending back users */ + + for (user_list_ndx = 0; user_list_ndx < num_users; ) { + struct getpwent_user *name_list = NULL; + uint32 result; + + /* Do we need to fetch another chunk of users? */ + + if (ent->num_sam_entries == ent->sam_entry_index) { + + while(ent && + !get_sam_user_entries(ent, state->mem_ctx)) { + struct getent_state *next_ent; + + /* Free state information for this domain */ + + SAFE_FREE(ent->sam_entries); + + next_ent = ent->next; + DLIST_REMOVE(state->getpwent_state, ent); + + SAFE_FREE(ent); + ent = next_ent; + } + + /* No more domains */ + + if (!ent) + break; + } + + name_list = (struct getpwent_user *)ent->sam_entries; + + /* Lookup user info */ + + result = winbindd_fill_pwent( + ent->domain_name, + name_list[ent->sam_entry_index].name, + &name_list[ent->sam_entry_index].user_sid, + &name_list[ent->sam_entry_index].group_sid, + name_list[ent->sam_entry_index].gecos, + name_list[ent->sam_entry_index].homedir, + name_list[ent->sam_entry_index].shell, + &user_list[user_list_ndx]); + + /* Add user to return list */ + + if (result) { + + user_list_ndx++; + state->response.data.num_entries++; + state->response.length += + sizeof(struct winbindd_pw); + + } else + DEBUG(1, ("could not lookup domain user %s\n", + name_list[ent->sam_entry_index].name)); + + ent->sam_entry_index++; + + } + + /* Out of domains */ + + if (user_list_ndx > 0) + request_ok(state); + else + request_error(state); +} + +/* List domain users without mapping to unix ids */ + +void winbindd_list_users(struct winbindd_cli_state *state) +{ + struct winbindd_domain *domain; + WINBIND_USERINFO *info; + const char *which_domain; + uint32 num_entries = 0, total_entries = 0; + char *extra_data = NULL; + int extra_data_len = 0; + enum winbindd_result rv = WINBINDD_ERROR; + + DEBUG(3, ("[%5lu]: list users\n", (unsigned long)state->pid)); + + /* Ensure null termination */ + state->request.domain_name[sizeof(state->request.domain_name)-1]='\0'; + which_domain = state->request.domain_name; + + /* Enumerate over trusted domains */ + + for (domain = domain_list(); domain; domain = domain->next) { + NTSTATUS status; + struct winbindd_methods *methods; + unsigned int i; + + /* if we have a domain name restricting the request and this + one in the list doesn't match, then just bypass the remainder + of the loop */ + + if ( *which_domain && !strequal(which_domain, domain->name) ) + continue; + + methods = domain->methods; + + /* Query display info */ + status = methods->query_user_list(domain, state->mem_ctx, + &num_entries, &info); + + if (!NT_STATUS_IS_OK(status)) { + continue; + } + + if (num_entries == 0) + continue; + + /* Allocate some memory for extra data */ + total_entries += num_entries; + + extra_data = (char *)SMB_REALLOC( + extra_data, sizeof(fstring) * total_entries); + + if (!extra_data) { + DEBUG(0,("failed to enlarge buffer!\n")); + goto done; + } + + /* Pack user list into extra data fields */ + + for (i = 0; i < num_entries; i++) { + fstring acct_name, name; + + if (!info[i].acct_name) { + fstrcpy(acct_name, ""); + } else { + fstrcpy(acct_name, info[i].acct_name); + } + + fill_domain_username(name, domain->name, acct_name, True); + + /* Append to extra data */ + memcpy(&extra_data[extra_data_len], name, + strlen(name)); + extra_data_len += strlen(name); + extra_data[extra_data_len++] = ','; + } + } + + /* Assign extra_data fields in response structure */ + + if (extra_data) { + extra_data[extra_data_len - 1] = '\0'; + state->response.extra_data.data = extra_data; + state->response.length += extra_data_len; + } + + /* No domains responded but that's still OK so don't return an + error. */ + + rv = WINBINDD_OK; + + done: + + if (rv == WINBINDD_OK) + request_ok(state); + else + request_error(state); +} -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/winbindd/winbindd_user.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index fac2832f56..01cdd0a9d3 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -27,7 +27,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -static BOOL fillup_pw_field(const char *lp_template, +static bool fillup_pw_field(const char *lp_template, const char *username, const char *domname, uid_t uid, @@ -67,7 +67,7 @@ static BOOL fillup_pw_field(const char *lp_template, } /* Fill a pwent structure with information we have obtained */ -static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, +static bool winbindd_fill_pwent(char *dom_name, char *user_name, DOM_SID *user_sid, DOM_SID *group_sid, char *full_name, char *homedir, char *shell, struct winbindd_pw *pw) @@ -178,15 +178,15 @@ struct getpwsid_state { gid_t gid; }; -static void getpwsid_queryuser_recv(void *private_data, BOOL success, +static void getpwsid_queryuser_recv(void *private_data, bool success, const char *acct_name, const char *full_name, const char *homedir, const char *shell, uint32 gid, uint32 group_rid); -static void getpwsid_sid2uid_recv(void *private_data, BOOL success, uid_t uid); -static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid); +static void getpwsid_sid2uid_recv(void *private_data, bool success, uid_t uid); +static void getpwsid_sid2gid_recv(void *private_data, bool success, gid_t gid); static void winbindd_getpwsid(struct winbindd_cli_state *state, const DOM_SID *sid) @@ -217,7 +217,7 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state, request_error(state); } -static void getpwsid_queryuser_recv(void *private_data, BOOL success, +static void getpwsid_queryuser_recv(void *private_data, bool success, const char *acct_name, const char *full_name, const char *homedir, @@ -282,7 +282,7 @@ static void getpwsid_queryuser_recv(void *private_data, BOOL success, getpwsid_sid2uid_recv, s); } -static void getpwsid_sid2uid_recv(void *private_data, BOOL success, uid_t uid) +static void getpwsid_sid2uid_recv(void *private_data, bool success, uid_t uid) { struct getpwsid_state *s = talloc_get_type_abort(private_data, struct getpwsid_state); @@ -299,7 +299,7 @@ static void getpwsid_sid2uid_recv(void *private_data, BOOL success, uid_t uid) getpwsid_sid2gid_recv, s); } -static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid) +static void getpwsid_sid2gid_recv(void *private_data, bool success, gid_t gid) { struct getpwsid_state *s = talloc_get_type_abort(private_data, struct getpwsid_state); @@ -357,7 +357,7 @@ static void getpwsid_sid2gid_recv(void *private_data, BOOL success, gid_t gid) /* Return a password structure from a username. */ -static void getpwnam_name2sid_recv(void *private_data, BOOL success, +static void getpwnam_name2sid_recv(void *private_data, bool success, const DOM_SID *sid, enum lsa_SidType type); void winbindd_getpwnam(struct winbindd_cli_state *state) @@ -409,7 +409,7 @@ void winbindd_getpwnam(struct winbindd_cli_state *state) state); } -static void getpwnam_name2sid_recv(void *private_data, BOOL success, +static void getpwnam_name2sid_recv(void *private_data, bool success, const DOM_SID *sid, enum lsa_SidType type) { struct winbindd_cli_state *state = @@ -438,7 +438,7 @@ static void getpwnam_name2sid_recv(void *private_data, BOOL success, winbindd_getpwsid(state, sid); } -static void getpwuid_recv(void *private_data, BOOL success, const char *sid) +static void getpwuid_recv(void *private_data, bool success, const char *sid) { struct winbindd_cli_state *state = (struct winbindd_cli_state *)private_data; @@ -475,7 +475,7 @@ void winbindd_getpwuid(struct winbindd_cli_state *state) /* Rewind file pointer for ntdom passwd database */ -static BOOL winbindd_setpwent_internal(struct winbindd_cli_state *state) +static bool winbindd_setpwent_internal(struct winbindd_cli_state *state) { struct winbindd_domain *domain; @@ -568,7 +568,7 @@ void winbindd_endpwent(struct winbindd_cli_state *state) field is incremented to the index of the next user to fetch. Return True if some users were returned, False otherwise. */ -static BOOL get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx) +static bool get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx) { NTSTATUS status; uint32 num_entries; -- cgit From 900288a2b86abd247f9eb4cd15dc5617a17cfef1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:11:36 +0100 Subject: Replace sid_string_static by sid_string_dbg in DEBUGs (This used to be commit bb35e794ec129805e874ceba882bcc1e84791a09) --- source3/winbindd/winbindd_user.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index 01cdd0a9d3..6241d84fe6 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -73,7 +73,6 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name, struct winbindd_pw *pw) { fstring output_username; - fstring sid_string; if (!pw || !dom_name || !user_name) return False; @@ -81,14 +80,16 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name, /* Resolve the uid number */ if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid))) { - DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid))); + DEBUG(1, ("error getting user id for sid %s\n", + sid_string_dbg(user_sid))); return False; } /* Resolve the gid number */ if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid))) { - DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid))); + DEBUG(1, ("error getting group id for sid %s\n", + sid_string_dbg(group_sid))); return False; } @@ -146,7 +147,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, &sid, &user_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("error getting user info for sid %s\n", - sid_string_static(&sid))); + sid_string_dbg(&sid))); return WINBINDD_ERROR; } @@ -158,7 +159,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, 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_static(&sid))); + sid_string_dbg(&sid))); return WINBINDD_ERROR; } @@ -203,7 +204,7 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state, s->domain = find_domain_from_sid_noinit(sid); if (s->domain == NULL) { DEBUG(3, ("Could not find domain for sid %s\n", - sid_string_static(sid))); + sid_string_dbg(sid))); goto error; } @@ -230,8 +231,8 @@ static void getpwsid_queryuser_recv(void *private_data, bool success, talloc_get_type_abort(private_data, struct getpwsid_state); if (!success) { - DEBUG(5, ("Could not query domain %s SID %s\n", s->domain->name, - sid_string_static(&s->user_sid))); + DEBUG(5, ("Could not query domain %s SID %s\n", + s->domain->name, sid_string_dbg(&s->user_sid))); request_error(s->state); return; } @@ -247,7 +248,7 @@ static void getpwsid_queryuser_recv(void *private_data, bool success, domain = find_lookup_domain_from_sid(&s->user_sid); if (domain == NULL) { DEBUG(5, ("find_lookup_domain_from_sid(%s) failed\n", - sid_string_static(&s->user_sid))); + sid_string_dbg(&s->user_sid))); request_error(s->state); return; } @@ -258,7 +259,7 @@ static void getpwsid_queryuser_recv(void *private_data, bool success, /* If this still fails we ar4e done. Just error out */ if ( !user_name ) { DEBUG(5,("Could not obtain a name for SID %s\n", - sid_string_static(&s->user_sid))); + sid_string_dbg(&s->user_sid))); request_error(s->state); return; } -- cgit From 120c09b125f656d6d03b979560f3ef6652217691 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Jun 2008 14:02:39 -0700 Subject: From Steve Danneman @ Isilon. Attached is the companion patch to (037b9689d9042a398cb91e4628a82fcdfa913c21), which made handling of WINBINDD_LIST_GROUPS asynchronous. Because most all of the list_groups code was reusable, I abstracted it, and implemented both list_groups and list_users on top of it. On my large test domain a "wbinfo -u" call went from 70 seconds to 30 seconds with this patch. Plus, the parent process is no longer blocked from receiving new requests during that time. Steven Danneman | Software Development Engineer Isilon Systems P +1-206-315-7500 F +1-206-315-7501 www.isilon.com (This used to be commit 5188f2861137ff06d5399561d55d7d00c3a08644) --- source3/winbindd/winbindd_user.c | 94 +--------------------------------------- 1 file changed, 1 insertion(+), 93 deletions(-) (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index 6241d84fe6..45918383b7 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -778,99 +778,7 @@ void winbindd_getpwent(struct winbindd_cli_state *state) } /* List domain users without mapping to unix ids */ - void winbindd_list_users(struct winbindd_cli_state *state) { - struct winbindd_domain *domain; - WINBIND_USERINFO *info; - const char *which_domain; - uint32 num_entries = 0, total_entries = 0; - char *extra_data = NULL; - int extra_data_len = 0; - enum winbindd_result rv = WINBINDD_ERROR; - - DEBUG(3, ("[%5lu]: list users\n", (unsigned long)state->pid)); - - /* Ensure null termination */ - state->request.domain_name[sizeof(state->request.domain_name)-1]='\0'; - which_domain = state->request.domain_name; - - /* Enumerate over trusted domains */ - - for (domain = domain_list(); domain; domain = domain->next) { - NTSTATUS status; - struct winbindd_methods *methods; - unsigned int i; - - /* if we have a domain name restricting the request and this - one in the list doesn't match, then just bypass the remainder - of the loop */ - - if ( *which_domain && !strequal(which_domain, domain->name) ) - continue; - - methods = domain->methods; - - /* Query display info */ - status = methods->query_user_list(domain, state->mem_ctx, - &num_entries, &info); - - if (!NT_STATUS_IS_OK(status)) { - continue; - } - - if (num_entries == 0) - continue; - - /* Allocate some memory for extra data */ - total_entries += num_entries; - - extra_data = (char *)SMB_REALLOC( - extra_data, sizeof(fstring) * total_entries); - - if (!extra_data) { - DEBUG(0,("failed to enlarge buffer!\n")); - goto done; - } - - /* Pack user list into extra data fields */ - - for (i = 0; i < num_entries; i++) { - fstring acct_name, name; - - if (!info[i].acct_name) { - fstrcpy(acct_name, ""); - } else { - fstrcpy(acct_name, info[i].acct_name); - } - - fill_domain_username(name, domain->name, acct_name, True); - - /* Append to extra data */ - memcpy(&extra_data[extra_data_len], name, - strlen(name)); - extra_data_len += strlen(name); - extra_data[extra_data_len++] = ','; - } - } - - /* Assign extra_data fields in response structure */ - - if (extra_data) { - extra_data[extra_data_len - 1] = '\0'; - state->response.extra_data.data = extra_data; - state->response.length += extra_data_len; - } - - /* No domains responded but that's still OK so don't return an - error. */ - - rv = WINBINDD_OK; - - done: - - if (rv == WINBINDD_OK) - request_ok(state); - else - request_error(state); + winbindd_list_ent(state, LIST_USERS); } -- cgit From d0a71a00bb0408713eca523807955b6dd087f2bc Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 6 Jul 2008 12:03:35 -0400 Subject: Make code more readable, fix indentation and traling spaces. (This used to be commit e19e12d5cbba28ccf682eaf0ff26909bd7e8e6c6) --- source3/winbindd/winbindd_user.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index 45918383b7..270a297b7c 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -365,23 +365,27 @@ void winbindd_getpwnam(struct winbindd_cli_state *state) { struct winbindd_domain *domain; fstring domname, username; + char *domuser; + size_t dusize; - /* Ensure null termination */ - state->request.data.username[sizeof(state->request.data.username)-1]='\0'; + domuser = state->request.data.username; + dusize = sizeof(state->request.data.username); - DEBUG(3, ("[%5lu]: getpwnam %s\n", (unsigned long)state->pid, - state->request.data.username)); + /* Ensure null termination (it's an fstring) */ + domuser[dusize-1] = '\0'; - ws_name_return( state->request.data.username, WB_REPLACE_CHAR ); + DEBUG(3, ("[%5lu]: getpwnam %s\n", + (unsigned long)state->pid, + domuser)); - if (!parse_domain_user(state->request.data.username, domname, - username)) { - DEBUG(5, ("Could not parse domain user: %s\n", - state->request.data.username)); + ws_name_return(domuser, WB_REPLACE_CHAR); + + if (!parse_domain_user(domuser, domname, username)) { + DEBUG(5, ("Could not parse domain user: %s\n", domuser)); request_error(state); return; } - + /* Get info for the domain */ domain = find_domain_from_name(domname); @@ -391,17 +395,19 @@ void winbindd_getpwnam(struct winbindd_cli_state *state) "Using primary domain\n", domname)); if ( (domain = find_our_domain()) == NULL ) { DEBUG(0,("Cannot find my primary domain structure!\n")); - request_error(state); - return; - } + request_error(state); + return; + } } - if ( strequal(domname, lp_workgroup()) && lp_winbind_trusted_domains_only() ) { - DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n", - domname, username)); + if (strequal(domname, lp_workgroup()) && + lp_winbind_trusted_domains_only() ) { + DEBUG(7,("winbindd_getpwnam: My domain -- " + "rejecting getpwnam() for %s\\%s.\n", + domname, username)); request_error(state); return; - } + } /* Get rid and name type from name. The following costs 1 packet */ -- cgit From 632e42e16503ba6e34e8bcb3a9449a2c39805426 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 6 Jul 2008 12:17:22 -0400 Subject: More clean up, indentation and trailing space removal (This used to be commit d17d401603c1c26a5fd5eca5ece245790445e6d4) --- source3/winbindd/winbindd_user.c | 79 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 40 deletions(-) (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index 270a297b7c..c75ed4adf1 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -564,7 +564,7 @@ void winbindd_endpwent(struct winbindd_cli_state *state) { DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid)); - free_getent_state(state->getpwent_state); + free_getent_state(state->getpwent_state); state->getpwent_initialized = False; state->getpwent_state = NULL; request_ok(state); @@ -600,23 +600,23 @@ static bool get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx) SAFE_FREE(ent->sam_entries); ent->num_sam_entries = 0; - + /* Call query_user_list to get a list of usernames and user rids */ num_entries = 0; - status = methods->query_user_list(domain, mem_ctx, &num_entries, - &info); - + status = methods->query_user_list(domain, mem_ctx, &num_entries, &info); + if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("get_sam_user_entries: query_user_list failed with %s\n", - nt_errstr(status) )); + DEBUG(10,("get_sam_user_entries: " + "query_user_list failed with %s\n", + nt_errstr(status))); return False; } if (num_entries) { - name_list = SMB_REALLOC_ARRAY(name_list, struct getpwent_user, ent->num_sam_entries + num_entries); - + name_list = SMB_REALLOC_ARRAY(name_list, struct getpwent_user, + ent->num_sam_entries + num_entries); if (!name_list) { DEBUG(0,("get_sam_user_entries realloc failed.\n")); return False; @@ -628,40 +628,40 @@ static bool get_sam_user_entries(struct getent_state *ent, TALLOC_CTX *mem_ctx) if (!info[i].acct_name) { fstrcpy(name_list[ent->num_sam_entries + i].name, ""); } else { - fstrcpy(name_list[ent->num_sam_entries + i].name, - info[i].acct_name); + fstrcpy(name_list[ent->num_sam_entries + i].name, + info[i].acct_name); } if (!info[i].full_name) { fstrcpy(name_list[ent->num_sam_entries + i].gecos, ""); } else { - fstrcpy(name_list[ent->num_sam_entries + i].gecos, - info[i].full_name); + fstrcpy(name_list[ent->num_sam_entries + i].gecos, + info[i].full_name); } if (!info[i].homedir) { - fstrcpy(name_list[ent->num_sam_entries + i].homedir, ""); + fstrcpy(name_list[ent->num_sam_entries + i].homedir,""); } else { - fstrcpy(name_list[ent->num_sam_entries + i].homedir, - info[i].homedir); + fstrcpy(name_list[ent->num_sam_entries + i].homedir, + info[i].homedir); } if (!info[i].shell) { fstrcpy(name_list[ent->num_sam_entries + i].shell, ""); } else { - fstrcpy(name_list[ent->num_sam_entries + i].shell, - info[i].shell); + fstrcpy(name_list[ent->num_sam_entries + i].shell, + info[i].shell); } - - + + /* User and group ids */ sid_copy(&name_list[ent->num_sam_entries+i].user_sid, &info[i].user_sid); sid_copy(&name_list[ent->num_sam_entries+i].group_sid, &info[i].group_sid); } - + ent->num_sam_entries += num_entries; - + /* Fill in remaining fields */ - + ent->sam_entries = name_list; ent->sam_entry_index = 0; return ent->num_sam_entries > 0; @@ -694,20 +694,20 @@ void winbindd_getpwent(struct winbindd_cli_state *state) request_error(state); return; } - - if ((state->response.extra_data.data = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users)) == NULL) { + + user_list = SMB_MALLOC_ARRAY(struct winbindd_pw, num_users); + if (!user_list) { request_error(state); return; } + /* will be freed by process_request() */ + state->response.extra_data.data = user_list; - memset(state->response.extra_data.data, 0, num_users * - sizeof(struct winbindd_pw)); - - user_list = (struct winbindd_pw *)state->response.extra_data.data; + memset(user_list, 0, num_users * sizeof(struct winbindd_pw)); if (!state->getpwent_initialized) winbindd_setpwent_internal(state); - + if (!(ent = state->getpwent_state)) { request_error(state); return; @@ -737,19 +737,19 @@ void winbindd_getpwent(struct winbindd_cli_state *state) SAFE_FREE(ent); ent = next_ent; } - + /* No more domains */ - if (!ent) + if (!ent) break; } name_list = (struct getpwent_user *)ent->sam_entries; /* Lookup user info */ - + result = winbindd_fill_pwent( - ent->domain_name, + ent->domain_name, name_list[ent->sam_entry_index].name, &name_list[ent->sam_entry_index].user_sid, &name_list[ent->sam_entry_index].group_sid, @@ -757,22 +757,21 @@ void winbindd_getpwent(struct winbindd_cli_state *state) name_list[ent->sam_entry_index].homedir, name_list[ent->sam_entry_index].shell, &user_list[user_list_ndx]); - + /* Add user to return list */ - + if (result) { - + user_list_ndx++; state->response.data.num_entries++; - state->response.length += - sizeof(struct winbindd_pw); + state->response.length += sizeof(struct winbindd_pw); } else DEBUG(1, ("could not lookup domain user %s\n", name_list[ent->sam_entry_index].name)); ent->sam_entry_index++; - + } /* Out of domains */ -- cgit From fae6a4e79b4476dcd77be7011011e25b27a36f22 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 6 Jul 2008 12:27:34 -0400 Subject: Clean up the rest of the file too (This used to be commit f6c92c4759096f839e3854a1e9eea56e6eecad4d) --- source3/winbindd/winbindd_user.c | 160 +++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 84 deletions(-) (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index c75ed4adf1..576300555a 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -27,12 +27,12 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -static bool fillup_pw_field(const char *lp_template, - const char *username, +static bool fillup_pw_field(const char *lp_template, + const char *username, const char *domname, uid_t uid, gid_t gid, - const char *in, + const char *in, fstring out) { char *templ; @@ -40,43 +40,43 @@ static bool fillup_pw_field(const char *lp_template, if (out == NULL) return False; - /* The substitution of %U and %D in the 'template + /* The substitution of %U and %D in the 'template homedir' is done by talloc_sub_specified() below. If we have an in string (which means the value has already been set in the nss_info backend), then use that. Otherwise use the template value passed in. */ if ( in && !strequal(in,"") && lp_security() == SEC_ADS ) { - templ = talloc_sub_specified(NULL, in, + templ = talloc_sub_specified(NULL, in, username, domname, uid, gid); } else { - templ = talloc_sub_specified(NULL, lp_template, + templ = talloc_sub_specified(NULL, lp_template, username, domname, - uid, gid); + uid, gid); } - + if (!templ) return False; safe_strcpy(out, templ, sizeof(fstring) - 1); TALLOC_FREE(templ); - + return True; - + } /* Fill a pwent structure with information we have obtained */ -static bool winbindd_fill_pwent(char *dom_name, char *user_name, +static bool winbindd_fill_pwent(char *dom_name, char *user_name, DOM_SID *user_sid, DOM_SID *group_sid, char *full_name, char *homedir, char *shell, struct winbindd_pw *pw) { fstring output_username; - + if (!pw || !dom_name || !user_name) return False; - + /* Resolve the uid number */ if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid))) { @@ -84,8 +84,8 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name, sid_string_dbg(user_sid))); return False; } - - /* Resolve the gid number */ + + /* Resolve the gid number */ if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid))) { DEBUG(1, ("error getting group id for sid %s\n", @@ -97,21 +97,21 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name, /* Username */ - fill_domain_username(output_username, dom_name, user_name, True); + fill_domain_username(output_username, dom_name, user_name, True); safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); - + /* Full name (gecos) */ - + safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1); /* Home directory and shell */ - - if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name, + + if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name, pw->pw_uid, pw->pw_gid, homedir, pw->pw_dir)) return False; - if (!fillup_pw_field(lp_template_shell(), user_name, dom_name, + if (!fillup_pw_field(lp_template_shell(), user_name, dom_name, pw->pw_uid, pw->pw_gid, shell, pw->pw_shell)) return False; @@ -135,7 +135,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; - DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, + DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, state->request.data.sid)); if (!string_to_sid(&sid, state->request.data.sid)) { @@ -155,7 +155,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, 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; + 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", @@ -181,7 +181,7 @@ struct getpwsid_state { static void getpwsid_queryuser_recv(void *private_data, bool success, const char *acct_name, - const char *full_name, + const char *full_name, const char *homedir, const char *shell, uint32 gid, @@ -217,10 +217,10 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state, error: request_error(state); } - + static void getpwsid_queryuser_recv(void *private_data, bool success, const char *acct_name, - const char *full_name, + const char *full_name, const char *homedir, const char *shell, uint32 gid, @@ -239,43 +239,43 @@ static void getpwsid_queryuser_recv(void *private_data, bool success, if ( acct_name && *acct_name ) { fstrcpy( username, acct_name ); - } else { + } else { char *domain_name = NULL; enum lsa_SidType type; char *user_name = NULL; struct winbindd_domain *domain = NULL; - + domain = find_lookup_domain_from_sid(&s->user_sid); if (domain == NULL) { DEBUG(5, ("find_lookup_domain_from_sid(%s) failed\n", sid_string_dbg(&s->user_sid))); request_error(s->state); - return; + return; } winbindd_lookup_name_by_sid(s->state->mem_ctx, domain, &s->user_sid, &domain_name, - &user_name, &type ); + &user_name, &type ); /* If this still fails we ar4e done. Just error out */ if ( !user_name ) { DEBUG(5,("Could not obtain a name for SID %s\n", sid_string_dbg(&s->user_sid))); request_error(s->state); - return; + return; } - fstrcpy( username, user_name ); + fstrcpy( username, user_name ); } strlower_m( username ); s->username = talloc_strdup(s->state->mem_ctx, username); ws_name_replace( s->username, WB_REPLACE_CHAR ); - + s->fullname = talloc_strdup(s->state->mem_ctx, full_name); s->homedir = talloc_strdup(s->state->mem_ctx, homedir); s->shell = talloc_strdup(s->state->mem_ctx, shell); - s->gid = gid; + s->gid = gid; sid_copy(&s->group_sid, &s->domain->sid); sid_append_rid(&s->group_sid, group_rid); @@ -328,18 +328,21 @@ static void getpwsid_sid2gid_recv(void *private_data, bool success, gid_t gid) pw = &s->state->response.data.pw; pw->pw_uid = s->uid; pw->pw_gid = s->gid; - fill_domain_username(output_username, s->domain->name, s->username, True); + fill_domain_username(output_username, s->domain->name, + s->username, True); safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1); - if (!fillup_pw_field(lp_template_homedir(), s->username, s->domain->name, - pw->pw_uid, pw->pw_gid, s->homedir, pw->pw_dir)) { + if (!fillup_pw_field(lp_template_homedir(), s->username, + s->domain->name, pw->pw_uid, pw->pw_gid, + s->homedir, pw->pw_dir)) { DEBUG(5, ("Could not compose homedir\n")); goto failed; } - if (!fillup_pw_field(lp_template_shell(), s->username, s->domain->name, - pw->pw_uid, pw->pw_gid, s->shell, pw->pw_shell)) { + if (!fillup_pw_field(lp_template_shell(), s->username, + s->domain->name, pw->pw_uid, pw->pw_gid, + s->shell, pw->pw_shell)) { DEBUG(5, ("Could not compose shell\n")); goto failed; } @@ -412,7 +415,7 @@ void winbindd_getpwnam(struct winbindd_cli_state *state) /* Get rid and name type from name. The following costs 1 packet */ winbindd_lookupname_async(state->mem_ctx, domname, username, - getpwnam_name2sid_recv, WINBINDD_GETPWNAM, + getpwnam_name2sid_recv, WINBINDD_GETPWNAM, state); } @@ -421,27 +424,25 @@ static void getpwnam_name2sid_recv(void *private_data, bool success, { struct winbindd_cli_state *state = (struct winbindd_cli_state *)private_data; - fstring domname, username; + fstring domname, username; + char *domuser = state->request.data.username; if (!success) { - DEBUG(5, ("Could not lookup name for user %s\n", - state->request.data.username)); + DEBUG(5, ("Could not lookup name for user %s\n", domuser)); request_error(state); return; } if ((type != SID_NAME_USER) && (type != SID_NAME_COMPUTER)) { - DEBUG(5, ("%s is not a user\n", state->request.data.username)); + DEBUG(5, ("%s is not a user\n", domuser)); request_error(state); return; } - if ( parse_domain_user(state->request.data.username, domname, username) ) { - check_domain_trusted( domname, sid ); + if (parse_domain_user(domuser, domname, username)) { + check_domain_trusted(domname, sid); } - - winbindd_getpwsid(state, sid); } @@ -457,7 +458,7 @@ static void getpwuid_recv(void *private_data, bool success, const char *sid) request_error(state); return; } - + DEBUG(10,("uid2sid_recv: uid %lu has sid %s\n", (unsigned long)(state->request.data.uid), sid)); @@ -468,12 +469,16 @@ static void getpwuid_recv(void *private_data, bool success, const char *sid) /* Return a password structure given a uid number */ void winbindd_getpwuid(struct winbindd_cli_state *state) { - DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid, - (unsigned long)state->request.data.uid)); + uid_t uid = state->request.data.uid; + + DEBUG(3, ("[%5lu]: getpwuid %lu\n", + (unsigned long)state->pid, + (unsigned long)uid)); /* always query idmap via the async interface */ - /* if this turns to be too slow we will add here a direct query to the cache */ - winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, getpwuid_recv, state); + /* if this turns to be too slow we will add here + * a direct query to the cache */ + winbindd_uid2sid_async(state->mem_ctx, uid, getpwuid_recv, state); } /* @@ -485,66 +490,53 @@ void winbindd_getpwuid(struct winbindd_cli_state *state) static bool winbindd_setpwent_internal(struct winbindd_cli_state *state) { struct winbindd_domain *domain; - + DEBUG(3, ("[%5lu]: setpwent\n", (unsigned long)state->pid)); - + /* Check user has enabled this */ - + if (!lp_winbind_enum_users()) { return False; } /* Free old static data if it exists */ - + if (state->getpwent_state != NULL) { free_getent_state(state->getpwent_state); state->getpwent_state = NULL; } -#if 0 /* JERRY */ - /* add any local users we have */ - - if ( (domain_state = (struct getent_state *)malloc(sizeof(struct getent_state))) == NULL ) - return False; - - ZERO_STRUCTP(domain_state); - - /* Add to list of open domains */ - - DLIST_ADD(state->getpwent_state, domain_state); -#endif - /* Create sam pipes for each domain we know about */ - + for(domain = domain_list(); domain != NULL; domain = domain->next) { struct getent_state *domain_state; - - - /* don't add our domaina if we are a PDC or if we + + + /* don't add our domaina if we are a PDC or if we are a member of a Samba domain */ - - if ( (IS_DC || lp_winbind_trusted_domains_only()) - && strequal(domain->name, lp_workgroup()) ) - { + + if ((IS_DC || lp_winbind_trusted_domains_only()) + && strequal(domain->name, lp_workgroup())) { continue; } - + /* Create a state record for this domain */ - - if ((domain_state = SMB_MALLOC_P(struct getent_state)) == NULL) { + + domain_state = SMB_MALLOC_P(struct getent_state); + if (!domain_state) { DEBUG(0, ("malloc failed\n")); return False; } - + ZERO_STRUCTP(domain_state); fstrcpy(domain_state->domain_name, domain->name); /* Add to list of open domains */ - + DLIST_ADD(state->getpwent_state, domain_state); } - + state->getpwent_initialized = True; return True; } -- cgit From 0fdffbc9595ac32969fbb30bc403b426af7a82d3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jul 2008 23:30:53 +0200 Subject: Fix an incompatible pointer warning (cherry picked from commit 3282f7289b7b33beeaa1ca649651cca6537a69af) (This used to be commit fc8641443951dc852dc9cf1e73626df452b815f7) --- source3/winbindd/winbindd_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index 576300555a..00e53eff74 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -184,7 +184,7 @@ static void getpwsid_queryuser_recv(void *private_data, bool success, const char *full_name, const char *homedir, const char *shell, - uint32 gid, + gid_t gid, uint32 group_rid); static void getpwsid_sid2uid_recv(void *private_data, bool success, uid_t uid); static void getpwsid_sid2gid_recv(void *private_data, bool success, gid_t gid); @@ -223,7 +223,7 @@ static void getpwsid_queryuser_recv(void *private_data, bool success, const char *full_name, const char *homedir, const char *shell, - uint32 gid, + gid_t gid, uint32 group_rid) { fstring username; -- cgit From 340ab6a256802a22c11b7f707748397249075b65 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 13 Jul 2008 12:07:40 +0200 Subject: idmap rewrite (This used to be commit 30a180f2fce8cf6a3e5548f6bba453272ba70b33) --- source3/winbindd/winbindd_user.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/winbindd/winbindd_user.c') diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index 00e53eff74..3b6dfdda1c 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -79,7 +79,8 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name, /* Resolve the uid number */ - if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_uid(dom_name, user_sid, + &pw->pw_uid))) { DEBUG(1, ("error getting user id for sid %s\n", sid_string_dbg(user_sid))); return False; @@ -87,7 +88,8 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name, /* Resolve the gid number */ - if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(dom_name, group_sid, + &pw->pw_gid))) { DEBUG(1, ("error getting group id for sid %s\n", sid_string_dbg(group_sid))); return False; -- cgit