auth_util.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,706 行 · 第 1/4 页

C
1,706
字号
	return nt_status;}/*************************************************************************** Make (and fill) a user_info struct from a SAM_ACCOUNT***************************************************************************/NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, 			      SAM_ACCOUNT *sampass){	NTSTATUS nt_status;	struct passwd *pwd;	if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))		return nt_status;	(*server_info)->sam_account    = sampass;	if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) )  {		DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",			  pdb_get_username(sampass)));		free_server_info(server_info);		return NT_STATUS_NO_SUCH_USER;	}	(*server_info)->unix_name = smb_xstrdup(pwd->pw_name);	(*server_info)->gid = pwd->pw_gid;	(*server_info)->uid = pwd->pw_uid;		passwd_free(&pwd);	if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass), 							 sampass,							 (*server_info)->uid, 							 (*server_info)->gid))) 	{		free_server_info(server_info);		return nt_status;	}	(*server_info)->sam_fill_level = SAM_FILL_ALL;	DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",		 pdb_get_username(sampass),		 (*server_info)->unix_name));	return nt_status;}/*************************************************************************** Make (and fill) a user_info struct from a Kerberos PAC logon_info by conversion  to a SAM_ACCOUNT***************************************************************************/NTSTATUS make_server_info_pac(auth_serversupplied_info **server_info, 			      char *unix_username,			      struct passwd *pwd,			      PAC_LOGON_INFO *logon_info){	NTSTATUS nt_status;	SAM_ACCOUNT *sampass = NULL;	DOM_SID user_sid, group_sid;	fstring dom_name;	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {				return nt_status;	}	if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {		return nt_status;	}	/* only copy user_sid, group_sid and domain name out of the PAC for	 * now, we will benefit from more later - Guenther */	sid_copy(&user_sid, &logon_info->info3.dom_sid.sid);	sid_append_rid(&user_sid, logon_info->info3.user_rid);	pdb_set_user_sid(sampass, &user_sid, PDB_SET);		sid_copy(&group_sid, &logon_info->info3.dom_sid.sid);	sid_append_rid(&group_sid, logon_info->info3.group_rid);	pdb_set_group_sid(sampass, &group_sid, PDB_SET);	unistr2_to_ascii(dom_name, &logon_info->info3.uni_logon_dom, -1);	pdb_set_domain(sampass, dom_name, PDB_SET);	pdb_set_logon_count(sampass, logon_info->info3.logon_count, PDB_SET);	(*server_info)->sam_account    = sampass;	if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,		sampass, pwd->pw_uid, pwd->pw_gid))) 	{		return nt_status;	}	(*server_info)->unix_name = smb_xstrdup(unix_username);	(*server_info)->sam_fill_level = SAM_FILL_ALL;	(*server_info)->uid = pwd->pw_uid;	(*server_info)->gid = pwd->pw_gid;	return nt_status;}/*************************************************************************** Make (and fill) a user_info struct from a 'struct passwd' by conversion  to a SAM_ACCOUNT***************************************************************************/NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,                              char *unix_username,			     struct passwd *pwd){	NTSTATUS nt_status;	SAM_ACCOUNT *sampass = NULL;	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {				return nt_status;	}	if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {		return nt_status;	}	(*server_info)->sam_account    = sampass;	if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,		sampass, pwd->pw_uid, pwd->pw_gid))) 	{		return nt_status;	}	(*server_info)->unix_name = smb_xstrdup(unix_username);	(*server_info)->sam_fill_level = SAM_FILL_ALL;	(*server_info)->uid = pwd->pw_uid;	(*server_info)->gid = pwd->pw_gid;	return nt_status;}/*************************************************************************** Make (and fill) a user_info struct for a guest login.***************************************************************************/static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info){	NTSTATUS nt_status;	SAM_ACCOUNT *sampass = NULL;	DOM_SID guest_sid;	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) {		return nt_status;	}	sid_copy(&guest_sid, get_global_sam_sid());	sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);	become_root();	if (!pdb_getsampwsid(sampass, &guest_sid)) {		unbecome_root();		return NT_STATUS_NO_SUCH_USER;	}	unbecome_root();	nt_status = make_server_info_sam(server_info, sampass);	if (NT_STATUS_IS_OK(nt_status)) {		static const char zeros[16];		(*server_info)->guest = True;				/* annoying, but the Guest really does have a session key, 		   and it is all zeros! */		(*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));		(*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));	}	return nt_status;}static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src){	auth_serversupplied_info *dst;	if (!NT_STATUS_IS_OK(make_server_info(&dst)))		return NULL;	dst->guest = src->guest;	dst->uid = src->uid;	dst->gid = src->gid;	dst->n_groups = src->n_groups;	if (src->n_groups != 0)		dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups);	else		dst->groups = NULL;	dst->ptok = dup_nt_token(src->ptok);	dst->user_session_key = data_blob(src->user_session_key.data,					  src->user_session_key.length);	dst->lm_session_key = data_blob(src->lm_session_key.data,					  src->lm_session_key.length);	pdb_copy_sam_account(src->sam_account, &dst->sam_account);	dst->pam_handle = NULL;	dst->unix_name = smb_xstrdup(src->unix_name);	return dst;}static auth_serversupplied_info *guest_info = NULL;BOOL init_guest_info(void){	if (guest_info != NULL)		return True;	return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));}NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info){	*server_info = copy_serverinfo(guest_info);	return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;}/*************************************************************************** Purely internal function for make_server_info_info3 Fill the sam account from getpwnam***************************************************************************/static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 				 const char *domain,				 const char *username,				 char **found_username,				 uid_t *uid, gid_t *gid,				 SAM_ACCOUNT **sam_account){	NTSTATUS nt_status;	fstring dom_user, lower_username;	fstring real_username;	struct passwd *passwd;	fstrcpy( lower_username, username );	strlower_m( lower_username );	fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 		lower_username);	/* get the passwd struct but don't create the user if he/she 	   does not exist.  We were explicitly called from a following	   a winbindd authentication request so we should assume that 	   nss_winbindd is working */	map_username( dom_user );	if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) )		return NT_STATUS_NO_SUCH_USER;	*uid = passwd->pw_uid;	*gid = passwd->pw_gid;	/* This is pointless -- there is no suport for differing 	   unix and windows names.  Make sure to always store the 	   one we actually looked up and succeeded. Have I mentioned	   why I hate the 'winbind use default domain' parameter?   	                                 --jerry              */	   	*found_username = talloc_strdup( mem_ctx, real_username );		DEBUG(5,("fill_sam_account: located username was [%s]\n",		*found_username));	nt_status = pdb_init_sam_pw(sam_account, passwd);	passwd_free(&passwd);	return nt_status;}/**************************************************************************** Wrapper to allow the getpwnam() call to strip the domain name and  try again in case a local UNIX user is already there.  Also run through  the username if we fallback to the username only. ****************************************************************************/ struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create ){	struct passwd *pw = NULL;	char *p;	fstring username;		/* we only save a copy of the username it has been mangled 	   by winbindd use default domain */	   	save_username[0] = '\0';	   	/* don't call map_username() here since it has to be done higher 	   up the stack so we don't call it mutliple times */	fstrcpy( username, domuser );		p = strchr_m( username, *lp_winbind_separator() );		/* code for a DOMAIN\user string */		if ( p ) {		fstring strip_username;		pw = Get_Pwnam_alloc( domuser );		if ( pw ) {				/* make sure we get the case of the username correct */			/* work around 'winbind use default domain = yes' */			if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {				char *domain;								/* split the domain and username into 2 strings */				*p = '\0';				domain = username;				fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);			}			else				fstrcpy( save_username, pw->pw_name );			/* whew -- done! */					return pw;		}		/* setup for lookup of just the username */		/* remember that p and username are overlapping memory */		p++;		fstrcpy( strip_username, p );		fstrcpy( username, strip_username );	}		/* just lookup a plain username */		pw = Get_Pwnam_alloc(username);			/* Create local user if requested. */		if ( !pw && create ) {		/* Don't add a machine account. */		if (username[strlen(username)-1] == '$')			return NULL;		smb_create_user(NULL, username, NULL);		pw = Get_Pwnam_alloc(username);	}		/* one last check for a valid passwd struct */		if ( pw )		fstrcpy( save_username, pw->pw_name );	return pw;}/*************************************************************************** Make a server_info struct from the info3 returned by a domain logon ***************************************************************************/NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 				const char *internal_username,				const char *sent_nt_username,				const char *domain,				auth_serversupplied_info **server_info, 				NET_USER_INFO_3 *info3) {	static const char zeros[16];	NTSTATUS nt_status = NT_STATUS_OK;	char *found_username;	const char *nt_domain;	const char *nt_username;	SAM_ACCOUNT *sam_account = NULL;	DOM_SID user_sid;	DOM_SID group_sid;	uid_t uid;	gid_t gid;	size_t n_lgroupSIDs;	DOM_SID *lgroupSIDs   = NULL;	gid_t *unix_groups = NULL;	NT_USER_TOKEN *token;	DOM_SID *all_group_SIDs;	size_t i;	/* 	   Here is where we should check the list of	   trusted domains, and verify that the SID 	   matches.	*/	sid_copy(&user_sid, &info3->dom_sid.sid);	if (!sid_append_rid(&user_sid, info3->user_rid)) {		return NT_STATUS_INVALID_PARAMETER;	}		sid_copy(&group_sid, &info3->dom_sid.sid);	if (!sid_append_rid(&group_sid, info3->group_rid)) {		return NT_STATUS_INVALID_PARAMETER;	}	if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {		/* If the server didn't give us one, just use the one we sent them */		nt_username = sent_nt_username;	}	if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {		/* If the server didn't give us one, just use the one we sent them */		nt_domain = domain;	}		/* try to fill the SAM account..  If getpwnam() fails, then try the 	   add user script (2.2.x behavior).	   We use the _unmapped_ username here in an attempt to provide	   consistent username mapping behavior between kerberos and NTLM[SSP]	   authentication in domain mode security.  I.E. Username mapping should	   be applied to the fully qualified username (e.g. DOMAIN\user) and	   no just the login name.  Yes this mean swe called map_username()	   unnecessarily in make_user_info_map() but that is how the current	   code is designed.  Making the change here is the least disruptive 	   place.    -- jerry */	   	nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,		&found_username, &uid, &gid, &sam_account);	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?