]> granicus.if.org Git - sudo/commitdiff
Add file:linenumber prefix to all Defaults warnings so we can see
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 2 Nov 2016 23:07:32 +0000 (17:07 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 2 Nov 2016 23:07:32 +0000 (17:07 -0600)
them when running sudo too.  For LDAP/SSSD we print the sudoRole
instead of the file name and omit the line number.

plugins/sudoers/defaults.c
plugins/sudoers/defaults.h
plugins/sudoers/gram.c
plugins/sudoers/gram.y
plugins/sudoers/ldap.c
plugins/sudoers/sssd.c

index 3faeff86037873ae11e5cd5107a5f98599c640c7..1d1aea07c8ce03ebe0bc94d7a071bf7acbcaa6fe 100644 (file)
@@ -90,6 +90,10 @@ static struct early_default early_defaults[] = {
     { NULL }
 };
 
+/* Flags for set_default_entry() and set_default_int() */
+#define        FLAG_DO_CALLBACK        0x01
+#define        FLAG_QUIET              0x02
+
 /*
  * Local prototypes.
  */
@@ -193,7 +197,7 @@ dump_defaults(void)
 
 static bool
 set_default_entry(struct sudo_defs_types *def, const char *val, int op,
-    bool quiet, bool do_callback)
+    const char *file, int lineno, int flags)
 {
     int rc;
     debug_decl(set_default_entry, SUDOERS_DEBUG_DEFAULTS)
@@ -201,8 +205,15 @@ set_default_entry(struct sudo_defs_types *def, const char *val, int op,
     if (val == NULL && !ISSET(def->type, T_FLAG)) {
        /* Check for bogus boolean usage or missing value if non-boolean. */
        if (!ISSET(def->type, T_BOOL) || op != false) {
-           if (!quiet)
-               sudo_warnx(U_("no value specified for `%s'"), def->name);
+           if (!ISSET(flags, FLAG_QUIET)) {
+               if (lineno > 0) {
+                   sudo_warnx(U_("%s:%d no value specified for `%s'"),
+                       file, lineno, def->name);
+               } else {
+                   sudo_warnx(U_("%s: no value specified for `%s'"),
+                       file, def->name);
+               }
+           }
            debug_return_bool(false);
        }
     }
@@ -216,9 +227,14 @@ set_default_entry(struct sudo_defs_types *def, const char *val, int op,
            break;
        case T_STR:
            if (ISSET(def->type, T_PATH) && val != NULL && *val != '/') {
-               if (!quiet) {
-                   sudo_warnx(U_("values for `%s' must start with a '/'"),
-                       def->name);
+               if (!ISSET(flags, FLAG_QUIET)) {
+                   if (lineno > 0) {
+                       sudo_warnx(U_("%s:%d values for `%s' must start with a '/'"),
+                           file, lineno, def->name);
+                   } else {
+                       sudo_warnx(U_("%s: values for `%s' must start with a '/'"),
+                           file, def->name);
+                   }
                }
                rc = -1;
                break;
@@ -239,9 +255,14 @@ set_default_entry(struct sudo_defs_types *def, const char *val, int op,
            break;
        case T_FLAG:
            if (val != NULL) {
-               if (!quiet) {
-                   sudo_warnx(U_("option `%s' does not take a value"),
-                       def->name);
+               if (!ISSET(flags, FLAG_QUIET)) {
+                   if (lineno > 0) {
+                       sudo_warnx(U_("%s:%d option `%s' does not take a value"),
+                           file, lineno, def->name);
+                   } else {
+                       sudo_warnx(U_("%s: option `%s' does not take a value"),
+                           file, def->name);
+                   }
                }
                rc = -1;
                break;
@@ -256,9 +277,14 @@ set_default_entry(struct sudo_defs_types *def, const char *val, int op,
            rc = store_tuple(val, def);
            break;
        default:
-           if (!quiet) {
-               sudo_warnx(U_("invalid Defaults type 0x%x for option `%s'"),
-                   def->type, def->name);
+           if (!ISSET(flags, FLAG_QUIET)) {
+               if (lineno > 0) {
+                   sudo_warnx(U_("%s:%d invalid Defaults type 0x%x for option `%s'"),
+                       file, lineno, def->type, def->name);
+               } else {
+                   sudo_warnx(U_("%s: invalid Defaults type 0x%x for option `%s'"),
+                       file, def->type, def->name);
+               }
            }
            rc = -1;
            break;
@@ -269,13 +295,18 @@ set_default_entry(struct sudo_defs_types *def, const char *val, int op,
        rc = false;
        break;
     case false:
-       if (!quiet) {
-           sudo_warnx(U_("value `%s' is invalid for option `%s'"),
-               val, def->name);
+       if (!ISSET(flags, FLAG_QUIET)) {
+           if (lineno > 0) {
+               sudo_warnx(U_("%s:%d value `%s' is invalid for option `%s'"),
+                   file, lineno, val, def->name);
+           } else {
+               sudo_warnx(U_("%s: value `%s' is invalid for option `%s'"),
+                   file, val, def->name);
+           }
        }
        break;
     case true:
-       if (do_callback && def->callback)
+       if (ISSET(flags, FLAG_DO_CALLBACK) && def->callback)
            rc = def->callback(&def->sd_un);
        break;
     }
@@ -304,8 +335,8 @@ is_early_default(const char *var)
  * This is only meaningful for variables that are *optional*.
  */
 static struct sudo_defs_types *
-set_default_int(const char *var, const char *val, int op, bool quiet,
-    bool do_callback)
+set_default_int(const char *var, const char *val, int op, const char *file,
+    int lineno, int flags)
 {
     struct sudo_defs_types *cur;
     int num;
@@ -316,12 +347,19 @@ set_default_int(const char *var, const char *val, int op, bool quiet,
            break;
     }
     if (!cur->name) {
-       if (!quiet)
-           sudo_warnx(U_("unknown defaults entry `%s'"), var);
+       if (!ISSET(flags, FLAG_QUIET)) {
+           if (lineno > 0) {
+               sudo_warnx(U_("%s:%d unknown defaults entry `%s'"),
+                   file, lineno, var);
+           } else {
+               sudo_warnx(U_("%s: unknown defaults entry `%s'"),
+                   file, var);
+           }
+       }
        debug_return_ptr(NULL);
     }
 
-    if (!set_default_entry(cur, val, op, quiet, do_callback))
+    if (!set_default_entry(cur, val, op, file, lineno, flags))
        debug_return_ptr(NULL);
     debug_return_ptr(cur);
 }
@@ -331,12 +369,16 @@ set_default_int(const char *var, const char *val, int op, bool quiet,
  * Runs the callback if present on success.
  */
 bool
-set_default(const char *var, const char *val, int op, bool quiet)
+set_default(const char *var, const char *val, int op, const char *file,
+    int lineno, bool quiet)
 {
     const struct sudo_defs_types *def;
+    int flags = FLAG_DO_CALLBACK;
     debug_decl(set_default, SUDOERS_DEBUG_DEFAULTS)
 
-    def = set_default_int(var, val, op, quiet, true);
+    if (quiet)
+       SET(flags, FLAG_QUIET);
+    def = set_default_int(var, val, op, file, lineno, flags);
     debug_return_bool(def != NULL);
 }
 
@@ -345,13 +387,16 @@ set_default(const char *var, const char *val, int op, bool quiet)
  * and does not run callbacks.
  */
 bool
-set_early_default(const char *var, const char *val, int op, bool quiet,
-    struct early_default *early)
+set_early_default(const char *var, const char *val, int op, const char *file,
+    int lineno, bool quiet, struct early_default *early)
 {
     const struct sudo_defs_types *def;
+    int flags = 0;
     debug_decl(set_early_default, SUDOERS_DEBUG_DEFAULTS)
 
-    def = set_default_int(var, val, op, quiet, false);
+    if (quiet)
+       SET(flags, FLAG_QUIET);
+    def = set_default_int(var, val, op, file, lineno, flags);
     if (def == NULL)
        debug_return_bool(false);
     early->def = def;
@@ -673,7 +718,7 @@ update_defaults(int what, bool quiet)
        if (!default_type_matches(def, what) ||
            !default_binding_matches(def, what))
            continue;
-       if (!set_early_default(def->var, def->val, def->op, quiet, early))
+       if (!set_early_default(def->var, def->val, def->op, "sudoers", 0, quiet, early))
            ret = false;
     }
     if (!run_early_defaults())
@@ -690,7 +735,7 @@ update_defaults(int what, bool quiet)
        if (!default_type_matches(def, what) ||
            !default_binding_matches(def, what))
            continue;
-       if (!set_default(def->var, def->val, def->op, quiet))
+       if (!set_default(def->var, def->val, def->op, "sudoers", 0, quiet))
            ret = false;
     }
     debug_return_bool(ret);
@@ -700,26 +745,37 @@ update_defaults(int what, bool quiet)
  * Check a defaults entry without actually setting it.
  */
 bool
-check_default(struct defaults *def, bool quiet)
+check_default(const char *var, const char *val, int op, const char *file,
+    int lineno, bool quiet)
 {
     struct sudo_defs_types *cur;
     bool ret = true;
+    int flags = 0;
     debug_decl(check_default, SUDOERS_DEBUG_DEFAULTS)
 
+    if (quiet)
+       SET(flags, FLAG_QUIET);
     for (cur = sudo_defs_table; cur->name != NULL; cur++) {
-       if (strcmp(def->var, cur->name) == 0) {
+       if (strcmp(var, cur->name) == 0) {
            /* Don't actually set the defaults value, just checking. */
            struct sudo_defs_types tmp = *cur;
            memset(&tmp.sd_un, 0, sizeof(tmp.sd_un));
-           if (!set_default_entry(&tmp, def->val, def->op, quiet, false))
+           if (!set_default_entry(&tmp, val, op, file, lineno, flags))
                ret = false;
            free_default(&tmp);
            break;
        }
     }
     if (cur->name == NULL) {
-       if (!quiet)
-           sudo_warnx(U_("unknown defaults entry `%s'"), def->var);
+       if (!quiet) {
+           if (lineno > 0) {
+               sudo_warnx(U_("%s:%d unknown defaults entry `%s'"),
+                   file, lineno, var);
+           } else {
+               sudo_warnx(U_("%s: unknown defaults entry `%s'"),
+                   file, var);
+           }
+       }
        ret = false;
     }
     debug_return_bool(ret);
index 7a4567d6897c885ba5682b5bc92c89b06eb729d0..55b08b36b685f307399446df37425349f0328ce7 100644 (file)
@@ -122,12 +122,12 @@ struct early_default {
 struct defaults;       /* in parse.h */
 
 void dump_default(void);
-bool check_default(struct defaults *def, bool quiet);
+bool check_default(const char *var, const char *val, int op, const char *file, int lineno, bool quiet);
 bool init_defaults(void);
 struct early_default *is_early_default(const char *var);
 bool run_early_defaults(void);
-bool set_early_default(const char *var, const char *val, int op, bool quiet, struct early_default *early);
-bool set_default(const char *var, const char *val, int op, bool quiet);
+bool set_early_default(const char *var, const char *val, int op, const char *file, int lineno, bool quiet, struct early_default *early);
+bool set_default(const char *var, const char *val, int op, const char *file, int lineno, bool quiet);
 bool update_defaults(int what, bool quiet);
 
 extern struct sudo_defs_types sudo_defs_table[];
index 29108319e9b0071f4a1a05824966b5937db03911..a87abdedfc894d28c4417ddf5748acb36879268e 100644 (file)
@@ -826,16 +826,16 @@ add_defaults(int type, struct member *bmem, struct defaults *defs)
         * Then add to the global defaults list if it parses.
         */
        HLTQ_FOREACH_SAFE(d, defs, entries, next) {
-           if (check_default(d, !sudoers_warnings)) {
+           if (check_default(d->var, d->val, d->op, sudoers, sudolineno, !sudoers_warnings)) {
                /* Append to defaults list */
                d->type = type;
                d->binding = binding;
                binding_used = true;
                TAILQ_INSERT_TAIL(&defaults, d, entries);
            } else {
-               /* Did not parse, warn and free it. */
+               /* Did not parse */
                if (!allow_unknown_defaults) {
-                   sudoerserror(N_("problem with defaults entries"));
+                   sudoerserror(NULL);
                    ret = false;
                }
                free(d->var);
index e52ddad887ab7aa306d2786aa5f249554e8a36c8..8f5e57d118df0ddcd761e9f10d9ababb81ce785a 100644 (file)
@@ -982,16 +982,16 @@ add_defaults(int type, struct member *bmem, struct defaults *defs)
         * Then add to the global defaults list if it parses.
         */
        HLTQ_FOREACH_SAFE(d, defs, entries, next) {
-           if (check_default(d, !sudoers_warnings)) {
+           if (check_default(d->var, d->val, d->op, sudoers, sudolineno, !sudoers_warnings)) {
                /* Append to defaults list */
                d->type = type;
                d->binding = binding;
                binding_used = true;
                TAILQ_INSERT_TAIL(&defaults, d, entries);
            } else {
-               /* Did not parse, warn and free it. */
+               /* Did not parse */
                if (!allow_unknown_defaults) {
-                   sudoerserror(N_("problem with defaults entries"));
+                   sudoerserror(NULL);
                    ret = false;
                }
                free(d->var);
index c85efe2d00b1242c866222e4918df5771cd93938..9aa586be4b291ade5100c04cf6e981984dc927eb 100644 (file)
@@ -380,6 +380,7 @@ static int sudo_ldap_display_privs(struct sudo_nss *nss, struct passwd *pw,
     struct sudo_lbuf *lbuf);
 static struct ldap_result *sudo_ldap_result_get(struct sudo_nss *nss,
     struct passwd *pw);
+static char *sudo_ldap_get_first_rdn(LDAP *ld, LDAPMessage *entry);
 
 /*
  * LDAP sudo_nss handle.
@@ -1129,7 +1130,7 @@ static bool
 sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry)
 {
     struct berval **bv, **p;
-    char *copy, *var, *val;
+    char *cn, *copy, *var, *val, *source = NULL;
     bool ret = false;
     int op;
     debug_decl(sudo_ldap_parse_options, SUDOERS_DEBUG_LDAP)
@@ -1138,6 +1139,16 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry)
     if (bv == NULL)
        debug_return_bool(true);
 
+    /* get the entry's dn for option error reporting */
+    cn = sudo_ldap_get_first_rdn(ld, entry);
+    if (cn != NULL) {
+       if (asprintf(&source, "sudoRole %s", cn) == -1) {
+           sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+           source = NULL;
+           goto done;
+       }
+    }
+
     /* walk through options, early ones first */
     for (p = bv; *p != NULL; p++) {
        struct early_default *early;
@@ -1148,8 +1159,10 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry)
        }
        op = sudo_ldap_parse_option(copy, &var, &val);
        early = is_early_default(var);
-       if (early != NULL)
-           set_early_default(var, val, op, false, early);
+       if (early != NULL) {
+           set_early_default(var, val, op,
+               source ? source : "sudoRole UNKNOWN", 0, false, early);
+       }
        free(copy);
     }
     run_early_defaults();
@@ -1161,13 +1174,18 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry)
            goto done;
        }
        op = sudo_ldap_parse_option(copy, &var, &val);
-       if (is_early_default(var) == NULL)
-           set_default(var, val, op, false);
+       if (is_early_default(var) == NULL) {
+           set_default(var, val, op,
+               source ? source : "sudoRole UNKNOWN", 0, false);
+       }
        free(copy);
     }
     ret = true;
 
 done:
+    free(source);
+    if (cn)
+       ldap_memfree(cn);
     ldap_value_free_len(bv);
 
     debug_return_bool(ret);
index bb2f139dac95b06f4365754f83d4e813d3b5b919..c1bf7baf32ca206c643af42e9fe338e3aa6ecc51 100644 (file)
@@ -1196,9 +1196,10 @@ static bool
 sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
 {
     int i, op;
-    char *copy, *var, *val;
+    char *copy, *var, *val, *source = NULL;
     bool ret = false;
     char **val_array = NULL;
+    char **cn_array = NULL;
     debug_decl(sudo_sss_parse_options, SUDOERS_DEBUG_SSSD);
 
     if (rule == NULL)
@@ -1215,6 +1216,20 @@ sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rul
        debug_return_bool(false);
     }
 
+    /* get the entry's cn for option error reporting */
+    if (handle->fn_get_values(rule, "cn", &cn_array) == 0) {
+       if (cn_array[0] != NULL) {
+           if (asprintf(&source, "sudoRole %s", cn_array[0]) == -1) {
+               sudo_warnx(U_("%s: %s"), __func__,
+                   U_("unable to allocate memory"));
+               source = NULL;
+               goto done;
+           }
+       }
+       handle->fn_free_values(cn_array);
+       cn_array = NULL;
+    }
+
     /* walk through options, early ones first */
     for (i = 0; val_array[i] != NULL; i++) {
        struct early_default *early;
@@ -1225,8 +1240,10 @@ sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rul
        }
        op = sudo_sss_parse_option(copy, &var, &val);
        early = is_early_default(var);
-       if (early != NULL)
-           set_early_default(var, val, op, false, early);
+       if (early != NULL) {
+           set_early_default(var, val, op,
+               source ? source : "sudoRole UNKNOWN", 0, false, early);
+       }
        free(copy);
     }
     run_early_defaults();
@@ -1238,13 +1255,16 @@ sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rul
            goto done;
        }
        op = sudo_sss_parse_option(copy, &var, &val);
-       if (is_early_default(var) == NULL)
-           set_default(var, val, op, false);
+       if (is_early_default(var) == NULL) {
+           set_default(var, val, op,
+               source ? source : "sudoRole UNKNOWN", 0, false);
+       }
        free(copy);
     }
     ret = true;
 
 done:
+    free(source);
     handle->fn_free_values(val_array);
     debug_return_bool(ret);
 }