/*
- * Copyright (c) 1999-2005, 2007-2008
+ * Copyright (c) 1999-2005, 2007-2008, 2010
* Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
#endif /* STDC_HEADERS */
#ifdef HAVE_STRING_H
# include <string.h>
-#else
-# ifdef HAVE_STRINGS_H
-# include <strings.h>
-# endif
#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include "parse.h"
#include <gram.h>
-#ifndef lint
-__unused static const char rcsid[] = "$Sudo: defaults.c,v 1.73 2008/11/09 14:13:12 millert Exp $";
-#endif /* lint */
-
/*
* For converting between syslog numbers and strings.
*/
static int store_syslogpri __P((char *, struct sudo_defs_types *, int));
static int store_tuple __P((char *, struct sudo_defs_types *, int));
static int store_uint __P((char *, struct sudo_defs_types *, int));
+static int store_float __P((char *, struct sudo_defs_types *, int));
static void list_op __P((char *, size_t, struct sudo_defs_types *, enum list_ops));
static const char *logfac2str __P((int));
static const char *logpri2str __P((int));
(void) printf(cur->desc, cur->sd_un.ival);
putchar('\n');
break;
+ case T_FLOAT:
+ (void) printf(cur->desc, cur->sd_un.fval);
+ putchar('\n');
+ break;
case T_MODE:
(void) printf(cur->desc, cur->sd_un.mode);
putchar('\n');
}
if (!cur->name) {
warningx("unknown defaults entry `%s'", var);
- return(FALSE);
+ return FALSE;
}
switch (cur->type & T_MASK) {
warningx("value `%s' is invalid for option `%s'", val, var);
else
warningx("no value specified for `%s'", var);
- return(FALSE);
+ return FALSE;
}
break;
case T_LOGPRI:
warningx("value `%s' is invalid for option `%s'", val, var);
else
warningx("no value specified for `%s'", var);
- return(FALSE);
+ return FALSE;
}
break;
case T_STR:
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
warningx("no value specified for `%s'", var);
- return(FALSE);
+ return FALSE;
}
}
if (ISSET(cur->type, T_PATH) && val && *val != '/') {
warningx("values for `%s' must start with a '/'", var);
- return(FALSE);
+ return FALSE;
}
if (!store_str(val, cur, op)) {
warningx("value `%s' is invalid for option `%s'", val, var);
- return(FALSE);
+ return FALSE;
}
break;
case T_INT:
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
warningx("no value specified for `%s'", var);
- return(FALSE);
+ return FALSE;
}
}
if (!store_int(val, cur, op)) {
warningx("value `%s' is invalid for option `%s'", val, var);
- return(FALSE);
+ return FALSE;
}
break;
case T_UINT:
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
warningx("no value specified for `%s'", var);
- return(FALSE);
+ return FALSE;
}
}
if (!store_uint(val, cur, op)) {
warningx("value `%s' is invalid for option `%s'", val, var);
- return(FALSE);
+ return FALSE;
+ }
+ break;
+ case T_FLOAT:
+ if (!val) {
+ /* Check for bogus boolean usage or lack of a value. */
+ if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
+ warningx("no value specified for `%s'", var);
+ return FALSE;
+ }
+ }
+ if (!store_float(val, cur, op)) {
+ warningx("value `%s' is invalid for option `%s'", val, var);
+ return FALSE;
}
break;
case T_MODE:
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
warningx("no value specified for `%s'", var);
- return(FALSE);
+ return FALSE;
}
}
if (!store_mode(val, cur, op)) {
warningx("value `%s' is invalid for option `%s'", val, var);
- return(FALSE);
+ return FALSE;
}
break;
case T_FLAG:
if (val) {
warningx("option `%s' does not take a value", var);
- return(FALSE);
+ return FALSE;
}
cur->sd_un.flag = op;
-
- /* Special action for I_FQDN. Move to own switch if we get more */
- if (num == I_FQDN && op)
- set_fqdn();
break;
case T_LIST:
if (!val) {
/* Check for bogus boolean usage or lack of a value. */
if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
warningx("no value specified for `%s'", var);
- return(FALSE);
+ return FALSE;
}
}
if (!store_list(val, cur, op)) {
warningx("value `%s' is invalid for option `%s'", val, var);
- return(FALSE);
+ return FALSE;
}
break;
case T_TUPLE:
if (!val && !ISSET(cur->type, T_BOOL)) {
warningx("no value specified for `%s'", var);
- return(FALSE);
+ return FALSE;
}
if (!store_tuple(val, cur, op)) {
warningx("value `%s' is invalid for option `%s'", val, var);
- return(FALSE);
+ return FALSE;
}
break;
}
- return(TRUE);
+ return TRUE;
}
/*
#ifdef SEND_MAIL_WHEN_NOT_OK
def_mail_no_perms = TRUE;
#endif
-#ifdef USE_TTY_TICKETS
+#ifndef NO_TTY_TICKETS
def_tty_tickets = TRUE;
#endif
#ifndef NO_LECTURE
#ifdef ENV_EDITOR
def_env_editor = TRUE;
#endif
+#ifdef UMASK_OVERRIDE
+ def_umask_override = TRUE;
+#endif
#ifdef _PATH_SUDO_ASKPASS
def_askpass = estrdup(_PATH_SUDO_ASKPASS);
#endif
+ def_iolog_dir = estrdup(_PATH_SUDO_IO_LOGDIR);
def_sudoers_locale = estrdup("C");
- def_env_reset = TRUE;
+ def_env_reset = ENV_RESET;
def_set_logname = TRUE;
def_closefrom = STDERR_FILENO + 1;
def_timestamp_timeout = TIMEOUT;
def_passwd_timeout = PASSWORD_TIMEOUT;
def_passwd_tries = TRIES_FOR_PASSWORD;
+#ifdef HAVE_ZLIB_H
+ def_compress_io = TRUE;
+#endif
/* Now do the strings */
def_mailto = estrdup(MAILTO);
/*
* Update the defaults based on what was set by sudoers.
- * Pass in a an OR'd list of which default types to update.
+ * Pass in an OR'd list of which default types to update.
*/
int
update_defaults(what)
int what;
{
struct defaults *def;
+ int rc = TRUE;
tq_foreach_fwd(&defaults, def) {
switch (def->type) {
case DEFAULTS:
if (ISSET(what, SETDEF_GENERIC) &&
!set_default(def->var, def->val, def->op))
- return(FALSE);
+ rc = FALSE;
break;
case DEFAULTS_USER:
if (ISSET(what, SETDEF_USER) &&
userlist_matches(sudo_user.pw, &def->binding) == ALLOW &&
!set_default(def->var, def->val, def->op))
- return(FALSE);
+ rc = FALSE;
break;
case DEFAULTS_RUNAS:
if (ISSET(what, SETDEF_RUNAS) &&
runaslist_matches(&def->binding, NULL) == ALLOW &&
!set_default(def->var, def->val, def->op))
- return(FALSE);
+ rc = FALSE;
break;
case DEFAULTS_HOST:
if (ISSET(what, SETDEF_HOST) &&
hostlist_matches(&def->binding) == ALLOW &&
!set_default(def->var, def->val, def->op))
- return(FALSE);
+ rc = FALSE;
break;
case DEFAULTS_CMND:
if (ISSET(what, SETDEF_CMND) &&
cmndlist_matches(&def->binding) == ALLOW &&
!set_default(def->var, def->val, def->op))
- return(FALSE);
+ rc = FALSE;
break;
}
}
- return(TRUE);
+ return rc;
}
static int
} else {
l = strtol(val, &endp, 10);
if (*endp != '\0')
- return(FALSE);
+ return FALSE;
/* XXX - should check against INT_MAX */
- def->sd_un.ival = (unsigned int)l;
+ def->sd_un.ival = (int)l;
}
if (def->callback)
- return(def->callback(val));
- return(TRUE);
+ return def->callback(val);
+ return TRUE;
}
static int
} else {
l = strtol(val, &endp, 10);
if (*endp != '\0' || l < 0)
- return(FALSE);
+ return FALSE;
/* XXX - should check against INT_MAX */
def->sd_un.ival = (unsigned int)l;
}
if (def->callback)
- return(def->callback(val));
- return(TRUE);
+ return def->callback(val);
+ return TRUE;
+}
+
+static int
+store_float(val, def, op)
+ char *val;
+ struct sudo_defs_types *def;
+ int op;
+{
+ char *endp;
+ double d;
+
+ if (op == FALSE) {
+ def->sd_un.fval = 0.0;
+ } else {
+ d = strtod(val, &endp);
+ if (*endp != '\0')
+ return FALSE;
+ /* XXX - should check against HUGE_VAL */
+ def->sd_un.fval = d;
+ }
+ if (def->callback)
+ return def->callback(val);
+ return TRUE;
}
static int
}
}
if (v->sval == NULL)
- return(FALSE);
+ return FALSE;
}
if (def->callback)
- return(def->callback(val));
- return(TRUE);
+ return def->callback(val);
+ return TRUE;
}
static int
else
def->sd_un.str = estrdup(val);
if (def->callback)
- return(def->callback(val));
- return(TRUE);
+ return def->callback(val);
+ return TRUE;
}
static int
end = str;
do {
/* Remove leading blanks, if nothing but blanks we are done. */
- for (start = end; isblank(*start); start++)
+ for (start = end; isblank((unsigned char)*start); start++)
;
if (*start == '\0')
break;
/* Find end position and perform operation. */
- for (end = start; *end && !isblank(*end); end++)
+ for (end = start; *end && !isblank((unsigned char)*end); end++)
;
list_op(start, end - start, def, op == '-' ? delete : add);
} while (*end++ != '\0');
}
- return(TRUE);
+ return TRUE;
}
static int
if (op == FALSE) {
def->sd_un.ival = FALSE;
- return(TRUE);
+ return TRUE;
}
#ifdef LOG_NFACILITIES
if (!val)
- return(FALSE);
+ return FALSE;
for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
;
if (fac->name == NULL)
- return(FALSE); /* not found */
+ return FALSE; /* not found */
def->sd_un.ival = fac->num;
#else
def->sd_un.ival = -1;
#endif /* LOG_NFACILITIES */
- return(TRUE);
+ return TRUE;
}
static const char *
for (fac = facilities; fac->name && fac->num != n; fac++)
;
- return(fac->name);
+ return fac->name;
#else
- return("default");
+ return "default";
#endif /* LOG_NFACILITIES */
}
struct strmap *pri;
if (op == FALSE || !val)
- return(FALSE);
+ return FALSE;
for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
;
if (pri->name == NULL)
- return(FALSE); /* not found */
+ return FALSE; /* not found */
def->sd_un.ival = pri->num;
- return(TRUE);
+ return TRUE;
}
static const char *
for (pri = priorities; pri->name && pri->num != n; pri++)
;
- return(pri->name);
+ return pri->name;
}
static int
} else {
l = strtol(val, &endp, 8);
if (*endp != '\0' || l < 0 || l > 0777)
- return(FALSE);
+ return FALSE;
def->sd_un.mode = (mode_t)l;
}
if (def->callback)
- return(def->callback(val));
- return(TRUE);
+ return def->callback(val);
+ return TRUE;
}
static void