common/alloc.c
common/atobool.c
common/atoid.c
+common/atomode.c
common/event.c
common/event_poll.c
common/event_select.c
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@
$(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
} 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) {
} 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:
--- /dev/null
+/*
+ * 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);
+}
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));
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)
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=")) {
/* 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 *);
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;
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;
}
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;
}
/* 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);