edauth.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,199 行 · 第 1/2 页

C
1,199
字号
					auth->a_authmask |= A_CHANGE_PASSWORD;				else if(!strcmp(s, "enter_password"))					auth->a_authmask |= A_ENTER_PASSWORD;				else {					fputs("Error, invalid authmask value \"", stderr);					fputs(s, stderr);					fputs("\"\n", stderr);					return FAIL;				}		}	} else {		fputs("Warning, unrecognized keyword \"", stderr);		fputs(s, stderr);		fputs("\" in temp file\n", stderr);	}	}/* * Analyze results.  Report missing or inconsistant values. */	if(!*auth->a_password)		fputs("Warning, no password\n", stderr);	if(pwmax_flag && !auth->a_pw_maxexp)		fputs("Warning, no password expiration\n", stderr);	if(!pwmin_flag) {		fputs("Warning, missing passlifemin entry, setting to zero\n", stderr);		auth->a_pw_minexp = 0;	}	if(!pwmod_flag) {		fputs("Warning, missing passmod entry, setting to zero\n", stderr);		auth->a_pass_mod = 0;	}	if(!fc_flag) {		fputs("Warning, missing fail_count entry, setting to zero\n", stderr);		auth->a_fail_count = 0;	}	if(!uid_flag) {		fputs("Error, missing uid entry\n", stderr);		return FAIL;	}	if(!aid_flag) {		fputs("Error, missing audit_id entry\n", stderr);		return FAIL;	}	if(!ac_flag) {		fputs("Error, missing audit_control entry\n", stderr);		return FAIL;	}	if(!pwmax_flag) {		fputs("Error, missing passlifemax entry\n", stderr);		return FAIL;	}	if(!am_flag) {		fputs("Error, missing authmask entry\n", stderr);		return FAIL;	}	return SUCCEED;}/* link with /sys/`machine`/BINARY/{syscalls.o,trustedevents.o} *//* get integer value from kernel */static int getkval(var)int var;{	static int vm_fd = -1;	static int km_fd;	int i = 0;	if(vm_fd == -1) {		if((vm_fd = open("/vmunix", 0)) == -1)			return -1;		if((km_fd = open("/dev/kmem", 0)) == -1)			return -1;		nlist("/vmunix", nlst);		if(nlst[0].n_type == 0)			return -1;	}	if(lseek(km_fd, nlst[var].n_value, 0) == -1)		return -1;	if(read(km_fd, &i, sizeof (int)) != sizeof (int))		return -1;	else		return i;}/* * Function to output an audit event value. */static void put_audit_value(value, file)int value;FILE *file;{	switch(value) {	case 3:		break;	case 2:		fputs(":1", file);		break;	case 1:		fputs(":0:1", file);		break;	case 0:	default:		fputs(":0:0", file);		break;	}}/* * Function to output the audit information of the record. */static void output_aud(file, acntl, amask)FILE *file;char acntl;char *amask;{	extern char *syscallnames[];	extern char *trustedevent[];	int nsyscalls, audit_flag;	int i, j, k;/* * Output acntl flag value. */	fputs("audit_control = ", file);	if(acntl & AUDIT_OFF)		fputs("off\n", file);	else if(acntl & AUDIT_AND)		fputs("and\n", file);	else if(acntl & AUDIT_USR)		fputs("user\n", file);	else		fputs("or\n", file);/* * Get # syscalls. */	nsyscalls = getkval(X_NSYSENT);	if ( nsyscalls == -1) {		perror ( "nsyscalls failed");		return;	}/* * Display syscall mask */	fputs("audit_syscalls = ", file);	i = 0;	for(j = 0; j < SYSCALL_MASK_LEN; j++)		for(k = 0; k < 8; k+=2) {			if((j<<2)+(k>>1) >= nsyscalls)				break;			if(amask[j] &(0x3 <<(6-k%8))) {				if(i)					putc(',', file);				if(!((++i)%6))					fputs("\\\n\t", file);				fputs(syscallnames[(j<<2)+(k>>1)], file);				audit_flag = 0;				audit_flag = amask[j] &(0x2 <<(6-k%8)) ? 2 : 0;				audit_flag |= amask[j] &(0x1 <<(6-k%8)) ? 1 : 0;				put_audit_value(audit_flag, file);			}		}/* * Kludge for shmsys operations */	j =(N_SYSCALLS*2)/8 - 1;	for(k = 0; k < 8; k+=2)		if(amask[j] &(0x3 <<(6-k%8))) {			if(i)				putc(',', file);			if(!((++i)%6))				fputs("\\\n\t", file);			fputs(special_event[k>>1], file);			audit_flag = 0;			audit_flag = amask[j] &(0x2 <<(6-k%8)) ? 2 : 0;			audit_flag |= amask[j] &(0x1 <<(6-k%8)) ? 1 : 0;			put_audit_value(audit_flag, file);		}	putc('\n', file);/* * Display trusted event mask */	fputs("audit_tevents = ", file);	i = 0;	for(j = SYSCALL_MASK_LEN; j < SYSCALL_MASK_LEN+TRUSTED_MASK_LEN; j++)		for(k = 0; k < 8; k+=2) {			if(amask[j] &(0x3 <<(6-k%8))) {				if(i)					putc(',', file);				if(!((++i)%8))					fputs("\\\n\t", file);				fputs(trustedevent[((j-SYSCALL_MASK_LEN)<<2)+(k>>1)], file);				audit_flag = 0;				audit_flag = amask[j] &(0x2 <<(6-k%8)) ? 2 : 0;				audit_flag |= amask[j] &(0x1 <<(6-k%8)) ? 1 : 0;				put_audit_value(audit_flag, file);			}		}	putc('\n', file);}/* * Function to display an integer value followed by a unit label. */static void put_unit(i, s, file)int i;char *s;FILE *file;{	fprintf(file, " %d %s", i, s);	if(i > 1)		putc('s', file);}/* * Function to output a time duration value broken down into units. */static void put_time(i, file)int i;FILE *file;{	int j;/* * If less than a minute output unlabelled value (seconds). */	if(i < 60) {		fprintf(file, " %d\n", i);		return;	}/* * If greater than a day output integral days. */	if(j=i/(60*60*24)) {		put_unit(j, "day", file);		i %= (60*60*24);	}/* * If remainder is greater than an hour, output integral hours. */	if(j=i/(60*60)) {		put_unit(j, "hour", file);		i %= (60*60);	}/* * If remainder is greater than a minute, output integral minutes. */	if(j=i/60) {		put_unit(j, "minute", file);		i %= 60;	}/* * Output remaining seconds, if any. */	if(i) {		put_unit(i, "second", file);	}	putc('\n', file);}/* * Function to convert a binary auth record into a human readable but still * machine parsable ASCII representation. */unparse(file, auth)FILE *file;AUTHORIZATION *auth;{	struct tm *tm;	int i, j;	fprintf(file, "uid = %d\n",  auth->a_uid);	fputs("password = ", file);	fputs(auth->a_password, file);	putc('\n', file);	fputs("passlifemin =", file);	put_time(auth->a_pw_minexp, file);	fputs("passlifemax =", file);	put_time(auth->a_pw_maxexp, file);	if(auth->a_pass_mod > 0) {		tm = localtime(&auth->a_pass_mod);		fprintf(file, "passmod = %02d/%02d/%02d - %02d:%02d:%02d\n",		    tm->tm_mon+1, tm->tm_mday, tm->tm_year%100,		    tm->tm_hour, tm->tm_min, tm->tm_sec);	} else		fputs("passmod = epoch\n", file);	fputs("authmask = ", file);	j = 0;	for(i=0; i < (sizeof auth->a_authmask)*8; i++) {		if(auth->a_authmask & (1<<i)) {			if(j++)				fputc(',',file);			switch(i) {			case 0:				fputs("login", file);				break;			case 1:				fputs("change_password", file);				break;			case 2:				fputs("enter_password", file);				break;			default: ;			}		}	}	putc('\n', file);	fprintf(file, "fail_count = %d\n", auth->a_fail_count);	fprintf(file, "audit_id = %d\n", auth->a_audit_id);	output_aud(file, auth->a_audit_control, auth->a_audit_mask);#ifdef	PRIV	fputs("privileges = ?\n", file);#endif	PRIV}/* * Function to unparse a binary auth record and put it into a new temporary * file.  The file name is returned as the value of the function.  If the * function fails it returns the NULL pointer. */static char *putinfile(auth)AUTHORIZATION *auth;{	static char *filename;	extern char *mktemp();	FILE *file;	filename = mktemp("/tmp/edauth.XXXXXX");	if(!(file=fopen(filename, "w")))		return (char *) NULL;	unparse(file, auth);	if(fclose(file) == EOF)		return (char *) NULL;	else		return filename;}/* * Function to read the named file and parse the data into a binary auth * record.  If the function is successful it returns a pointer to a static * area containing the auth record.  Otherwise it returns the NULL pointer. */static AUTHORIZATION *getfromfile(filename)char *filename;{	char line[1024];	FILE *file;	static AUTHORIZATION auth;	if(!(file=fopen(filename, "r"))) {		fputs("Unable to reopen tmp file.\n", stderr);		exit(1);	}	if(parse(file, &auth)) {		fclose(file);		return &auth;	} else {		fclose(file);		return (AUTHORIZATION *) NULL;	}}/* * Function to edit an auth record. */AUTHORIZATION *editit(auth)AUTHORIZATION *auth;{	static char def_editor[] = "/bin/ed";	union wait status;	int pid;	char *editor, *filename, *getenv();	char line[BUFSIZ];/* * Put ASCII representation of record into a new temporary file. */	filename = putinfile(auth);/* * Edit the file with the editor of choice until successful. */	while(1) {	fflush(stdout);	fflush(stderr);	signal(SIGINT, SIG_IGN);	pid = fork();	if(pid < 0) {		perror(progname);		exit(1);	}	if(pid) {		wait(&status);	} else {		signal(SIGINT, SIG_DFL);		if(!(editor=getenv("EDITOR")))			editor = def_editor;		execlp(editor, editor, filename, 0);		exit(1);	}	signal(SIGINT, SIG_DFL);/* * Get the record from the file and convert to binary. */	auth = getfromfile(filename);/* * If problems give the user another shot at fixing it up. */	if(!auth) {		fputs("Error in file, do you wish to resume editing?> ", stdout);		if(fgetline(line, sizeof line, stdin))			if(*line == 'y' || *line == 'Y')				continue;		break;	} else		break;	}/* * Dispose of temporary file. */	unlink(filename);	if(!auth || (status.w_status&0xffff))		return (AUTHORIZATION *) NULL;	else		return auth;}/* * Print an error message. */static void audevent(statustr, status)char *statustr;int status;{		char tmask[AUD_NPARAM];	struct {		char *a;		int  b;	} aud_arg;	int i;/* * Build token mask. */	tmask[0] = T_CHARP;	if(status == 0)		tmask[1] = T_RESULT;	else		tmask[1] = T_ERROR;	tmask[2] = '\0';	aud_arg.a = statustr;	aud_arg.b = status;/* * Generate audit record. */        if(audgen(AUTH_EVENT, tmask, &aud_arg) == -1 )		perror("audgen" );}/* * Error termination function. */static void getout(statustr, status)int status;char *statustr;{	if(statustr) {		audevent(statustr, status);		fputs(statustr, stderr);		putc('\n', stderr);	}	exit(status);}static char usage[] = "usage: edauth [-p protouser] username";main(argc, argv)/* * The main event. */int argc;char *argv[];{	AUTHORIZATION authorization, *auth;	int uid, protouid, pflag=0, c;	char user[17], protouser[17], buf[AUD_BUF_LEN];	extern int optind;	extern char *optarg;/* turn off auditing of all events except for LOGIN and failed setgroups */	if ( audcntl (SET_PROC_ACNTL, (char *)0, 0, AUDIT_AND, 0) == -1)		perror ( "audcntl" );	A_PROCMASK_SET ( buf, AUTH_EVENT, 1, 1 );	if (audcntl(SET_PROC_AMASK, buf, AUD_BUF_LEN, 0, 0) == -1 )		perror ( "audcntl" );	if(argc > 0)		progname = argv[0];	while((c=getopt(argc, argv, "p:")) != EOF)		switch(c) {		case 'p':			pflag = 1;			strncpy(protouser, optarg, sizeof protouser);			break;		default:			getout(usage, 1);		}	if(optind == (argc-1))		strncpy(user, argv[optind], sizeof user);	else {		getout(usage, 1);	}	umask(077);	if(pflag)		if((protouid=getuser(protouser)) == -1)			getout("Protouser not found in passwd data base.", 1);	if((uid=getuser(user)) == -1) {		getout("User not found in passwd data base.", 1);	}	if(open_auth(AUTHORIZATION_DB, O_RDWR)) {		getout("Unable to open auth data base.", 1);	}/* * Get auth record. */	if(pflag) {		if(get_auth(protouid, &authorization) < 0)			getout("Protouser not found in auth data base.", 1);	} else		if(get_auth(uid, &authorization) < 0)			getout("User not found in auth data base.", 1);/* * Save the record from the static area used in getauthent(). */	auth = &authorization;	bcopy(auth, &authsave, sizeof (AUTHORIZATION));/* * If creating from protouser, set the new UID and clear the audit ID. */	if(pflag) {		authorization.a_uid = uid;		authorization.a_audit_id = 0;		authorization.a_fail_count = 0;	}/* * Don't leave the auth files open when giving the user their editor. */	close_auth();	if(!(auth=editit(auth))) {		getout("Edit failed.", 1);	}/* * If the record didn't change at all don't do anything. */	if(!bcmp(auth, &authsave, sizeof (AUTHORIZATION))) {		getout("Record unchanged.", 0);	}	if(open_auth(AUTHORIZATION_DB, O_RDWR)) {		getout("Unable to reopen auth data base.", 1);	}/* * If the UID field of the record changed we have to take special action. * This is because the UID is the key into the data base.  If we just * stored out the new record the old one would also still be around.  So we * must delete the record stored undewr the old UID first. */	if(auth->a_uid != authsave.a_uid) {		char buf[100];		sprintf(buf, "Warning, changing UID from %d to %d",		    authsave.a_uid, auth->a_uid);		fputs(buf, stderr);		putc('\n', stderr);		if(delete_auth(authsave.a_uid) < 0) {			getout("Unable to remove old entry.", 1);		}		audevent(buf, 0);	}/* * Store out new record. */	bcopy(auth, &authsave, sizeof (AUTHORIZATION));	auth = &authsave;	if(storeauthent(auth) < 0) {		close_auth();		getout("Failed to store new entry.", 1);	} else {		char buf[100];		close_auth();		sprintf(buf, "Updated auth entry for uid %d.", auth->a_uid);		getout(buf, 0);	}}

⌨️ 快捷键说明

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