plugins/sudoers/filedigest_gcrypt.c
plugins/sudoers/filedigest_openssl.c
plugins/sudoers/find_path.c
+plugins/sudoers/fmtsudoers.c
plugins/sudoers/gc.c
plugins/sudoers/gentime.c
plugins/sudoers/getdate.c
timestr.lo toke.lo toke_util.lo
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo \
- env_pattern.lo find_path.lo gc.lo goodpath.lo group_plugin.lo \
- interfaces.lo iolog.lo iolog_path.lo locale.lo logging.lo \
- logwrap.lo mkdir_parents.lo parse.lo policy.lo prompt.lo \
- set_perms.lo starttime.lo sudo_nss.lo sudoers.lo \
+ env_pattern.lo find_path.lo fmtsudoers.lo gc.lo goodpath.lo \
+ group_plugin.lo interfaces.lo iolog.lo iolog_path.lo locale.lo \
+ logging.lo logwrap.lo mkdir_parents.lo parse.lo policy.lo \
+ prompt.lo set_perms.lo starttime.lo sudo_nss.lo sudoers.lo \
timestamp.lo @SUDOERS_OBJS@
VISUDO_OBJS = editor.o find_path.o goodpath.o locale.o stubs.o sudo_printf.o visudo.o
CVTSUDOERS_OBJS = cvtsudoers.o cvtsudoers_json.o cvtsudoers_ldif.o \
- locale.o stubs.o sudo_printf.o
+ fmtsudoers.o locale.o stubs.o sudo_printf.o
REPLAY_OBJS = getdate.o sudoreplay.o
$(top_builddir)/pathnames.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/find_path.c
find_path.o: find_path.lo
+fmtsudoers.lo: $(srcdir)/fmtsudoers.c $(devdir)/def_data.h $(devdir)/gram.h \
+ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
+ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
+ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
+ $(incdir)/sudo_lbuf.h $(incdir)/sudo_plugin.h \
+ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
+ $(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
+ $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
+ $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
+ $(top_builddir)/pathnames.h
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/fmtsudoers.c
+fmtsudoers.o: fmtsudoers.lo
fwtk.lo: $(authdir)/fwtk.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
return fopen(sudoers, "r");
}
-/*
- * Write the contents of a struct member to lbuf
- */
-static bool
-print_member_sudoers(struct sudo_lbuf *lbuf, struct member *m)
-{
- struct sudo_command *c;
- debug_decl(print_member_sudoers, SUDOERS_DEBUG_UTIL)
-
- switch (m->type) {
- case ALL:
- sudo_lbuf_append(lbuf, "%sALL", m->negated ? "!" : "");
- break;
- case MYSELF:
- /* nothing to print */
- break;
- case COMMAND:
- c = (struct sudo_command *)m->name;
- if (m->negated)
- sudo_lbuf_append(lbuf, "!");
- sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED" \t", "%s", c->cmnd);
- if (c->args) {
- sudo_lbuf_append(lbuf, " ");
- sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", c->args);
- }
- break;
- default:
- /* Do not quote UID/GID, all others get quoted. */
- if (m->name[0] == '#' &&
- m->name[strspn(m->name + 1, "0123456789") + 1] == '\0') {
- sudo_lbuf_append(lbuf, "%s%s", m->negated ? "!" : "", m->name);
- } else {
- if (strpbrk(m->name, " \t") != NULL) {
- sudo_lbuf_append(lbuf, "%s\"", m->negated ? "!" : "");
- sudo_lbuf_append_quoted(lbuf, "\"", "%s", m->name);
- sudo_lbuf_append(lbuf, "\"");
- } else {
- sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s%s",
- m->negated ? "!" : "", m->name);
- }
- }
- break;
- }
- debug_return_bool(!sudo_lbuf_error(lbuf));
-}
-
/*
* Display Defaults entries
*/
TAILQ_FOREACH(m, def->binding, entries) {
if (m != TAILQ_FIRST(def->binding))
sudo_lbuf_append(lbuf, ", ");
- print_member_sudoers(lbuf, m);
+ sudoers_format_member(lbuf, m, NULL, UNSPEC);
}
/* Print Defaults with the same binding, there may be multiple. */
for (;;) {
+ sudo_lbuf_append(lbuf, " ");
+ sudoers_format_default(lbuf, def);
next = TAILQ_NEXT(def, entries);
- if (def->val != NULL) {
- sudo_lbuf_append(lbuf, " %s%s", def->var,
- def->op == '+' ? "+=" : def->op == '-' ? "-=" : "=");
- if (strpbrk(def->val, " \t") != NULL) {
- sudo_lbuf_append(lbuf, "\"");
- sudo_lbuf_append_quoted(lbuf, "\"", "%s", def->val);
- sudo_lbuf_append(lbuf, "\"");
- } else
- sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", def->val);
- } else {
- sudo_lbuf_append(lbuf, " %s%s",
- def->op == false ? "!" : "", def->var);
- }
if (next == NULL || def->binding != next->binding)
break;
def = next;
TAILQ_FOREACH(m, &a->members, entries) {
if (m != TAILQ_FIRST(&a->members))
sudo_lbuf_append(lbuf, ", ");
- print_member_sudoers(lbuf, m);
+ sudoers_format_member(lbuf, m, NULL, UNSPEC);
}
sudo_lbuf_append(lbuf, "\n");
debug_return_bool(!sudo_lbuf_error(lbuf));
}
-#define TAG_CHANGED(ocs, ncs, tt) \
- (TAG_SET((ncs)->tags.tt) && \
- ((ocs) == NULL || (ncs)->tags.tt != (ocs)->tags.tt))
-
-/*
- * XXX - same as parse.c:sudo_file_append_cmnd()
- */
-static bool
-print_cmndspec_sudoers(struct cmndspec *cs, struct cmndspec *prev_cs,
- struct sudo_lbuf *lbuf)
-{
- debug_decl(print_cmndspec_sudoers, SUDOERS_DEBUG_UTIL)
-
-#ifdef HAVE_PRIV_SET
- if (cs->privs != NULL && cs->privs != prev_cs->privs)
- sudo_lbuf_append(lbuf, "PRIVS=\"%s\" ", cs->privs);
- if (cs->limitprivs != NULL && cs->limitprivs != prev_cs->limitprivs)
- sudo_lbuf_append(lbuf, "LIMITPRIVS=\"%s\" ", cs->limitprivs);
-#endif /* HAVE_PRIV_SET */
-#ifdef HAVE_SELINUX
- if (cs->role != NULL && cs->role != prev_cs->role)
- sudo_lbuf_append(lbuf, "ROLE=%s ", cs->role);
- if (cs->type != NULL && cs->type != prev_cs->type)
- sudo_lbuf_append(lbuf, "TYPE=%s ", cs->type);
-#endif /* HAVE_SELINUX */
- if (cs->timeout > 0 && cs->timeout != prev_cs->timeout) {
- char numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
- snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);
- sudo_lbuf_append(lbuf, "TIMEOUT=%s ", numbuf);
- }
- if (cs->notbefore != UNSPEC && cs->notbefore != prev_cs->notbefore) {
- char buf[sizeof("CCYYMMDDHHMMSSZ")];
- struct tm *tm = gmtime(&cs->notbefore);
- snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
- sudo_lbuf_append(lbuf, "NOTBEFORE=%s ", buf);
- }
- if (cs->notafter != UNSPEC && cs->notafter != prev_cs->notafter) {
- char buf[sizeof("CCYYMMDDHHMMSSZ")];
- struct tm *tm = gmtime(&cs->notafter);
- snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
- sudo_lbuf_append(lbuf, "NOTAFTER=%s ", buf);
- }
- if (TAG_CHANGED(prev_cs, cs, setenv))
- sudo_lbuf_append(lbuf, cs->tags.setenv ? "SETENV: " : "NOSETENV: ");
- if (TAG_CHANGED(prev_cs, cs, noexec))
- sudo_lbuf_append(lbuf, cs->tags.noexec ? "NOEXEC: " : "EXEC: ");
- if (TAG_CHANGED(prev_cs, cs, nopasswd))
- sudo_lbuf_append(lbuf, cs->tags.nopasswd ? "NOPASSWD: " : "PASSWD: ");
- if (TAG_CHANGED(prev_cs, cs, log_input))
- sudo_lbuf_append(lbuf, cs->tags.log_input ? "LOG_INPUT: " : "NOLOG_INPUT: ");
- if (TAG_CHANGED(prev_cs, cs, log_output))
- sudo_lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " : "NOLOG_OUTPUT: ");
- if (TAG_CHANGED(prev_cs, cs, send_mail))
- sudo_lbuf_append(lbuf, cs->tags.send_mail ? "MAIL: " : "NOMAIL: ");
- if (TAG_CHANGED(prev_cs, cs, follow))
- sudo_lbuf_append(lbuf, cs->tags.follow ? "FOLLOW: " : "NOFOLLOW: ");
- print_member_sudoers(lbuf, cs->cmnd);
- debug_return_bool(!sudo_lbuf_error(lbuf));
-}
-
-/*
- * Derived from parse.c:sudo_file_display_priv_short()
- */
-static bool
-print_userspec_sudoers(struct sudo_lbuf *lbuf, struct userspec *us)
-{
- struct cmndspec *cs, *prev_cs;
- struct privilege *priv;
- struct member *m;
- debug_decl(print_userspec_sudoers, SUDOERS_DEBUG_UTIL)
-
- /* Print users list. */
- TAILQ_FOREACH(m, &us->users, entries) {
- if (m != TAILQ_FIRST(&us->users))
- sudo_lbuf_append(lbuf, ", ");
- print_member_sudoers(lbuf, m);
- }
-
- TAILQ_FOREACH(priv, &us->privileges, entries) {
- /* Print hosts list. */
- if (priv != TAILQ_FIRST(&us->privileges))
- sudo_lbuf_append(lbuf, " : ");
- else
- sudo_lbuf_append(lbuf, " ");
- TAILQ_FOREACH(m, &priv->hostlist, entries) {
- if (m != TAILQ_FIRST(&priv->hostlist))
- sudo_lbuf_append(lbuf, ", ");
- print_member_sudoers(lbuf, m);
- }
-
- /* Print commands. */
- sudo_lbuf_append(lbuf, " = ");
- prev_cs = NULL;
- TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
- if (prev_cs == NULL || RUNAS_CHANGED(cs, prev_cs)) {
- if (cs != TAILQ_FIRST(&priv->cmndlist))
- sudo_lbuf_append(lbuf, ", ");
- if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL)
- sudo_lbuf_append(lbuf, "(");
- if (cs->runasuserlist != NULL) {
- TAILQ_FOREACH(m, cs->runasuserlist, entries) {
- if (m != TAILQ_FIRST(cs->runasuserlist))
- sudo_lbuf_append(lbuf, ", ");
- print_member_sudoers(lbuf, m);
- }
- }
- if (cs->runasgrouplist != NULL) {
- sudo_lbuf_append(lbuf, " : ");
- TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
- if (m != TAILQ_FIRST(cs->runasgrouplist))
- sudo_lbuf_append(lbuf, ", ");
- print_member_sudoers(lbuf, m);
- }
- }
- if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL)
- sudo_lbuf_append(lbuf, ") ");
- } else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
- sudo_lbuf_append(lbuf, ", ");
- }
- print_cmndspec_sudoers(cs, prev_cs, lbuf);
- prev_cs = cs;
- }
- }
- sudo_lbuf_append(lbuf, "\n");
-
- debug_return_bool(!sudo_lbuf_error(lbuf));
-}
-
-/*
- * Display User_Specs
- */
-static bool
-print_userspecs_sudoers(struct sudo_lbuf *lbuf)
-{
- struct userspec *us;
- debug_decl(print_userspecs_sudoers, SUDOERS_DEBUG_UTIL)
-
- TAILQ_FOREACH(us, &userspecs, entries) {
- if (!print_userspec_sudoers(lbuf, us))
- break;
- }
-
- debug_return_bool(!sudo_lbuf_error(lbuf));
-}
-
static FILE *output_fp; /* global for convert_sudoers_output */
static int
}
/* Print User_Specs */
- if (!print_userspecs_sudoers(&lbuf))
+ if (!sudoers_format_userspecs(&lbuf, &userspecs, false))
goto done;
if (lbuf.len > 1) {
sudo_lbuf_print(&lbuf);
--- /dev/null
+/*
+ * Copyright (c) 2004-2005, 2007-2018 Todd C. Miller <Todd.Miller@sudo.ws>
+ *
+ * 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>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <time.h>
+
+#include "sudoers.h"
+#include "parse.h"
+#include "sudo_lbuf.h"
+#include <gram.h>
+
+/*
+ * Write the contents of a struct member to the lbuf.
+ * If alias_type is not UNSPEC, expand aliases using that type with
+ * the specified separator (which must not be NULL in the UNSPEC case).
+ */
+static bool
+sudoers_format_member_int(struct sudo_lbuf *lbuf, char *name, int type,
+ int negated, const char *separator, int alias_type)
+{
+ struct alias *a;
+ struct member *m;
+ struct sudo_command *c;
+ debug_decl(sudoers_format_member_int, SUDOERS_DEBUG_UTIL)
+
+ switch (type) {
+ case ALL:
+ sudo_lbuf_append(lbuf, "%sALL", negated ? "!" : "");
+ break;
+ case MYSELF:
+ sudo_lbuf_append(lbuf, "%s%s", negated ? "!" : "", user_name);
+ break;
+ case COMMAND:
+ c = (struct sudo_command *) name;
+ if (negated)
+ sudo_lbuf_append(lbuf, "!");
+ sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED" \t", "%s", c->cmnd);
+ if (c->args) {
+ sudo_lbuf_append(lbuf, " ");
+ sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", c->args);
+ }
+ break;
+ case ALIAS:
+ if (alias_type != UNSPEC) {
+ if ((a = alias_get(name, alias_type)) != NULL) {
+ TAILQ_FOREACH(m, &a->members, entries) {
+ if (m != TAILQ_FIRST(&a->members))
+ sudo_lbuf_append(lbuf, "%s", separator);
+ sudoers_format_member_int(lbuf, m->name, m->type,
+ negated ? !m->negated : m->negated, separator,
+ alias_type);
+ }
+ alias_put(a);
+ break;
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ /* Do not quote UID/GID, all others get quoted. */
+ if (name[0] == '#' &&
+ name[strspn(name + 1, "0123456789") + 1] == '\0') {
+ sudo_lbuf_append(lbuf, "%s%s", negated ? "!" : "", name);
+ } else {
+ if (strpbrk(name, " \t") != NULL) {
+ sudo_lbuf_append(lbuf, "%s\"", negated ? "!" : "");
+ sudo_lbuf_append_quoted(lbuf, "\"", "%s", name);
+ sudo_lbuf_append(lbuf, "\"");
+ } else {
+ sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s%s",
+ negated ? "!" : "", name);
+ }
+ }
+ break;
+ }
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+bool
+sudoers_format_member(struct sudo_lbuf *lbuf, struct member *m,
+ const char *separator, int alias_type)
+{
+ return sudoers_format_member_int(lbuf, m->name, m->type, m->negated,
+ separator, alias_type);
+}
+
+#define FIELD_CHANGED(ocs, ncs, fld) \
+ ((ocs) == NULL || (ncs)->fld != (ocs)->fld)
+
+#define TAG_CHANGED(ocs, ncs, tt) \
+ (TAG_SET((ncs)->tags.tt) && FIELD_CHANGED(ocs, ncs, tags.tt))
+
+/*
+ * Write a cmndspec to lbuf in sudoers format.
+ */
+bool
+sudoers_format_cmndspec(struct sudo_lbuf *lbuf, struct cmndspec *cs,
+ struct cmndspec *prev_cs, bool expand_aliases)
+{
+ debug_decl(sudoers_format_cmndspec, SUDOERS_DEBUG_UTIL)
+
+#ifdef HAVE_PRIV_SET
+ if (cs->privs != NULL && FIELD_CHANGED(prev_cs, cs, privs))
+ sudo_lbuf_append(lbuf, "PRIVS=\"%s\" ", cs->privs);
+ if (cs->limitprivs != NULL && FIELD_CHANGED(prev_cs, cs, limitprivs))
+ sudo_lbuf_append(lbuf, "LIMITPRIVS=\"%s\" ", cs->limitprivs);
+#endif /* HAVE_PRIV_SET */
+#ifdef HAVE_SELINUX
+ if (cs->role != NULL && FIELD_CHANGED(prev_cs, cs, role))
+ sudo_lbuf_append(lbuf, "ROLE=%s ", cs->role);
+ if (cs->type != NULL && FIELD_CHANGED(prev_cs, cs, type))
+ sudo_lbuf_append(lbuf, "TYPE=%s ", cs->type);
+#endif /* HAVE_SELINUX */
+ if (cs->timeout > 0 && FIELD_CHANGED(prev_cs, cs, timeout)) {
+ char numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
+ snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);
+ sudo_lbuf_append(lbuf, "TIMEOUT=%s ", numbuf);
+ }
+ if (cs->notbefore != UNSPEC && FIELD_CHANGED(prev_cs, cs, notbefore)) {
+ char buf[sizeof("CCYYMMDDHHMMSSZ")];
+ struct tm *tm = gmtime(&cs->notbefore);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ sudo_lbuf_append(lbuf, "NOTBEFORE=%s ", buf);
+ }
+ if (cs->notafter != UNSPEC && FIELD_CHANGED(prev_cs, cs, notafter)) {
+ char buf[sizeof("CCYYMMDDHHMMSSZ")];
+ struct tm *tm = gmtime(&cs->notafter);
+ snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ sudo_lbuf_append(lbuf, "NOTAFTER=%s ", buf);
+ }
+ if (TAG_CHANGED(prev_cs, cs, setenv))
+ sudo_lbuf_append(lbuf, cs->tags.setenv ? "SETENV: " : "NOSETENV: ");
+ if (TAG_CHANGED(prev_cs, cs, noexec))
+ sudo_lbuf_append(lbuf, cs->tags.noexec ? "NOEXEC: " : "EXEC: ");
+ if (TAG_CHANGED(prev_cs, cs, nopasswd))
+ sudo_lbuf_append(lbuf, cs->tags.nopasswd ? "NOPASSWD: " : "PASSWD: ");
+ if (TAG_CHANGED(prev_cs, cs, log_input))
+ sudo_lbuf_append(lbuf, cs->tags.log_input ? "LOG_INPUT: " : "NOLOG_INPUT: ");
+ if (TAG_CHANGED(prev_cs, cs, log_output))
+ sudo_lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " : "NOLOG_OUTPUT: ");
+ if (TAG_CHANGED(prev_cs, cs, send_mail))
+ sudo_lbuf_append(lbuf, cs->tags.send_mail ? "MAIL: " : "NOMAIL: ");
+ if (TAG_CHANGED(prev_cs, cs, follow))
+ sudo_lbuf_append(lbuf, cs->tags.follow ? "FOLLOW: " : "NOFOLLOW: ");
+ sudoers_format_member(lbuf, cs->cmnd, ", ",
+ expand_aliases ? CMNDALIAS : UNSPEC);
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Write a privilege to lbuf in sudoers format.
+ */
+bool
+sudoers_format_privilege(struct sudo_lbuf *lbuf, struct privilege *priv,
+ bool expand_aliases)
+{
+ struct cmndspec *cs, *prev_cs;
+ struct member *m;
+ debug_decl(sudoers_format_userspec, SUDOERS_DEBUG_UTIL)
+
+ /* Print hosts list. */
+ TAILQ_FOREACH(m, &priv->hostlist, entries) {
+ if (m != TAILQ_FIRST(&priv->hostlist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, m, ", ",
+ expand_aliases ? HOSTALIAS : UNSPEC);
+ }
+
+ /* Print commands. */
+ sudo_lbuf_append(lbuf, " = ");
+ prev_cs = NULL;
+ TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+ if (prev_cs == NULL || RUNAS_CHANGED(cs, prev_cs)) {
+ if (cs != TAILQ_FIRST(&priv->cmndlist))
+ sudo_lbuf_append(lbuf, ", ");
+ if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL)
+ sudo_lbuf_append(lbuf, "(");
+ if (cs->runasuserlist != NULL) {
+ TAILQ_FOREACH(m, cs->runasuserlist, entries) {
+ if (m != TAILQ_FIRST(cs->runasuserlist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, m, ", ",
+ expand_aliases ? RUNASALIAS : UNSPEC);
+ }
+ }
+ if (cs->runasgrouplist != NULL) {
+ sudo_lbuf_append(lbuf, " : ");
+ TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
+ if (m != TAILQ_FIRST(cs->runasgrouplist))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, m, ", ",
+ expand_aliases ? RUNASALIAS : UNSPEC);
+ }
+ }
+ if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL)
+ sudo_lbuf_append(lbuf, ") ");
+ } else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
+ sudo_lbuf_append(lbuf, ", ");
+ }
+ sudoers_format_cmndspec(lbuf, cs, prev_cs, expand_aliases);
+ prev_cs = cs;
+ }
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Write a userspec to lbuf in sudoers format.
+ */
+bool
+sudoers_format_userspec(struct sudo_lbuf *lbuf, struct userspec *us,
+ bool expand_aliases)
+{
+ struct privilege *priv;
+ struct member *m;
+ debug_decl(sudoers_format_userspec, SUDOERS_DEBUG_UTIL)
+
+ /* Print users list. */
+ TAILQ_FOREACH(m, &us->users, entries) {
+ if (m != TAILQ_FIRST(&us->users))
+ sudo_lbuf_append(lbuf, ", ");
+ sudoers_format_member(lbuf, m, NULL, UNSPEC);
+ }
+
+ TAILQ_FOREACH(priv, &us->privileges, entries) {
+ if (priv != TAILQ_FIRST(&us->privileges))
+ sudo_lbuf_append(lbuf, " : ");
+ else
+ sudo_lbuf_append(lbuf, " ");
+ if (!sudoers_format_privilege(lbuf, priv, expand_aliases))
+ break;
+ }
+ sudo_lbuf_append(lbuf, "\n");
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Write a userspec_list to lbuf in sudoers format.
+ */
+bool
+sudoers_format_userspecs(struct sudo_lbuf *lbuf, struct userspec_list *usl,
+ bool expand_aliases)
+{
+ struct userspec *us;
+ debug_decl(sudoers_format_userspecs, SUDOERS_DEBUG_UTIL)
+
+ TAILQ_FOREACH(us, usl, entries) {
+ if (!sudoers_format_userspec(lbuf, us, expand_aliases))
+ break;
+ }
+
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
+
+/*
+ * Format and append a defaults entry to the specified lbuf.
+ */
+bool
+sudoers_format_default(struct sudo_lbuf *lbuf, struct defaults *d)
+{
+ debug_decl(sudoers_format_default, SUDOERS_DEBUG_UTIL)
+
+ if (d->val != NULL) {
+ sudo_lbuf_append(lbuf, "%s%s", d->var,
+ d->op == '+' ? "+=" : d->op == '-' ? "-=" : "=");
+ if (strpbrk(d->val, " \t") != NULL) {
+ sudo_lbuf_append(lbuf, "\"");
+ sudo_lbuf_append_quoted(lbuf, "\"", "%s", d->val);
+ sudo_lbuf_append(lbuf, "\"");
+ } else
+ sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
+ } else {
+ sudo_lbuf_append(lbuf, "%s%s", d->op == false ? "!" : "", d->var);
+ }
+ debug_return_bool(!sudo_lbuf_error(lbuf));
+}
sudo_lbuf_append(lbuf, "%s", prefix);
d.op = sudo_ldap_parse_option((*p)->bv_val, &d.var, &d.val);
- sudo_lbuf_append_default(lbuf, &d);
+ sudoers_format_default(lbuf, &d);
prefix = ", ";
count++;
}
static int sudo_file_open(struct sudo_nss *);
static int sudo_file_parse(struct sudo_nss *);
static int sudo_file_setdefs(struct sudo_nss *);
-static void print_member(struct sudo_lbuf *lbuf, struct member *m, int alias_type);
-static void print_member_sep(struct sudo_lbuf *lbuf, struct member *m, const char *separator, int alias_type);
/* sudo_nss implementation */
struct sudo_nss sudo_nss_file = {
debug_return_int(validated);
}
-#define TAG_CHANGED(ocs, ncs, tt) \
- (TAG_SET((ncs)->tags.tt) && \
- ((ocs) == NULL || (ncs)->tags.tt != (ocs)->tags.tt))
-
-static bool
-sudo_file_append_cmnd(struct cmndspec *cs, struct cmndspec *prev_cs,
- struct sudo_lbuf *lbuf)
-{
- debug_decl(sudo_file_append_cmnd, SUDOERS_DEBUG_NSS)
-
-#ifdef HAVE_PRIV_SET
- if (cs->privs != NULL && cs->privs != prev_cs->privs)
- sudo_lbuf_append(lbuf, "PRIVS=\"%s\" ", cs->privs);
- if (cs->limitprivs != NULL && cs->limitprivs != prev_cs->limitprivs)
- sudo_lbuf_append(lbuf, "LIMITPRIVS=\"%s\" ", cs->limitprivs);
-#endif /* HAVE_PRIV_SET */
-#ifdef HAVE_SELINUX
- if (cs->role != NULL && cs->role != prev_cs->role)
- sudo_lbuf_append(lbuf, "ROLE=%s ", cs->role);
- if (cs->type != NULL && cs->type != prev_cs->type)
- sudo_lbuf_append(lbuf, "TYPE=%s ", cs->type);
-#endif /* HAVE_SELINUX */
- if (cs->timeout > 0 && cs->timeout != prev_cs->timeout) {
- char numbuf[(((sizeof(int) * 8) + 2) / 3) + 2];
- snprintf(numbuf, sizeof(numbuf), "%d", cs->timeout);
- sudo_lbuf_append(lbuf, "TIMEOUT=%s ", numbuf);
- }
- if (cs->notbefore != UNSPEC && cs->notbefore != prev_cs->notbefore) {
- char buf[sizeof("CCYYMMDDHHMMSSZ")];
- struct tm *tm = gmtime(&cs->notbefore);
- snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
- sudo_lbuf_append(lbuf, "NOTBEFORE=%s ", buf);
- }
- if (cs->notafter != UNSPEC && cs->notafter != prev_cs->notafter) {
- char buf[sizeof("CCYYMMDDHHMMSSZ")];
- struct tm *tm = gmtime(&cs->notafter);
- snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
- sudo_lbuf_append(lbuf, "NOTAFTER=%s ", buf);
- }
- if (TAG_CHANGED(prev_cs, cs, setenv))
- sudo_lbuf_append(lbuf, cs->tags.setenv ? "SETENV: " : "NOSETENV: ");
- if (TAG_CHANGED(prev_cs, cs, noexec))
- sudo_lbuf_append(lbuf, cs->tags.noexec ? "NOEXEC: " : "EXEC: ");
- if (TAG_CHANGED(prev_cs, cs, nopasswd))
- sudo_lbuf_append(lbuf, cs->tags.nopasswd ? "NOPASSWD: " : "PASSWD: ");
- if (TAG_CHANGED(prev_cs, cs, log_input))
- sudo_lbuf_append(lbuf, cs->tags.log_input ? "LOG_INPUT: " : "NOLOG_INPUT: ");
- if (TAG_CHANGED(prev_cs, cs, log_output))
- sudo_lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " : "NOLOG_OUTPUT: ");
- if (TAG_CHANGED(prev_cs, cs, send_mail))
- sudo_lbuf_append(lbuf, cs->tags.send_mail ? "MAIL: " : "NOMAIL: ");
- if (TAG_CHANGED(prev_cs, cs, follow))
- sudo_lbuf_append(lbuf, cs->tags.follow ? "FOLLOW: " : "NOFOLLOW: ");
- print_member(lbuf, cs->cmnd, CMNDALIAS);
- debug_return_bool(!sudo_lbuf_error(lbuf));
-}
-
-/*
- * Format and append a defaults entry to the specified lbuf.
- */
-void
-sudo_lbuf_append_default(struct sudo_lbuf *lbuf, struct defaults *d)
-{
- debug_decl(sudo_lbuf_append_default, SUDOERS_DEBUG_NSS)
-
- if (d->val != NULL) {
- sudo_lbuf_append(lbuf, "%s%s", d->var,
- d->op == '+' ? "+=" : d->op == '-' ? "-=" : "=");
- if (strpbrk(d->val, " \t") != NULL) {
- sudo_lbuf_append(lbuf, "\"");
- sudo_lbuf_append_quoted(lbuf, "\"", "%s", d->val);
- sudo_lbuf_append(lbuf, "\"");
- } else
- sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
- } else {
- sudo_lbuf_append(lbuf, "%s%s", d->op == false ? "!" : "", d->var);
- }
- debug_return;
-}
-
static int
sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
struct sudo_lbuf *lbuf)
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
if (m != TAILQ_FIRST(cs->runasuserlist))
sudo_lbuf_append(lbuf, ", ");
- print_member(lbuf, m, RUNASALIAS);
+ sudoers_format_member(lbuf, m, ", ", RUNASALIAS);
}
} else if (cs->runasgrouplist == NULL) {
sudo_lbuf_append(lbuf, "%s", def_runas_default);
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
if (m != TAILQ_FIRST(cs->runasgrouplist))
sudo_lbuf_append(lbuf, ", ");
- print_member(lbuf, m, RUNASALIAS);
+ sudoers_format_member(lbuf, m, ", ", RUNASALIAS);
}
}
sudo_lbuf_append(lbuf, ") ");
} else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
sudo_lbuf_append(lbuf, ", ");
}
- sudo_file_append_cmnd(cs, prev_cs, lbuf);
+ sudoers_format_cmndspec(lbuf, cs, prev_cs, true);
prev_cs = cs;
nfound++;
}
{
struct cmndspec *cs, *prev_cs;
struct privilege *priv;
- struct defaults *def;
- struct member *m;
int nfound = 0, olen;
debug_decl(sudo_file_display_priv_long, SUDOERS_DEBUG_NSS)
continue;
prev_cs = NULL;
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
+ struct defaults *d;
+ struct member *m;
+
if (new_long_entry(cs, prev_cs)) {
if (priv->ldap_role != NULL) {
sudo_lbuf_append(lbuf, _("\nLDAP Role: %s\n"),
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
if (m != TAILQ_FIRST(cs->runasuserlist))
sudo_lbuf_append(lbuf, ", ");
- print_member(lbuf, m, RUNASALIAS);
+ sudoers_format_member(lbuf, m, ", ", RUNASALIAS);
}
} else if (cs->runasgrouplist == NULL) {
sudo_lbuf_append(lbuf, "%s", def_runas_default);
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
if (m != TAILQ_FIRST(cs->runasgrouplist))
sudo_lbuf_append(lbuf, ", ");
- print_member(lbuf, m, RUNASALIAS);
+ sudoers_format_member(lbuf, m, ", ", RUNASALIAS);
}
sudo_lbuf_append(lbuf, "\n");
}
olen = lbuf->len;
sudo_lbuf_append(lbuf, _(" Options: "));
- TAILQ_FOREACH(def, &priv->defaults, entries) {
- sudo_lbuf_append_default(lbuf, def);
+ TAILQ_FOREACH(d, &priv->defaults, entries) {
+ sudoers_format_default(lbuf, d);
sudo_lbuf_append(lbuf, ", ");
}
if (TAG_SET(cs->tags.setenv))
sudo_lbuf_append(lbuf, _(" Commands:\n"));
}
sudo_lbuf_append(lbuf, "\t");
- print_member_sep(lbuf, cs->cmnd, "\n\t", CMNDALIAS);
+ sudoers_format_member(lbuf, cs->cmnd, "\n\t", CMNDALIAS);
sudo_lbuf_append(lbuf, "\n");
prev_cs = cs;
nfound++;
continue;
}
sudo_lbuf_append(lbuf, "%s", prefix);
- sudo_lbuf_append_default(lbuf, d);
+ sudoers_format_default(lbuf, d);
prefix = ", ";
nfound++;
}
TAILQ_FOREACH(m, binding, entries) {
if (m != TAILQ_FIRST(binding))
sudo_lbuf_append(lbuf, ",");
- print_member(lbuf, m, atype);
+ sudoers_format_member(lbuf, m, ", ", atype);
sudo_lbuf_append(lbuf, " ");
}
} else
sudo_lbuf_append(lbuf, ", ");
- sudo_lbuf_append_default(lbuf, d);
+ sudoers_format_default(lbuf, d);
}
if (sudo_lbuf_error(lbuf))
done:
debug_return_int(ret);
}
-
-/*
- * Write the contents of a struct member to the lbuf
- */
-static void
-print_member_int(struct sudo_lbuf *lbuf, char *name, int type, int negated,
- const char *separator, int alias_type)
-{
- struct alias *a;
- struct member *m;
- struct sudo_command *c;
- debug_decl(print_member_int, SUDOERS_DEBUG_NSS)
-
- switch (type) {
- case ALL:
- sudo_lbuf_append(lbuf, "%sALL", negated ? "!" : "");
- break;
- case MYSELF:
- sudo_lbuf_append(lbuf, "%s%s", negated ? "!" : "", user_name);
- break;
- case COMMAND:
- c = (struct sudo_command *) name;
- if (negated)
- sudo_lbuf_append(lbuf, "!");
- sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED" \t", "%s", c->cmnd);
- if (c->args) {
- sudo_lbuf_append(lbuf, " ");
- sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", c->args);
- }
- break;
- case ALIAS:
- if ((a = alias_get(name, alias_type)) != NULL) {
- TAILQ_FOREACH(m, &a->members, entries) {
- if (m != TAILQ_FIRST(&a->members))
- sudo_lbuf_append(lbuf, "%s", separator);
- print_member_int(lbuf, m->name, m->type,
- negated ? !m->negated : m->negated, separator,
- alias_type);
- }
- alias_put(a);
- break;
- }
- /* FALLTHROUGH */
- default:
- /* Do not quote UID/GID, all others get quoted. */
- if (name[0] == '#' &&
- name[strspn(name + 1, "0123456789") + 1] == '\0') {
- sudo_lbuf_append(lbuf, "%s%s", negated ? "!" : "", name);
- } else {
- if (strpbrk(name, " \t") != NULL) {
- sudo_lbuf_append(lbuf, "%s\"", negated ? "!" : "");
- sudo_lbuf_append_quoted(lbuf, "\"", "%s", name);
- sudo_lbuf_append(lbuf, "\"");
- } else {
- sudo_lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s%s",
- negated ? "!" : "", name);
- }
- }
- break;
- }
- debug_return;
-}
-
-static void
-print_member(struct sudo_lbuf *lbuf, struct member *m, int alias_type)
-{
- print_member_int(lbuf, m->name, m->type, m->negated, ", ", alias_type);
-}
-
-static void
-print_member_sep(struct sudo_lbuf *lbuf, struct member *m,
- const char *separator, int alias_type)
-{
- print_member_int(lbuf, m->name, m->type, m->negated, separator, alias_type);
-}
/* parse.c */
struct sudo_lbuf;
int sudo_display_userspecs(struct userspec_list *usl, struct passwd *pw, struct sudo_lbuf *lbuf);
-void sudo_lbuf_append_default(struct sudo_lbuf *lbuf, struct defaults *d);
+
+/* fmtsudoers.c */
+bool sudoers_format_cmndspec(struct sudo_lbuf *lbuf, struct cmndspec *cs, struct cmndspec *prev_cs, bool expand_aliases);
+bool sudoers_format_default(struct sudo_lbuf *lbuf, struct defaults *d);
+bool sudoers_format_member(struct sudo_lbuf *lbuf, struct member *m, const char *separator, int alias_type);
+bool sudoers_format_privilege(struct sudo_lbuf *lbuf, struct privilege *priv, bool expand_aliases);
+bool sudoers_format_userspec(struct sudo_lbuf *lbuf, struct userspec *us, bool expand_aliases);
+bool sudoers_format_userspecs(struct sudo_lbuf *lbuf, struct userspec_list *usl, bool expand_aliases);
#endif /* SUDOERS_PARSE_H */
sudo_lbuf_append(lbuf, "%s", prefix);
d.op = sudo_ldap_parse_option(val_array[j], &d.var, &d.val);
- sudo_lbuf_append_default(lbuf, &d);
+ sudoers_format_default(lbuf, &d);
prefix = ", ";
count++;
}