[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-gnu-radius] Failthru proxying?
From: |
Sergey Poznyakoff |
Subject: |
Re: [Help-gnu-radius] Failthru proxying? |
Date: |
Tue, 09 Jul 2002 13:14:28 +0300 |
> I was searching something like that but I didn't find anything.
> So I thought that a feature like in tacacs -
> IF user_not_fount THEN do
> stay quiet (do not send reject nor ack ...)
> will help, having 2 or more radius server configured on NAS-es
Well, this can be done. The following patch introduces a new
authentication type Ignore. To obtain the desired behaviour,
add the following entry to the end of your raddb/users:
DEFAULT Auth-Type = Ignore
NULL
The patch is agains version 0.96.3. It includes all improvements
discussed in the list so far. When configuring the patched version
use --enable-maintainer-mode option to configure.
Regards,
Sergey
==============================================================================
Index: ChangeLog
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/ChangeLog
/home/gray/radius-0.96-series/ChangeLog
--- /home/gray/tmp/gnu-radius-0.96.3/ChangeLog Wed Jun 5 14:40:28 2002
+++ /home/gray/radius-0.96-series/ChangeLog Fri Jul 5 15:00:37 2002
@@ -1,3 +1,43 @@
+2002-07-05 Sergey Poznyakoff
+
+ * radiusd/auth.c (sfn_validate): Synchronized with the
+ main trunc.
+
+2002-07-05 Sergey Poznyakoff
+
+ * radiusd/acct.c (rad_accounting): Bugfix. The reply value
+ was not used. Thanks to Michael Samuel.
+
+2002-07-02 Sergey Poznyakoff
+
+ * radiusd/radius.c (radrecv): Add NAS-IP-Address to the packet
+ if the NAS didn't supply one.
+ * radiusd/auth.c (sfn_validate): Bugfix: the return from
+ check_expiration() was handled incorrectly.
+ * raddb/dictionary (Expiration): Fixed properties.
+ * THANKS: Added Cornel Cristea
+
+ * test/radiusd.m4: Added tests for Expiration attribute.
+ * test/raddb/users.in: Likewise.
+
+2002-06-20 Sergey Poznyakoff
+
+ * configure.in: YACC_OPTS are always -t.
+ * radiusd/config.y (channel_stmt production): bugfix (sync'ed
+ with the main trunc).
+
+ * radiusd/rewrite.y: New statement: `delete'. New notation:
+ %[attr](n).
+ * doc/texinfo/extensions.texi: Documented `delete' statement
+ and %[attr](n) notation.
+ * radlib/avl.c: (avl_find_n, avl_delete_n): New functions.
+ * include/radius.h (avl_find_n, avl_delete_n): New functions.
+ * mibs/GNU-RADIUS-STAT-MIB.txt: Fixed revision syntax
+
+2002-06-05 Sergey Poznyakoff
+
+ -= Version 0.96.3 released =-
+
2002-06-05 Sergey Poznyakoff
* TODO: Updated. Lots of entries were already implemented in 1.0,
Index: doc/texinfo/extensions.texi
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/doc/texinfo/extensions.texi
/home/gray/radius-0.96-series/doc/texinfo/extensions.texi
--- /home/gray/tmp/gnu-radius-0.96.3/doc/texinfo/extensions.texi Tue Mar
19 16:31:59 2002
+++ /home/gray/radius-0.96-series/doc/texinfo/extensions.texi Thu Jun 20
15:09:49 2002
@@ -579,12 +579,28 @@ whose entries can be accessed using the
@example
@samp{%[} @var{attribute-name} @samp{]}
address@hidden @var{attribute-name} @samp{]} @samp{(} @var{n} @samp{)}
@end example
@noindent
-Thus notation returns the value of the attribute @var{attribute-name}.
+The first notation returns the value of the attribute @var{attribute-name}.
@var{attribute-name} should be a valid Radius dictionary name
(@pxref{dictionary file}).
+
+The second notation returns the value of the @var{n}th attribute of type
address@hidden . Index @var{n} is counted from zero, so
+
address@hidden
+ address@hidden(0)
address@hidden example
+
address@hidden
+is equivalent to
+
address@hidden
+ address@hidden
address@hidden example
+
@item Identifiers
Identifiers represent functions and variables. These are described in
the next section.
@@ -701,6 +717,7 @@ An @dfn{expression} is:
@item A boolean expression
@item An assignment
@item A function call
address@hidden A delete statement
@end itemize
@subheading Type coercion
@@ -763,6 +780,20 @@ function.
@emph{Please note} that, unlike in C, the mismatch between the
number of actual arguments and number of formal parameters in the
compiled function declaration is not an error but rather a warning.
+
address@hidden Delete statement
+
+The @samp{delete} statement is used to delete an attribute or attributes
+from the incoming request. Its syntax is:
+
address@hidden
+delete @var{attribute-name};
+delete @var{attribute-name}(@var{n});
address@hidden example
+
+The first variant deletes @emph{all} the atributes of the given type.
+The second variant deletes only @var{n}th occurrence of the matching
+attribute.
@comment **L4***************************************************************
@node Built-in Functions
Index: include/radius.h
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/include/radius.h
/home/gray/radius-0.96-series/include/radius.h
--- /home/gray/tmp/gnu-radius-0.96.3/include/radius.h Thu May 30 16:43:19 2002
+++ /home/gray/radius-0.96-series/include/radius.h Thu Jun 20 12:51:29 2002
@@ -261,7 +261,9 @@ VALUE_PAIR *avp_alloc();
void avp_free();
void avl_free(VALUE_PAIR *);
VALUE_PAIR *avl_find(VALUE_PAIR *, int);
+VALUE_PAIR *avl_find_n(VALUE_PAIR *, int, int);
void avl_delete(VALUE_PAIR **, int);
+void avl_delete_n(VALUE_PAIR **first, int attr, int n);
void avl_add_list(VALUE_PAIR **, VALUE_PAIR *);
void avl_add_pair(VALUE_PAIR **, VALUE_PAIR *);
VALUE_PAIR *avl_dup(VALUE_PAIR *from);
Index: include/radiusd.h
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/include/radiusd.h
/home/gray/radius-0.96-series/include/radiusd.h
--- /home/gray/tmp/gnu-radius-0.96.3/include/radiusd.h Tue Mar 19 16:32:00 2002
+++ /home/gray/radius-0.96-series/include/radiusd.h Tue Jul 9 12:28:05 2002
@@ -201,6 +201,7 @@ void snmp_req_drop(int type, SNMP_REQ *r
#define AUTH_FAIL 1 /* Password fail */
#define AUTH_NOUSER 2 /* No such user */
#define AUTH_REJECT 3 /* Rejected */
+#define AUTH_IGNORE 4 /* Ignored */
/* Logging modes */
#define RLOG_AUTH 0x0001
Index: raddb/dictionary
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/raddb/dictionary
/home/gray/radius-0.96-series/raddb/dictionary
--- /home/gray/tmp/gnu-radius-0.96.3/raddb/dictionary Tue Mar 19 16:32:00 2002
+++ /home/gray/radius-0.96-series/raddb/dictionary Tue Jul 9 12:26:26 2002
@@ -1,5 +1,5 @@
#
-# $Id: dictionary,v 1.24 2001/12/21 11:13:02 gray Exp $
+# $Id: dictionary,v 1.24.2.1 2002/07/02 20:54:28 gray Exp $
#
## NOTE: Beside its usual functions this file also serves as a source
@@ -140,7 +140,7 @@ ATTRIBUTE Password-Expire-Days 2145 inte
# Non-Protocol Attributes
# These attributes are used internally by the server
#
-ATTRIBUTE Expiration 21 date - [------]
+ATTRIBUTE Expiration 21 date - [L-----]
ATTRIBUTE Auth-Type 1000 integer - [L--R-R]
ATTRIBUTE Menu 1001 string - [-R----]=
ATTRIBUTE Termination-Menu 1002 string - [-R----]=
@@ -251,6 +251,7 @@ VALUE Auth-Type System
1
VALUE Auth-Type SecurID 2
VALUE Auth-Type Crypt-Local 3
VALUE Auth-Type Reject 4
+VALUE Auth-Type Ignore 5
#
# Extensions introduced by Cistron
Index: radiusd/acct.c
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/radiusd/acct.c
/home/gray/radius-0.96-series/radiusd/acct.c
--- /home/gray/tmp/gnu-radius-0.96.3/radiusd/acct.c Thu May 30 17:06:15 2002
+++ /home/gray/radius-0.96-series/radiusd/acct.c Fri Jul 5 14:45:42 2002
@@ -19,7 +19,7 @@
#ifndef lint
static char rcsid[] =
-"@(#) $Id: acct.c,v 1.28.2.2 2002/05/30 14:06:15 gray Exp $";
+"@(#) $Id: acct.c,v 1.28.2.3 2002/07/05 11:45:42 gray Exp $";
#endif
#define LOG_EMPTY_USERNAME
@@ -622,7 +622,7 @@ rad_accounting(radreq, activefd)
write_detail(radreq, auth, "detail");
avl_move_attr(&reply, &radreq->request, DA_PROXY_STATE);
rad_send_reply(RT_ASCEND_EVENT_RESPONSE,
- radreq, NULL, NULL, activefd);
+ radreq, reply, NULL, activefd);
avl_move_attr(&radreq->request, &reply, DA_PROXY_STATE);
stat_inc(acct, radreq->ipaddr, num_resp);
return 0;
@@ -635,7 +635,7 @@ rad_accounting(radreq, activefd)
VALUE_PAIR *reply = NULL;
avl_move_attr(&reply, &radreq->request, DA_PROXY_STATE);
rad_send_reply(RT_ACCOUNTING_RESPONSE,
- radreq, NULL, NULL, activefd);
+ radreq, reply, NULL, activefd);
avl_move_attr(&radreq->request, &reply, DA_PROXY_STATE);
stat_inc(acct, radreq->ipaddr, num_resp);
return 0;
Index: radiusd/auth.c
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/radiusd/auth.c
/home/gray/radius-0.96-series/radiusd/auth.c
--- /home/gray/tmp/gnu-radius-0.96.3/radiusd/auth.c Thu May 30 17:06:41 2002
+++ /home/gray/radius-0.96-series/radiusd/auth.c Tue Jul 9 12:27:44 2002
@@ -18,7 +18,7 @@
#define RADIUS_MODULE_AUTH_C
#ifndef lint
static char rcsid[] =
-"@(#) $Id: auth.c,v 1.47.2.2 2002/05/30 14:06:41 gray Exp $";
+"@(#) $Id: auth.c,v 1.47.2.4 2002/07/05 11:58:18 gray Exp $";
#endif
#ifdef HAVE_CONFIG_H
@@ -218,7 +218,7 @@ unix_pass(name, passwd)
* AUTH_FAIL Password fail
* AUTH_NOUSER No such user
* AUTH_REJECT Rejected
- *
+ * AUTH_IGNORE Silently Ignored
*/
int
rad_check_password(radreq, check_item, namepair, user_msg, userpass)
@@ -247,12 +247,17 @@ rad_check_password(radreq, check_item, n
if ((tmp = avl_find(check_item, DA_AUTH_TYPE)) != NULL)
auth_type = tmp->lvalue;
- if (auth_type == DV_AUTH_TYPE_ACCEPT)
+ switch (auth_type) {
+ case DV_AUTH_TYPE_ACCEPT:
return AUTH_OK;
- if (auth_type == DV_AUTH_TYPE_REJECT)
+ case DV_AUTH_TYPE_REJECT:
return AUTH_REJECT;
+ case DV_AUTH_TYPE_IGNORE:
+ return AUTH_IGNORE;
+ }
+
/* Find the password sent by the user. If it's not present,
authentication fails. */
@@ -938,56 +943,58 @@ sfn_validate(m)
RADIUS_REQ *radreq = m->req;
int rc;
- /*
- * Validate the user
- */
- if ((rc = check_expiration(m)) >= 0) {
- rc = rad_check_password(radreq,
- m->user_check, m->namepair,
- &m->user_msg,
- m->userpass);
-
- if (rc != AUTH_OK) {
- stat_inc(auth, radreq->ipaddr, num_rejects);
- newstate(as_reject);
- auth_format_msg(m, MSG_ACCESS_DENIED);
+ avl_move_attr(&m->user_reply, &m->proxy_pairs, DA_PROXY_STATE);
+ rc = rad_check_password(radreq,
+ m->user_check, m->namepair,
+ &m->user_msg,
+ m->userpass);
+ if (rc != AUTH_OK) {
+ stat_inc(auth, radreq->ipaddr, num_rejects);
- if (is_log_mode(m, RLOG_AUTH)) {
- switch (rc) {
- case AUTH_REJECT:
- auth_log(m, _("Rejected"),
- NULL, NULL, NULL);
- return;
+ if (is_log_mode(m, RLOG_AUTH)) {
+ switch (rc) {
+ case AUTH_IGNORE:
+ auth_log(m, _("Ignored"),
+ NULL, NULL, NULL);
+ newstate(as_stop);
+ return;
- case AUTH_NOUSER:
- auth_log(m, _("Invalid user"),
- NULL, NULL, NULL);
- return;
+ case AUTH_REJECT:
+ auth_log(m, _("Rejected"),
+ NULL, NULL, NULL);
+ break;
- case AUTH_FAIL:
- break;
- }
- }
- }
- /*if (p = avl_find(m->user_reply, DA_REPLY_MESSAGE))
- m->user_msg = dup_string(p->strvalue);*/
- }
-
- avl_move_attr(&m->user_reply, &m->proxy_pairs, DA_PROXY_STATE);
+ case AUTH_NOUSER:
+ auth_log(m, _("Invalid user"),
+ NULL, NULL, NULL);
+ break;
+
+ case AUTH_FAIL:
+ auth_log(m,
+ _("Login incorrect"),
+ is_log_mode(m, RLOG_FAILED_PASS) ?
+ m->userpass : NULL,
+ NULL, NULL);
+ break;
- if (rc != AUTH_OK) {
- /*
- * Failed to validate the user.
- */
- newstate(as_reject);
- if (is_log_mode(m, RLOG_AUTH)) {
- auth_log(m,
- _("Login incorrect"),
- is_log_mode(m, RLOG_FAILED_PASS) ?
- m->userpass : NULL,
- NULL, NULL);
+ default:
+ insist_fail("sfn_validate");
+ }
}
+ newstate(as_reject);
+ auth_format_msg(m, MSG_ACCESS_DENIED);
}
+
+ if (check_expiration(m) != AUTH_OK) {
+ newstate(as_reject);
+ if (is_log_mode(m, RLOG_AUTH)) {
+ auth_log(m,
+ _("Login incorrect"),
+ is_log_mode(m, RLOG_FAILED_PASS) ?
+ m->userpass : NULL,
+ _("Password expired"), "");
+ }
+ }
}
void
Index: radiusd/config.y
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/radiusd/config.y
/home/gray/radius-0.96-series/radiusd/config.y
--- /home/gray/tmp/gnu-radius-0.96.3/radiusd/config.y Tue Mar 19 17:10:18 2002
+++ /home/gray/radius-0.96-series/radiusd/config.y Thu Jun 20 16:40:30 2002
@@ -18,7 +18,7 @@
#ifndef lint
static char rcsid[] =
- "@(#) $Id: config.y,v 1.30.2.1 2002/03/19 15:10:18 gray Exp $";
+ "@(#) $Id: config.y,v 1.30.2.2 2002/06/20 13:40:30 gray Exp $";
#endif
#ifdef HAVE_CONFIG_H
@@ -470,6 +470,7 @@ channel_stmt : T_CHANNEL channel_name
channel_name : { expect_string = 1; } T_STRING
{
expect_string = 0;
+ memset(&channel, 0, sizeof(channel));
channel.mode = LM_UNKNOWN;
strcpy($$, $2);
}
Index: radiusd/radius.c
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/radiusd/radius.c
/home/gray/radius-0.96-series/radiusd/radius.c
--- /home/gray/tmp/gnu-radius-0.96.3/radiusd/radius.c Tue Mar 19 16:32:00 2002
+++ /home/gray/radius-0.96-series/radiusd/radius.c Tue Jul 2 23:54:53 2002
@@ -18,7 +18,7 @@
#define RADIUS_MODULE_RADIUS_C
#ifndef lint
static char rcsid[] =
-"@(#) $Id: radius.c,v 1.20 2001/12/19 14:05:08 gray Exp $";
+"@(#) $Id: radius.c,v 1.20.2.1 2002/07/02 20:54:53 gray Exp $";
#endif
#ifdef HAVE_CONFIG_H
@@ -473,6 +473,12 @@ radrecv(host, udp_port, buffer, length)
}
ptr += attrlen;
length -= attrlen;
+ }
+ if (!avl_find(first_pair, DA_NAS_IP_ADDRESS)) {
+ pair = avp_create(DA_NAS_IP_ADDRESS,
+ 0, NULL,
+ host);
+ avl_add_pair(&first_pair, pair);
}
radreq->request = first_pair;
return(radreq);
Index: radiusd/rewrite.y
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/radiusd/rewrite.y
/home/gray/radius-0.96-series/radiusd/rewrite.y
--- /home/gray/tmp/gnu-radius-0.96.3/radiusd/rewrite.y Tue Mar 19 16:32:00 2002
+++ /home/gray/radius-0.96-series/radiusd/rewrite.y Thu Jun 20 16:41:20 2002
@@ -38,7 +38,7 @@
#ifndef lint
static char rcsid[] =
- "@(#) $Id: rewrite.y,v 1.27 2001/12/19 14:02:18 gray Exp $";
+ "@(#) $Id: rewrite.y,v 1.27.2.1 2002/06/20 13:41:20 gray Exp $";
#endif
typedef long RWSTYPE;
@@ -157,6 +157,7 @@ typedef enum {
Attr,
Attr_asgn,
Attr_check,
+ Attr_delete,
Max_mtxtype
} Mtxtype;
@@ -426,6 +427,7 @@ typedef struct {
typedef struct {
COMMON_EXPR_MTX
int attrno; /* Attribute number */
+ MTX *index; /* Index expression */
MTX *rval; /* Rvalue */
} ATTR_MTX;
@@ -560,10 +562,10 @@ static MTX * mtx_cond(MTX *cond, MTX *if
static MTX * mtx_coerce(Datatype type, MTX *arg);
static MTX * mtx_call(FUNCTION *fun, MTX *args);
static MTX * mtx_builtin(builtin_t *bin, MTX *args);
-static MTX * mtx_attr(DICT_ATTR *attr);
-static MTX * mtx_attr_asgn(DICT_ATTR *attr, MTX *rval);
-static MTX * mtx_attr_check(DICT_ATTR *attr);
-
+static MTX * mtx_attr(DICT_ATTR *attr, MTX *index);
+static MTX * mtx_attr_asgn(DICT_ATTR *attr, MTX *index, MTX *rval);
+static MTX * mtx_attr_check(DICT_ATTR *attr, MTX *index);
+static MTX * mtx_attr_delete(DICT_ATTR *attr, MTX *index);
static MTX * coerce(MTX *arg, Datatype type);
/*
* Regular expressions
@@ -625,7 +627,7 @@ static void run_init(pctr_t pc, VALUE_PA
};
%token <type> TYPE
-%token IF ELSE RETURN WHILE FOR DO BREAK CONTINUE
+%token IF ELSE RETURN WHILE FOR DO BREAK CONTINUE DELETE
%token <string> STRING IDENT
%token <number> NUMBER REFERENCE
%token <var> VARIABLE
@@ -952,6 +954,14 @@ stmt : begin list end
$$->jump.link = (MTX*)loop_last->lp_cont;
loop_last->lp_cont = (JUMP_MTX*)$$;
}
+ | DELETE ATTR ';'
+ {
+ $$ = mtx_attr_delete($2, NULL);
+ }
+ | DELETE ATTR '(' expr ')' ';'
+ {
+ $$ = mtx_attr_delete($2, $4);
+ }
;
while : WHILE
@@ -1016,15 +1026,27 @@ expr : NUMBER
}
| ATTR
{
- $$ = mtx_attr($1);
+ $$ = mtx_attr($1, NULL);
}
- | '*' ATTR
+ | ATTR '(' expr ')'
{
- $$ = mtx_attr_check($2);
+ $$ = mtx_attr($1, $3);
}
+ | '*' ATTR
+ {
+ $$ = mtx_attr_check($2, NULL);
+ }
+ | '*' ATTR '(' expr ')'
+ {
+ $$ = mtx_attr_check($2, $4);
+ }
| ATTR '=' expr
{
- $$ = mtx_attr_asgn($1, $3);
+ $$ = mtx_attr_asgn($1, NULL, $3);
+ }
+ | ATTR '(' expr ')' '=' expr
+ {
+ $$ = mtx_attr_asgn($1, $3, $6);
}
| FUN '(' args ')'
{
@@ -1454,6 +1476,7 @@ static struct keyword rw_kw[] = {
"while", WHILE,
"break", BREAK,
"continue", CONTINUE,
+ "delete", DELETE,
NULL
};
@@ -2228,30 +2251,35 @@ attr_datatype(type)
}
MTX *
-mtx_attr(attr)
+mtx_attr(attr, index)
DICT_ATTR *attr;
+ MTX *index;
{
ATTR_MTX *mtx = (ATTR_MTX*)mtx_alloc(Attr);
mtx_append(mtx);
mtx->attrno = attr->value;
mtx->datatype = attr_datatype(attr->type);
+ mtx->index = index;
return (MTX*)mtx;
}
MTX *
-mtx_attr_check(attr)
+mtx_attr_check(attr, index)
DICT_ATTR *attr;
+ MTX *index;
{
ATTR_MTX *mtx = (ATTR_MTX*)mtx_alloc(Attr_check);
mtx_append(mtx);
mtx->attrno = attr->value;
mtx->datatype = Integer;
+ mtx->index = index;
return (MTX*)mtx;
}
MTX *
-mtx_attr_asgn(attr, rval)
+mtx_attr_asgn(attr, index, rval)
DICT_ATTR *attr;
+ MTX *index;
MTX *rval;
{
ATTR_MTX *mtx = (ATTR_MTX*)mtx_alloc(Attr_asgn);
@@ -2266,11 +2294,25 @@ mtx_attr_asgn(attr, rval)
datatype_str(mtx->datatype));
rval = coerce(rval, mtx->datatype);
}
+ mtx->index = index;
mtx->rval = rval;
return (MTX*)mtx;
}
MTX *
+mtx_attr_delete(attr, index)
+ DICT_ATTR *attr;
+ MTX *index;
+{
+ ATTR_MTX *mtx = (ATTR_MTX*)mtx_alloc(Attr_delete);
+ mtx_append(mtx);
+ mtx->attrno = attr->value;
+ mtx->datatype = attr_datatype(attr->type);
+ mtx->index = index;
+ return (MTX*)mtx;
+}
+
+MTX *
mtx_bin(opcode, arg1, arg2)
Bopcode opcode;
MTX *arg1, *arg2;
@@ -2778,24 +2820,34 @@ debug_print_mtxlist(s)
break;
CASE (Attr)
- fprintf(fp, "%3.3s A:%d",
+ fprintf(fp, "%3.3s A:%d I:%d",
datatype_str(mtx->gen.datatype),
- mtx->attr.attrno);
+ mtx->attr.attrno,
+ mtx->attr.index);
break;
CASE (Attr_check)
- fprintf(fp, "%3.3s A:%d",
+ fprintf(fp, "%3.3s A:%d I:%d",
datatype_str(mtx->gen.datatype),
- mtx->attr.attrno);
+ mtx->attr.attrno,
+ mtx->attr.index);
break;
CASE (Attr_asgn)
- fprintf(fp, "%3.3s A:%d M:%d",
+ fprintf(fp, "%3.3s A:%d I:%d M:%d",
datatype_str(mtx->gen.datatype),
mtx->attr.attrno,
+ mtx->attr.index,
LINK(mtx->attr.rval));
break;
-
+
+ CASE (Attr_delete)
+ fprintf(fp, "%3.3s A:%d I:%d",
+ datatype_str(mtx->gen.datatype),
+ mtx->attr.attrno,
+ mtx->attr.index);
+ break;
+
default:
fprintf(fp, "UNKNOWN: %d", mtx->gen.type);
}
@@ -3082,8 +3134,8 @@ pass2()
case String:
/*NO STRING OPS SO FAR */;
}
- } else if (mtx->bin.opcode == And ||
- mtx->bin.opcode == Or) {
+ } else if (mtx->bin.opcode == And
+ || mtx->bin.opcode == Or) {
mtx_bool(mtx);
}
break;
@@ -3091,6 +3143,16 @@ pass2()
case Jump:
if (mtx->jump.dest == mtx->jump.next)
mtx_remove(mtx);
+ break;
+
+ case Attr:
+ case Attr_asgn:
+ case Attr_check:
+ case Attr_delete:
+ /*FIXME: the rw_attr.0 functions should
+ expect an immediate value after the
+ attribute number */
+ break;
}
mtx = next;
}
@@ -3235,9 +3297,15 @@ static void rw_popa();
static void rw_call();
static void rw_builtin();
static void rw_attrs();
+static void rw_attrs0();
static void rw_attrn();
+static void rw_attrn0();
static void rw_attrcheck();
+static void rw_attrcheck0();
static void rw_attrasgn();
+static void rw_attrasgn0();
+static void rw_attr_delete();
+static void rw_attr_delete0();
INSTR bin_codetab[] = {
rw_eq,
@@ -3453,25 +3521,44 @@ codegen()
case Attr:
switch (mtx->attr.datatype) {
case Integer:
- code(rw_attrn);
+ if (mtx->attr.index)
+ code(rw_attrn);
+ else
+ code(rw_attrn0);
break;
case String:
- code(rw_attrs);
+ if (mtx->attr.index)
+ code(rw_attrs);
+ else
+ code(rw_attrs0);
break;
}
data(mtx->attr.attrno);
break;
case Attr_check:
- code(rw_attrcheck);
+ if (mtx->attr.index)
+ code(rw_attrcheck);
+ else
+ code(rw_attrcheck0);
data(mtx->attr.attrno);
break;
case Attr_asgn:
- code(rw_attrasgn);
+ if (mtx->attr.index)
+ code(rw_attrasgn);
+ else
+ code(rw_attrasgn0);
data(mtx->attr.attrno);
break;
-
+
+ case Attr_delete:
+ if (mtx->attr.index)
+ code(rw_attr_delete);
+ else
+ code(rw_attr_delete0);
+ data(mtx->attr.attrno);
+ break;
}
}
@@ -3887,47 +3974,79 @@ rw_asgn()
* Check if the A/V pair is supplied in the request
*/
void
+rw_attrcheck0()
+{
+ int attr = (int) rw_rt.code[rw_rt.pc++];
+
+ pushn(avl_find(rw_rt.request, attr) != NULL);
+}
+
+void
rw_attrcheck()
{
int attr = (int) rw_rt.code[rw_rt.pc++];
+ RWSTYPE index;
+ VALUE_PAIR *p = rw_rt.request;
- pushn(avl_find(rw_rt.request, attr) != NULL);
+ cpopn(&index);
+ pushn(avl_find_n(rw_rt.request, attr, index) != NULL);
}
/*
* Assign a value to an A/V pair
*/
void
-rw_attrasgn()
+attrasgn_internal(attr, pair, val)
+ int attr;
+ VALUE_PAIR *pair;
+ RWSTYPE val;
{
- int attr = (int) rw_rt.code[rw_rt.pc++];
- RWSTYPE val;
- VALUE_PAIR *pair;
-
- cpopn(&val);
- if ((pair = avl_find(rw_rt.request, attr)) == NULL) {
+ if (!pair) {
pair = avp_create(attr, 0, NULL, 0);
if (!pair)
rw_error("can't create A/V pair");
avl_add_pair(&rw_rt.request, pair);
}
- switch (pair->type) {
- case TYPE_STRING:
- case TYPE_DATE:
- replace_string(&pair->strvalue, (char*)val);
- pair->strlength = strlen((char*) val);
- break;
- case TYPE_INTEGER:
- case TYPE_IPADDR:
- pair->lvalue = val;
- break;
- }
+
+ switch (pair->type) {
+ case TYPE_STRING:
+ case TYPE_DATE:
+ replace_string(&pair->strvalue, (char*)val);
+ pair->strlength = strlen((char*) val);
+ break;
+ case TYPE_INTEGER:
+ case TYPE_IPADDR:
+ pair->lvalue = val;
+ break;
+ }
+
+ pushn(val);
+}
- pushn(val);
+void
+rw_attrasgn0()
+{
+ int attr = (int) rw_rt.code[rw_rt.pc++];
+ RWSTYPE val;
+
+ cpopn(&val);
+ attrasgn_internal(attr, avl_find(rw_rt.request, attr), val);
}
void
-rw_attrs()
+rw_attrasgn()
+{
+ int attr = (int) rw_rt.code[rw_rt.pc++];
+ RWSTYPE val;
+ RWSTYPE index;
+
+ cpopn(&val);
+ cpopn(&index);
+ attrasgn_internal(attr, avl_find_n(rw_rt.request, attr, index), val);
+}
+
+void
+rw_attrs0()
{
int attr = (int) rw_rt.code[rw_rt.pc++];
VALUE_PAIR *pair;
@@ -3939,7 +4058,7 @@ rw_attrs()
}
void
-rw_attrn()
+rw_attrn0()
{
int attr = (int) rw_rt.code[rw_rt.pc++];
VALUE_PAIR *pair;
@@ -3948,6 +4067,51 @@ rw_attrn()
pushn(0);
else
pushn(pair->lvalue);
+}
+
+void
+rw_attrs()
+{
+ int attr = (int) rw_rt.code[rw_rt.pc++];
+ VALUE_PAIR *pair;
+ RWSTYPE index;
+
+ cpopn(&index);
+ if ((pair = avl_find_n(rw_rt.request, attr, index)) == NULL)
+ pushs(&nil, 1);
+ else
+ pushstr(pair->strvalue, pair->strlength);
+}
+
+void
+rw_attrn()
+{
+ int attr = (int) rw_rt.code[rw_rt.pc++];
+ VALUE_PAIR *pair;
+ RWSTYPE index;
+
+ cpopn(&index);
+ if ((pair = avl_find_n(rw_rt.request, attr, index)) == NULL)
+ pushn(0);
+ else
+ pushn(pair->lvalue);
+}
+
+void
+rw_attr_delete0()
+{
+ int attr = (int) rw_rt.code[rw_rt.pc++];
+ avl_delete(&rw_rt.request, attr);
+}
+
+void
+rw_attr_delete()
+{
+ int attr = (int) rw_rt.code[rw_rt.pc++];
+ RWSTYPE index;
+
+ cpopn(&index);
+ avl_delete_n(&rw_rt.request, attr, index);
}
/*
Index: radlib/avl.c
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/radlib/avl.c
/home/gray/radius-0.96-series/radlib/avl.c
--- /home/gray/tmp/gnu-radius-0.96.3/radlib/avl.c Tue Mar 19 18:11:58 2002
+++ /home/gray/radius-0.96-series/radlib/avl.c Thu Jun 20 16:42:22 2002
@@ -17,7 +17,7 @@
#ifndef lint
static char rcsid[] =
-"$Id: avl.c,v 1.7.2.1 2002/03/19 16:11:58 gray Exp $";
+"$Id: avl.c,v 1.7.2.2 2002/06/20 13:42:22 gray Exp $";
#endif
#ifdef HAVE_CONFIG_H
@@ -191,6 +191,19 @@ avl_find(first, attr)
return first;
}
+VALUE_PAIR *
+avl_find_n(first, attr, n)
+ VALUE_PAIR *first;
+ int attr;
+ int n;
+{
+ for ( ; first; first = first->next) {
+ if (first->attribute == attr && n-- == 0)
+ break;
+ }
+ return first;
+}
+
/* Delete the pairs with the matching attribute
*/
void
@@ -208,6 +221,29 @@ avl_delete(first, attr)
else
*first = next;
avp_free(pair);
+ } else
+ last = pair;
+ }
+}
+
+/* Delete Nth matching pair */
+void
+avl_delete_n(first, attr, n)
+ VALUE_PAIR **first;
+ int attr;
+ int n;
+{
+ VALUE_PAIR *pair, *next, *last = NULL;
+
+ for (pair = *first; pair; pair = next) {
+ next = pair->next;
+ if (pair->attribute == attr && n-- == 0) {
+ if (last)
+ last->next = next;
+ else
+ *first = next;
+ avp_free(pair);
+ break;
} else
last = pair;
}
Index: test/raddb/users.in
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/test/raddb/users.in
/home/gray/radius-0.96-series/test/raddb/users.in
--- /home/gray/tmp/gnu-radius-0.96.3/test/raddb/users.in Tue Mar 19
16:32:05 2002
+++ /home/gray/radius-0.96-series/test/raddb/users.in Tue Jul 2 23:38:23 2002
@@ -42,7 +42,18 @@ crypt Auth-Type = Crypt-Local,
## Access.exp: bad-one should be rejected.
bad-one Auth-Type = Accept NULL
-
+
+## Expiration.exp
+expire Auth-Type = Local,
+ Password = "expire",
+ Expiration = "Jan 01 1970"
+ Service-Type = Framed-User
+
+no-expire Auth-Type = Local,
+ Password = "expire",
+ Expiration = "Jan 01 2011"
+ Service-Type = Framed-User
+
## Reply.exp: Test Reply Attributes
reply Auth-Type = Local,
Password = "guessme"
Index: test/radiusd.m4
diff -rpu /home/gray/tmp/gnu-radius-0.96.3/test/radiusd.m4
/home/gray/radius-0.96-series/test/radiusd.m4
--- /home/gray/tmp/gnu-radius-0.96.3/test/radiusd.m4 Tue Mar 19 16:32:05 2002
+++ /home/gray/radius-0.96-series/test/radiusd.m4 Tue Jul 2 23:56:15 2002
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-# $Id: radiusd.m4,v 1.3 2001/12/26 14:50:52 gray Exp $
+# $Id: radiusd.m4,v 1.3.2.1 2002/07/02 20:56:15 gray Exp $
TOOLDIR(radiusd)
BEGIN
@@ -113,6 +113,13 @@ SEQUENCE(Access,
Checking Access Lists,
[TEST(send auth 1 User-Name = QUOTE(bad-one),
expect 3 Reply-Message = QUOTE([[Sorry, your account is currently
closed]]ESC(\r,\n)))])
+
+SEQUENCE(Expiration,
+Checking Expiration Attribute,
+[TEST(send auth 1 User-Name = QUOTE(expire) Password = QUOTE(expire),
+ expect 3 Reply-Message = QUOTE([[Password Has Expired]]ESC(\r,\n)))
+ TEST(send auth 1 User-Name = QUOTE(no-expire) Password = QUOTE(expire),
+ expect 2)])
IFSEQUENCE(Menu, USE_LIVINGSTON_MENUS,
Checking Menus,
==============================================================================