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

📄 passwd.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
				DO_ERROR("Warning, shell not in /etc/shells\n");			} else				DO_EXIT("Invalid shell selection, shell unchanged.\n", 1);		}		if (access(shell, X_OK) < 0) {			char buf[MAXPATHLEN+50];			strcpy(buf, shell);			strcat(buf, " is unavailable.\n");			DO_EXIT(buf, 1);		}		if(!strcmp(shell, DEFSHELL))			strcpy(shell, "");		pwd->pw_shell = shell;		if(storepwent(pwd)) {			DO_EXIT("Shell not changed.\n", 1);		} else			audevent("Shell successfully changed.", 0);	}	if(fopt) {		char *name, *office, *ophone, *hphone;		char newname[ENTRY_SIZE], newoffice[ENTRY_SIZE], newophone[ENTRY_SIZE], newhphone[ENTRY_SIZE];		char line[1024];		fputs("Changing finger information for ", stdout);		puts(pwd->pw_name);		name = office = ophone = hphone = "";		name = pwd->pw_gecos;		if(name) {		office = strpbrk(name, ",:\n");		if(office) {			if(*office == ',') {				*office = '\0';				office++;				ophone = strpbrk(office, ",:\n");				if(ophone) {					if(*ophone == ',') {						*ophone = '\0';						ophone++;						hphone = strpbrk(ophone, ",:\n");						if(hphone) {							if(*hphone == ',') {								*hphone = '\0';								hphone++;							}						} else							hphone = "";					}				} else					ophone = "";			}		} else			office = "";		}		name = getentry("Name", name, newname, ENTRY_SIZE);		office = getentry("Office number", office, newoffice, ENTRY_SIZE);		ophone = getentry("Office Phone", ophone, newophone, ENTRY_SIZE);		hphone = getentry("Home Phone", hphone, newhphone,  ENTRY_SIZE);		sprintf(line, "%s,%s,%s,%s", name, office, ophone, hphone);		pwd->pw_gecos = line;		if(storepwent(pwd)) {			DO_EXIT("Finger information not changed.\n", 1);		} else			audevent("Finger information successfully changed.", 0);	}	if(!sopt && !fopt) {		if (!eopt) {			fputs("Changing password for ", stdout);			puts(pwd->pw_name);		}		umask(077);		now = time((long *) 0);/*  If we are running with C2 or less security look for the password first in the  passwd data base.*/		if(sec_level >= SEC_UPGRADE) {/*  Open the auth file and get the users auth entry using their UID as the key.*/			auth = getauthuid(user_id);			if(auth == (AUTHORIZATION *) NULL && root == 2)				auth = getauthuid_hesiod(user_id);			if(auth == (AUTHORIZATION *) NULL) {                                char buf[256];                                sprintf(&buf[0], "Unable to retrieve auth information for %s.\n", user_name);                                DO_EXIT(&buf[0], 2);			}		} else			auth = (AUTHORIZATION *) NULL;		if(ypuid && (sec_level == SEC_ENHANCED))  			{  /* wierd case: Yp served uid at ENHANCED level */			hesflg=1;	/* Assume hesiod served auth */			if(root)				root=2;			}/*  Retrieve old encrypted password.*/		if(sec_level == SEC_BSD ||		    sec_level <= SEC_UPGRADE && pwd->pw_passwd && strcmp(pwd->pw_passwd, "*"))			strncpy(crypt_pass, pwd->pw_passwd, sizeof crypt_pass);		else			strncpy(crypt_pass, auth->a_password, sizeof crypt_pass);/*  If the invoker is not privileged (SSO or ROOT) require re-authentication,  verify that they have CHANGE_PASSWORD privilege, and check the minimum  expiration time.*/		if(!priv) {/*  Check CHANGE_PASSWORD privilege.*/			if(auth && !(auth->a_authmask & A_CHANGE_PASSWORD)) 				DO_EXIT("You do not have the privilege to change your password.\n", 1);		}/*  Check minimum password expiration time.*/		if(!priv && auth) {			deadline = auth->a_pass_mod;			period = auth->a_pw_minexp;			deadline += period;			if(now < deadline)				DO_EXIT("Sorry, the minimum password lifetime has not expired yet.\n", 1);		}/*  Reauthenticate.*/		if(!priv && *crypt_pass) {			strncpy(salt, crypt_pass, 2);			salt[2] = '\0';			s = getpass("Old password: ");			strncpy(old_pass, s, sizeof (PASSWORD));			old_pass[MAX_PASSWORD_LENGTH] = '\0';			putchar('\n');			if(sec_level == SEC_BSD ||			    sec_level <= SEC_UPGRADE && pwd->pw_passwd && strcmp(pwd->pw_passwd, "*"))				cp = crypt(old_pass, salt);			else				cp = crypt16(old_pass, salt);			if(!hesflg)			 	bzero(old_pass, sizeof old_pass);			if(strcmp(crypt_pass, cp)) {				audevent("Failed authentication", 1);				sleep(2);				puts("Sorry");				exit(1);			}		}/* * The current prompter protocol does not support reauthentication; this * forces 'passwd -e' to be invokable only by root and to kludge the use of * priv when in extended protocol mode.  This has the side affect of including * root in further checks if 'passwd -e root'. */		if (eopt) {			priv = 0;		}/*  Get the new password.*/		if(!auth) {			max_pw_len = 8;			if(min_pw_len > max_pw_len)				min_pw_len = max_pw_len;		} else			if(!priv && !(auth->a_authmask & A_ENTER_PASSWORD))				aopt = 1;		if (eopt) {			static REQ	request;			REQ		*req = &request;			LISTOFPAIRS	pairs;			LISTOFPAIRS	*pair_list 	= &pairs;			LISTOFPASSWORDS *passwd_list	= (LISTOFPASSWORDS *)req->data;			int length;				makeseed(&i, 4);			srandom(i);						/* Get password */			do {				bzero(pair_list, sizeof(LISTOFPAIRS));				pair_list->count = RANDOM_WORDS;				for(i=0; i < RANDOM_WORDS; i++) {					randomword(pair_list->pairs[i].passwd.data, 						pair_list->pairs[i].phonetic.data, 						min_pw_len, max_pw_len, 0);					pair_list->pairs[i].passwd.length = 						strlen(pair_list->pairs[i].passwd.data);					pair_list->pairs[i].phonetic.length = 						strlen(pair_list->pairs[i].phonetic.data);				}				SENDREQ(req, CHZPWD, pair_list, sizeof(LISTOFPAIRS));	again:				SENDREQ(req, GETPWD, (char *)0, 0);				GETREQ(req, i);				if(i <= 0)					exit(2);				if (req->opcode != PASSWD) {					DO_ERROR("Did not receive PASSWD request.\n");					goto again;				}				if (passwd_list->count && auth && !(auth->a_authmask & A_ENTER_PASSWORD)) {					for (i=0; i < RANDOM_WORDS; i++) {						if (!strcmp(passwd_list->passwords[0].data, 							pair_list->pairs[i].passwd.data))							break;					}					if(i >= RANDOM_WORDS) {						DO_ERROR("You must select from the list shown.\n");						goto again;					} 				}			} while (passwd_list->count == 0);			/* Save password and verify string */			length = passwd_list->passwords[0].length;			if(length > MAX_PASSWORD_LENGTH)				length = MAX_PASSWORD_LENGTH;			strncpy(new_pass, passwd_list->passwords[0].data, 				length);			new_pass[length] = '\0';			length = passwd_list->passwords[1].length;			if(length > MAX_PASSWORD_LENGTH)				length = MAX_PASSWORD_LENGTH;			strncpy(verify, passwd_list->passwords[1].data, 				length);			s = (unsigned char *) passwd_list->passwords[0].data;			/* Clear temp space */			bzero(pair_list, sizeof(LISTOFPAIRS)); 		} else if (aopt) {			makeseed(&i, 4);			srandom(i);			do {				puts("Here are some suggested passwords:\n");				for(i=0; i < NUM_CHOICES; i++) {					randomword(gen_password[i], hyph_password, min_pw_len, max_pw_len, 0);					printf("%-16s %-16s\n", gen_password[i], hyph_password);				}				s = getpass("\nEnter new password: ");				strncpy(new_pass, s, sizeof (PASSWORD));				new_pass[MAX_PASSWORD_LENGTH] = '\0';				putchar('\n');				if(!priv && *new_pass && auth && !(auth->a_authmask & A_ENTER_PASSWORD)) {					for(i=0; i < NUM_CHOICES; i++) {						if(!strcmp(new_pass, gen_password[i]))							break;					}					if(i >= NUM_CHOICES) {						new_pass[0] = '\0';						DO_ERROR("You must select from the list shown.\n");					} else						break;				}			} while(strlen(new_pass) == 0);		} else {			s = getpass("Enter new password: ");			strncpy(new_pass, s, sizeof (PASSWORD));			new_pass[MAX_PASSWORD_LENGTH] = '\0';			putchar('\n');		}/*  Check password length.*/		if(!*new_pass)			DO_EXIT("Password unchanged.\n", 1);		if((i=strlen(s)) < min_pw_len) {			char buf[256];			bzero(new_pass, sizeof new_pass);			sprintf(&buf[0], "Password must be at least %d characters long, password unchanged.\n",				min_pw_len);			DO_EXIT(&buf[0], 1);		}		if(i > max_pw_len) {			char buf[256];			new_pass[max_pw_len] = '\0';			if(sec_level <= SEC_BSD)				sprintf(&buf[0], "Warning, only the first %d characters of the password are significant.\n",					max_pw_len);			else {				sprintf(&buf[0], "%s, your password cannot be longer than %d characters.\n",					eopt?"Error":"Warning", max_pw_len);				if(eopt)					DO_EXIT(&buf[0], 1);			}			DO_ERROR(&buf[0]);		}/*  If the user is not privileged check to make sure their password meets  some minimal requirements.*/		if(!priv) {/*  Make sure new password is not the same as old password.*/			if(*crypt_pass) {				salt[0] = crypt_pass[0];				salt[1] = crypt_pass[1];				salt[2] = '\0';				if(auth)					cp = crypt16(new_pass, salt);				else					cp = crypt(new_pass, salt);				if(!strcmp(crypt_pass, cp)) {					bzero(new_pass, sizeof new_pass);					DO_EXIT("Password is not different enough, unchanged.\n", 1);				}			}/*  Make sure the password does not equal the logname.*/			cp2 = new_pass;			cp = pwd->pw_name;			for(cp2=new_pass, cp=pwd->pw_name; *cp2 && *cp; cp2++, cp++)				if(lcase(*cp) != lcase(*cp2))					break;			if(lcase(*cp) == lcase(*cp2))				DO_EXIT("Password must be different than logname.\n", 1);#ifdef		CHECKCHARS/*  Make sure password uses a rich enough character set.*/			for(cp2=new_pass; *cp2; cp2++)				chartab[*cp2]++;			for(i=0; i < sizeof chartab; i++)				if(chartab[i])					charset++;			if(charset < CHECKCHARS) {				char buf[256];				bzero(new_pass, sizeof new_pass);				bzero(chartab, sizeof chartab);				charset = 0;				sprintf(&buf[0], "Password must contain at least %d different characters.\n", CHECKCHARS);				DO_EXIT(&buf[0], 1);			}#endif		}/*  Verify password to prevent typos.*/		if (!eopt) {			s = getpass("Verify: ");			strncpy(verify, s, sizeof (PASSWORD));			verify[MAX_PASSWORD_LENGTH] = '\0';			putchar('\n');			if((i=strlen(verify)) > max_pw_len)				if(sec_level > SEC_BSD) {					DO_EXIT("Error, password too long.\n", 1);				} else					verify[max_pw_len] = '\0';		}		if(strcmp(new_pass, verify))			DO_EXIT("Verification failed, password unchanged.\n", 1);		bzero(verify, sizeof verify);/*  Encrypt and store the new password.*/		srandom(time(0));		salt[0] = salt_table[random() % 64];		salt[1] = salt_table[random() % 64];		if(sec_level == SEC_BSD || !auth)			pwd->pw_passwd = crypt(new_pass, salt);		else			bcopy(crypt16(new_pass, salt), auth->a_password, CRYPT_PASSWORD_LENGTH);		bzero(new_pass, sizeof new_pass);/*  If the user is privileged set the expiration periods.*/#ifdef	XYZ		if(!eopt && priv && auth) {/*  Set the maximum expiration period.*/			printf("Enter expiration period in days (RET for %1d, 0 for none): ",				DEF_EXP_PERIOD/60/60/24);			fgets(string, sizeof string, stdin);			if(string[0] == '\n')				period = DEF_EXP_PERIOD;			else				period = atoi(string)*60*60*24;			auth->a_pw_maxexp = period;/*  Set the minimum expiration period.*/			fputs("Enter minimum password lifetime in minutes (RET for 0): ", stdout);			fgets(string, sizeof string, stdin);			if(string[0] == '\n')				period = 0;			else				period = atoi(string)*60;			auth->a_pw_minexp = period;		}#endif/************************************************************************//*                                                                      *//*      The hesupd call processing					*//*                                                                      *//************************************************************************/		if(hesflg)			{			signal(SIGHUP, SIG_IGN);			signal(SIGINT, SIG_IGN);			signal(SIGQUIT, SIG_IGN);			(void) umask(0);		        bzero((char *)&hupmsg, sizeof(struct hesupdmsg));	        	strcpy(hupmsg.oldpwd,old_pass);			hupmsg.hesuid = pwd->pw_uid;			hupmsg.opcode=PASSCHG;			if(auth)				strcpy(hupmsg.newcrypt,auth->a_password);			else	strcpy(hupmsg.newcrypt,pwd->pw_passwd);	        	if(hupdtp(&hupmsg))				{	                	DO_EXIT("Your distributed password is updated\n", 0);				}	        	else    {				DO_EXIT("Your distributed password has not been changed\n", 2);				}			exit(0);			/*****end of hesupd processing*********/			}		if(auth) {/*  Set the password modification time to now and store the new auth  entry.*/			auth->a_pass_mod = now;			if(storeauthent(auth))				DO_EXIT("Unable to set new password.\n", 2);			endauthent();			if(gp=getgrnam("authread"))				auth_gid = gp->gr_gid;			else				auth_gid = 9;			if(our_id == 0)				i = chown(AUTHORIZATION_DB, sso_id, auth_gid);			else				i = chown(AUTHORIZATION_DB, -1, auth_gid);			if(i >= 0)				chmod(AUTHORIZATION_DB, 0640);			if(strcmp(passave, "*")) {				pwd->pw_passwd = "*";				umask(022);				if(storepwent(pwd))					DO_EXIT("Unable to change passwd file.\n", 2);			}		} else {			umask(022);			if(storepwent(pwd))				DO_EXIT("Unable to set password.\n", 2);		}		if(aopt && !eopt)			DO_ERROR("Remember to destroy any printed passwords.\n");		audevent("Password successfully changed.", 0);	}	exit(0);}/************************************************************************//*									*//*	hesupd transaction processing module				*//*									*//************************************************************************/inthupdtp(hup)		struct hesupdmsg *hup;{	static struct sockaddr sock, sock2;        struct hostent *hp;	char host[34];        struct sockaddr_in sin;	struct  servent *sp;            /* service spec for tcp/hesupd */        int hlen = 32;        	int net, socklen, amount, i, t, j, retmsg=HESUPDNAK;	int ans, port, retry;	/* first check to see if we are the bind master */        gethostname(host,hlen);	hp = gethostbyname(bindmaster);        if(hp == 0)		return(0); /* cant lookup the bindmaster hostname */        if(!strcmp(host,hp->h_name) && root == 2 )		{	/* bingo - I am root and this is the bindmaster */        	if (chdir(homebase) < 0) {                	fprintf(stderr, "passwd can't chdir to %s\n",homebase);                	return(0);        		}        	switch(svcp->svcauth.seclevel)			{			case	SEC_BSD:                        	return(chpw_bsd(hup->hesuid,hup->oldpwd,hup->newcrypt));			case	SEC_UPGRADE:                        	return(chpw_upgrade(hup->hesuid,hup->oldpwd,hup->newcrypt));			case	SEC_ENHANCED:                        	return(chpw_enhanced(hup->hesuid,hup->oldpwd,hup->newcrypt));			}		}	mix(hup);	/*****						*****/	/*****   Get port number of hesupd		*****/	/*****						*****/	sp=getservbyname("hesupd","tcp");        if (sp == 0) {                DO_ERROR("hesupd/tcp: unknown service\n");                return(0);        }	/*****						*****/	/*****    Get Bind master hostname		*****/	/*****						*****/	hp = gethostbyname(bindmaster);	if (hp == NULL) {		DO_ERROR("No registered hesiod master\n");		return(0);	}	/*****						*****/	/***** 		Setup the socket		*****/	/*****						*****/	bzero((char *)&sin, sizeof (sin));        bcopy(hp->h_addr,(char *)&sin.sin_addr, hp->h_length);/* Save the remote address for auditing *//*	bcopy(hp->h_addr, remote_hostaddr.sa_data, sizeof (long));	remote_hostaddr.sa_family = hp->h_addrtype;	remote_hostflag = 1;*/	sin.sin_family = hp->h_addrtype;	sin.sin_port = sp->s_port;	/*****						*****/	/***** Try HESRETRY times to connect to hesupd	*****/	/*****						*****/	for(retry=HESRETRY; retry != 0; retry-- )		{        	net = socket(AF_INET, SOCK_STREAM, 0);        	if (net < 0) 			{            		DO_ERROR("hesupd: socket error\n");            		return(0);			}		/*****					*****/		/***** Make connection to Hesupd	*****/		/*****					*****/		if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) 			{			(void) close(net);			net = -1;			continue;			}		/*****					*****/		/***** Send out hesupd message		*****/		/*****					*****/		amount = send(net, (char *) hup, sizeof(struct hesupdmsg), 0); 		if(amount < sizeof(struct hesupdmsg))			{			(void) close(net);			DO_ERROR("hesupd send error\n");			return(0);			}		/*****					*****/		/*****	Receive Ack or Nak from Hesupd  *****/		/*****  This will hang if hesupd dies   *****/		/*****					*****/     		amount = recv(net, (char *)&retmsg, sizeof(retmsg), 0);                if(amount < sizeof(retmsg))                        {			(void) close(net);                        DO_ERROR("hesupd recv error\n");                        return(0);                        }		else	break;		}	(void) close(net);	net = -1;	if(retmsg == HESUPDACK)

⌨️ 快捷键说明

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