auth_util.c

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

C
1,706
字号
/*   Unix SMB/CIFS implementation.   Authentication utility functions   Copyright (C) Andrew Tridgell 1992-1998   Copyright (C) Andrew Bartlett 2001   Copyright (C) Jeremy Allison 2000-2001   Copyright (C) Rafal Szczesniak 2002   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_AUTH/**************************************************************************** Create a UNIX user on demand.****************************************************************************/static int smb_create_user(const char *domain, const char *unix_username, const char *homedir){	pstring add_script;	int ret;	pstrcpy(add_script, lp_adduser_script());	if (! *add_script)		return -1;	all_string_sub(add_script, "%u", unix_username, sizeof(pstring));	if (domain)		all_string_sub(add_script, "%D", domain, sizeof(pstring));	if (homedir)		all_string_sub(add_script, "%H", homedir, sizeof(pstring));	ret = smbrun(add_script,NULL);	flush_pwnam_cache();	DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));	return ret;}/**************************************************************************** Create an auth_usersupplied_data structure****************************************************************************/static NTSTATUS make_user_info(auth_usersupplied_info **user_info,                                const char *smb_name,                                const char *internal_username,                               const char *client_domain,                                const char *domain,                               const char *wksta_name,                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,                               DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,                               DATA_BLOB *plaintext,                                BOOL encrypted){	DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));	*user_info = SMB_MALLOC_P(auth_usersupplied_info);	if (!user_info) {		DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));		return NT_STATUS_NO_MEMORY;	}	ZERO_STRUCTP(*user_info);	DEBUG(5,("making strings for %s's user_info struct\n", internal_username));	(*user_info)->smb_name.str = SMB_STRDUP(smb_name);	if ((*user_info)->smb_name.str) { 		(*user_info)->smb_name.len = strlen(smb_name);	} else {		free_user_info(user_info);		return NT_STATUS_NO_MEMORY;	}		(*user_info)->internal_username.str = SMB_STRDUP(internal_username);	if ((*user_info)->internal_username.str) { 		(*user_info)->internal_username.len = strlen(internal_username);	} else {		free_user_info(user_info);		return NT_STATUS_NO_MEMORY;	}	(*user_info)->domain.str = SMB_STRDUP(domain);	if ((*user_info)->domain.str) { 		(*user_info)->domain.len = strlen(domain);	} else {		free_user_info(user_info);		return NT_STATUS_NO_MEMORY;	}	(*user_info)->client_domain.str = SMB_STRDUP(client_domain);	if ((*user_info)->client_domain.str) { 		(*user_info)->client_domain.len = strlen(client_domain);	} else {		free_user_info(user_info);		return NT_STATUS_NO_MEMORY;	}	(*user_info)->wksta_name.str = SMB_STRDUP(wksta_name);	if ((*user_info)->wksta_name.str) { 		(*user_info)->wksta_name.len = strlen(wksta_name);	} else {		free_user_info(user_info);		return NT_STATUS_NO_MEMORY;	}	DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));	if (lm_pwd)		(*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);	if (nt_pwd)		(*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);	if (lm_interactive_pwd)		(*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);	if (nt_interactive_pwd)		(*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);	if (plaintext)		(*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);	(*user_info)->encrypted = encrypted;	(*user_info)->logon_parameters = 0;	DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));	return NT_STATUS_OK;}/**************************************************************************** Create an auth_usersupplied_data structure after appropriate mapping.****************************************************************************/NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, 			    const char *smb_name, 			    const char *client_domain, 			    const char *wksta_name,  			    DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd, 			    DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,			    DATA_BLOB *plaintext, 			    BOOL encrypted){	const char *domain;	fstring internal_username;	fstrcpy(internal_username, smb_name);	map_username(internal_username); 		DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",	      client_domain, smb_name, wksta_name));		/* don't allow "" as a domain, fixes a Win9X bug 	   where it doens't supply a domain for logon script	   'net use' commands.                                 */	if ( *client_domain )		domain = client_domain;	else		domain = lp_workgroup();	/* do what win2k does.  Always map unknown domains to our own	   and let the "passdb backend" handle unknown users. */	if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) 		domain = get_default_sam_name();		/* we know that it is a trusted domain (and we are allowing them) or it is our domain */		return make_user_info(user_info, smb_name, internal_username, 			      client_domain, domain, wksta_name, 			      lm_pwd, nt_pwd,			      lm_interactive_pwd, nt_interactive_pwd,			      plaintext, encrypted);}/**************************************************************************** Create an auth_usersupplied_data, making the DATA_BLOBs here.  Decrypt and encrypt the passwords.****************************************************************************/BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 				     const char *smb_name, 				     const char *client_domain, 				     const char *wksta_name, 				     uint32 logon_parameters,				     const uchar *lm_network_pwd, int lm_pwd_len,				     const uchar *nt_network_pwd, int nt_pwd_len){	BOOL ret;	NTSTATUS nt_status;	DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);	DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);	nt_status = make_user_info_map(user_info,				       smb_name, client_domain, 				       wksta_name, 				       lm_pwd_len ? &lm_blob : NULL, 				       nt_pwd_len ? &nt_blob : NULL,				       NULL, NULL, NULL,				       True);	if (NT_STATUS_IS_OK(nt_status)) {		(*user_info)->logon_parameters = logon_parameters;	}	ret = NT_STATUS_IS_OK(nt_status) ? True : False;	data_blob_free(&lm_blob);	data_blob_free(&nt_blob);	return ret;}/**************************************************************************** Create an auth_usersupplied_data, making the DATA_BLOBs here.  Decrypt and encrypt the passwords.****************************************************************************/BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 					 const char *smb_name, 					 const char *client_domain, 					 const char *wksta_name, 					 uint32 logon_parameters,					 const uchar chal[8], 					 const uchar lm_interactive_pwd[16], 					 const uchar nt_interactive_pwd[16], 					 const uchar *dc_sess_key){	char lm_pwd[16];	char nt_pwd[16];	unsigned char local_lm_response[24];	unsigned char local_nt_response[24];	unsigned char key[16];		ZERO_STRUCT(key);	memcpy(key, dc_sess_key, 8);		if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));	if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));	#ifdef DEBUG_PASSWORD	DEBUG(100,("key:"));	dump_data(100, (char *)key, sizeof(key));		DEBUG(100,("lm owf password:"));	dump_data(100, lm_pwd, sizeof(lm_pwd));		DEBUG(100,("nt owf password:"));	dump_data(100, nt_pwd, sizeof(nt_pwd));#endif		if (lm_interactive_pwd)		SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd));		if (nt_interactive_pwd)		SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd));	#ifdef DEBUG_PASSWORD	DEBUG(100,("decrypt of lm owf password:"));	dump_data(100, lm_pwd, sizeof(lm_pwd));		DEBUG(100,("decrypt of nt owf password:"));	dump_data(100, nt_pwd, sizeof(nt_pwd));#endif		if (lm_interactive_pwd)		SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);	if (nt_interactive_pwd)		SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);		/* Password info paranoia */	ZERO_STRUCT(key);	{		BOOL ret;		NTSTATUS nt_status;		DATA_BLOB local_lm_blob;		DATA_BLOB local_nt_blob;		DATA_BLOB lm_interactive_blob;		DATA_BLOB nt_interactive_blob;				if (lm_interactive_pwd) {			local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));			lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd));			ZERO_STRUCT(lm_pwd);		}				if (nt_interactive_pwd) {			local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));			nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd));			ZERO_STRUCT(nt_pwd);		}		nt_status = make_user_info_map(user_info, 		                               smb_name, client_domain, 		                               wksta_name, 		                               lm_interactive_pwd ? &local_lm_blob : NULL,		                               nt_interactive_pwd ? &local_nt_blob : NULL,		                               lm_interactive_pwd ? &lm_interactive_blob : NULL,		                               nt_interactive_pwd ? &nt_interactive_blob : NULL,		                               NULL,		                               True);		if (NT_STATUS_IS_OK(nt_status)) {			(*user_info)->logon_parameters = logon_parameters;		}		ret = NT_STATUS_IS_OK(nt_status) ? True : False;		data_blob_free(&local_lm_blob);		data_blob_free(&local_nt_blob);		data_blob_free(&lm_interactive_blob);		data_blob_free(&nt_interactive_blob);		return ret;	}}/**************************************************************************** Create an auth_usersupplied_data structure****************************************************************************/BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 			      const char *smb_name, 			      const char *client_domain,			      const uint8 chal[8],			      DATA_BLOB plaintext_password){	DATA_BLOB local_lm_blob;	DATA_BLOB local_nt_blob;	NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;				/*	 * Not encrypted - do so.	 */		DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));		if (plaintext_password.data) {		unsigned char local_lm_response[24];		#ifdef DEBUG_PASSWORD		DEBUG(10,("Unencrypted password (len %d):\n",(int)plaintext_password.length));		dump_data(100, (const char *)plaintext_password.data, plaintext_password.length);#endif		SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response);		local_lm_blob = data_blob(local_lm_response, 24);				/* We can't do an NT hash here, as the password needs to be		   case insensitive */		local_nt_blob = data_blob(NULL, 0); 			} else {		local_lm_blob = data_blob(NULL, 0); 		local_nt_blob = data_blob(NULL, 0); 	}		ret = make_user_info_map(user_info, smb_name,	                         client_domain, 	                         get_remote_machine_name(),	                         local_lm_blob.data ? &local_lm_blob : NULL,	                         local_nt_blob.data ? &local_nt_blob : NULL,				 NULL, NULL,	                         plaintext_password.data ? &plaintext_password : NULL, 	                         False);		data_blob_free(&local_lm_blob);	return NT_STATUS_IS_OK(ret) ? True : False;}/**************************************************************************** Create an auth_usersupplied_data structure****************************************************************************/NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,                                       const char *smb_name,                                      const char *client_domain,                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp){	return make_user_info_map(user_info, smb_name, 				  client_domain, 				  get_remote_machine_name(), 				  lm_resp.data ? &lm_resp : NULL, 				  nt_resp.data ? &nt_resp : NULL, 				  NULL, NULL, NULL,				  True);}/**************************************************************************** Create a guest user_info blob, for anonymous authenticaion.****************************************************************************/BOOL make_user_info_guest(auth_usersupplied_info **user_info) {	NTSTATUS nt_status;	nt_status = make_user_info(user_info, 				   "","", 				   "","", 				   "", 				   NULL, NULL, 				   NULL, NULL, 				   NULL,				   True);			      	return NT_STATUS_IS_OK(nt_status) ? True : False;}/**************************************************************************** prints a NT_USER_TOKEN to debug output.****************************************************************************/void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)

⌨️ 快捷键说明

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