diff options
Diffstat (limited to 'source3/winbindd/winbindd_user.c')
-rw-r--r-- | source3/winbindd/winbindd_user.c | 382 |
1 files changed, 1 insertions, 381 deletions
diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index c445ef0bdc..240b0f524f 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, +bool fillup_pw_field(const char *lp_template, const char *username, const char *domname, uid_t uid, @@ -195,386 +195,6 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, 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; - bool username_mapped; -}; - -static void getpwsid_queryuser_recv(void *private_data, bool success, - const char *acct_name, - const char *full_name, - const char *homedir, - const char *shell, - gid_t gid, - uint32 group_rid); -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_queryuser(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_dbg(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, - gid_t gid, - uint32 group_rid) -{ - fstring username; - struct getpwsid_state *s = - talloc_get_type_abort(private_data, struct getpwsid_state); - char *mapped_name; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - if (!success) { - DEBUG(5, ("Could not query domain %s SID %s\n", - s->domain->name, sid_string_dbg(&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_dbg(&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 are 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; - } - - fstrcpy( username, user_name ); - } - - strlower_m( username ); - s->username = talloc_strdup(s->state->mem_ctx, username); - - nt_status = normalize_name_map(s->state->mem_ctx, s->domain, - s->username, &mapped_name); - - /* Basic removal of whitespace */ - if (NT_STATUS_IS_OK(nt_status)) { - s->username = mapped_name; - s->username_mapped = false; - } - /* Complete name replacement */ - else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) { - s->username = mapped_name; - s->username_mapped = true; - } - /* No change at all */ - else { - s->username_mapped = false; - } - - 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; - - /* allow username to be overridden by the alias mapping */ - - if ( s->username_mapped ) { - fstrcpy( output_username, s->username ); - } else { - 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; - char *mapped_user = NULL; - char *domuser; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - - domuser = state->request->data.username; - - /* Ensure null termination (it's an fstring) */ - domuser[sizeof(state->request->data.username)-1] = '\0'; - - DEBUG(3, ("[%5lu]: getpwnam %s\n", - (unsigned long)state->pid, - domuser)); - - nt_status = normalize_name_unmap(state->mem_ctx, domuser, - &mapped_user); - - /* If we could not convert from an aliased name or a - normalized name, then just use the original name */ - - if (!NT_STATUS_IS_OK(nt_status) && - !NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED)) - { - mapped_user = domuser; - } - - if (!parse_domain_user(mapped_user, 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_noinit(domname); - - if (domain == NULL) { - DEBUG(7, ("could not find domain entry for domain %s. " - "Using primary domain\n", domname)); - domain = find_our_domain(); - if (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; - char *domuser = state->request->data.username; - - if (!success) { - 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", domuser)); - request_error(state); - return; - } - - if (parse_domain_user(domuser, domname, username)) { - check_domain_trusted(domname, sid); - } - - getpwsid_queryuser(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)); - - if (!string_to_sid(&user_sid, sid)) { - DEBUG(1,("uid2sid_recv: Could not convert sid %s " - "from string\n,", sid)); - request_error(state); - return; - } - - getpwsid_queryuser(state, &user_sid); -} - -/* Return a password structure given a uid number */ -void winbindd_getpwuid(struct winbindd_cli_state *state) -{ - 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, uid, getpwuid_recv, state); -} - -/* Return a password structure given a sid */ -void winbindd_getpwsid(struct winbindd_cli_state *state) -{ - DOM_SID sid; - - /* Ensure null termination */ - state->request->data.sid[sizeof(state->request->data.sid)-1]='\0'; - - DEBUG(3, ("[%5lu]: getpwsid %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)); - request_error(state); - return; - } - - getpwsid_queryuser(state, &sid); -} - /* * set/get/endpwent functions */ |