edauth.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,199 行 · 第 1/2 页
C
1,199 行
#ifndef lintstatic char *sccsid = "@(#)edauth.c 4.3 (ULTRIX) 11/13/90";#endif lint/************************************************************************ * * * Copyright (c) 1989, 1990 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. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * 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 * * 04-Sep-1990 dlong * Added "-p protouser" option, support for AUDIT_USER, and use the * library routine getopt(). * * 12-Nov-1990 scott * Added AUDIT_USR to output_aud */#include <sys/wait.h>#include <sys/file.h>#include <sys/audit.h>#include <sys/time.h>#include <signal.h>#include <time.h>#include <nlist.h>#include <limits.h>#include <stdio.h>#include <pwd.h>#include <auth.h>#define AUD_BUF_LEN (SYSCALL_MASK_LEN+TRUSTED_MASK_LEN)#define SUCCEED 1#define FAIL 0/* * Code to convert a date back into time(2) format. */#define dysize(A) (((A)%4)? 365: 366)static int dmsize[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };/* * Add up the seconds since the epoch */long julian_second(year, month, day, hour, minute, second)int year, month, day, hour, minute, second;{ long jtime=0; int i; if(year < 100) year += 1900; for (i = 1970; i < year; i++) jtime += dysize(i); /* * Leap year */ if (dysize(year) == 366 && month >= 3) jtime++; /* * Do the current year */ while (--month) jtime += dmsize[month-1]; jtime += day-1; jtime = 24*jtime + hour; jtime = 60*jtime + minute; jtime = 60*jtime + second; return jtime;}/* * Module-wide definitions and declarations. */typedef struct passwd PWD;extern char *strchr();static char *progname = "???";static AUTHORIZATION authsave;struct nlist nlst[] = { { "_nsysent" },#define X_NSYSENT 0 { 0 },};char *special_event[] = { "shmget", "shmdt", "shmctl", "shmat"};/* * Function to check a string and return success if all digits. */static int alldigits(s)register char *s;{ register c; c = *s++; do { if (!isdigit(c)) return (0); } while (c = *s++); return (1);}/* * Function to convert a username or uid into a uid. */static int getuser(user)char *user;{ PWD *pwd; int uid;/* * Look it up first to see if it's in the passwd file. */ setpwent(); pwd = getpwnam(user); if(!pwd) {/* * If not in the passwd file see if it's an integer uid. */ if(alldigits(user)) uid = atoi(user); else uid = -1; } else/* * Otherwise return the uid field from the passwd file entry. */ uid = pwd->pw_uid; return uid;}/* * Function to remove leading and trailing white space from a string. * Returns a pointer to the first non-white character in the string. */static char *trim(s)char *s;{ char *start, *end, *strpbrk(); int i;/* * Skip over leading white space. */ start = s + strspn(s, " \t"); i = strlen(start);/* * Step from back to front while still encountering white-space characters. */ for(end=start+i-1; i; i--) { if(!strchr(" \t", *end)) break; *end-- = '\0'; }/* * Return pointer to first non-white character in string. */ return start;}extern char *strtok();/* * Function to read a number using the string initialized in strtok(). * If successful returns non-zero and stores the number in the integer * pointed to by the argument. Otherwise returns zero and strores zero in * the location pointed to by the argument. */static int getnum(i)int *i;{ char *s; if(s=strtok(NULL, " \t\n")) { s = trim(s); if(*s && alldigits(s)) { *i = atoi(s); return SUCCEED; } } *i = 0; return FAIL;}/* * Internal function to safely get a line from the named stream. If * the line is too long to fit into the buffer it is thrown away and a * new line is fetched until successful or end-of-file. */static char *fgetline(string, len, file)char *string;int len;FILE *file;{ register char *s; int c, i=0, j;/* * Keep trying until successful or end-of-file. */ while(s=fgets(&string[i], len, file)) { j = strlen(s); len -= j; i += j;/* * If not a complete line throw it away and go to the next line. */ if(!strchr(s, '\n')) { while((c=getc(file)) != EOF && c != '\n') ; break; }/* * If line ends in backslash-newline, get next line and concatenate. */ if(i >= 2 && s[j-2] == '\\') { i -= 2; len += 2; } else break; } if(s) return s; else return NULL;}/* Parsing functions *//* set auth auditmask */#define REQ_LEN 32extern char *syscallnames[];extern char *trustedevent[];/* * Function to convert a value subfield from an audit event token into * the appropriate value. */static int event_value(string)char *string;{ switch(*string) { case '0': return FAIL; case '1': return SUCCEED; default: return -1; }}/* * Function to add an audit event into the appropriate audit mask. */static int change_audit(amask, event)char *amask;char *event;{ char flags, *value; int nsyscalls; int i;/* * Process event and get value fields if present. */ if(value=strchr(event, ':')) { *value++ = '\0'; if((i=event_value(value)) >= 0) { flags = i << 1; if(value=strchr(value, ':')) { value++; if((i=event_value(value)) >= 0) flags |= i; else { fputs("Error, bad value for event fail flag, must be 0 or 1\n", stderr); return FAIL; } } } else { fputs("Error, bad value for event success flag, must be 0 or 1\n", stderr); return FAIL; } } else/* * No value fields present, default to both success and fail. */ flags = 0x3;/* * get # syscalls by reading kernel. */ nsyscalls = getkval (X_NSYSENT); if (nsyscalls == -1) { perror ("failed"); exit(1); }/* * set syscall event. */ for (i = 0; i < nsyscalls; i++) if (strcmp (event, syscallnames[i]) == 0) { A_PROCMASK_SET (amask, i, (flags&0x2)>>1, flags&0x1); return SUCCEED; }/* * kludge for shmsys operations. */ for (i = 0; i < 4; i++) if (strcmp (event, special_event[i]) == 0) { A_PROCMASK_SET (amask, (N_SYSCALLS-4+i), (flags&0x2)>>1, flags&0x1); return SUCCEED; }/* * set trusted event. */ for (i = 0; i < N_TRUSTED_EVENTS; i++) if (strcmp (event, trustedevent[i]) == 0) { A_PROCMASK_SET (amask, i+MIN_TRUSTED_EVENT, (flags&0x2)>>1, flags&0x1); return SUCCEED; }/* * invalid event. */ if (i == N_TRUSTED_EVENTS) { fputs("Error, can't find audit event \"", stderr); fputs(event, stderr); fputs("\"\n", stderr); } return FAIL;}/* * Function to read and parse an ASCII duration value. Duration may be * specified as time in seconds, minutes, hours, days, or a combination * of all of the preceeding. The default for unlabelled time values is * seconds. If the function returns non-zero if successful, zero otherwise. * The result is the time duration in seconds and is stored into the integer * variable pointed to by the argument. */static int get_time(i)int *i;{ char *s; int total=0, j; if(!getnum(&j)) return FAIL; do { if(s=strtok(NULL, " \t\n")) { s = trim(s); switch(*s) {/* * Days. */ case 'd': case 'D': total += j * (60*60*24); break;/* * Hours. */ case 'h': case 'H': total += j * (60*60); break;/* * Minutes. */ case 'm': case 'M': total += j * 60; break;/* * Seconds. */ case 's': case 'S': total += j; break;/* * Unrecognized value label. */ default: return FAIL; } } else {/* * Default to seconds. */ total += j; break; } } while(getnum(&j)); *i = total; return SUCCEED;}/* * Read in an ASCII representation of the auth record for a user, parsing it * into a binary representation. The open file is the first argument, and the * binary output record is pointed to by the second argument. */parse(file, auth)FILE *file;AUTHORIZATION *auth;{ char line[4097]; char *s, pw_flag, pwmin_flag, pwmax_flag, pwmod_flag, am_flag; char aid_flag, ac_flag, uid_flag, fc_flag; int i;/* * Initialize flags used to catch missing mandatory fields. */ pw_flag = pwmin_flag = pwmax_flag = pwmod_flag = am_flag = 0; aid_flag = ac_flag = uid_flag = fc_flag = 0;/* * Parse the file. */ while(fgetline(line, sizeof line, file)) {/* * Reject comment lines */ s = line + strspn(line, " \t\n"); if(!*s || *s == '#') continue;/* * Get first token */ if(!(s=strtok(line, "="))) { fputs("Error, bad line in file\n", stderr); return FAIL; }#ifdef DEBUGfputs("first token = ", stderr);fputs(s, stderr);putc('\n', stderr);fflush(stderr);#endif DEBUG/* * Process token value(s) */ s = trim(s); if(!strcmp(s, "fail_count")) { fc_flag = 1; if(!getnum(&i)) { i = authsave.a_fail_count; fprintf(stderr, "Warning bad or missing fail_count value, setting to %d\n", i); } auth->a_fail_count = i; } else if(!strcmp(s, "audit_id")) { aid_flag = 1; if(getnum(&i) && i > 0) auth->a_audit_id = i; else { fputs("Error, bad or missing audit_id value\n", stderr); return FAIL; } } else if(!strcmp(s, "audit_syscalls") || !strcmp(s, "audit_tevents")) { while(s=strtok(NULL, ",\n")) { s = trim(s); if(*s) if(!change_audit(auth->a_audit_mask, s)) { fputs("Error in audit event \"", stderr); fputs(s, stderr); fputs("\"\n", stderr); return FAIL; } } } else if(!strcmp(s, "uid")) { uid_flag = 1; if(getnum(&i) && i <= UID_MAX && i >= -UID_MAX) auth->a_uid = i; else { fputs("Error, bad or missing uid value\n", stderr); return FAIL; } } else if(!strcmp(s, "password")) { pw_flag = 1; if(s=strtok(NULL, " \t\n")) s = trim(s); else s = ""; bzero(auth->a_password, sizeof auth->a_password); strncpy(auth->a_password, s, sizeof auth->a_password); } else if(!strcmp(s, "passmod")) { int month, day, year, hour, minute, second; long jtime; hour = minute = second = 0; pwmod_flag = 1; if(s=strtok(NULL, "\n")) s = trim(s); if(s && !strcmp(s, "epoch")) jtime = 0; else if(s && sscanf(s, "%d/%d/%d - %d:%d:%d", &month, &day, &year, &hour, &minute, &second) >= 3) { extern long julian_second(); extern struct tm *localtime(); struct timeval tv; struct timezone tz; jtime = julian_second(year, month, day, hour, minute, second); gettimeofday(&tv, &tz); jtime += tz.tz_minuteswest*60; if(localtime(&jtime)->tm_isdst) jtime -= 60*60; } else { jtime = authsave.a_pass_mod; fputs("Warning, bad or missing passmod value, setting to ", stderr); if(jtime) fputs(ctime(&jtime), stderr); else fputs("epoch\n", stderr); } auth->a_pass_mod = jtime; } else if(!strcmp(s, "passlifemin")) { pwmin_flag = 1; if(!get_time(&i)) { i = authsave.a_pw_minexp; fprintf(stderr, "Warning, bad or missing passlifemin value, setting to %d\n", i); } auth->a_pw_minexp = i; } else if(!strcmp(s, "passlifemax")) { pwmax_flag = 1; if(!get_time(&i)) { i = authsave.a_pw_maxexp; fprintf(stderr, "Warning, bad or missing passlifemax value, setting to %d\n", i); } auth->a_pw_maxexp = i; } else if(!strcmp(s, "audit_control")) { ac_flag = 1; s = strtok(NULL, " \t\n"); s = trim(s); if(!strcmp(s, "or")) auth->a_audit_control = AUDIT_OR; else if(!strcmp(s, "and")) auth->a_audit_control = AUDIT_AND; else if(!strcmp(s, "off")) auth->a_audit_control = AUDIT_OFF; else if(!strcmp(s, "user")) auth->a_audit_control = AUDIT_USR; else { fputs("Error, invalid audit_control value\n", stderr); return FAIL; } } else if(!strcmp(s, "authmask")) { am_flag = 1; while(s=strtok(NULL, ",\n")) { s = trim(s); if(*s) if(!strcmp(s, "login")) auth->a_authmask |= A_LOGIN; else if(!strcmp(s, "change_password"))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?