used indent to "fix" coding style
This commit is contained in:
684
parse.c
684
parse.c
@@ -20,15 +20,17 @@
|
||||
* them to include in future releases. Feel free to send them to:
|
||||
* Jeff Nieusma nieusma@rootgroup.com
|
||||
* 3959 Arbol CT (303) 447-8093
|
||||
* Boulder, CO 80301-1752
|
||||
* Boulder, CO 80301-1752
|
||||
*
|
||||
********************************************************************************
|
||||
* parse.c, sudo project
|
||||
* David R. Hieb
|
||||
* March 18, 1991
|
||||
*
|
||||
* routines to implement and maintain the parsing and list management.
|
||||
*******************************************************************************/
|
||||
**************************************************************************
|
||||
*
|
||||
* parse.c, sudo project
|
||||
* David R. Hieb
|
||||
* March 18, 1991
|
||||
*
|
||||
* routines to implement and maintain the parsing and list management.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
@@ -37,7 +39,9 @@
|
||||
|
||||
#include "sudo.h"
|
||||
|
||||
/* there are 3 main lists (User, Host_Alias, Cmnd_Alias) and 1 extra list */
|
||||
/*
|
||||
* there are 3 main lists (User, Host_Alias, Cmnd_Alias) and 1 extra list
|
||||
*/
|
||||
#define NUM_LISTS 3+1
|
||||
|
||||
extern char *user, *host, *cmnd;
|
||||
@@ -49,357 +53,397 @@ int parse_error = FALSE, found_user = FALSE;
|
||||
int next_type, num_host_alias = 0, num_cmnd_alias = 0;
|
||||
LINK tmp_ptr, reset_ptr, save_ptr, list_ptr[NUM_LISTS];
|
||||
|
||||
/*******************************************************************************
|
||||
* inserts a node into list 'list_num' and updates list_ptr[list_num]
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* inserts a node into list 'list_num' and updates list_ptr[list_num]
|
||||
*/
|
||||
|
||||
void insert_member(list_num, token_type, op_type, data_string)
|
||||
int token_type, list_num;
|
||||
char op_type;
|
||||
char *data_string;
|
||||
int token_type, list_num;
|
||||
char op_type;
|
||||
char *data_string;
|
||||
{
|
||||
tmp_ptr = (LINK)malloc(sizeof(LIST));
|
||||
tmp_ptr->type = token_type;
|
||||
tmp_ptr->op = op_type;
|
||||
tmp_ptr->data = (char *)malloc(strlen(data_string)+1);
|
||||
strcpy(tmp_ptr->data, data_string);
|
||||
tmp_ptr->next = (new_list[list_num] == TRUE) ? NULL : list_ptr[list_num];
|
||||
tmp_ptr = (LINK) malloc(sizeof(LIST));
|
||||
tmp_ptr -> type = token_type;
|
||||
tmp_ptr -> op = op_type;
|
||||
tmp_ptr -> data = (char *) malloc(strlen(data_string) + 1);
|
||||
strcpy(tmp_ptr -> data, data_string);
|
||||
tmp_ptr -> next = (new_list[list_num] == TRUE) ? NULL : list_ptr[list_num];
|
||||
|
||||
list_ptr[list_num] = list_ptr[EXTRA_LIST] = tmp_ptr;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* diagnostic list printing utility that prints list 'list_num'
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* diagnostic list printing utility that prints list 'list_num'
|
||||
*/
|
||||
|
||||
void print_list(list_num)
|
||||
int list_num;
|
||||
int list_num;
|
||||
{
|
||||
LINK tmptmp_ptr;
|
||||
LINK tmptmp_ptr;
|
||||
|
||||
tmptmp_ptr = list_ptr[list_num];
|
||||
tmptmp_ptr = list_ptr[list_num];
|
||||
|
||||
while (list_ptr[list_num] != NULL) {
|
||||
printf("type = %d, op = %c, data = %s\n", list_ptr[list_num]->type,
|
||||
list_ptr[list_num]->op, list_ptr[list_num]->data);
|
||||
tmp_ptr = list_ptr[list_num];
|
||||
list_ptr[list_num] = tmp_ptr->next;
|
||||
while (list_ptr[list_num] != NULL) {
|
||||
(void) printf("type = %d, op = %c, data = %s\n",
|
||||
list_ptr[list_num] -> type,
|
||||
list_ptr[list_num] -> op, list_ptr[list_num] -> data);
|
||||
tmp_ptr = list_ptr[list_num];
|
||||
list_ptr[list_num] = tmp_ptr -> next;
|
||||
}
|
||||
list_ptr[list_num] = tmptmp_ptr;
|
||||
list_ptr[list_num] = tmptmp_ptr;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* delete list utility that deletes list 'list_num'
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* delete list utility that deletes list 'list_num'
|
||||
*/
|
||||
|
||||
void delete_list(list_num)
|
||||
int list_num;
|
||||
int list_num;
|
||||
{
|
||||
while (list_ptr[list_num] != NULL) {
|
||||
tmp_ptr = list_ptr[list_num];
|
||||
list_ptr[list_num] = tmp_ptr->next;
|
||||
/* free(tmp_ptr); */
|
||||
while (list_ptr[list_num] != NULL) {
|
||||
tmp_ptr = list_ptr[list_num];
|
||||
list_ptr[list_num] = tmp_ptr -> next;
|
||||
/* free(tmp_ptr); */
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* this routine is what the lex/yacc code calls to build the different lists.
|
||||
* once the lists are all built, control eventually returns to validate().
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* this routine is what the lex/yacc code calls to build the different lists.
|
||||
* once the lists are all built, control eventually returns to validate().
|
||||
*/
|
||||
|
||||
int call_back(token_type, op_type, data_string)
|
||||
int token_type;
|
||||
char op_type;
|
||||
char *data_string;
|
||||
int token_type;
|
||||
char op_type;
|
||||
char *data_string;
|
||||
{
|
||||
/* all nodes start out in the extra list since the node name is received last */
|
||||
list_num = EXTRA_LIST;
|
||||
/*
|
||||
* all nodes start out in the extra list since the node name
|
||||
* is received last
|
||||
*/
|
||||
list_num = EXTRA_LIST;
|
||||
|
||||
/*
|
||||
* if the last received node is TYPE1, then we can classify the list
|
||||
* and effectively transfer the extra list to the correct list type.
|
||||
*/
|
||||
if (token_type == TYPE1) {
|
||||
/* we have just build a "Host_Alias" list */
|
||||
if (strcmp(data_string, "Host_Alias") == 0) {
|
||||
list_num = HOST_LIST;
|
||||
if (num_host_alias > 0) {
|
||||
reset_ptr->next = list_ptr[HOST_LIST];
|
||||
}
|
||||
num_host_alias++;
|
||||
}
|
||||
/* we have just build a "Cmnd_Alias" list */
|
||||
else if (strcmp(data_string, "Cmnd_Alias") == 0) {
|
||||
list_num = CMND_LIST;
|
||||
if (num_cmnd_alias > 0) {
|
||||
reset_ptr->next = list_ptr[CMND_LIST];
|
||||
}
|
||||
num_cmnd_alias++;
|
||||
}
|
||||
/* we have just build a "User" list */
|
||||
else {
|
||||
list_num = USER_LIST;
|
||||
user_list_found = TRUE;
|
||||
}
|
||||
new_list[EXTRA_LIST] = TRUE;
|
||||
new_list[list_num] = FALSE;
|
||||
list_ptr[list_num] = list_ptr[EXTRA_LIST];
|
||||
/*
|
||||
* if the last received node is TYPE1, then we can classify the list
|
||||
* and effectively transfer the extra list to the correct list type.
|
||||
*/
|
||||
if (token_type == TYPE1) {
|
||||
/*
|
||||
* we have just build a "Host_Alias" list
|
||||
*/
|
||||
if (strcmp(data_string, "Host_Alias") == 0) {
|
||||
list_num = HOST_LIST;
|
||||
if (num_host_alias > 0) {
|
||||
reset_ptr -> next = list_ptr[HOST_LIST];
|
||||
}
|
||||
num_host_alias++;
|
||||
}
|
||||
/*
|
||||
* we have just build a "Cmnd_Alias" list
|
||||
*/
|
||||
else if (strcmp(data_string, "Cmnd_Alias") == 0) {
|
||||
list_num = CMND_LIST;
|
||||
if (num_cmnd_alias > 0) {
|
||||
reset_ptr -> next = list_ptr[CMND_LIST];
|
||||
}
|
||||
num_cmnd_alias++;
|
||||
}
|
||||
/*
|
||||
* we have just build a "User" list
|
||||
*/
|
||||
else {
|
||||
list_num = USER_LIST;
|
||||
user_list_found = TRUE;
|
||||
}
|
||||
new_list[EXTRA_LIST] = TRUE;
|
||||
new_list[list_num] = FALSE;
|
||||
list_ptr[list_num] = list_ptr[EXTRA_LIST];
|
||||
}
|
||||
/*
|
||||
* actually link the new node into list 'list_num'
|
||||
*/
|
||||
insert_member(list_num, token_type, op_type, data_string);
|
||||
|
||||
/* actually link the new node into list 'list_num' */
|
||||
insert_member(list_num, token_type, op_type, data_string);
|
||||
|
||||
if (new_list[list_num] == TRUE) {
|
||||
reset_ptr = list_ptr[list_num];
|
||||
new_list[list_num] = FALSE;
|
||||
if (new_list[list_num] == TRUE) {
|
||||
reset_ptr = list_ptr[list_num];
|
||||
new_list[list_num] = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* we process one user record at a time from the sudoers file. if we
|
||||
* find the user were looking for, we return to lex/yacc declaring
|
||||
* that we have done so. otherwise, we reset the user list, delete the
|
||||
* nodes and start over again looking for the user.
|
||||
*/
|
||||
if (user_list_found == TRUE) {
|
||||
if (list_ptr[list_num]->type == TYPE1 &&
|
||||
strcmp(list_ptr[list_num]->data, user) == 0) {
|
||||
return(FOUND_USER);
|
||||
}
|
||||
else {
|
||||
new_list[list_num] = TRUE;
|
||||
user_list_found = FALSE;
|
||||
delete_list(list_num);
|
||||
}
|
||||
/*
|
||||
* we process one user record at a time from the sudoers file. if we
|
||||
* find the user were looking for, we return to lex/yacc declaring
|
||||
* that we have done so. otherwise, we reset the user list, delete the
|
||||
* nodes and start over again looking for the user.
|
||||
*/
|
||||
if (user_list_found == TRUE) {
|
||||
if (list_ptr[list_num] -> type == TYPE1 &&
|
||||
strcmp(list_ptr[list_num] -> data, user) == 0) {
|
||||
return (FOUND_USER);
|
||||
} else {
|
||||
new_list[list_num] = TRUE;
|
||||
user_list_found = FALSE;
|
||||
delete_list(list_num);
|
||||
}
|
||||
}
|
||||
return(NOT_FOUND_USER);
|
||||
return (NOT_FOUND_USER);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* this routine is called from cmnd_check() to resolve whether or not
|
||||
* a user is permitted to perform a to-yet-be-determined command for
|
||||
* a certain host name.
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* this routine is called from cmnd_check() to resolve whether or not
|
||||
* a user is permitted to perform a to-yet-be-determined command for
|
||||
* a certain host name.
|
||||
*/
|
||||
|
||||
int host_type_ok()
|
||||
{
|
||||
/* check for the reserved keyword 'ALL'. if so, don't check the host name */
|
||||
if (strcmp(list_ptr[USER_LIST]->data, "ALL") == 0) {
|
||||
return(TRUE);
|
||||
}
|
||||
/* this case is the normal lowercase hostname */
|
||||
else if (isupper(list_ptr[USER_LIST]->data[0]) == FALSE) {
|
||||
return(strcmp(list_ptr[USER_LIST]->data, host) == 0);
|
||||
}
|
||||
/* by now we have a Host_Alias that will have to be expanded */
|
||||
else {
|
||||
save_ptr = list_ptr[HOST_LIST];
|
||||
while (list_ptr[HOST_LIST] != NULL) {
|
||||
if ((list_ptr[HOST_LIST]->type == TYPE2) &&
|
||||
(strcmp(list_ptr[HOST_LIST]->data,
|
||||
list_ptr[USER_LIST]->data) == 0)) {
|
||||
next_type = list_ptr[HOST_LIST]->next->type;
|
||||
tmp_ptr = list_ptr[HOST_LIST];
|
||||
list_ptr[HOST_LIST] = tmp_ptr->next;
|
||||
while (next_type == TYPE3) {
|
||||
if (strcmp(list_ptr[HOST_LIST]->data, host) == 0) {
|
||||
list_ptr[HOST_LIST] = save_ptr;
|
||||
return(TRUE);
|
||||
}
|
||||
if (list_ptr[HOST_LIST]->next != NULL) {
|
||||
next_type = list_ptr[HOST_LIST]->next->type;
|
||||
tmp_ptr = list_ptr[HOST_LIST];
|
||||
list_ptr[HOST_LIST] = tmp_ptr->next;
|
||||
}
|
||||
else {
|
||||
next_type = ~TYPE3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tmp_ptr = list_ptr[HOST_LIST];
|
||||
list_ptr[HOST_LIST] = tmp_ptr->next;
|
||||
}
|
||||
}
|
||||
list_ptr[HOST_LIST] = save_ptr;
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* this routine is called from cmnd_check() to resolve whether or not
|
||||
* a user is permitted to perform a certain command on the already
|
||||
* established host.
|
||||
*******************************************************************************/
|
||||
int cmnd_type_ok()
|
||||
{
|
||||
/* check for the reserved keyword 'ALL'. */
|
||||
if (strcmp(list_ptr[USER_LIST]->data, "ALL") == 0) {
|
||||
/* if the command has an absolute path, let them do it */
|
||||
if (cmnd[0] == '/') {
|
||||
return(MATCH);
|
||||
}
|
||||
/* if the command does not have an absolute path, forget it */
|
||||
else {
|
||||
return(NO_MATCH);
|
||||
}
|
||||
}
|
||||
/* if the command has an absolute path, check it out */
|
||||
else if (list_ptr[USER_LIST]->data[0] == '/') {
|
||||
/* op | data | return value
|
||||
*---------------------------------
|
||||
* ' ' | No Match | return(NO_MATCH)
|
||||
* '!' | No Match | return(NO_MATCH)
|
||||
* ' ' | A Match | return(MATCH)
|
||||
* '!' | A Match | return(QUIT_NOW)
|
||||
*
|
||||
* these special cases are important in subtracting from the
|
||||
* Universe of commands in something like:
|
||||
* user machine=ALL,!/bin/rm,!/etc/named ...
|
||||
/*
|
||||
* check for the reserved keyword 'ALL'. if so, don't check the host name
|
||||
*/
|
||||
if (strcmp(list_ptr[USER_LIST]->data, cmnd) == 0) {
|
||||
if (list_ptr[USER_LIST]->op == '!') {
|
||||
return(QUIT_NOW);
|
||||
}
|
||||
else {
|
||||
return(MATCH);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return(NO_MATCH);
|
||||
}
|
||||
if (strcmp(list_ptr[USER_LIST] -> data, "ALL") == 0) {
|
||||
return (TRUE);
|
||||
}
|
||||
/* by now we have a Cmnd_Alias that will have to be expanded */
|
||||
else {
|
||||
save_ptr = list_ptr[CMND_LIST];
|
||||
while (list_ptr[CMND_LIST] != NULL) {
|
||||
if ((list_ptr[CMND_LIST]->type == TYPE2) &&
|
||||
(strcmp(list_ptr[CMND_LIST]->data,
|
||||
list_ptr[USER_LIST]->data) == 0)) {
|
||||
next_type = list_ptr[CMND_LIST]->next->type;
|
||||
tmp_ptr = list_ptr[CMND_LIST];
|
||||
list_ptr[CMND_LIST] = tmp_ptr->next;
|
||||
while (next_type == TYPE3) {
|
||||
if (strcmp(list_ptr[CMND_LIST]->data, cmnd) == 0) {
|
||||
if (list_ptr[USER_LIST]->op == '!') {
|
||||
list_ptr[CMND_LIST] = save_ptr;
|
||||
return(QUIT_NOW);
|
||||
}
|
||||
else {
|
||||
list_ptr[CMND_LIST] = save_ptr;
|
||||
return(MATCH);
|
||||
}
|
||||
}
|
||||
if (list_ptr[CMND_LIST]->next != NULL) {
|
||||
next_type = list_ptr[CMND_LIST]->next->type;
|
||||
tmp_ptr = list_ptr[CMND_LIST];
|
||||
list_ptr[CMND_LIST] = tmp_ptr->next;
|
||||
}
|
||||
else {
|
||||
next_type = ~TYPE3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tmp_ptr = list_ptr[CMND_LIST];
|
||||
list_ptr[CMND_LIST] = tmp_ptr->next;
|
||||
}
|
||||
}
|
||||
list_ptr[CMND_LIST] = save_ptr;
|
||||
return(NO_MATCH);
|
||||
/*
|
||||
* this case is the normal lowercase hostname
|
||||
*/
|
||||
else if (isupper(list_ptr[USER_LIST] -> data[0]) == FALSE) {
|
||||
return (strcmp(list_ptr[USER_LIST] -> data, host) == 0);
|
||||
}
|
||||
/*
|
||||
* by now we have a Host_Alias that will have to be expanded
|
||||
*/
|
||||
else {
|
||||
save_ptr = list_ptr[HOST_LIST];
|
||||
while (list_ptr[HOST_LIST] != NULL) {
|
||||
if ((list_ptr[HOST_LIST] -> type == TYPE2) &&
|
||||
(strcmp(list_ptr[HOST_LIST] -> data,
|
||||
list_ptr[USER_LIST] -> data) == 0)) {
|
||||
next_type = list_ptr[HOST_LIST] -> next -> type;
|
||||
tmp_ptr = list_ptr[HOST_LIST];
|
||||
list_ptr[HOST_LIST] = tmp_ptr -> next;
|
||||
while (next_type == TYPE3) {
|
||||
if (strcmp(list_ptr[HOST_LIST] -> data, host) == 0) {
|
||||
list_ptr[HOST_LIST] = save_ptr;
|
||||
return (TRUE);
|
||||
}
|
||||
if (list_ptr[HOST_LIST] -> next != NULL) {
|
||||
next_type = list_ptr[HOST_LIST] -> next -> type;
|
||||
tmp_ptr = list_ptr[HOST_LIST];
|
||||
list_ptr[HOST_LIST] = tmp_ptr -> next;
|
||||
} else {
|
||||
next_type = ~TYPE3;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmp_ptr = list_ptr[HOST_LIST];
|
||||
list_ptr[HOST_LIST] = tmp_ptr -> next;
|
||||
}
|
||||
}
|
||||
list_ptr[HOST_LIST] = save_ptr;
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* this routine is called from validate() after the call_back() routine
|
||||
* has built all the possible lists. this routine steps thru the user list
|
||||
* calling on host_type_ok() and cmnd_type_ok() trying to resolve whether
|
||||
* or not the user will be able to execute the command on the host.
|
||||
*******************************************************************************/
|
||||
int cmnd_check()
|
||||
{
|
||||
int return_code;
|
||||
|
||||
while (list_ptr[USER_LIST] != NULL) {
|
||||
if ((list_ptr[USER_LIST]->type == TYPE2) && host_type_ok()) {
|
||||
next_type = list_ptr[USER_LIST]->next->type;
|
||||
tmp_ptr = list_ptr[USER_LIST];
|
||||
list_ptr[USER_LIST] = tmp_ptr->next;
|
||||
while (next_type == TYPE3) {
|
||||
return_code = cmnd_type_ok();
|
||||
if (return_code == MATCH) {
|
||||
return(VALIDATE_OK);
|
||||
}
|
||||
else if (return_code == QUIT_NOW) {
|
||||
return(VALIDATE_NOT_OK);
|
||||
}
|
||||
if (list_ptr[USER_LIST]->next != NULL) {
|
||||
next_type = list_ptr[USER_LIST]->next->type;
|
||||
tmp_ptr = list_ptr[USER_LIST];
|
||||
list_ptr[USER_LIST] = tmp_ptr->next;
|
||||
}
|
||||
else {
|
||||
next_type = ~TYPE3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tmp_ptr = list_ptr[USER_LIST];
|
||||
list_ptr[USER_LIST] = tmp_ptr->next;
|
||||
}
|
||||
}
|
||||
return(VALIDATE_NOT_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* this routine is called from the sudo.c module and tries to validate
|
||||
* the user, host and command triplet.
|
||||
*******************************************************************************/
|
||||
int validate()
|
||||
{
|
||||
FILE *sudoers_fp;
|
||||
int i, return_code;
|
||||
|
||||
if ((sudoers_fp = fopen(SUDOERS, "r")) == NULL ) {
|
||||
perror(SUDOERS);
|
||||
log_error( NO_SUDOERS_FILE );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
yyin = sudoers_fp;
|
||||
yyout = stdout;
|
||||
|
||||
for (i = 0; i < NUM_LISTS; i++)
|
||||
new_list[i] = TRUE;
|
||||
|
||||
/*
|
||||
* yyparse() returns with one of 3 values: 0) yyparse() worked fine;
|
||||
* 1) yyparse() failed; FOUND_USER) the user was found and yyparse()
|
||||
* was returned from prematurely.
|
||||
* this routine is called from cmnd_check() to resolve whether or not
|
||||
* a user is permitted to perform a certain command on the already
|
||||
* established host.
|
||||
*/
|
||||
return_code = yyparse();
|
||||
|
||||
/* don't need to keep this open... */
|
||||
(void) fclose (sudoers_fp);
|
||||
|
||||
/* if a parsing error occurred, set return_code accordingly */
|
||||
if (parse_error == TRUE) {
|
||||
return_code = PARSE_ERROR;
|
||||
int cmnd_type_ok()
|
||||
{
|
||||
/*
|
||||
* check for the reserved keyword 'ALL'.
|
||||
*/
|
||||
if (strcmp(list_ptr[USER_LIST] -> data, "ALL") == 0) {
|
||||
/* if the command has an absolute path, let them do it */
|
||||
if (cmnd[0] == '/') {
|
||||
return (MATCH);
|
||||
}
|
||||
/* if the command does not have an absolute path, forget it */
|
||||
else {
|
||||
return (NO_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
/* if the user was not found, set the return_code accordingly */
|
||||
if (found_user == FALSE) {
|
||||
return_code = NOT_FOUND_USER;
|
||||
/*
|
||||
* if the command has an absolute path, check it out
|
||||
*/
|
||||
else if (list_ptr[USER_LIST] -> data[0] == '/') {
|
||||
/*
|
||||
* op | data | return value
|
||||
* ---------------------------------
|
||||
* ' ' | No Match | return(NO_MATCH)
|
||||
* '!' | No Match | return(NO_MATCH)
|
||||
* ' ' | A Match | return(MATCH)
|
||||
* '!' | A Match | return(QUIT_NOW)
|
||||
*
|
||||
* these special cases are important in subtracting from the Universe
|
||||
* of commands in something like:
|
||||
* user machine=ALL,!/bin/rm,!/etc/named ...
|
||||
*/
|
||||
if (strcmp(list_ptr[USER_LIST] -> data, cmnd) == 0) {
|
||||
if (list_ptr[USER_LIST] -> op == '!') {
|
||||
return (QUIT_NOW);
|
||||
} else {
|
||||
return (MATCH);
|
||||
}
|
||||
} else {
|
||||
return (NO_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
/* handle the 3 cases individually &*/
|
||||
switch(return_code) {
|
||||
case FOUND_USER:
|
||||
return_code = cmnd_check();
|
||||
delete_list(USER_LIST);
|
||||
delete_list(HOST_LIST);
|
||||
delete_list(CMND_LIST);
|
||||
return(return_code);
|
||||
break;
|
||||
case NOT_FOUND_USER:
|
||||
return(VALIDATE_NO_USER);
|
||||
break;
|
||||
case PARSE_ERROR:
|
||||
return(VALIDATE_ERROR);
|
||||
break;
|
||||
/*
|
||||
* by now we have a Cmnd_Alias that will have to be expanded
|
||||
*/
|
||||
else {
|
||||
save_ptr = list_ptr[CMND_LIST];
|
||||
while (list_ptr[CMND_LIST] != NULL) {
|
||||
if ((list_ptr[CMND_LIST] -> type == TYPE2) &&
|
||||
(strcmp(list_ptr[CMND_LIST] -> data,
|
||||
list_ptr[USER_LIST] -> data) == 0)) {
|
||||
next_type = list_ptr[CMND_LIST] -> next -> type;
|
||||
tmp_ptr = list_ptr[CMND_LIST];
|
||||
list_ptr[CMND_LIST] = tmp_ptr -> next;
|
||||
while (next_type == TYPE3) {
|
||||
if (strcmp(list_ptr[CMND_LIST] -> data, cmnd) == 0) {
|
||||
if (list_ptr[USER_LIST] -> op == '!') {
|
||||
list_ptr[CMND_LIST] = save_ptr;
|
||||
return (QUIT_NOW);
|
||||
} else {
|
||||
list_ptr[CMND_LIST] = save_ptr;
|
||||
return (MATCH);
|
||||
}
|
||||
}
|
||||
if (list_ptr[CMND_LIST] -> next != NULL) {
|
||||
next_type = list_ptr[CMND_LIST] -> next -> type;
|
||||
tmp_ptr = list_ptr[CMND_LIST];
|
||||
list_ptr[CMND_LIST] = tmp_ptr -> next;
|
||||
} else {
|
||||
next_type = ~TYPE3;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmp_ptr = list_ptr[CMND_LIST];
|
||||
list_ptr[CMND_LIST] = tmp_ptr -> next;
|
||||
}
|
||||
}
|
||||
list_ptr[CMND_LIST] = save_ptr;
|
||||
return (NO_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* this routine is called from validate() after the call_back() routine
|
||||
* has built all the possible lists. this routine steps thru the user list
|
||||
* calling on host_type_ok() and cmnd_type_ok() trying to resolve whether
|
||||
* or not the user will be able to execute the command on the host.
|
||||
*/
|
||||
|
||||
int cmnd_check()
|
||||
{
|
||||
int return_code;
|
||||
|
||||
while (list_ptr[USER_LIST] != NULL) {
|
||||
if ((list_ptr[USER_LIST] -> type == TYPE2) && host_type_ok()) {
|
||||
next_type = list_ptr[USER_LIST] -> next -> type;
|
||||
tmp_ptr = list_ptr[USER_LIST];
|
||||
list_ptr[USER_LIST] = tmp_ptr -> next;
|
||||
while (next_type == TYPE3) {
|
||||
return_code = cmnd_type_ok();
|
||||
if (return_code == MATCH) {
|
||||
return (VALIDATE_OK);
|
||||
} else if (return_code == QUIT_NOW) {
|
||||
return (VALIDATE_NOT_OK);
|
||||
}
|
||||
if (list_ptr[USER_LIST] -> next != NULL) {
|
||||
next_type = list_ptr[USER_LIST] -> next -> type;
|
||||
tmp_ptr = list_ptr[USER_LIST];
|
||||
list_ptr[USER_LIST] = tmp_ptr -> next;
|
||||
} else {
|
||||
next_type = ~TYPE3;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmp_ptr = list_ptr[USER_LIST];
|
||||
list_ptr[USER_LIST] = tmp_ptr -> next;
|
||||
}
|
||||
}
|
||||
return (VALIDATE_NOT_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* this routine is called from the sudo.c module and tries to validate
|
||||
* the user, host and command triplet.
|
||||
*/
|
||||
|
||||
int validate()
|
||||
{
|
||||
FILE *sudoers_fp;
|
||||
int i, return_code;
|
||||
|
||||
if ((sudoers_fp = fopen(SUDOERS, "r")) == NULL) {
|
||||
perror(SUDOERS);
|
||||
log_error(NO_SUDOERS_FILE);
|
||||
exit(1);
|
||||
}
|
||||
yyin = sudoers_fp;
|
||||
yyout = stdout;
|
||||
|
||||
for (i = 0; i < NUM_LISTS; i++)
|
||||
new_list[i] = TRUE;
|
||||
|
||||
/*
|
||||
* yyparse() returns with one of 3 values: 0) yyparse() worked fine;
|
||||
* 1) yyparse() failed; FOUND_USER) the user was found and yyparse()
|
||||
* was returned from prematurely.
|
||||
*/
|
||||
return_code = yyparse();
|
||||
|
||||
/*
|
||||
* don't need to keep this open...
|
||||
*/
|
||||
(void) fclose(sudoers_fp);
|
||||
|
||||
/*
|
||||
* if a parsing error occurred, set return_code accordingly
|
||||
*/
|
||||
if (parse_error == TRUE) {
|
||||
return_code = PARSE_ERROR;
|
||||
}
|
||||
/*
|
||||
* if the user was not found, set the return_code accordingly
|
||||
*/
|
||||
if (found_user == FALSE) {
|
||||
return_code = NOT_FOUND_USER;
|
||||
}
|
||||
/*
|
||||
* handle the 3 cases individually
|
||||
*/
|
||||
switch (return_code) {
|
||||
case FOUND_USER:
|
||||
return_code = cmnd_check();
|
||||
delete_list(USER_LIST);
|
||||
delete_list(HOST_LIST);
|
||||
delete_list(CMND_LIST);
|
||||
return (return_code);
|
||||
break;
|
||||
case NOT_FOUND_USER:
|
||||
return (VALIDATE_NO_USER);
|
||||
break;
|
||||
case PARSE_ERROR:
|
||||
return (VALIDATE_ERROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user