winbindd_user.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 820 行 · 第 1/2 页
C
820 行
/* 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"#include "winbindd.h"#undef DBGC_CLASS#define DBGC_CLASS DBGC_WINBINDextern userdom_struct current_user_info;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; if (in && !strequal(in,"") && lp_security() == SEC_ADS && use_nss_info("sfu")) { safe_strcpy(out, in, sizeof(fstring) - 1); return True; } /* Home directory and shell - use template config parameters. The defaults are /tmp for the home directory and /bin/false for shell. */ /* The substitution of %U and %D in the 'template homedir' is done by alloc_sub_specified() below. */ templ = alloc_sub_specified(lp_template, username, domname, uid, gid); if (!templ) return False; safe_strcpy(out, templ, sizeof(fstring) - 1); SAFE_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, 0))) { 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, 0))) { 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); 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 - use template config parameters. The defaults are /tmp for the home directory and /bin/false for shell. */ /* The substitution of %U and %D in the 'template homedir' is done by alloc_sub_specified() below. */ fstrcpy(current_user_info.domain, 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, pw->pw_uid, pw->pw_gid, shell, pw->pw_shell)) return False; /* Password - set to "x" as we can't generate anything useful here. Authentication can be done using the pam_winbind module. */ safe_strcpy(pw->pw_passwd, "x", 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); 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 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_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 group_rid){ fstring username; struct getpwsid_state *s = talloc_get_type_abort(private_data, struct getpwsid_state); if (!success) { DEBUG(5, ("Could not query user %s\\%s\n", s->domain->name, s->username)); request_error(s->state); return; } fstrcpy( username, acct_name ); strlower_m( username ); s->username = talloc_strdup(s->state->mem_ctx, username); 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); 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 user's %s\\%s uid\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; if (!success) { DEBUG(5, ("Could not query user's %s\\%s\n gid", s->domain->name, s->username)); goto failed; } 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); safe_strcpy(pw->pw_name, output_username, sizeof(pw->pw_name) - 1); safe_strcpy(pw->pw_gecos, s->fullname, sizeof(pw->pw_gecos) - 1); fstrcpy(current_user_info.domain, s->domain->name); 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 "x" as we can't generate anything useful here. Authentication can be done using the pam_winbind module. */ safe_strcpy(pw->pw_passwd, "x", 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 SID_NAME_USE 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)); if (!parse_domain_user(state->request.data.username, domname, username)) { DEBUG(0, ("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\n", domname)); 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, state);}static void getpwnam_name2sid_recv(void *private_data, BOOL success, const DOM_SID *sid, enum SID_NAME_USE type){ struct winbindd_cli_state *state = private_data; 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; } winbindd_getpwsid(state, sid);}/* Return a password structure given a uid number */void winbindd_getpwuid(struct winbindd_cli_state *state){ DOM_SID user_sid; NTSTATUS status; /* Bug out if the uid isn't in the winbind range */ if ((state->request.data.uid < server_state.uid_low ) || (state->request.data.uid > server_state.uid_high)) { request_error(state); return; } DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid, (unsigned long)state->request.data.uid)); status = idmap_uid_to_sid(&user_sid, state->request.data.uid, ID_QUERY_ONLY | ID_CACHE_ONLY);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?