pass_check.c

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

C
784
字号
/*    Unix SMB/CIFS implementation.   Password checking   Copyright (C) Andrew Tridgell 1992-1998      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.*//* this module is for checking a username/password against a system   password database. The SMB encrypted password support is elsewhere */#include "includes.h"#undef DBGC_CLASS#define DBGC_CLASS DBGC_AUTH/* these are kept here to keep the string_combinations function simple */static fstring this_user;#if !defined(WITH_PAM) static fstring this_salt;static fstring this_crypted;#endif#ifdef WITH_AFS#include <afs/stds.h>#include <afs/kautils.h>/*******************************************************************check on AFS authentication********************************************************************/static BOOL afs_auth(char *user, char *password){	long password_expires = 0;	char *reason;	/* For versions of AFS prior to 3.3, this routine has few arguments, */	/* but since I can't find the old documentation... :-)               */	setpag();	if (ka_UserAuthenticateGeneral	    (KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG, user, (char *)0,	/* instance */	     (char *)0,		/* cell */	     password, 0,	/* lifetime, default */	     &password_expires,	/*days 'til it expires */	     0,			/* spare 2 */	     &reason) == 0)	{		return (True);	}	DEBUG(1,	      ("AFS authentication for \"%s\" failed (%s)\n", user, reason));	return (False);}#endif#ifdef WITH_DFS#include <dce/dce_error.h>#include <dce/sec_login.h>/***************************************************************** This new version of the DFS_AUTH code was donated by Karsten Muuss <muuss@or.uni-bonn.de>. It fixes the following problems with the old code :  - Server credentials may expire  - Client credential cache files have wrong owner  - purge_context() function is called with invalid argument This new code was modified to ensure that on exit the uid/gid is still root, and the original directory is restored. JRA.******************************************************************/sec_login_handle_t my_dce_sec_context;int dcelogin_atmost_once = 0;/*******************************************************************check on a DCE/DFS authentication********************************************************************/static BOOL dfs_auth(char *user, char *password){	error_status_t err;	int err2;	int prterr;	signed32 expire_time, current_time;	boolean32 password_reset;	struct passwd *pw;	sec_passwd_rec_t passwd_rec;	sec_login_auth_src_t auth_src = sec_login_auth_src_network;	unsigned char dce_errstr[dce_c_error_string_len];	gid_t egid;	if (dcelogin_atmost_once)		return (False);#ifdef HAVE_CRYPT	/*	 * We only go for a DCE login context if the given password	 * matches that stored in the local password file.. 	 * Assumes local passwd file is kept in sync w/ DCE RGY!	 */	if (strcmp((char *)crypt(password, this_salt), this_crypted))	{		return (False);	}#endif	sec_login_get_current_context(&my_dce_sec_context, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE can't get current context. %s\n", dce_errstr));		return (False);	}	sec_login_certify_identity(my_dce_sec_context, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE can't get current context. %s\n", dce_errstr));		return (False);	}	sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE can't get expiration. %s\n", dce_errstr));		return (False);	}	time(&current_time);	if (expire_time < (current_time + 60))	{		struct passwd *pw;		sec_passwd_rec_t *key;		sec_login_get_pwent(my_dce_sec_context,				    (sec_login_passwd_t *) & pw, &err);		if (err != error_status_ok)		{			dce_error_inq_text(err, dce_errstr, &err2);			DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));			return (False);		}		sec_login_refresh_identity(my_dce_sec_context, &err);		if (err != error_status_ok)		{			dce_error_inq_text(err, dce_errstr, &err2);			DEBUG(0, ("DCE can't refresh identity. %s\n",				  dce_errstr));			return (False);		}		sec_key_mgmt_get_key(rpc_c_authn_dce_secret, NULL,				     (unsigned char *)pw->pw_name,				     sec_c_key_version_none,				     (void **)&key, &err);		if (err != error_status_ok)		{			dce_error_inq_text(err, dce_errstr, &err2);			DEBUG(0, ("DCE can't get key for %s. %s\n",				  pw->pw_name, dce_errstr));			return (False);		}		sec_login_valid_and_cert_ident(my_dce_sec_context, key,					       &password_reset, &auth_src,					       &err);		if (err != error_status_ok)		{			dce_error_inq_text(err, dce_errstr, &err2);			DEBUG(0,			      ("DCE can't validate and certify identity for %s. %s\n",			       pw->pw_name, dce_errstr));		}		sec_key_mgmt_free_key(key, &err);		if (err != error_status_ok)		{			dce_error_inq_text(err, dce_errstr, &err2);			DEBUG(0, ("DCE can't free key.\n", dce_errstr));		}	}	if (sec_login_setup_identity((unsigned char *)user,				     sec_login_no_flags,				     &my_dce_sec_context, &err) == 0)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE Setup Identity for %s failed: %s\n",			  user, dce_errstr));		return (False);	}	sec_login_get_pwent(my_dce_sec_context,			    (sec_login_passwd_t *) & pw, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));		return (False);	}	sec_login_purge_context(&my_dce_sec_context, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE can't purge context. %s\n", dce_errstr));		return (False);	}	/*	 * NB. I'd like to change these to call something like change_to_user()	 * instead but currently we don't have a connection	 * context to become the correct user. This is already	 * fairly platform specific code however, so I think	 * this should be ok. I have added code to go	 * back to being root on error though. JRA.	 */	egid = getegid();	set_effective_gid(pw->pw_gid);	set_effective_uid(pw->pw_uid);	if (sec_login_setup_identity((unsigned char *)user,				     sec_login_no_flags,				     &my_dce_sec_context, &err) == 0)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE Setup Identity for %s failed: %s\n",			  user, dce_errstr));		goto err;	}	sec_login_get_pwent(my_dce_sec_context,			    (sec_login_passwd_t *) & pw, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));		goto err;	}	passwd_rec.version_number = sec_passwd_c_version_none;	passwd_rec.pepper = NULL;	passwd_rec.key.key_type = sec_passwd_plain;	passwd_rec.key.tagged_union.plain = (idl_char *) password;	sec_login_validate_identity(my_dce_sec_context,				    &passwd_rec, &password_reset,				    &auth_src, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0,		      ("DCE Identity Validation failed for principal %s: %s\n",		       user, dce_errstr));		goto err;	}	sec_login_certify_identity(my_dce_sec_context, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE certify identity failed: %s\n", dce_errstr));		goto err;	}	if (auth_src != sec_login_auth_src_network)	{		DEBUG(0, ("DCE context has no network credentials.\n"));	}	sec_login_set_context(my_dce_sec_context, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0,		      ("DCE login failed for principal %s, cant set context: %s\n",		       user, dce_errstr));		sec_login_purge_context(&my_dce_sec_context, &err);		goto err;	}	sec_login_get_pwent(my_dce_sec_context,			    (sec_login_passwd_t *) & pw, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));		goto err;	}	DEBUG(0, ("DCE login succeeded for principal %s on pid %d\n",		  user, sys_getpid()));	DEBUG(3, ("DCE principal: %s\n"		  "          uid: %d\n"		  "          gid: %d\n",		  pw->pw_name, pw->pw_uid, pw->pw_gid));	DEBUG(3, ("         info: %s\n"		  "          dir: %s\n"		  "        shell: %s\n",		  pw->pw_gecos, pw->pw_dir, pw->pw_shell));	sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0, ("DCE can't get expiration. %s\n", dce_errstr));		goto err;	}	set_effective_uid(0);	set_effective_gid(0);	DEBUG(0,	      ("DCE context expires: %s", asctime(localtime(&expire_time))));	dcelogin_atmost_once = 1;	return (True);      err:	/* Go back to root, JRA. */	set_effective_uid(0);	set_effective_gid(egid);	return (False);}void dfs_unlogin(void){	error_status_t err;	int err2;	unsigned char dce_errstr[dce_c_error_string_len];	sec_login_purge_context(&my_dce_sec_context, &err);	if (err != error_status_ok)	{		dce_error_inq_text(err, dce_errstr, &err2);		DEBUG(0,		      ("DCE purge login context failed for server instance %d: %s\n",		       sys_getpid(), dce_errstr));	}}#endif#ifdef LINUX_BIGCRYPT/****************************************************************************an enhanced crypt for Linux to handle password longer than 8 characters****************************************************************************/static int linux_bigcrypt(char *password, char *salt1, char *crypted){#define LINUX_PASSWORD_SEG_CHARS 8	char salt[3];	int i;	StrnCpy(salt, salt1, 2);	crypted += 2;	for (i = strlen(password); i > 0; i -= LINUX_PASSWORD_SEG_CHARS) {		char *p = crypt(password, salt) + 2;		if (strncmp(p, crypted, LINUX_PASSWORD_SEG_CHARS) != 0)			return (0);		password += LINUX_PASSWORD_SEG_CHARS;

⌨️ 快捷键说明

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