Skip to content
This repository was archived by the owner on Aug 22, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions tacacs-F4.0.4.28/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@
#endif
opap = cleartext <string> |
global = cleartext <string> |
msg = <string>
msg = <string> |
before authorization = <string> |
after authorization = <string>
after authorization = <string> |
before enable = <string>

<svc> := <svc_auth> | <cmd_auth>

Expand Down Expand Up @@ -186,6 +187,7 @@ typedef struct user {
char *enable; /* user enable pwd */
int noenablepwd; /* user requires no enable password */
char *enableacl; /* hosts (NASs) to allow/deny enabling */
char *before_enable; /* command to run before enabling */
# endif
#endif
char *global; /* password to use if none set */
Expand Down Expand Up @@ -1124,10 +1126,31 @@ parse_user(void)

case S_before:
sym_get();
#ifdef UENABLE
switch (sym_code) {
case S_authorization:
sym_get();
if (user->before_author)
free(user->before_author);
user->before_author = tac_strdup(sym_buf);
break;
case S_enable:
sym_get();
if (user->before_enable)
free(user->before_enable);
user->before_enable = tac_strdup(sym_buf);
break;
default:
parse_error("expecting '%s' or '%s' but found '%s' on line %d",
codestring(S_authorization), codestring(S_enable), sym_buf, sym_line);
return(1);
}
#else // UENABLE
parse(S_authorization);
if (user->before_author)
free(user->before_author);
user->before_author = tac_strdup(sym_buf);
#endif // UENABLE
sym_get();
continue;

Expand Down Expand Up @@ -1784,6 +1807,9 @@ get_value(USER *user, int field)
case S_enableacl:
v.pval = user->enableacl;
break;
case S_beforeenable:
v.pval = user->before_enable;
break;
# endif
#endif

Expand Down
24 changes: 24 additions & 0 deletions tacacs-F4.0.4.28/enable.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ enable_fn(struct authen_data *data)
char *passwd;
struct private_data *p;
int pwlen;
#ifdef UENABLE
char *cmd;
#endif

p = (struct private_data *)data->method_data;

Expand Down Expand Up @@ -180,6 +183,27 @@ enable_fn(struct authen_data *data)
data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
break;
}
cmd = cfg_get_pvalue(data->NAS_id->username, TAC_IS_USER,
S_beforeenable, TAC_PLUS_RECURSE);
if (cmd) {
// check CMD
int status;
char error_str[255];
int error_len = 255;
status = call_pre_enable(cmd, data, error_str, error_len);
switch (status) {
case 0: /* Permit */
case 2: /* Use replacement AV pairs from program as final result */
break;
case 1: /* Deny */
case 3: /* deny, but return attributes and server-msg to NAS */
default:
report(LOG_INFO, "setting authen_status_fail %d", status);
data->server_msg = tac_strdup("Denied due to enable authentication.");
data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
return(0);
}
}
#endif
/* Request a password */
data->flags = TAC_PLUS_AUTHEN_FLAG_NOECHO;
Expand Down
3 changes: 3 additions & 0 deletions tacacs-F4.0.4.28/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,6 @@
#define S_writetimeout 55
#define S_accepttimeout 56
#define S_logauthor 57
#ifdef UENABLE
#define S_beforeenable 58
#endif
59 changes: 59 additions & 0 deletions tacacs-F4.0.4.28/programs.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,65 @@ read_args(int n, int fd)
return(out);
}

/*
* Do variable interpolation on a string, then invoke it as a shell command.
* Write a faked set of AV pairs to standard input of the command and
* disregard its standard output. Return the commands final status
* when it terminates
*/
int
call_pre_enable(char *string, struct authen_data *authen_data, char *error, int err_len)
{
/*char **new_args;*/
int readfd, writefd, errorfd;
int status;/*, i;*/
char *cmd = NULL;
char fakeoutput[] = "service=shell\ncmd=enable\ncmd-arg=<cr>\n";
struct author_data data;
#if HAVE_PID_T
pid_t pid;
#else
int pid;
#endif
data.id = authen_data->NAS_id;
data.authen_method = AUTHEN_METH_ENABLE;
data.authen_type = authen_data->type;
data.service = authen_data->service;
data.status = authen_data->status;

cmd = substitute(string, &data);
pid = my_popen(cmd, &readfd, &writefd, &errorfd);
memset(error, '\0', err_len);
free(cmd);

if (pid < 0) {
close_fds(readfd, writefd, errorfd);
return(1); /* deny */
}

/* write a fake enable input */
write(writefd, fakeoutput, sizeof(fakeoutput) - 1);
close(writefd);
writefd = -1;

/*new_args = read_args(0, readfd);*/

read_string(errorfd, error, err_len);
if (error[0] != '\0') {
report(LOG_ERR, "Error from program (%d): \"%s\" ",
strlen(error), error);
}

/* count the args */
/*for (i = 0; new_args[i]; i++)*/
/* NULL stmt */ ;

status = waitfor(pid);
close_fds(readfd, writefd, errorfd);
return(status);
}


/*
* Do variable interpolation on a string, then invoke it as a shell command.
* Write an appropriate set of AV pairs to standard input of the command and
Expand Down
1 change: 1 addition & 0 deletions tacacs-F4.0.4.28/tac_plus.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ int keycode(char *);
void parser_init(void);

/* programs.c */
int call_pre_enable(char *, struct authen_data *, char *, int);
int call_pre_process(char *, struct author_data *, char ***, int *, char *,
int);
int call_post_process(char *, struct author_data *, char ***, int *);
Expand Down