]> granicus.if.org Git - sudo/commitdiff
Add atomode() function for parsing a file mode.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 10 Dec 2013 23:56:54 +0000 (16:56 -0700)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 10 Dec 2013 23:56:54 +0000 (16:56 -0700)
MANIFEST
common/Makefile.in
common/atoid.c
common/atomode.c [new file with mode: 0644]
plugins/sudoers/defaults.c
plugins/sudoers/policy.c
plugins/sudoers/sudoers.h
src/sudo.c
src/sudo.h

index bc93d7c0e3f6b7996b20c612bbe3e49c2df3a59b..8271d14add422a26cc3c8880947ae7798245ad21 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -13,6 +13,7 @@ common/aix.c
 common/alloc.c
 common/atobool.c
 common/atoid.c
+common/atomode.c
 common/event.c
 common/event_poll.c
 common/event_select.c
index 3314fd1eba44f4672c19e5d4be29af6fcf7c8d92..929fdc78916035e2c7df4fd79ebcc529eac4523e 100644 (file)
@@ -66,7 +66,7 @@ DEFS = @OSDEFS@ -D_PATH_SUDO_CONF=\"$(sysconfdir)/sudo.conf\"
 
 SHELL = @SHELL@
 
-LTOBJS = alloc.lo atobool.lo atoid.lo event.lo fatal.lo fileops.lo \
+LTOBJS = alloc.lo atobool.lo atoid.lo atomode.lo event.lo fatal.lo fileops.lo \
         fmt_string.lo gidlist.lo lbuf.lo progname.lo secure_path.lo \
         setgroups.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo sudo_printf.lo \
         term.lo ttysize.lo @COMMON_OBJS@
@@ -179,6 +179,9 @@ atoid.lo: $(srcdir)/atoid.c $(incdir)/gettext.h $(incdir)/missing.h \
           $(incdir)/sudo_debug.h $(top_builddir)/config.h \
           $(top_srcdir)/compat/stdbool.h
        $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/atoid.c
+atomode.lo: $(srcdir)/atomode.c $(incdir)/gettext.h $(incdir)/missing.h \
+            $(incdir)/sudo_debug.h $(top_builddir)/config.h
+       $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/atomode.c
 conf_test.lo: $(srcdir)/regress/sudo_conf/conf_test.c $(incdir)/missing.h \
               $(incdir)/queue.h $(incdir)/sudo_conf.h $(top_builddir)/config.h \
               $(top_srcdir)/compat/stdbool.h
index 1d7d87c28f49a3595d079351d167d80536e5a6c4..29397f6e0215ee8b14815048f08423cb35655a82 100644 (file)
@@ -74,18 +74,24 @@ atoid(const char *p, const char *sep, char **endp, const char **errstr)
            } while (*sep++ != '\0');
        }
        if (!valid) {
-           *errstr = N_("invalid value");
+           if (errstr != NULL)
+               *errstr = N_("invalid");
            errno = EINVAL;
            goto done;
        }
-       if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
-           (lval > INT_MAX || lval < INT_MIN)) {
+       if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) {
            errno = ERANGE;
-           *errstr = N_("value out of range");
+           if (errstr != NULL)
+               *errstr = N_("too large");
+           goto done;
+       }
+       if ((errno == ERANGE && lval == LONG_MIN) || lval < INT_MIN) {
+           errno = ERANGE;
+           if (errstr != NULL)
+               *errstr = N_("too small");
            goto done;
        }
        rval = (id_t)lval;
-       *errstr = NULL;
     } else {
        unsigned long ulval = strtoul(p, &ep, 10);
        if (ep != p) {
@@ -96,18 +102,21 @@ atoid(const char *p, const char *sep, char **endp, const char **errstr)
            } while (*sep++ != '\0');
        }
        if (!valid) {
-           *errstr = N_("invalid value");
+           if (errstr != NULL)
+               *errstr = N_("invalid");
            errno = EINVAL;
            goto done;
        }
        if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) {
            errno = ERANGE;
-           *errstr = N_("value too large");
+           if (errstr != NULL)
+               *errstr = N_("too large");
            goto done;
        }
        rval = (id_t)ulval;
-       *errstr = NULL;
     }
+    if (errstr != NULL)
+       *errstr = NULL;
     if (endp != NULL)
        *endp = ep;
 done:
diff --git a/common/atomode.c b/common/atomode.c
new file mode 100644 (file)
index 0000000..9c4d299
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#include <errno.h>
+
+#define DEFAULT_TEXT_DOMAIN    "sudo"
+#include "gettext.h"
+
+#include "missing.h"
+#include "sudo_debug.h"
+
+/*
+ * Parse an octal file mode in the range [0, 0777].
+ * On success, returns the parsed mode and clears errstr.
+ * On error, returns 0 and sets errstr.
+ */
+int
+atomode(const char *cp, const char **errstr)
+{
+    char *ep;
+    long lval;
+    debug_decl(atomode, SUDO_DEBUG_UTIL)
+
+    errno = 0;
+    lval = strtol(cp, &ep, 8);
+    if (ep == cp || *ep != '\0') {
+       if (errstr != NULL)
+           *errstr = N_("invalid");
+       errno = EINVAL;
+       debug_return_int(0);
+    }
+    if (lval < 0 || lval > 0777) {
+       if (errstr != NULL)
+           *errstr = lval < 0 ? N_("too small") : N_("too large");
+       errno = ERANGE;
+       debug_return_int(0);
+    }
+    debug_return_int((int)lval);
+}
index b6f7622c5742a4fd954b290b9cf1aaa90bb46ecb..9459c50f6e1845e6380a0f6af3345dd7e7eacb3f 100644 (file)
@@ -811,17 +811,20 @@ logpri2str(int n)
 static bool
 store_mode(char *val, struct sudo_defs_types *def, int op)
 {
-    char *endp;
-    long l;
+    mode_t mode;
+    const char *errstr;
     debug_decl(store_mode, SUDO_DEBUG_DEFAULTS)
 
     if (op == false) {
-       def->sd_un.mode = (mode_t)0777;
+       def->sd_un.mode = 0777;
     } else {
-       l = strtol(val, &endp, 8);
-       if (endp == val || *endp != '\0' || l < 0 || l > 0777)
+       mode = atomode(val, &errstr);
+       if (errstr != NULL) {
+           sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+               "%s is %s", val, errstr);
            debug_return_bool(false);
-       def->sd_un.mode = (mode_t)l;
+       }
+       def->sd_un.mode = mode;
     }
     if (def->callback)
        debug_return_bool(def->callback(val));
index 0824abac71525b4f234acbccebd0d807190ec92c..9d08ed47e0d6a31fcb354ee2906d4f8a343901ef 100644 (file)
@@ -91,7 +91,6 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
     const char *debug_flags = NULL;
     const char *remhost = NULL;
     int flags = 0;
-    char *ep;
     debug_decl(sudoers_policy_deserialize_info, SUDO_DEBUG_PLUGIN)
 
 #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
@@ -118,17 +117,10 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
                continue;
            }
            if (MATCHES(*cur, "sudoers_mode=")) {
-               long lval;
-               errno = 0;
                p = *cur + sizeof("sudoers_mode=") - 1;
-               lval = strtol(p, &ep, 8);
-               if (ep == p || *ep != '\0')
-                   fatalx(U_("%s: %s"), *cur, U_("invalid"));
-               if (lval < 0)
-                   fatalx(U_("%s: %s"), *cur, U_("too small"));
-               if (lval > 0777)
-                   fatalx(U_("%s: %s"), *cur, U_("too large"));
-               sudoers_mode = (mode_t) lval;
+               sudoers_mode = atomode(p, &errstr);
+               if (errstr != NULL)
+                   fatalx(U_("%s: %s"), *cur, U_(errstr));
                continue;
            }
            if (MATCHES(*cur, "ldap_conf=")) {
index 1ee6265a60bd015885ace5c08a6452a1980aa2b0..56d9dae9c5b91f40648c272b6a19df2d9c46f21f 100644 (file)
@@ -321,6 +321,9 @@ int atobool(const char *str);
 /* atoid.c */
 int atoid(const char *str, const char *sep, char **endp, const char **errstr);
 
+/* atomode.c */
+int atomode(const char *cp, const char **errstr);
+
 /* boottime.c */
 int get_boottime(struct timeval *);
 
index f8c3fab53e1d4f2d28fc50beb1167768bfa05922..b6d23315519bb026e596d9c40e318779a609852c 100644 (file)
@@ -555,7 +555,7 @@ command_info_to_details(char * const info[], struct command_details *details)
                    cp = info[i] + sizeof("closefrom=") - 1;
                    details->closefrom = strtonum(cp, 0, INT_MAX, &errstr);
                    if (errstr != NULL)
-                       fatalx(U_("%s: %s"), cp, U_(errstr));
+                       fatalx(U_("%s: %s"), info[i], U_(errstr));
                    break;
                }
                break;
@@ -574,7 +574,7 @@ command_info_to_details(char * const info[], struct command_details *details)
                    cp = info[i] + sizeof("nice=") - 1;
                    details->priority = strtonum(cp, INT_MIN, INT_MAX, &errstr);
                    if (errstr != NULL)
-                       fatalx(U_("%s: %s"), cp, U_(errstr));
+                       fatalx(U_("%s: %s"), info[i], U_(errstr));
                    SET(details->flags, CD_SET_PRIORITY);
                    break;
                }
@@ -676,25 +676,17 @@ command_info_to_details(char * const info[], struct command_details *details)
                    cp = info[i] + sizeof("timeout=") - 1;
                    details->timeout = strtonum(cp, 0, INT_MAX, &errstr);
                    if (errstr != NULL)
-                       fatalx(U_("%s: %s"), cp, U_(errstr));
+                       fatalx(U_("%s: %s"), info[i], U_(errstr));
                    SET(details->flags, CD_SET_TIMEOUT);
                    break;
                }
                break;
            case 'u':
                if (strncmp("umask=", info[i], sizeof("umask=") - 1) == 0) {
-                   long lval;
-                   char *ep;
-                   errno = 0;
                    cp = info[i] + sizeof("umask=") - 1;
-                   lval = strtol(cp, &ep, 8);
-                   if (ep == cp || *ep != '\0')
-                       fatalx(U_("%s: %s"), info[i], U_("invalid"));
-                   if (lval < 0)
-                       fatalx(U_("%s: %s"), info[i], U_("too small"));
-                   if (lval > 0777)
-                       fatalx(U_("%s: %s"), info[i], U_("too large"));
-                   details->umask = (mode_t)lval;
+                   details->umask = atomode(cp, &errstr);
+                   if (errstr != NULL)
+                       fatalx(U_("%s: %s"), info[i], U_(errstr));
                    SET(details->flags, CD_SET_UMASK);
                    break;
                }
index a8af1e4e33f4f62b4d5cd37cba6b5d499c838151..6fced6d2b061077ff710ddbdaa6ca847f8144186 100644 (file)
@@ -189,6 +189,9 @@ bool atobool(const char *str);
 /* atoid.c */
 id_t atoid(const char *str, const char *sep, char **endp, const char **errstr);
 
+/* atomode.c */
+int atomode(const char *cp, const char **errstr);
+
 /* parse_args.c */
 int parse_args(int argc, char **argv, int *nargc, char ***nargv,
     char ***settingsp, char ***env_addp);