From 2f818e2c32dd6462bbcc35f6cf31fb41fafb4d73 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 11 Dec 2001 23:00:34 +0000 Subject: [PATCH] o Add a new LIST type and functions to manipulate it. o This is for use with environment handling variables. o Call new init_envtables() routine inside init_defaults() to initialize the environment lists. --- defaults.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++- defaults.h | 23 +++++++++-- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/defaults.c b/defaults.c index 7d2f6cace..cd5102810 100644 --- a/defaults.c +++ b/defaults.c @@ -34,6 +34,7 @@ #include "config.h" +#include #include #ifdef STDC_HEADERS #include @@ -108,11 +109,13 @@ static int store_syslogfac __P((char *, struct sudo_defs_types *, int)); static int store_syslogpri __P((char *, struct sudo_defs_types *, int)); static int store_mode __P((char *, struct sudo_defs_types *, int)); static int store_pwflag __P((char *, struct sudo_defs_types *, int)); +static int store_list __P((char *, struct sudo_defs_types *, int)); +static void list_op __P((char *, size_t, struct sudo_defs_types *, enum list_ops)); /* * Table describing compile-time and run-time options. */ -#include "def_data.c" +#include /* * Print version and configure info. @@ -121,6 +124,7 @@ void dump_defaults() { struct sudo_defs_types *cur; + struct list_member *item; for (cur = sudo_defs_table; cur->name; cur++) { if (cur->desc) { @@ -147,6 +151,13 @@ dump_defaults() (void) printf(cur->desc, cur->sd_un.mode); putchar('\n'); break; + case T_LIST: + if (cur->sd_un.list) { + puts(cur->desc); + for (item = cur->sd_un.list; item; item = item->next) + printf("\t%s\n", item->value); + } + break; } } } @@ -335,6 +346,22 @@ set_default(var, val, op) if (num == I_FQDN && op) set_fqdn(); break; + case T_LIST: + if (!val) { + /* Check for bogus boolean usage or lack of a value. */ + if (!(cur->type & T_BOOL) || op != FALSE) { + (void) fprintf(stderr, + "%s: no value specified for `%s' on line %d\n", Argv[0], + var, sudolineno); + return(FALSE); + } + } + if (!store_list(val, cur, op)) { + (void) fprintf(stderr, + "%s: value '%s' is invalid for option '%s'\n", Argv[0], + val, var); + return(FALSE); + } } return(TRUE); @@ -363,6 +390,9 @@ init_defaults() def->sd_un.str = NULL; } break; + case T_LIST: + list_op(NULL, 0, def, freeall); + break; } } @@ -444,7 +474,7 @@ init_defaults() def_ival(I_PASSWD_TIMEOUT) = PASSWORD_TIMEOUT; def_ival(I_PASSWD_TRIES) = TRIES_FOR_PASSWORD; - /* Finally do the strings */ + /* Now do the strings */ def_str(I_MAILTO) = estrdup(MAILTO); def_str(I_MAILSUB) = estrdup(MAILSUBJECT); def_str(I_BADPASS_MESSAGE) = estrdup(INCORRECT_PASSWORD); @@ -466,6 +496,9 @@ init_defaults() #endif def_str(I_EDITOR) = estrdup(EDITOR); + /* Finally do the lists (currently just environment tables). */ + init_envtables(); + /* * The following depend on the above values. * We use a pointer to the string so that if its @@ -535,6 +568,34 @@ store_str(val, def, op) return(TRUE); } +static int +store_list(str, def, op) + char *str; + struct sudo_defs_types *def; + int op; +{ + char *start, *end; + + /* Remove all old members. */ + if (op == FALSE || op == TRUE) + list_op(NULL, 0, def, freeall); + + /* Split str into multiple space-separated words and act on each one. */ + if (op != FALSE) { + for (start = str; isblank(*start); start++) + ; + while ((end = strpbrk(start, " \t"))) { + list_op(start, end - start, def, op == '-' ? delete : add); + start = end; + for (; isblank(*start); start++) + ; + } + if (*start) + list_op(start, strlen(start), def, op == '-' ? delete : add); + } + return(TRUE); +} + static int store_syslogfac(val, def, op) char *val; @@ -668,3 +729,49 @@ store_pwflag(val, def, op) return(TRUE); } + +static void +list_op(val, len, def, op) + char *val; + size_t len; + struct sudo_defs_types *def; + enum list_ops op; +{ + struct list_member *cur, *prev, *tmp; + + if (op == freeall) { + for (cur = def->sd_un.list; cur; ) { + tmp = cur; + cur = tmp->next; + free(tmp->value); + free(tmp); + } + def->sd_un.list = NULL; + return; + } + + for (cur = def->sd_un.list, prev = NULL; cur; prev = cur, cur = cur->next) { + if ((strncmp(cur->value, val, len) == 0 && cur->value[len] == '\0')) { + + if (op == add) + return; /* already exists */ + + /* Delete node */ + if (prev != NULL) + prev->next = cur->next; + else + def->sd_un.list = cur->next; + free(cur->value); + free(cur); + break; + } + } + + /* Add new node to the head of the list. */ + if (op == add) { + cur = emalloc(sizeof(struct list_member)); + cur->value = estrdup(val); + cur->next = def->sd_un.list; + def->sd_un.list = cur; + } +} diff --git a/defaults.h b/defaults.h index dbbe89a93..fd3e44b3a 100644 --- a/defaults.h +++ b/defaults.h @@ -37,6 +37,17 @@ #ifndef _SUDO_DEFAULTS_H #define _SUDO_DEFAULTS_H +struct list_member { + char *value; + struct list_member *next; +}; + +enum list_ops { + add, + delete, + freeall +}; + /* * Structure describing compile-time and run-time options. */ @@ -49,6 +60,7 @@ struct sudo_defs_types { int ival; char *str; mode_t mode; + struct list_member *list; } sd_un; }; @@ -67,12 +79,14 @@ struct sudo_defs_types { #define T_FLAG 0x004 #undef T_MODE #define T_MODE 0x005 +#undef T_LIST +#define T_LIST 0x006 #undef T_LOGFAC -#define T_LOGFAC 0x006 +#define T_LOGFAC 0x007 #undef T_LOGPRI -#define T_LOGPRI 0x007 +#define T_LOGPRI 0x008 #undef T_PWFLAG -#define T_PWFLAG 0x008 +#define T_PWFLAG 0x009 #undef T_MASK #define T_MASK 0x0FF #undef T_BOOL @@ -83,7 +97,7 @@ struct sudo_defs_types { /* * Indexes into sudo_defs_table */ -#include "def_data.h" +#include #define I_LOGFAC I_SYSLOG_IFAC #define I_GOODPRI I_SYSLOG_IGOODPRI #define I_BADPRI I_SYSLOG_IBADPRI @@ -94,6 +108,7 @@ struct sudo_defs_types { #define def_flag(_i) (sudo_defs_table[(_i)].sd_un.flag) #define def_ival(_i) (sudo_defs_table[(_i)].sd_un.ival) #define def_str(_i) (sudo_defs_table[(_i)].sd_un.str) +#define def_list(_i) (sudo_defs_table[(_i)].sd_un.list) #define def_mode(_i) (sudo_defs_table[(_i)].sd_un.mode) /* -- 2.40.0