xtacacsd.c

来自「RADIUS协议的认证计费服务」· C语言 代码 · 共 1,593 行 · 第 1/3 页

C
1,593
字号
		}	}#else				/* VMS */	if (pw_verify (name, passwd, &pw))	{		tp->oresponse = TA_A_ACCEPTED;		tp->oreason = TA_A_NONE;		/*		 * Now check the expiration time.		 */		expired = check_expiration (pw->pw_shell);		if (expired == 2)		{			tp->oresponse = TA_A_DENIED;			tp->oreason = TA_A_EXPIRING;		}		else if (expired == 1)			tp->oreason = TA_A_EXPIRING;	}#endif				/* VMS */o_ok:	if (logging)	{#ifdef VMS		syslog (LOG_INFO, "login query for %s@%s %s\n", name,			(char *) inet_ntoa (from.sin_addr),		  tp->oresponse == TA_A_ACCEPTED ? "accepted" : "rejected");#else				/* VMS */		if (pw != NULL)			syslog (LOG_INFO, "login query for %s (%s) %s\n", name, pw->pw_gecos,				tp->oresponse == TA_A_ACCEPTED ? "accepted" : "rejected");		else			syslog (LOG_INFO, "login query for %s %s\n", name,				tp->oresponse == TA_A_ACCEPTED ? "accepted" : "rejected");#endif				/* VMS */	}	tp->type = TA_ANSWER;	if (sendto (s, buf, sizeof (tacacstype), 0, client,		    sizeof (struct sockaddr_in)) != sizeof (tacacstype))		syslog (LOG_ERR, "write: %m\n");#ifndef SYSV	free (name);	free (passwd);#endif#ifdef DEBUG	fprintf (stderr, "process: done\r\n");#endif}/* * new_process * Perform necessary stuff to do a query operation. Return ANSWER. */new_process (s, client, buf)int             s;struct sockaddr_in *client;newxtacacstype *buf;{#ifdef DEBUG	fprintf (stderr, "new_process: start\r\n");#endif	querytime = time (NULL);	switch (buf->tp.type)	{	    case XTA_SLIPADDR:	    case XTA_LOGIN:		xlogin (s, client, buf);		break;	    case XTA_CONNECT:		xconnect (s, client, buf->tp);		break;	    case XTA_ENABLE:		xenable (s, client, buf->tp);		break;	    case XTA_LOGOUT:		xlogout (s, client, buf->tp);		break;	    case XTA_RELOAD:		xreload (s, client, buf->tp);		break;	    case XTA_SLIPON:		xslipon (s, client, buf->tp);		break;	    case XTA_SLIPOFF:		xslipoff (s, client, buf->tp);		break;	    default:		if (logging)			syslog (LOG_INFO, "illegal type specified: %d\n", buf->tp.type);	}}#ifndef VMScheck_expiration (date)char           *date;{	long            day,	                month,	                year,	                leaps,	                now,	                expiration,	                warning;	char            monthstr[10];	/*	 * If no date or a shell, let it pass.  (Backward compatability.)	 */	if (!date || (strlen (date) == 0) || (*date == '/'))		return (0);	/*	 * Parse date string.  Fail it upon error.	 */	if (sscanf (date, "%s %d %d", monthstr, &day, &year) != 3)		return (2);	/*	 * Compute the expiration date in days.	 */	for (month = 0; month < 12; month++)		if (strncmp (monthstr, monthname[month], 3) == 0)			break;	if (month > 11)		return (2);	leaps = (year - 1969) / 4 + (((year % 4) == 0) && (month > 2));	expiration = (((year - 1970) * 365) + days_ere_month[month] + (day - 1) + leaps);	warning = expiration - WARNING_PERIOD;	/*	 * Get the current time (to the day)	 */	now = querytime / SEC_IN_DAY;	if (now > expiration)		return (2);	if (now > warning)		return (1);	return (0);}#endif				/* VMS */#ifndef BSD43#ifndef VMS/* * setpwfile * Hack to get around the default for the pw routines using /etc/passwd */#include <sys/stat.h>setpwfile (file)char           *file;{	FILE           *f;	struct stat     pwbuf,	                fbuf;	int             i;	char           *c;	if (stat ("/etc/passwd", &pwbuf) < 0)	{		syslog (LOG_ERR, "stat: %m\n");		exit (1);	}	setpwent ();		/* open /etc/passwd */	/*	 * This loop assumes that the stdio file buffers are contiguous which	 * isn't true for 4.3, but then we won't be here.	 */	for (f = stderr + 1; f < stdin + getdtablesize (); f++)		if (f->_flag & (_IOREAD | _IOWRT | _IORW) &&				fstat (fileno (f), &fbuf) >= 0 &&				pwbuf.st_dev == fbuf.st_dev &&				pwbuf.st_ino == fbuf.st_ino)		{			freopen (file, "r", f);			fprintf (stderr, "hit at %d\n", fileno (f));			return;		}	syslog (LOG_ERR, "couldn't find /etc/passwd to replace\n");	exit (1);}#endif				/* VMS */#endif#ifdef SYSVgetdtablesize (){	return (_NFILE);}#endifwtmp_entry (line, name, host)char           *line,               *name,               *host;{#ifdef VMS	return;			/* No WTMP file support yet */#else				/* VMS */	struct utmp     entry;	if (wtmpf == NULL)		return;	bzero (&entry, sizeof entry);	if (strlen (line) < sizeof entry.ut_line)		strcpy (entry.ut_line, line);	else		bcopy (line, entry.ut_line, sizeof entry.ut_line);	if (strlen (name) < sizeof entry.ut_name)		strcpy (entry.ut_name, name);	else		bcopy (name, entry.ut_name, sizeof entry.ut_name);	if (strlen (host) < sizeof entry.ut_host)		strcpy (entry.ut_host, host);	else		bcopy (host, entry.ut_host, sizeof entry.ut_host);	entry.ut_time = querytime;	if (fwrite (&entry, sizeof entry, 1, wtmpf) != 1)	{		if (logging)			syslog (LOG_ERR, "couldn't write syslog file\n");	}	else		fflush (wtmpf);#ifdef DEBUG1	fprintf (stderr, "\nwtmp: %s, %s %s %d", line, name, host, querytime);#endif#endif				/* VMS */}xlogin (s, client, buf)int             s;struct sockaddr_in *client;register newxtacacstype *buf;{#ifdef SYSV	char            name[SOME_ARBITRARILY_LARGE_NUMBER];	char            passwd[SOME_ARBITRARILY_LARGE_NUMBER];#else	char           *name,	               *passwd,	               *secret,	               *filename;	char           *vector,	               *buffer_ptr;	uchar           buffer[BUFSIZ];	uchar           digest[32];#endif#ifdef VMS	int             pw,	                i;#else				/* VMS */	struct passwd  *pw;#endif				/* VMS */	int             expired;	char            linename[20];#ifdef DEBUG	fprintf (stderr, "xlogin: starting\r\n");	fprintf (stderr, "xlogin: namelen %d, pwdlen %d\r\n",		 buf->tp.namelen, buf->tp.pwlen);#endif#ifndef SYSV	name = (char *) malloc (buf->tp.namelen + 1);	if (name == NULL)		perror ("Malloc");	passwd = (char *) malloc (buf->tp.pwlen + 1);	if (passwd == NULL)		perror ("Malloc");	secret = (char *) malloc (40);	if (secret == NULL)		perror ("Malloc");	if (name == NULL || passwd == NULL)		return;#endif				/* not SYSV *//*    strncpy(name, ((char *)tp)+XTACACSSIZE, tp->namelen); */	strncpy (name, buf->data, buf->tp.namelen);/*   name[tp->namelen] = '\0'; */	name[buf->tp.namelen] = '\0';/*    strncpy(passwd, ((char *)tp)+XTACACSSIZE + tp->namelen + 1,              tp->pwlen-1); */	strncpy (passwd, &(buf->data[buf->tp.namelen + 1]), buf->tp.pwlen - 1);/*    if (tp->pwlen > PASSWD_LENGTH)	tp->pwlen = PASSWD_LENGTH;    passwd[tp->pwlen] = '\0';*/	if (buf->tp.pwlen > PASSWD_LENGTH)		buf->tp.pwlen = PASSWD_LENGTH;	passwd[buf->tp.pwlen] = '\0';/* 16 uchar random vector to be appended to the secret *//*    vector = (char *) ((char *) tp + sizeof(*tp) +		       (u_long) tp->namelen + (u_long) tp->pwlen);*/	vector = &(buf->data[buf->tp.namelen + buf->tp.pwlen]);	if (get_secret (secret) < 0)	{		fprintf (stderr, "Access Denied");		return;	}	strcpy (buffer, secret);	buffer_ptr = (char *) (buffer + (u_long) strlen (secret));	memcpy (buffer_ptr, vector, VECTOR_LEN);	md5_calc (digest, buffer, strlen (secret) + VECTOR_LEN);	for (i = 0; i < strlen (secret); i++)		passwd[i] ^= digest[i];#ifdef DEBUG/*    fprintf(stderr, "packet: %s %s\r\n", (char *)(tp + 1),	    (char *)(tp + 1) + tp->namelen);    fprintf(stderr, "local:  %s %s\r\n", name, passwd);*/#endif#ifdef DEBUG1	fprintf (stderr, "\nxlogin: user %s on tty%x, host %s", name, buf->tp.lport,		 SenderHost);#endif	/*	 * Assume failure	 */	buf->tp.response = TA_A_REJECTED;	buf->tp.reason = TA_A_DENIED;/* HUJI - check whether the user is in our local database */	{		char            phone[256],		                flags;		if (get_user_entry (name, passwd, &flags, phone))		{		/* got it ok */			if (flags & F_DIALBACK)			{	/* Need a dialback */				syslog (LOG_INFO, "Dialback requested by '%s' to phone %s\n",					name, phone);				buf->tp.reason = TA_A_EXPIRING;	/* Reject with expired								 * message */			}			else			{	/* OK - let him in */				syslog (LOG_INFO, "User '%s' passed-in according to NUI file\n",					name);				buf->tp.response = TA_A_ACCEPTED;				buf->tp.reason = TA_A_NONE;			}			goto n_ok;	/* jump over the regular					 * authorization */		}	}/* HUJI - If there is @ or % then remove it and check the address. If it is ours -   continue as usual. If not, and if the other machine is listed in the ones   we trust - ask it */	{		char           *p;		p = strchr (name, '@');		if (p == NULL)			p = strchr (name, '%');		if (p != NULL)		{			*p++ = '\0';	/* Remove the @ from the username */			upcase_string (p);			if (strcmp (p, LOCAL_INTERNET_NAME) != 0)			{	/* Not us */				verify_user_remote (p, name, passwd);				goto RemoteVerified;			}		}	}/* HUJI - end of modifications */#ifdef VMS	if (check_username (name, filename) == 1)	{		if ((verify_user (name, passwd, &pw) & 0x1) == 1)		{		/* Verify returned ok */			if (pw == USER_OK)			{				buf->tp.response = TA_A_ACCEPTED;				buf->tp.reason = TA_A_NONE;			}			else if (pw == USER_EXPIRING)			{				buf->tp.response = TA_A_ACCEPTED;				buf->tp.reason = TA_A_EXPIRING;			}			else if (pw == USER_EXPIRED)			{				buf->tp.response = TA_A_DENIED;				buf->tp.reason = TA_A_EXPIRING;			}		}	}#else				/* VMS */	if (pw_verify (name, passwd, &pw))	{		buf->tp.response = XTA_A_ACCEPTED;		buf->tp.reason = XTA_A_NONE;		buf->tp.uuid = pw->pw_uid;		buf->tp.accesslist = pw->pw_gid;		buf->tp.flags = xta_getflags (pw->pw_gecos);		/*		 * Now check the expiration time.		 */		expired = check_expiration (pw->pw_shell);		if (expired == 2)		{			buf->tp.response = TA_A_DENIED;			buf->tp.reason = TA_A_EXPIRING;		}		else if (expired == 1)			buf->tp.reason = TA_A_EXPIRING;	}#endif				/* VMS */n_ok:RemoteVerified:	sprintf (linename, "TTY%x", buf->tp.lport);	if (buf->tp.response == TA_A_ACCEPTED && buf->tp.type == XTA_LOGIN)		wtmp_entry (linename, name, SenderHost);	if (logging && buf->tp.type == XTA_LOGIN)	{#ifdef VMS		syslog (LOG_INFO, "xlogin query from %s %s for %s %s\n",			SenderHost,			linename, name,		buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");#else				/* VMS */		if (pw != NULL)			syslog (LOG_INFO, "xlogin query from %s %s for %s (%s) %s\n",				SenderHost,				linename, name, pw->pw_gecos,				buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");		else			syslog (LOG_INFO, "xlogin query from %s %s for %s %s\n",				SenderHost,				linename, name,				buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");#endif				/* VMS */	}	if (logging && buf->tp.type == XTA_SLIPADDR)	{#ifdef VMS		syslog (LOG_INFO, "slipaddress from %s %s for %s %s\n",			SenderHost,			linename, name,		buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");#else				/* VMS */		if (pw != NULL)			syslog (LOG_INFO, "slipaddress from %s %s for %s (%s) %s\n",				SenderHost,				linename, name, pw->pw_gecos,				buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");		else			syslog (LOG_INFO, "slipaddress from %s %s for %s %s\n",				SenderHost,				linename, name,				buf->tp.response == TA_A_ACCEPTED ? "accepted" : "rejected");#endif	}	buf->tp.type = TA_ANSWER;	/* We want to copy the current data stored in tp to buffer */	/*	 * we want to copy the vector we received from the sender to the end	 * of the packet we want to send to md5	 */

⌨️ 快捷键说明

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