Only in radiusd-cistron-1.5.4.3: README.1st diff -u -r radiusd-cistron-1.5.4.3.orig/doc/README radiusd-cistron-1.5.4.3/doc/README --- radiusd-cistron-1.5.4.3.orig/doc/README Sat Oct 31 22:10:11 1998 +++ radiusd-cistron-1.5.4.3/doc/README Fri Nov 6 21:03:43 1998 @@ -148,7 +148,14 @@ Exec-Program string program to execute after authentication Exec-Program-Wait string ditto, but wait for program to finish before sending back auth. reply - + Exec-Program-Timeout string same as Exec-Program-Wait, except when + auth is OK (zero exit status), stdout of + program will show session timeout in + seconds + Exec-Program-Account string same as Exec-Program, except that it is + called on arrival of accounting (not + authentication!) messages. + Exec-Program can take arguments. You can use macros in the arguments: %p Port number @@ -157,6 +164,16 @@ %u User name %a Protocol (SLIP/PPP) %s Speed (connect string - eg "28800/V42.BIS") + %e Length of session (Acct-Session-Time attribute), in seconds + %d Delay Time (Acct-Delay-Time attribute), in seconds + %i Session ID (Acct-Session-ID attribute) + %r Input-Octets (Acct-Input-Octets attribute) + %w Output-Octets (Acct-Output-Octets attribute) + %q Input-Packets (Acct-Input-Packets attribute) + %y Output-Packets (Acct-Output-Packets attribute) + + Be aware that %e, %d and %i macros have meaning only when used with + Exec-Program-Account attribute. For example, use the following entry for someone who has BSMTP (queued SMTP) service. "brunq" is the program that runs the SMTP queue. @@ -169,6 +186,38 @@ denied to the user. If the external program printed something on its standard output, this will be sent along with the rejection as Port-Message. + If Exec-Program-Timeout returns a non-zero exit status, access will be + denied to the user. If the external program printed something on its + standard output, this will be sent along with the rejection as Port-Message. + If exit status is zero, access will be enabled to the user, and + Session-Timeout will be set to value which is printed on standard output + (in seconds). If this value is zero, no Session-Timeout will be set. + If Exec-Program-Timeout attribute is present, any other manually set + Session-Timeout attribute will be deleted. It means that attribute + Exec-Program-Timeout excludes Session-Timeout attribute. + + When external program is called due to presence of Exec-Program-Account + attribute, radiusd will not wait for it to finish and will not chech its exit + status. Exec-Program-Account atrtibute is to be set in users file, and + You must be very careful where to place it, since users file is not scanned + during accounting process in radiusd normal behaviour. I suggest to place it + in the beginning of the file, before any other statements (to make sure that it + is the only statement used from users file during accounting). For example: + + # Beginning of users file + # + + DEFAULT Acct-Status-Type = "Start" + Exec-Program-Account = "/usr/local/radius/acct-start %u %i %p %n %f %a %s %e %d" + + DEFAULT Acct-Status-Type = "Stop" + Exec-Program-Account = "/usr/local/radius/acct-stop %u %i %p %n %f %a %s %e %d" + + # ... other statements ... + + Note that there is no "Fall-Through" statement, and that it is possible to + use separate programs for "Start" and "Stop" accounting requests. + 5. LOG FILES 5a. /var/log/radutmp diff -u -r radiusd-cistron-1.5.4.3.orig/raddb/dictionary radiusd-cistron-1.5.4.3/raddb/dictionary --- radiusd-cistron-1.5.4.3.orig/raddb/dictionary Tue Nov 3 01:08:07 1998 +++ radiusd-cistron-1.5.4.3/raddb/dictionary Fri Nov 6 21:08:13 1998 @@ -73,6 +73,8 @@ ATTRIBUTE Acct-Session-Id 44 string ATTRIBUTE Acct-Authentic 45 integer ATTRIBUTE Acct-Session-Time 46 integer +ATTRIBUTE Acct-Input-Packets 47 integer +ATTRIBUTE Acct-Output-Packets 48 integer ATTRIBUTE Acct-Terminate-Cause 49 integer ATTRIBUTE CHAP-Challenge 60 string ATTRIBUTE NAS-Port-Type 61 integer @@ -93,6 +95,8 @@ ATTRIBUTE Exec-Program-Wait 1039 string ATTRIBUTE Hint 1040 string ATTRIBUTE Pam-Auth 1041 string +ATTRIBUTE Exec-Program-Timeout 1042 string +ATTRIBUTE Exec-Program-Account 1043 string # # Non-Protocol Attributes diff -u -r radiusd-cistron-1.5.4.3.orig/src/Makefile radiusd-cistron-1.5.4.3/src/Makefile --- radiusd-cistron-1.5.4.3.orig/src/Makefile Sat Oct 31 22:19:57 1998 +++ radiusd-cistron-1.5.4.3/src/Makefile Fri Nov 6 21:57:18 1998 @@ -21,8 +21,8 @@ DBM = -DNDBM DBMLIB = -ldb -#PAM = -DPAM -#PAMLIB = -lpam -ldl +PAM = -DPAM +PAMLIB = -lpam -ldl BINDIR = /usr/local/bin SBINDIR = /usr/local/sbin diff -u -r radiusd-cistron-1.5.4.3.orig/src/acct.c radiusd-cistron-1.5.4.3/src/acct.c --- radiusd-cistron-1.5.4.3.orig/src/acct.c Sun Nov 1 00:22:13 1998 +++ radiusd-cistron-1.5.4.3/src/acct.c Fri Nov 6 21:06:15 1998 @@ -197,6 +197,56 @@ return 0; } +/* + * Move attributes from one list to the other + * if not already present. + */ +static void pairmove(VALUE_PAIR **to, VALUE_PAIR **from) +{ + VALUE_PAIR *tail, *i, *next; + VALUE_PAIR *last = NULL; + int has_password = 0; + + if (*to == NULL) { + *to = *from; + *from = NULL; + return; + } + + tail = *to; + for(i = *to; i; i = i->next) { + if (i->attribute == PW_PASSWORD || + i->attribute == PW_CHAP_PASSWORD || + i->attribute == PW_CRYPT_PASSWORD) + has_password = 1; + tail = i; + } + + for(i = *from; i; i = next) { + next = i->next; + if (has_password && + (i->attribute == PW_PASSWORD || + i->attribute == PW_CHAP_PASSWORD || + i->attribute == PW_CRYPT_PASSWORD)) { + last = i; + continue; + } + if (i->attribute == PW_FALL_THROUGH || + (i->attribute != PW_HINT && + pairfind(*to, i->attribute) != 0)) { + last = i; + continue; + } + if (last) + last->next = next; + else + *from = next; + tail->next = i; + i->next = NULL; + tail = i; + } +} + /* * Store logins in the RADIUS utmp file. @@ -206,6 +256,8 @@ struct radutmp ut, u; struct utmp wt; VALUE_PAIR *vp; + VALUE_PAIR *user_check = NULL; + VALUE_PAIR *user_reply = NULL; int rb_record = 0; int status = -1; int nas_address = 0; @@ -216,6 +268,8 @@ int fd; int ret = 0; int just_an_update = 0; + int exec_account = 0; + char *exec_account_program = NULL; /* * Which type is this. @@ -284,6 +338,17 @@ hints_setup(authreq->request); presuf_setup(authreq->request); } + + /* + * Add attributes from users file for this username + */ + if (user_find((pairfind(authreq->request, PW_USER_NAME))->strvalue, + authreq->request, &user_check, &user_reply) == 0) { + pairmove(&(authreq->request), &user_reply); + pairfree(user_reply); + pairfree(user_check); + } + time(&t); memset(&ut, 0, sizeof(ut)); memset(&wt, 0, sizeof(wt)); @@ -324,6 +389,10 @@ if (vp->lvalue >= 0 && vp->lvalue <= 4) ut.porttype = porttypes[vp->lvalue]; break; + case PW_EXEC_PROGRAM_ACCOUNT: + exec_account = 1; + exec_account_program = strdup(vp->strvalue); + break; } } @@ -496,7 +565,13 @@ fclose(fp); } - + /* + * Call external accounting program. + */ + if (exec_account) + radius_exec_program(exec_account_program, + authreq->request, authreq->request, 0, NULL ); + return ret; } diff -u -r radiusd-cistron-1.5.4.3.orig/src/auth.c radiusd-cistron-1.5.4.3/src/auth.c --- radiusd-cistron-1.5.4.3.orig/src/auth.c Thu Oct 8 20:12:43 1998 +++ radiusd-cistron-1.5.4.3/src/auth.c Fri Nov 6 21:56:38 1998 @@ -500,6 +500,7 @@ VALUE_PAIR *user_check; VALUE_PAIR *user_reply; VALUE_PAIR *proxy_pairs; + VALUE_PAIR *session_timeout; int result, r; char pw_digest[16]; char userpass[128]; @@ -509,6 +510,9 @@ char *exec_program; int exec_wait; int seen_callback_id; + int exec_timeout; + DICT_ATTR *attr; + user_check = NULL; user_reply = NULL; @@ -673,6 +677,7 @@ */ exec_program = NULL; exec_wait = 0; + exec_timeout = 0; if ((auth_item = pairfind(user_reply, PW_EXEC_PROGRAM)) != NULL) { exec_wait = 0; exec_program = strdup(auth_item->strvalue); @@ -683,6 +688,14 @@ exec_program = strdup(auth_item->strvalue); pairdelete(&user_reply, PW_EXEC_PROGRAM_WAIT); } + if ((auth_item = pairfind(user_reply, PW_EXEC_PROGRAM_TIMEOUT)) != NULL) { + exec_wait = 1; + exec_timeout = 1; + exec_program = strdup(auth_item->strvalue); + pairdelete(&user_reply, PW_EXEC_PROGRAM_TIMEOUT); + if (pairfind(user_reply, PW_SESSION_TIMEOUT)) + pairdelete(&user_reply, PW_SESSION_TIMEOUT); + } /* * Hack - allow % expansion in certain value strings. @@ -723,6 +736,32 @@ pairfree(user_check); pairfree(user_reply); return 0; + } else if (exec_timeout) { + /* + * session_timeout is stored in user_msg + */ + if (atoi(user_msg)) { + /* + * set actuall session_timeout, if not + * equal to 0; otherwise there is no + * session_timeout + */ + if((session_timeout = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) == + (VALUE_PAIR *)NULL) { + log(L_CONS|L_ERR, "no memory"); + exit(1); + } + attr = dict_attrfind( "Session-Timeout" ); + strcpy(session_timeout->name, attr->name); + session_timeout->attribute = attr->value; + session_timeout->type = attr->type; + session_timeout->lvalue = (UINT4)atoi(user_msg); + pairadd(&user_reply, session_timeout); + log(L_AUTH, + "Login OK: session_timeout=%i", + session_timeout->lvalue); + } + user_msg = NULL; } } diff -u -r radiusd-cistron-1.5.4.3.orig/src/exec.c radiusd-cistron-1.5.4.3/src/exec.c --- radiusd-cistron-1.5.4.3.orig/src/exec.c Fri Oct 2 14:31:44 1998 +++ radiusd-cistron-1.5.4.3/src/exec.c Fri Nov 6 21:40:37 1998 @@ -34,6 +34,13 @@ * %t MTU * %a Protocol (SLIP/PPP) * %s Speed (PW_CONNECT_INFO) + * %e Session-Time (PW_ACCT_SESSION_TIME) + * %d Delay-Time (PW_ACCT_DELAY_TIME) + * %i Session-ID (PW_ACCT_SESSION_ID) + * %r Input-Octets (PW_ACCT_INPUT_OCTETS) + * %w Output-Octets (PW_ACCT_OUTPUT_OCTETS) + * %q Input-Packets (PW_ACCT_INPUT_PACKETS) + * %y Output-Packets (PW_ACCT_OUTPUT_PACKETS) * */ char *radius_xlate(char *str, VALUE_PAIR *request, VALUE_PAIR *reply) @@ -122,6 +129,68 @@ strcpy(buf + i, "unknown"); i += strlen(buf + i); break; + case 'e': /* Session-Time */ + n = 0; + if ((tmp = pairfind(request, + PW_ACCT_SESSION_TIME)) != NULL) { + n = tmp->lvalue; + } + sprintf(buf + i, "%d", n); + i += strlen(buf + i); + break; + case 'd': /* Delay-Time */ + n = 0; + if ((tmp = pairfind(request, + PW_ACCT_DELAY_TIME)) != NULL) { + n = tmp->lvalue; + } + sprintf(buf + i, "%d", n); + i += strlen(buf + i); + break; + case 'i': /* Session-ID */ + if ((tmp = pairfind(request, + PW_ACCT_SESSION_ID)) != NULL) + strcpy(buf + i, tmp->strvalue); + else + strcpy(buf + i, "unknown"); + i += strlen(buf + i); + break; + case 'r': /* Input-Octets */ + n = 0; + if ((tmp = pairfind(request, + PW_ACCT_INPUT_OCTETS )) != NULL) { + n = tmp->lvalue; + } + sprintf(buf + i, "%d", n); + i += strlen(buf + i); + break; + case 'w': /* Output-Octets */ + n = 0; + if ((tmp = pairfind(request, + PW_ACCT_OUTPUT_OCTETS )) != NULL) { + n = tmp->lvalue; + } + sprintf(buf + i, "%d", n); + i += strlen(buf + i); + break; + case 'q': /* Input-Packets */ + n = 0; + if ((tmp = pairfind(request, + PW_ACCT_INPUT_PACKETS )) != NULL) { + n = tmp->lvalue; + } + sprintf(buf + i, "%d", n); + i += strlen(buf + i); + break; + case 'y': /* Output-Packets */ + n = 0; + if ((tmp = pairfind(request, + PW_ACCT_OUTPUT_PACKETS )) != NULL) { + n = tmp->lvalue; + } + sprintf(buf + i, "%d", n); + i += strlen(buf + i); + break; default: buf[i++] = '%'; buf[i++] = *p; diff -u -r radiusd-cistron-1.5.4.3.orig/src/radius.h radiusd-cistron-1.5.4.3/src/radius.h --- radiusd-cistron-1.5.4.3.orig/src/radius.h Fri Oct 30 15:30:10 1998 +++ radiusd-cistron-1.5.4.3/src/radius.h Fri Nov 6 21:07:40 1998 @@ -129,6 +129,8 @@ #define PW_EXEC_PROGRAM_WAIT 1039 #define PW_HINT 1040 #define PAM_AUTH_ATTR 1041 +#define PW_EXEC_PROGRAM_TIMEOUT 1042 +#define PW_EXEC_PROGRAM_ACCOUNT 1043 /* * INTEGER TRANSLATIONS diff -u -r radiusd-cistron-1.5.4.3.orig/src/radzap.c radiusd-cistron-1.5.4.3/src/radzap.c --- radiusd-cistron-1.5.4.3.orig/src/radzap.c Fri Jun 19 21:55:56 1998 +++ radiusd-cistron-1.5.4.3/src/radzap.c Fri Nov 6 21:03:43 1998 @@ -139,6 +139,11 @@ return 0; } +int radius_exec_program(char *cmd, VALUE_PAIR *request, VALUE_PAIR *reply, + int exec_wait, char **user_msg) +{ +} + UINT4 findnas(char *nasname) {