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 + -
显示快捷键?