⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 passdb.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    Unix SMB/CIFS implementation.   Password and authentication handling   Copyright (C) Jeremy Allison 		1996-2001   Copyright (C) Luke Kenneth Casson Leighton 	1996-1998   Copyright (C) Gerald (Jerry) Carter		2000-2001   Copyright (C) Andrew Bartlett		2001-2002   Copyright (C) Simo Sorce			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"#undef DBGC_CLASS#define DBGC_CLASS DBGC_PASSDB/****************************************************************** get the default domain/netbios name to be used when  testing authentication.  For example, if you connect to a Windows member server using a bogus domain name, the Windows box will map the BOGUS\user to DOMAIN\user.  A  standalone box will map to WKS\user.******************************************************************/const char *get_default_sam_name(void){	/* standalone servers can only use the local netbios name */	if ( lp_server_role() == ROLE_STANDALONE )		return global_myname();	/* Windows domain members default to the DOMAIN	   name when not specified */	return lp_workgroup();}/************************************************************ Fill the SAM_ACCOUNT with default values. ***********************************************************/void pdb_fill_default_sam(SAM_ACCOUNT *user){	ZERO_STRUCT(user->private_u); /* Don't touch the talloc context */	/* no initial methods */	user->methods = NULL;        /* Don't change these timestamp settings without a good reason.           They are important for NT member server compatibility. */	user->private_u.logon_time            = (time_t)0;	user->private_u.pass_last_set_time    = (time_t)0;	user->private_u.pass_can_change_time  = (time_t)0;	user->private_u.logoff_time           = 	user->private_u.kickoff_time          = 	user->private_u.pass_must_change_time = get_time_t_max();	user->private_u.fields_present        = 0x00ffffff;	user->private_u.logon_divs = 168; 	/* hours per week */	user->private_u.hours_len = 21; 		/* 21 times 8 bits = 168 */	memset(user->private_u.hours, 0xff, user->private_u.hours_len); /* available at all hours */	user->private_u.bad_password_count = 0;	user->private_u.logon_count = 0;	user->private_u.unknown_6 = 0x000004ec; /* don't know */	/* Some parts of samba strlen their pdb_get...() returns, 	   so this keeps the interface unchanged for now. */	   	user->private_u.username = "";	user->private_u.domain = "";	user->private_u.nt_username = "";	user->private_u.full_name = "";	user->private_u.home_dir = "";	user->private_u.logon_script = "";	user->private_u.profile_path = "";	user->private_u.acct_desc = "";	user->private_u.workstations = "";	user->private_u.unknown_str = "";	user->private_u.munged_dial = "";	user->private_u.plaintext_pw = NULL;	/* 	   Unless we know otherwise have a Account Control Bit	   value of 'normal user'.  This helps User Manager, which	   asks for a filtered list of users.	*/	user->private_u.acct_ctrl = ACB_NORMAL;}	static void destroy_pdb_talloc(SAM_ACCOUNT **user) {	if (*user) {		data_blob_clear_free(&((*user)->private_u.lm_pw));		data_blob_clear_free(&((*user)->private_u.nt_pw));		if((*user)->private_u.plaintext_pw!=NULL)			memset((*user)->private_u.plaintext_pw,'\0',strlen((*user)->private_u.plaintext_pw));		talloc_destroy((*user)->mem_ctx);		*user = NULL;	}}/********************************************************************** Allocates memory and initialises a struct sam_passwd on supplied mem_ctx.***********************************************************************/NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user){	if (*user != NULL) {		DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));#if 0		smb_panic("non-NULL pointer passed to pdb_init_sam\n");#endif		return NT_STATUS_UNSUCCESSFUL;	}	if (!mem_ctx) {		DEBUG(0,("pdb_init_sam_talloc: mem_ctx was NULL!\n"));		return NT_STATUS_UNSUCCESSFUL;	}	*user=TALLOC_P(mem_ctx, SAM_ACCOUNT);	if (*user==NULL) {		DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));		return NT_STATUS_NO_MEMORY;	}	(*user)->mem_ctx = mem_ctx;	(*user)->free_fn = NULL;	pdb_fill_default_sam(*user);		return NT_STATUS_OK;}/************************************************************* Allocates memory and initialises a struct sam_passwd. ************************************************************/NTSTATUS pdb_init_sam(SAM_ACCOUNT **user){	TALLOC_CTX *mem_ctx;	NTSTATUS nt_status;		mem_ctx = talloc_init("passdb internal SAM_ACCOUNT allocation");	if (!mem_ctx) {		DEBUG(0,("pdb_init_sam: error while doing talloc_init()\n"));		return NT_STATUS_NO_MEMORY;	}	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, user))) {		talloc_destroy(mem_ctx);		return nt_status;	}		(*user)->free_fn = destroy_pdb_talloc;	return NT_STATUS_OK;}/************************************************************************** * This function will take care of all the steps needed to correctly * allocate and set the user SID, please do use this function to create new * users, messing with SIDs is not good. * * account_data must be provided initialized, pwd may be null. * 									SSS ***************************************************************************/static NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd){	const char *guest_account = lp_guestaccount();	GROUP_MAP map;	BOOL ret;		if (!account_data || !pwd) {		return NT_STATUS_INVALID_PARAMETER;	}	/* this is a hack this thing should not be set	   this way --SSS */	if (!(guest_account && *guest_account)) {		DEBUG(1, ("NULL guest account!?!?\n"));		return NT_STATUS_UNSUCCESSFUL;	} else {		/* Ensure this *must* be set right */		if (strcmp(pwd->pw_name, guest_account) == 0) {			if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) {				return NT_STATUS_UNSUCCESSFUL;			}			if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) {				return NT_STATUS_UNSUCCESSFUL;			}			return NT_STATUS_OK;		}	}	if (!pdb_set_user_sid_from_rid(account_data, algorithmic_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) {		DEBUG(0,("Can't set User SID from RID!\n"));		return NT_STATUS_INVALID_PARAMETER;	}		/* call the mapping code here */	become_root();	ret = pdb_getgrgid(&map, pwd->pw_gid);	unbecome_root();		if( ret ) {		if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){			DEBUG(0,("Can't set Group SID!\n"));			return NT_STATUS_INVALID_PARAMETER;		}	} 	else {		if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) {			DEBUG(0,("Can't set Group SID\n"));			return NT_STATUS_INVALID_PARAMETER;		}	}	return NT_STATUS_OK;}/************************************************************* Initialises a struct sam_passwd with sane values. ************************************************************/NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd){	NTSTATUS ret;	if (!pwd) {		return NT_STATUS_UNSUCCESSFUL;	}	pdb_fill_default_sam(sam_account);	pdb_set_username(sam_account, pwd->pw_name, PDB_SET);	pdb_set_fullname(sam_account, pwd->pw_gecos, PDB_SET);	pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET);	pdb_set_domain (sam_account, get_global_sam_name(), PDB_DEFAULT);		/* When we get a proper uid -> SID and SID -> uid allocation	   mechinism, we should call it here.  	   	   We can't just set this to 0 or allow it only to be filled	   in when added to the backend, because the user's SID 	   may already be in security descriptors etc.	   	   -- abartlet 11-May-02	*/	ret = pdb_set_sam_sids(sam_account, pwd);	if (!NT_STATUS_IS_OK(ret)) return ret;	/* check if this is a user account or a machine account */	if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')	{		pdb_set_profile_path(sam_account, 				     talloc_sub_specified((sam_account)->mem_ctx, 							    lp_logon_path(), 							    pwd->pw_name, global_myname(), 							    pwd->pw_uid, pwd->pw_gid), 				     PDB_DEFAULT);				pdb_set_homedir(sam_account, 				talloc_sub_specified((sam_account)->mem_ctx, 						       lp_logon_home(),						       pwd->pw_name, global_myname(), 						       pwd->pw_uid, pwd->pw_gid),				PDB_DEFAULT);				pdb_set_dir_drive(sam_account, 				  talloc_sub_specified((sam_account)->mem_ctx, 							 lp_logon_drive(),							 pwd->pw_name, global_myname(), 							 pwd->pw_uid, pwd->pw_gid),				  PDB_DEFAULT);				pdb_set_logon_script(sam_account, 				     talloc_sub_specified((sam_account)->mem_ctx, 							    lp_logon_script(),							    pwd->pw_name, global_myname(), 							    pwd->pw_uid, pwd->pw_gid), 				     PDB_DEFAULT);		if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) {			DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n", pwd->pw_name));			return NT_STATUS_UNSUCCESSFUL;		}	} else {		if (!pdb_set_acct_ctrl(sam_account, ACB_WSTRUST, PDB_DEFAULT)) {			DEBUG(1, ("Failed to set 'trusted workstation account' flags for user %s.\n", pwd->pw_name));			return NT_STATUS_UNSUCCESSFUL;		}	}	return NT_STATUS_OK;}/************************************************************* Initialises a struct sam_passwd with sane values. ************************************************************/NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd){	NTSTATUS nt_status;	if (!pwd) {		new_sam_acct = NULL;		return NT_STATUS_INVALID_PARAMETER;	}	if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {		new_sam_acct = NULL;		return nt_status;	}	if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {		pdb_free_sam(new_sam_acct);		new_sam_acct = NULL;		return nt_status;	}	return NT_STATUS_OK;}/************************************************************* Initialises a SAM_ACCOUNT ready to add a new account, based on the UNIX user.  Pass in a RID if you have one ************************************************************/NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username,                          uint32 rid){	NTSTATUS 	nt_status = NT_STATUS_NO_MEMORY;	struct passwd 	*pwd;	BOOL		ret;		pwd = Get_Pwnam(username);	if (!pwd) 		return NT_STATUS_NO_SUCH_USER;		if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(new_sam_acct, pwd))) {		*new_sam_acct = NULL;		return nt_status;	}		/* see if we need to generate a new rid using the 2.2 algorithm */	if ( rid == 0 && lp_enable_rid_algorithm() ) {		DEBUG(10,("pdb_init_sam_new: no RID specified.  Generating one via old algorithm\n"));		rid = algorithmic_pdb_uid_to_user_rid(pwd->pw_uid);	}		/* set the new SID */		ret = pdb_set_user_sid_from_rid( *new_sam_acct, rid, PDB_SET );	 	return (ret ? NT_STATUS_OK : NT_STATUS_NO_SUCH_USER);}/** * Free the contets of the SAM_ACCOUNT, but not the structure. * * Also wipes the LM and NT hashes and plaintext password from  * memory. * * @param user SAM_ACCOUNT to free members of. **/static void pdb_free_sam_contents(SAM_ACCOUNT *user){	/* Kill off sensitive data.  Free()ed by the	   talloc mechinism */	data_blob_clear_free(&(user->private_u.lm_pw));	data_blob_clear_free(&(user->private_u.nt_pw));	if (user->private_u.plaintext_pw!=NULL)		memset(user->private_u.plaintext_pw,'\0',strlen(user->private_u.plaintext_pw));	if (user->private_u.backend_private_data && user->private_u.backend_private_data_free_fn) {		user->private_u.backend_private_data_free_fn(&user->private_u.backend_private_data);	}}/************************************************************ Reset the SAM_ACCOUNT and free the NT/LM hashes. ***********************************************************/NTSTATUS pdb_reset_sam(SAM_ACCOUNT *user){	if (user == NULL) {		DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));#if 0		smb_panic("NULL pointer passed to pdb_free_sam\n");#endif		return NT_STATUS_UNSUCCESSFUL;	}		pdb_free_sam_contents(user);	pdb_fill_default_sam(user);	return NT_STATUS_OK;}/************************************************************ Free the SAM_ACCOUNT and the member pointers. ***********************************************************/NTSTATUS pdb_free_sam(SAM_ACCOUNT **user){	if (*user == NULL) {		DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));#if 0		smb_panic("NULL pointer passed to pdb_free_sam\n");#endif		return NT_STATUS_UNSUCCESSFUL;	}	pdb_free_sam_contents(*user);		if ((*user)->free_fn) {		(*user)->free_fn(user);	}	return NT_STATUS_OK;	}/********************************************************** Encode the account control bits into a string.

⌨️ 快捷键说明

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