diff -Naur tac_plus.F4.0.3.alpha/.directory tac_plus.F4.0.3.alpha-PAM-0.3/.directory --- tac_plus.F4.0.3.alpha/.directory Thu Jan 1 01:00:00 1970 +++ tac_plus.F4.0.3.alpha-PAM-0.3/.directory Wed Sep 15 11:33:33 1999 @@ -0,0 +1,5 @@ +# KDE Config File +[KDE Desktop Entry] +BgImage= +MiniIcon= +Icon= diff -Naur tac_plus.F4.0.3.alpha/Makefile tac_plus.F4.0.3.alpha-PAM-0.3/Makefile --- tac_plus.F4.0.3.alpha/Makefile Sat Apr 3 08:03:48 1999 +++ tac_plus.F4.0.3.alpha-PAM-0.3/Makefile Tue Nov 16 18:05:44 1999 @@ -17,7 +17,7 @@ # LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE. -# CC = gcc +CC = gcc # For AIX # See /usr/lpp/bos/bsdport on your system for details of how to define bsdcc @@ -31,8 +31,8 @@ # OS=-DMIPS # For Solaris (SUNOS 5.3, 5.4, 5.5, 5.6) uncomment the following two lines -OS=-DSOLARIS -OSLIBS=-lsocket -lnsl +#OS=-DSOLARIS +#OSLIBS=-lsocket -lnsl # For FreeBSD # OS=-DFREEBSD @@ -47,9 +47,13 @@ # # On REDHAT 5.0 systems, or systems that use the new glibc, # you might instead need the following: -# OS=-DLINUX -DGLIBC -# OSLIBS=-lcrypt +OS=-DLINUX -DGLIBC +OSLIBS=-lcrypt + +#For PAM +DEFINES = -DUSE_PAM +OSLIBS+= -lpam -ldl -lc # Athough invoked as root, most of the time you don't want tac_plus to # be running as root. If USERID and GROUPID are set, tac_plus will @@ -67,7 +71,7 @@ # INCLUDES = -I../crimelab/skey/src # Debugging flags -DEBUG = -g +DEBUG = -O3 # Enforce a limit on maximum sessions per user. See the user's guide # for more information. @@ -97,7 +101,7 @@ do_author.c dump.c encrypt.c expire.c $(MSCHAP_MD4_SRC) md5.c \ packet.c report.c sendauth.c tac_plus.c utils.c pw.c hash.c \ parse.c regexp.c programs.c enable.c pwlib.c default_fn.c \ - skey_fn.c default_v0_fn.c sendpass.c maxsess.c + skey_fn.c default_v0_fn.c sendpass.c maxsess.c tac_pam_auth.c OBJS = $(SRCS:.c=.o) diff -Naur tac_plus.F4.0.3.alpha/README.PAM tac_plus.F4.0.3.alpha-PAM-0.3/README.PAM --- tac_plus.F4.0.3.alpha/README.PAM Thu Jan 1 01:00:00 1970 +++ tac_plus.F4.0.3.alpha-PAM-0.3/README.PAM Tue Nov 16 18:05:07 1999 @@ -0,0 +1,34 @@ +Tacacs+ with PAM Authentication support. + +patch version 0.3 (17 November 1999) +tac_pam_auth is MT-safe now. +Tacacs reports pam error strings. +More examples into the tac_plus.conf. Corrected the version number at start-up. + +patch version 0.2 (31 August 1999) +Pammified default authentication. If -DUSE_PAM used, I hope that PAM is the default +system authentication method. The PAM service used is the name of the passwd_file (???). +Yes, it's terrible, but I have not time to spend for changing +default authentication = file /etc/passwd + in +default authentication = pam name_of_service..........any volunteer ??? +As usual, look at the tac_plus.conf file. + +patch version 0.1 (August 1999) +I introduced an optional new authetication method via PAM. This makes authentication +modular and external to the tacacs+ code. +I have not implemented pam-authorization because the existence of pre and post autorization +calls. +In order to pass tacacs+ attributes to the pam modules, I use the PAM_RUSER item +for storing the rem_addr. Have a look to tac_pam_auth.c for the details. +As you can see, pam-authentication only works for pap and login authetication-types: +I would like to extend it to the default authetication case, but the code seems so +cryptic :-(....... +You can choose the pam service by the configuration file,for a simple example look +into tac_plus.conf. + + + +Max Liccardo + + diff -Naur tac_plus.F4.0.3.alpha/config.c tac_plus.F4.0.3.alpha-PAM-0.3/config.c --- tac_plus.F4.0.3.alpha/config.c Sat Apr 3 08:03:45 1999 +++ tac_plus.F4.0.3.alpha-PAM-0.3/config.c Mon Sep 13 10:32:39 1999 @@ -48,8 +48,11 @@ := file | skey | - cleartext | + cleartext | des | +#ifdef USE_PAM + pam | +#endif nopassword := name = | @@ -63,6 +66,9 @@ #endif pap = cleartext | pap = des | +#ifdef USE_PAM + pap = pam | +#endif opap = cleartext | global = cleartext | msg = @@ -706,16 +712,25 @@ case S_file: case S_cleartext: case S_des: +#ifdef USE_PAM + case S_pam: +#endif /* USE_PAM */ sprintf(buf, "%s ", sym_buf); sym_get(); strcat(buf, sym_buf); user->login = tac_strdup(buf); break; - + default: +#ifdef USE_PAM + parse_error( + "expecting 'file', 'cleartext', 'pam'.'nopassword', 'skey', or 'des' keyword after 'login =' on line %d", + sym_line); +#else parse_error( "expecting 'file', 'cleartext', 'nopassword', 'skey', or 'des' keyword after 'login =' on line %d", sym_line); +#endif /* USE_PAM */ } sym_get(); continue; @@ -733,16 +748,29 @@ case S_cleartext: case S_des: +#ifdef USE_PAM + case S_pam: +#endif /*USE_PAM */ sprintf(buf, "%s ", sym_buf); sym_get(); strcat(buf, sym_buf); user->pap = tac_strdup(buf); + break; + + sprintf(buf, "%s ", sym_buf); + user->pap = tac_strdup(buf); break; default: +#ifdef USE_PAM + parse_error( + "expecting 'cleartext', 'pam', or 'des' keyword after 'pap =' on line %d", + sym_line); +#else parse_error( "expecting 'cleartext', or 'des' keyword after 'pap =' on line %d", sym_line); +#endif /*USE_PAM */ } sym_get(); continue; diff -Naur tac_plus.F4.0.3.alpha/parse.c tac_plus.F4.0.3.alpha-PAM-0.3/parse.c --- tac_plus.F4.0.3.alpha/parse.c Sat Apr 3 08:03:46 1999 +++ tac_plus.F4.0.3.alpha-PAM-0.3/parse.c Mon Sep 13 10:32:40 1999 @@ -71,6 +71,9 @@ declare("ms-chap", S_mschap); #endif /* MSCHAP */ declare("cleartext", S_cleartext); +#ifdef USE_PAM + declare("pam", S_pam); +#endif /*USE_PAM */ declare("nopassword", S_nopasswd); declare("cmd", S_cmd); declare("default", S_default); @@ -182,6 +185,10 @@ return ("opap"); case S_cleartext: return ("cleartext"); +#ifdef USE_PAM + case S_pam: + return ("pam"); +#endif /*USE_PAM */ case S_nopasswd: return("nopassword"); case S_des: diff -Naur tac_plus.F4.0.3.alpha/parse.h tac_plus.F4.0.3.alpha-PAM-0.3/parse.h --- tac_plus.F4.0.3.alpha/parse.h Sat Apr 3 08:03:47 1999 +++ tac_plus.F4.0.3.alpha-PAM-0.3/parse.h Mon Sep 13 10:32:41 1999 @@ -75,3 +75,6 @@ #ifdef MSCHAP #define S_mschap 42 #endif /* MSCHAP */ +#ifdef USE_PAM +#define S_pam 43 +#endif /*USE_PAM */ diff -Naur tac_plus.F4.0.3.alpha/pwlib.c tac_plus.F4.0.3.alpha-PAM-0.3/pwlib.c --- tac_plus.F4.0.3.alpha/pwlib.c Sat Apr 3 08:03:47 1999 +++ tac_plus.F4.0.3.alpha-PAM-0.3/pwlib.c Mon Sep 13 10:32:40 1999 @@ -24,6 +24,11 @@ #include #endif +#ifdef USE_PAM +int +tac_pam_auth(char *UserName,char *Password,struct authen_data *data,char *Service); +#endif /* USE_PAM */ + /* Generic password verification routines for des, file and cleartext passwords */ @@ -119,7 +124,27 @@ if (!cfg_passwd) { char *file = cfg_get_authen_default(); if (file) { +#ifdef USE_PAM + if (debug & DEBUG_PASSWD_FLAG) + report(LOG_DEBUG, "verify daemon %s == NAS %s", p, passwd); + if (tac_pam_auth(name, passwd, data,file)) { + if (debug & DEBUG_PASSWD_FLAG) + report(LOG_DEBUG, "Password is incorrect"); + data->status = TAC_PLUS_AUTHEN_STATUS_FAIL; + return(0); + } else { + data->status = TAC_PLUS_AUTHEN_STATUS_PASS; + + if (debug & DEBUG_PASSWD_FLAG) + report(LOG_DEBUG, "Password is correct"); + } + + exp_date = cfg_get_expires(name, recurse); + set_expiration_status(exp_date, data); + return (data->status == TAC_PLUS_AUTHEN_STATUS_PASS); +#else return (passwd_file_verify(name, passwd, data, file)); +#endif /* USE_PAM */ } /* otherwise, we fail */ @@ -130,6 +155,7 @@ /* We have a configured password. Deal with it depending on its type */ + p = tac_find_substring("cleartext ", cfg_passwd); if (p) { if (debug & DEBUG_PASSWD_FLAG) @@ -151,6 +177,31 @@ set_expiration_status(exp_date, data); return (data->status == TAC_PLUS_AUTHEN_STATUS_PASS); } + +#ifdef USE_PAM + p = tac_find_substring("pam ", cfg_passwd); + if (p) { + if (debug & DEBUG_PASSWD_FLAG) + report(LOG_DEBUG, "verify daemon %s == NAS %s", p, passwd); + + if (tac_pam_auth(name, passwd, data,p)) { + if (debug & DEBUG_PASSWD_FLAG) + report(LOG_DEBUG, "Password is incorrect"); + data->status = TAC_PLUS_AUTHEN_STATUS_FAIL; + return(0); + } else { + data->status = TAC_PLUS_AUTHEN_STATUS_PASS; + + if (debug & DEBUG_PASSWD_FLAG) + report(LOG_DEBUG, "Password is correct"); + } + + exp_date = cfg_get_expires(name, recurse); + set_expiration_status(exp_date, data); + return (data->status == TAC_PLUS_AUTHEN_STATUS_PASS); + } + +#endif /* USE_PAM */ p = tac_find_substring("des ", cfg_passwd); if (p) { diff -Naur tac_plus.F4.0.3.alpha/tac_pam_auth.c tac_plus.F4.0.3.alpha-PAM-0.3/tac_pam_auth.c --- tac_plus.F4.0.3.alpha/tac_pam_auth.c Thu Jan 1 01:00:00 1970 +++ tac_plus.F4.0.3.alpha-PAM-0.3/tac_pam_auth.c Thu Nov 18 14:55:55 1999 @@ -0,0 +1,133 @@ +/* tac_pam_auth.c + * A simple pam authentication routine written by Max Liccardo + * PAM_RUSER=username/rem_addr. + */ + + + /* + This program was contributed by Shane Watts + [modifications by AGM] + + You need to add the following (or equivalent) to the /etc/pam.conf file. + # check authorization + check_user auth required /usr/lib/security/pam_unix_auth.so + check_user account required /usr/lib/security/pam_unix_acct.so + */ +#ifdef USE_PAM + +#include +#include +#include +#include +#include "tac_plus.h" + +typedef struct +{ + char *UserName; + char *Passwd; +} UserCred; + + +static int fconv(int num_msg, const struct pam_message **msg, + struct pam_response **resp,void *appdata_ptr) +{ + int i; + UserCred *lUserCred; + + + lUserCred = appdata_ptr; + + if(lUserCred == NULL) + { + report(LOG_ERR,"argh....maybe a SunOs 5.6 ???"); + return(PAM_CONV_ERR); + } + + + *resp = (struct pam_response *) calloc(num_msg,sizeof(struct pam_response)); + + for(i=0;imsg_style) + { + case PAM_PROMPT_ECHO_OFF: + resp[i]->resp = strdup(lUserCred->Passwd); + break; + + case PAM_PROMPT_ECHO_ON: + resp[i]->resp = strdup(lUserCred->UserName); + break; + + default: + report(LOG_DEBUG,"conv default"); + break; + } + resp[i]->resp_retcode = 0; + } + + return(PAM_SUCCESS); +} + + + + +int +tac_pam_auth(char *aszUserName,char *aszPassword,struct authen_data *data, + char *aszService) +{ + pam_handle_t *pamh=NULL; + int retval; + char *lpszRemoteUser; /* Username/NAC address */ + struct pam_conv s_conv; + UserCred s_UserCred; + + + s_UserCred.UserName = aszUserName; + s_UserCred.Passwd = aszPassword; + + s_conv.conv = fconv; + s_conv.appdata_ptr = (void *) &s_UserCred; + + + if((lpszRemoteUser = calloc(strlen(aszUserName)+strlen(data->NAS_id->NAC_address)+2,sizeof(char))) == NULL) + { + report(LOG_ERR,"cannot malloc"); + return(1); + } + + retval = pam_start(aszService,aszUserName , &s_conv, &pamh); + + if (retval != PAM_SUCCESS) + { + report(LOG_ERR, "cannot start pam-authentication"); + pamh = NULL; + return(1); + } + + sprintf(lpszRemoteUser,"%s:%s",aszUserName,data->NAS_id->NAC_address); + + pam_set_item(pamh,PAM_RUSER,lpszRemoteUser); + pam_set_item(pamh,PAM_RHOST,data->NAS_id->NAS_name); + pam_set_item(pamh,PAM_TTY,data->NAS_id->NAS_port); + + free(lpszRemoteUser); + + retval = pam_authenticate(pamh,0); /* is user really user? */ + + if(retval != PAM_SUCCESS) + report(LOG_ERR, "%s",pam_strerror(pamh,retval)); + + if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */ + pamh = NULL; + return(1); + } + + return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */ +} + + +#endif /* USE_PAM */ + + + + diff -Naur tac_plus.F4.0.3.alpha/tac_plus.conf tac_plus.F4.0.3.alpha-PAM-0.3/tac_plus.conf --- tac_plus.F4.0.3.alpha/tac_plus.conf Thu Jan 1 01:00:00 1970 +++ tac_plus.F4.0.3.alpha-PAM-0.3/tac_plus.conf Tue Nov 16 18:03:58 1999 @@ -0,0 +1,23 @@ +#tac_plus.conf - a simple configuration file + +key = "Cisco" + +# in PAM mode, we're using the pam-login service +default authentication = file login + +accounting file = "/var/log/tactest.acct" + +user=DEFAULT { + default service = permit +} + +# repeat as necessary for each user +user=test { + default service = permit +# in order to work, you need the file /etc/pam.d/login or a "login" entry into the /etc/pam.conf file + login = pam login + +# in order to work, you need the file /etc/pam.d/pap or a "pap" entry into the /etc/pam.conf file + pap = pam pap +} + diff -Naur tac_plus.F4.0.3.alpha/tac_plus.h tac_plus.F4.0.3.alpha-PAM-0.3/tac_plus.h --- tac_plus.F4.0.3.alpha/tac_plus.h Sat Apr 3 08:03:47 1999 +++ tac_plus.F4.0.3.alpha-PAM-0.3/tac_plus.h Mon Sep 13 10:32:42 1999 @@ -68,7 +68,7 @@ */ /* #define REARMSIGNAL */ -#define VERSION "F4.0.3.alpha" +#define VERSION "F4.0.3.alpha-PAM-0.3" /* * System definitions. diff -Naur tac_plus.F4.0.3.alpha/tac_plus.init tac_plus.F4.0.3.alpha-PAM-0.3/tac_plus.init --- tac_plus.F4.0.3.alpha/tac_plus.init Thu Jan 1 01:00:00 1970 +++ tac_plus.F4.0.3.alpha-PAM-0.3/tac_plus.init Mon Sep 13 15:01:34 1999 @@ -0,0 +1,46 @@ +#!/bin/sh +# +# tacacs+ This shell script takes care of starting and stopping +# Tacacs+. +# + + +TAC_PLUS=/usr/local/bin/tac_plus +TAC_CONF=/etc/tac_plus.conf +TAC_LOG=/var/log/tac_plus.log +DEBUG_LEVEL=280 + +[ -f $TAC_PLUS ] || exit 0 + +[ -f $TAC_CONF ] || exit 0 + +# See how we were called. +case "$1" in + start) + # Start daemons. + echo "Starting tacacs+ " + $TAC_PLUS -C $TAC_CONF -d $DEBUG_LEVEL -l $TAC_LOG + ;; + stop) + # Stop daemons. + echo "Shutting down tac_plus: " + kill `cat /etc/tac_plus.pid` + echo "done" + ;; + status) + status tac_plus + exit $? + ;; + restart) + $0 stop + $0 start + ;; + reload) + kill -USR1 `cat /etc/tac_plus.pid` + ;; + *) + echo "Usage: tac_plus {start|stop|status|restart|reload}" + exit 1 +esac + +exit 0