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

📄 passwd.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic  char    *sccsid = "@(#)passwd.c	4.5  (ULTRIX)        2/1/91";#endif lint/************************************************************************/************************************************************************ *									* *			Copyright (c) 1988, 1989, 1990, 1991 by		* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * Modification history: * * 07-Aug-90	dlong *	Don't reauthenticate before checking minexp and change_pass.  Also, *	allow root to set any shell. * * 28-Nov-89	dlong *	Catch SIGINT and SIGTERM while echo is turned off.  Don't terminate if *	new password is too long, just warn and truncate. * * 6-Sep-89	dlong *	Fixed usage lines for chfn and chsh. Also, only reopen /dev/tty for *	passwd command. * * 22-Aug-88	dlong *	Check status from GETREQ to prevent infinite looping. * * 18-Aug-89	dlong *	Fixed check for user supplied password privilege when using -e. *	Also, don't issue message to eat password in -ea mode. * * 16-Aug-89	dws *	Added eopt and code to support extended Xprompter protocol. *	Cleaned up code in the fopt code path. * * 14-Aug-89 - Synced up hesupd with passwd * * 9-Aug-89	D. Long *	Do more checking on pasword form (CHECKCHARS).  Use optind for argv[1]. *	Include privileged users on password length checks.  Don't allow chsh *	to work on restricted accounts.  Change SEC_TRANS to SEC_UPGRADE. * * 19-Jul-89 - D. Long *	Set seed random number generator before making salt. */#include <errno.h>#include <sys/file.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/svcinfo.h>#include <ctype.h>#include <stdio.h>#include <signal.h>#include <sgtty.h>#include <strings.h>#include <pwd.h>#include <grp.h>#include <auth.h>#include <netdb.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/un.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/lock.h>#include <netinet/in.h>#include <sys/param.h>#ifdef AUTHEN#include <krb.h>#endif AUTHEN#define	DEFSHELL		"/bin/sh"#define	CHECKCHARS		3#define ENTRY_SIZE		100#define	AUD_BUF_LEN	(SYSCALL_MASK_LEN+TRUSTED_MASK_LEN)#define         PASSCHG         1#define         HESUPD_PORT     800#define         HESUPDACK       6#define         HESUPDNAK       9#define         HESRETRY        3                                                char bindmaster[] = "bindmaster";char defhome[] = "/var/dss/namedb/src";char *homebase = defhome;struct svcinfo *svcp;int root=0;char *index();struct hesupdmsg {                char    newcrypt[64];                int     opcode;                int     hesuid;                char    oldpwd[32];                };                                                                     #define	NUM_CHOICES	5#define	PASSWD_DB	"/etc/passwd"#define	ETCSHELLS	"/etc/shells"extern int min_pw_len, max_pw_len, soft_exp, sec_level;/*  Privileged program for changing a users password.*/char *progname = "passwd";static char salt_table[] =     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";/*  Function to read a password from the users terminal with character  echoing turned off.*/static int setmodes = 0;static struct sgttyb modes;static int flags, fid;static struct passwd *pwd = (struct passwd *) 0;static struct sockaddr remote_hostaddr;static int remote_hostflag = 0;restoremodes(sig, code, scp)int sig, code, *scp;{	if(setmodes) {/*  Restore original tty modes.*/		modes.sg_flags = flags;		ioctl(fid, TIOCSETP, &modes);		setmodes = 0;	}	exit(3);}unsigned char *getpass(prompt)char *prompt;{	int last;	unsigned char *cp;	static unsigned char buff[80];	bzero(buff, sizeof buff);/*  Get the current terminal modes.*/	fid = fileno(stdin);	ioctl(fid, TIOCGETP, &modes);	flags = modes.sg_flags;/*  If echo is on, turn it off, prompt for a password, read the password,  and restore echo mode.*/	if(flags & ECHO) {/*  Turn off echo.*/		setmodes = 1;		modes.sg_flags &= ~ECHO;		ioctl(fid, TIOCSETP, &modes);/*  Prompt for and read the password.*/		fputs(prompt, stdout);		cp = (unsigned char *) fgets(buff, sizeof buff, stdin);/*  Restore original tty modes.*/		modes.sg_flags = flags;		ioctl(fid, TIOCSETP, &modes);		setmodes = 0;	} else {/*  Echo was already off.  Prompt for and read the password.*/		fputs(prompt, stdout);		cp = (unsigned char *) fgets(buff, sizeof buff, stdin);	}	if(cp == NULL)/*  Error reading input.*/		exit(1);/*  Clean up the password.*/	last = strlen(buff) - 1;	if(buff[last] == '\n')		buff[last] = '\0';	return buff;}/*  Function for converting to lower case alphabetics.*/char lcase(c)char c;{	if(c >= 'A' && c <= 'Z')		return c|040;	else		return c;}/* * Function to match a shell name against a pathname. */path_match(path, shell)char *path, *shell;{	char *cp;	cp = strchr(path, '\n');	if(cp)		*cp = '\0';	if(*shell != '/') {		cp = strrchr(path, '/');		if(!cp)			cp = path;		else			cp++;	} else		cp = path;	if(!strcmp(shell, cp)) {		return 1;	}	return 0;}#include "../login.d/proto.h"	/* Extended protocol support.	*/int eopt = 0;			/* Global for error macros. 	*//* * Print an error message. */DO_ERROR(msg)char *msg;{	int i;	if (eopt) {		REQ rbuf, *req = &rbuf;		SENDREQ(req, ERROR, (msg), strlen((msg)));		do {			GETREQ(req, i);			if(i <= 0)				exit(2);		} while (req->opcode != ACKNOWLEDGE);	} else {		fputs((msg), stderr);		fflush(stderr);	}}/* * Print an error message and exit. */#define DO_EXIT(msg, stat) {						\	audevent(msg, stat);						\	DO_ERROR((msg)); 						\	exit(stat);							\}/* * Generate an audit record. */static void audevent(statustr, status)char *statustr;int status;{	char tmask[AUD_NPARAM];	char *aud_arg[AUD_NPARAM];	int i=0;	tmask[i] = T_CHARP;	aud_arg[i++] = progname;	tmask[i] = T_CHARP;	aud_arg[i++] = statustr;/* * Determine if error or result token. */	if(status == 0)		tmask[i] = T_RESULT;	else		tmask[i] = T_ERROR;	aud_arg[i++] = (char *) status;/*	if(remote_hostflag) {		tmask[i] = T_HOSTADDR2;		bcopy(remote_hostaddr.sa_data, aud_arg[i++], sizeof (long));	}*/	if(pwd) {		tmask[i] = T_CHARP;		aud_arg[i++] = pwd->pw_name;		tmask[i] = T_UID2;		aud_arg[i++] = (char *) pwd->pw_uid;	}	tmask[i] = '\0';/* * Generate audit record. */        if(audgen(AUTH_EVENT, tmask, aud_arg) == -1 )		perror("audgen" );}/*  The main program.*/main(argc, argv)int argc;char *argv[];{	extern char *optarg;	extern int optind;	AUTHORIZATION *auth, *getauthuid(), *getauthuid_hesiod();	PASSWORD old_pass, new_pass, gen_password[NUM_CHOICES];	PASSWORD verify;	CRYPT_PASSWORD crypt_pass;	UID user_id, sso_id, our_id, euid;	long period, deadline, now, time();	int i, priv=0, owner=0, fopt=0, sopt=0, aopt=0, ypuid=0;	char string[MAXPATHLEN+1], salt[3], *cp, *getlogin(), passave[9];	unsigned char *cp2;	char hyph_password[MAX_PASSWORD_LENGTH*2], *crypt(), *crypt16();	char user_name[17], *usage;	char *getentry();	unsigned char *s;        static struct hesupdmsg hupmsg;#ifdef	CHECKCHARS	int charset=0;	static char chartab[256];#endif#ifdef AUTHEN	char namebuf[ANAME_SZ];	char *ptr;#endif AUTHEN	struct passwd *getpwnam_bind();	struct group *gp;	int auth_gid;	int hesflg=0; /* set to initially no hesiod stuff */	struct stat stat_buf;	char audit_buf[AUD_BUF_LEN];/* turn off auditing of all events except for AUTH events */	if ( audcntl (SET_PROC_ACNTL, (char *)0, 0, AUDIT_AND, 0) == -1)		perror ( "audcntl" );	A_PROCMASK_SET ( audit_buf, AUTH_EVENT, 1, 1 );	if (audcntl(SET_PROC_AMASK, audit_buf, AUD_BUF_LEN, 0, 0) == -1 )		perror ( "audcntl" );	progname = strrchr(argv[0], '/');	if(progname)		progname++;	else		progname = argv[0];	signal(SIGINT, restoremodes);	signal(SIGTERM, restoremodes);	if(!strcmp(progname, "chfn")) {		optind = 1;		fopt = 1;		usage = "usage: chfn [username]\n";	} else if(!strcmp(progname, "chsh")) {		optind = 1;		sopt = 1;		usage = "usage: chsh [username]\n";	} else {		usage = "usage: passwd [-aefs] [username]\n";		while((i=getopt(argc, argv, "fsae")) != EOF)			switch((char) i) {			case 'f':				fopt = 1;				break;			case 's':				sopt = 1;				break;			case 'a':				aopt = 1;				break;			case 'e':				eopt = 1;				break;			case '?':			default:				DO_EXIT(usage, 1);			}	}	if((eopt || aopt) && (sopt || fopt))		DO_EXIT("passwd: illegal option combination.\n", 1);	if(fopt && sopt)		DO_EXIT("passwd: Only one of -f and -s allowed.\n", 1);/*  Check the command line.*/	if((argc-optind) > 1)		DO_EXIT(usage, 1);	our_id = getuid();	if(our_id == 0)		root=1;/*  Process the password configuration file.*/	config_auth();#ifdef AUTHEN        if((svcp = getsvc()) == NULL)                {                DO_EXIT("Cannot access security type\n", 2);                }        if(svcp->svcauth.seclevel >= SEC_UPGRADE)                {                for (i = 0 ; svcp->svcpath[SVC_AUTH][i] != SVC_LAST; i++)                        if (svcp->svcpath[SVC_AUTH][i] == SVC_BIND) {                                if(gethostname(namebuf, sizeof(namebuf)) == -1)                                        {                                        fputs("gethostname failure\n", stderr);                                        }			if((ptr = index(namebuf, '.')) != (char *)0)				*ptr = '\0';                        if(krb_svc_init("hesiod", namebuf, (char *)NULL, 0,                                (char *)NULL, "/var/dss/kerberos/tkt/tkt.passwd")                                        != RET_OK) {                                fputs("Kerberos initialization failure\n", stderr);                                }                        }                }#endif AUTHEN/*  Use the login name as the username if none was suplied on the command line.  Get the login name from the current real UID, not utmp.*/	if((argc-optind) > 0) {		pwd = getpwnam(argv[optind]);		if(!pwd && root) /* allow root to change a hesiod password */			{			root=2;			pwd = getpwnam_bind(argv[optind]);			hesflg=1;			}	} else		pwd = getpwuid(our_id);	if(svc_lastlookup == SVC_BIND)		{		hesflg=1;		if(root)			root=2;		}	if(svc_lastlookup == SVC_YP)		{		ypuid=1;			if(sec_level == SEC_UPGRADE)			DO_EXIT("YP cannot be used in UPGRADE mode.\n", 2);		}	if(!pwd) 		DO_EXIT("User not found in passwd data base.\n", 2);	if(!pwd->pw_name)		DO_EXIT("Error, no username.\n", 2);	strncpy(user_name, pwd->pw_name, sizeof user_name);	strncpy(passave, pwd->pw_passwd, sizeof passave);/*  The auth file is keyed by UID.  Use the usernames UID retrieved from the  passwd file as the key.*/	user_id = pwd->pw_uid;	if(user_id == our_id)		owner = 1;	else		owner = 0;/*  Make sure we are talking to a tty line if not using extended protocol.*/	if (!eopt && !fopt && !sopt) {		if(!freopen("/dev/tty", "w", stdout)) 			DO_EXIT("Unable to write /dev/tty.\n", 2);		if(!freopen("/dev/tty", "r", stdin)) 			DO_EXIT("Unable to read /dev/tty.\n", 2);	}/*  By definition the SSO is the owner of the auth file. (or the passwd file  if we are running BSD compatible).*/	if(sec_level < SEC_UPGRADE) {		if(stat(PASSWD_DB, &stat_buf) != 0) 			DO_EXIT("Cannot stat passwd file.\n", 3);	} else if(stat("/etc/auth.dir", &stat_buf) != 0) 			DO_EXIT("Cannot stat auth file.\n", 3);	sso_id = stat_buf.st_uid;	euid = geteuid();/*	if(euid != sso_id) 		DO_EXIT("Bad ownership on auth data base or passwd command.\n", 3);*/	if(our_id == sso_id || our_id == 0)		priv = 1;	else		priv = 0;/*  Make sure the user is authorized to attempt changing this password.*/	if((!owner && !priv) || (!priv && eopt))		DO_EXIT("Insufficient privilege.\n", 1);	umask(022);	if(sopt) {		char shell[MAXPATHLEN+1], line[MAXPATHLEN+1];		FILE *fp;		if(!(fp=fopen(ETCSHELLS, "r"))) {			char buf[MAXPATHLEN+50];			strcpy(buf, "Unable to open ");			strcat(buf, ETCSHELLS);			strcat(buf, "\n");			DO_EXIT(buf, 2);		}		fputs("Changing login shell for ", stdout);		puts(pwd->pw_name);		if(!priv && *pwd->pw_shell) {			int ok = 0;			while(fgets(line, sizeof line, fp)) {				if(path_match(line, pwd->pw_shell)) {					ok = 1;					break;				}			}			if(!ok) {				char buf[MAXPATHLEN+50];				strcpy(buf, "Cannot change from restricted shell ");				strcat(buf, pwd->pw_shell);				strcat(buf, "\n");				DO_EXIT(buf, 1);			}			rewind(fp);		}		printf("Shell [%s]: ", pwd->pw_shell);		if(!fgets(shell, sizeof shell, stdin)) {			DO_EXIT("Login shell unchanged.\n", 0);		}		cp = strchr(shell, '\n');		if(cp)			*cp = '\0';		if(!*shell) {			DO_EXIT("Login shell unchanged.\n", 0);		}		while(fgets(line, sizeof line, fp)) {			if(path_match(line, shell)) {				strcpy(shell, line);				break;			}		}		if(strcmp(shell, line)) {			if(priv) {

⌨️ 快捷键说明

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