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

📄 tacacs-routines.c

📁 RADIUS协议的认证计费服务
💻 C
字号:
/* tacacs-routines.c *   Support routines for the tacacs server. * * Last modified: 25-Dec-1990/al * * 25-Dec-1990  al      Busy little elves * 24-Dec-1990  al      Yanked out of big tacacs-server.c * */#include "includes.h"/* init_tacacs_uaf *   Do some razzledazzle with logical names so that $GETUAI can find the *   TACACS user authorization file without interfering with the real *   system files. * *   When the dust settles, things will look like this: *   * LNM$FILE_DEV will be defined in EXEC mode in the LNM$PROCESS_DIRECTORY *     table as "LNM$PROCESS", "LNM$JOB", "LNM$GROUP", "LNM$SYSTEM" *   * SYSUAF will be defined in EXEC mode in the LNM$PROCESS table as *     "TACACS_UAF" *   * RIGHTSLIST and NETPROXY will be defined in EXEC mode in the LNM$PROCESS *     table as "_NLA0:" * *   All of this foolishness will be undone by the exit handler *   tacacs_exit_handler(). * *   The logical name TACACS_UAF *must* be defined in EXEC mode. * *   Returns status from SYS$TRNLNM(), SYS$CRELNM() or stat(). */#define LNMPROCESS  "LNM$PROCESS"#define LNMJOB      "LNM$JOB"#define LNMGROUP    "LNM$GROUP"#define LNMSYSTEM   "LNM$SYSTEM"#define NLA0        "_NLA0:"unsigned long int init_tacacs_uaf (){	unsigned long int status,	                SYS$CRELNM (),	                SYS$TRNLNM ();	int             stat ();	stat_t          statbuf;	char           *lnmprocess = LNMPROCESS;	char           *lnmjob = LNMJOB;	char           *lnmgroup = LNMGROUP;	char           *lnmsystem = LNMSYSTEM;	char           *nla0 = NLA0;	BYTE            acmode = PSL$C_EXEC;	$DESCRIPTOR (processtable, "LNM$PROCESS_TABLE");	$DESCRIPTOR (processdirectory, "LNM$PROCESS_DIRECTORY");	$DESCRIPTOR (file_dev, "LNM$FILE_DEV");	$DESCRIPTOR (lognam, TACACS_UAF);	$DESCRIPTOR (sysuaf, "SYSUAF");	$DESCRIPTOR (rightslist, "RIGHTSLIST");	$DESCRIPTOR (netproxy, "NETPROXY");	ITEM            cre_sysuaf_itmlst[] = {		{(WORD) sizeof (TACACS_UAF) - 1, LNM$_STRING, lognam.dsc$a_pointer, 0},		{0, 0, 0, 0}	};	ITEM            cre_file_dev_itmlst[] = {		{(WORD) sizeof (LNMPROCESS) - 1, LNM$_STRING, lnmprocess, 0},		{(WORD) sizeof (LNMJOB) - 1, LNM$_STRING, lnmjob, 0},		{(WORD) sizeof (LNMGROUP) - 1, LNM$_STRING, lnmgroup, 0},		{(WORD) sizeof (LNMSYSTEM) - 1, LNM$_STRING, lnmsystem, 0},		{0, 0, 0, 0}	};	ITEM            cre_nla0_itmlst[] = {		{(WORD) sizeof (NLA0) - 1, LNM$_STRING, nla0, 0},		{0, 0, 0, 0}	};/* First - Declare the exit handler. */	void            tacacs_exit_handler ();	EXH_BLK         exh_blk = {0, tacacs_exit_handler, 0, &status};	status = SYS$DCLEXH (&exh_blk);	if ((status & 0x1) == 0)		exit (status);	/* Define LNM$FILE_DEV in exec mode in the process directory table */	status = SYS$CRELNM (0, &processdirectory, &file_dev, &acmode,			     &cre_file_dev_itmlst);	iferr (status)	{		printf ("Can't create logical name\n");		exit (status);	}	/* Check to make sure that "TACACS_UAF" is defined in exec mode. */	status = SYS$TRNLNM (0, &file_dev, &lognam, &acmode, 0);	iferr (status)	{		printf ("Can't get TACACS_UAF logical name\n");		exit (status);	}	/* Check to see whether this file is accessible */	status = stat (TACACS_UAF, &statbuf);	if (status != 0)	{		printf ("Can;t stat on TACACS_UAF\n");		exit (vaxc$errno);	}	/*	 * Define SYSUAF in exec mode in the process LNM table as	 * "TACACS_UAF"	 */	status = SYS$CRELNM (0, &processtable, &sysuaf, &acmode, &cre_sysuaf_itmlst);	iferr (status)	{		printf ("Can't define SYSUAF to be TACACS-UAF\n");		exit (status);	}	/* Define RIGHTSLIST in exec mode in the process LNM table as "_NLA0" */	status = SYS$CRELNM (0, &processtable, &rightslist, &acmode,			     &cre_nla0_itmlst);	iferr (status)	{		printf ("Can't define RIGHTLIST\n");		exit (status);	}	/* Define NETPROXY in exec mode in the process LNM table as "_NLA0" */	status = SYS$CRELNM (0, &processtable, &netproxy, &acmode,			     &cre_nla0_itmlst);	iferr (status)	{		printf ("Can't define NETPROXY\n");		exit (status);	}}				/* init_tacacs_uaf *//* logerror *   Log an error message.  By default, log to OPCOM; if TACACS_ERRLOG *   is defined, log to it. * *   Returns status. */#define MAX_OPCOM_MSG	255typedef struct _opc_mess_buf	/* message buffer for $SNDOPR */{	char            type;	/* OPC$B_MS_TYPE */	unsigned        target:24;	/* OPC$B_MS_TARGET */	unsigned long   rqstid;	/* OPC$B_MS_RQSTID */	char            text[MAX_OPCOM_MSG + 1];	/* OPC$L_MS_TEXT */}               opc_mess_buf;LONG logerror (s)char           *s;		/* string to write out to log */{	char           *getenv ();	opc_mess_buf    mb;	/* message buffer for $SNDOPR call */	unsigned long int status;	char           *logfile;	char           *opcom = "OPCOM";	struct dsc$descriptor sndopr_desc;	FILE           *lf;	logfile = getenv (TACACS_ERRLOG);	if (logfile == NULL)		logfile = opcom;	if (strcmp (logfile, "OPCOM") == 0)	{		if (strlen (s) > MAX_OPCOM_MSG)			s[MAX_OPCOM_MSG] = '\0';		mb.type = OPC$_RQ_RQST;		mb.target = OPC$M_NM_NTWORK;	/* make OPCOM send to NETWORK						 * opers */		mb.rqstid = 0;		strcpy (mb.text, s);		sndopr_desc.dsc$w_length = sizeof mb.type + sizeof mb.target +			sizeof mb.rqstid + strlen (s);		sndopr_desc.dsc$b_dtype = DSC$K_DTYPE_T;		sndopr_desc.dsc$b_class = DSC$K_CLASS_S;		sndopr_desc.dsc$a_pointer = &mb;		status = SYS$SNDOPR (&sndopr_desc, 0);		return (status);	}	else	{		/* try logging the message to a file */		lf = fopen (logfile, "a+");		if (lf == NULL)			return (vaxc$errno);		fputs (s, lf);		fputc ('\n', lf);		fclose (lf);		return (SS$_NORMAL);	}}				/* logerror *//* verify_user *   Verify this username/password combination against the TACACS_UAF. *   Inputs: username, password. * All hyphens in the username are replaced with underscores for SLIP addresses. *   Returns VMS system call status - should always be SS$_NORMAL unless *   some unexpected strange system service status. * *   Returns one of the following in user_status: *   USER_BOGUS     - no such user, bad password, etc. *   USER_EXPIRED   - user password expired *   USER_EXPIRING  - user password < TACACS_PASSWORD_THRESHOLD days from *                    expiring *   USER_OK        - user is authorized to do his thing */unsigned long int verify_user (username, password, user_status)char           *username;char           *password;unsigned long int *user_status;{	void            upcase_string ();	LONG            SYS$GETTIM (),	                SYS$GETUAI (),	                SYS$HASH_PASSWORD (),	                LIB$ADD_TIMES (),	                LIB$CVT_TO_INTERNAL_TIME ();	LONG            status,	                uai_flags;	QUAD            uai_pwd_date,	                uai_pwd_lifetime,	                uai_pwd,	                putative_pw,	                uai_pwd_expiration,	                tacacs_pw_thresh,	                now,	                warn_if_before;	WORD            uai_salt;	BYTE            uai_encrypt;	struct dsc$descriptor usernameD,	                passwordD;	char           *p,	                Username[256];	/*	 * $GETUAI this user.  Return the following fields: UAI$_FLAGS (we	 * are interested in UAI$V_DISACNT, UAI$V_PWD_EXPIRED) UAI$_PWD_DATE	 * (date of last pw change) UAI$_PWD_LIFETIME UAI$_ENCRYPT	 * (encryption algorithm used) UAI$_SALT UAI$_PWD	 */	ITEM            itmlst[] = {		{4, UAI$_FLAGS, &uai_flags, 0},		{8, UAI$_PWD_DATE, uai_pwd_date, 0},		{8, UAI$_PWD_LIFETIME, uai_pwd_lifetime, 0},		{1, UAI$_ENCRYPT, &uai_encrypt, 0},		{2, UAI$_SALT, &uai_salt, 0},		{8, UAI$_PWD, uai_pwd, 0},		{0, 0, 0, 0}	};/* If the password or the username are empty - return error (HUJI) */	if ((*username == '\0') || (*password == '\0'))		return RMS$_RNF;/* No such user *//* Do not ruin the username - copy it elsewhere */	strcpy (Username, username);	upcase_string (Username);	upcase_string (password);/* Replace all - in username to _ */	while ((p = strchr (Username, '-')) != NULL)		*p = '_';/* If there is .SLIP in it then remove it */	if ((p = strchr (Username, '.')) != NULL)		if (strncmp (p, ".SLIP", 5) == 0)			*p = '\0';	str2desc (usernameD, Username);	status = SYS$GETUAI (0, 0, &usernameD, &itmlst, 0, 0, 0);	if (status == RMS$_RNF || (UAI$M_DISACNT & uai_flags))	{		/*		 * A record was not found for this username, or the guy's		 * disuser'd		 */		*user_status = USER_BOGUS;		return (SS$_NORMAL);	}	iferr (status)		return (status);/* unexpected error of some kind */	/*	 * Now hash the putative password to see if it matches the one on	 * file.	 */	str2desc (passwordD, password);	status = SYS$HASH_PASSWORD (&passwordD, uai_encrypt, uai_salt, &usernameD,				    putative_pw);	iferr (status)		return (status);	if ((putative_pw[0] != uai_pwd[0]) || putative_pw[1] != uai_pwd[1])	{		*user_status = USER_BOGUS;		return (SS$_NORMAL);	}	/* The putative password matches the one on file, but has it expired? */	if (UAI$M_PWD_EXPIRED & uai_flags)	{		*user_status = USER_EXPIRED;		return (SS$_NORMAL);	}	/* Is this password < TACACS_PASSWORD_THRESHOLD days from expiring? */	if (uai_pwd_lifetime[0] == 0 && uai_pwd_lifetime[1] == 0)	{		/* I.e. this password will never expire */		*user_status = USER_OK;		return (SS$_NORMAL);	}	LIB$ADD_TIMES (uai_pwd_date, uai_pwd_lifetime, uai_pwd_expiration);	LIB$CVT_TO_INTERNAL_TIME (&LIB$K_DELTA_DAYS, &TACACS_PASSWORD_THRESHOLD,				  tacacs_pw_thresh);	SYS$GETTIM (now);	LIB$ADD_TIMES (now, tacacs_pw_thresh, warn_if_before);	if (warn_if_before[1] > uai_pwd_expiration[1] ||	((warn_if_before[1] == uai_pwd_expiration[1]) && (warn_if_before[0] >						    uai_pwd_expiration[0])))	{		*user_status = USER_EXPIRING;	}	else	{		*user_status = USER_OK;	}	return (SS$_NORMAL);}				/* verify_user *//* log_transaction *   Log a tacacs authentication transaction to some file. */log_transaction (client, name, tp)struct sockaddr_in *client;char           *name;struct tacacspkt *tp;{	char           *getenv (),	               *inet_ntoa (),	               *ctime ();	FILE           *fopen ();	LONG            logerror ();	int             sprintf (),	                fputs (),	                fclose ();	time_t          time ();	void           *malloc (),	                free ();	LONG            status;	char           *logfilename,	               *nowstring,	               *in_addr_string;	extern char    *tacacs_responses[],	               *tacacs_reasons[];	/* in tacacs-server.h */	char            outstring[BIG_STRING];	FILE           *lf;	time_t         *now;	logfilename = getenv (TACACS_LOG);	if (logfilename == NULL)		return;	lf = fopen (logfilename, "a+");	if (lf == NULL)	{		sprintf (outstring, "error opening TACACS_LOG: %X", vaxc$errno);		logerror (outstring);		return;	}	now = malloc (sizeof (time_t));	*now = time (NULL);	nowstring = malloc (26);/* malloc room for the time string */	nowstring = ctime (now);	nowstring[24] = '\0';	/* trim off newline */	in_addr_string = inet_ntoa (client->sin_addr);	sprintf (outstring, "%s %s(%u) %s Response: %s Reason: %s\n",		 nowstring, in_addr_string, client->sin_port, name,		 tacacs_responses[tp->response], tacacs_reasons[tp->reason]);	fputs (outstring, lf);	free (now);	free (nowstring);	status = fclose (lf);	if (status != 0)	{		sprintf (outstring, "error closing TACACS_LOG: %X", vaxc$errno);		logerror (outstring);	}}				/* log_transaction *//* upcase_string *   Upcase a string in place. */void upcase_string (s)char           *s;{	while (*s)	{		*s = _toupper (*s);		s++;	}}				/* upcase_string *//* tacacs_exit_handler *   Exit handler for the tacacs server.  Our main work here is to *   undo the logical name tomfoolery that init_tacacs_uaf() inflicted on *   our process. * */void tacacs_exit_handler (exit_status)LONG            exit_status;{	LONG            status,	                SYS$DELLNM ();	BYTE            acmode = PSL$C_EXEC;	$DESCRIPTOR (processtable, "LNM$PROCESS_TABLE");	$DESCRIPTOR (processdirectory, "LNM$PROCESS_DIRECTORY");	$DESCRIPTOR (rightslist, "RIGHTSLIST");	$DESCRIPTOR (netproxy, "NETPROXY");	$DESCRIPTOR (sysuaf, "SYSUAF");	$DESCRIPTOR (filedev, "LNM$FILE_DEV");	status = SYS$DELLNM (&processdirectory, &filedev, &acmode);	status = SYS$DELLNM (&processtable, &sysuaf, &acmode);	status = SYS$DELLNM (&processtable, &rightslist, &acmode);	status = SYS$DELLNM (&processtable, &netproxy, &acmode);}				/* tacacs_exit_handler *//* tacacs-routines.c */

⌨️ 快捷键说明

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