Add "headless" tail queues and use them in place of the semi-circular
lists in sudoers. Once the headless tail queue is built up it is converted to a normal TAILQ. This removes the last consumer of list.c and list.h so those can now be removed.
This commit is contained in:
3
MANIFEST
3
MANIFEST
@@ -20,7 +20,6 @@ common/fileops.c
|
||||
common/fmt_string.c
|
||||
common/gidlist.c
|
||||
common/lbuf.c
|
||||
common/list.c
|
||||
common/regress/sudo_conf/conf_test.c
|
||||
common/regress/sudo_conf/test1.in
|
||||
common/regress/sudo_conf/test1.out.ok
|
||||
@@ -47,6 +46,7 @@ common/regress/sudo_parseln/test5.in
|
||||
common/regress/sudo_parseln/test5.out.ok
|
||||
common/regress/sudo_parseln/test6.in
|
||||
common/regress/sudo_parseln/test6.out.ok
|
||||
common/regress/tailq/hltq_test.c
|
||||
common/secure_path.c
|
||||
common/setgroups.c
|
||||
common/sudo_conf.c
|
||||
@@ -145,7 +145,6 @@ include/fatal.h
|
||||
include/fileops.h
|
||||
include/gettext.h
|
||||
include/lbuf.h
|
||||
include/list.h
|
||||
include/missing.h
|
||||
include/queue.h
|
||||
include/secure_path.h
|
||||
|
@@ -55,7 +55,7 @@ SSP_CFLAGS = @SSP_CFLAGS@
|
||||
SSP_LDFLAGS = @SSP_LDFLAGS@
|
||||
|
||||
# Regression tests
|
||||
TEST_PROGS = conf_test parseln_test
|
||||
TEST_PROGS = conf_test parseln_test hltq_test
|
||||
TEST_LIBS = @LIBS@ @LIBINTL@ ../compat/libreplace.la
|
||||
TEST_LDFLAGS = @LDFLAGS@
|
||||
|
||||
@@ -67,7 +67,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 \
|
||||
fmt_string.lo gidlist.lo lbuf.lo list.lo secure_path.lo \
|
||||
fmt_string.lo gidlist.lo lbuf.lo secure_path.lo \
|
||||
setgroups.lo sudo_conf.lo sudo_debug.lo sudo_printf.lo term.lo \
|
||||
ttysize.lo @COMMON_OBJS@
|
||||
|
||||
@@ -75,6 +75,8 @@ PARSELN_TEST_OBJS = parseln_test.lo
|
||||
|
||||
CONF_TEST_OBJS = conf_test.lo
|
||||
|
||||
HLTQ_TEST_OBJS = hltq_test.lo
|
||||
|
||||
all: libcommon.la
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in
|
||||
@@ -94,6 +96,9 @@ conf_test: $(CONF_TEST_OBJS) libcommon.la
|
||||
parseln_test: $(PARSELN_TEST_OBJS) libcommon.la
|
||||
$(LIBTOOL) --mode=link $(CC) -o $@ $(PARSELN_TEST_OBJS) libcommon.la $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
hltq_test: $(HLTQ_TEST_OBJS) libcommon.la
|
||||
$(LIBTOOL) --mode=link $(CC) -o $@ $(HLTQ_TEST_OBJS) libcommon.la $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
pre-install:
|
||||
|
||||
install:
|
||||
@@ -113,6 +118,12 @@ uninstall:
|
||||
check: $(TEST_PROGS)
|
||||
@if test X"$(cross_compiling)" != X"yes"; then \
|
||||
passed=0; failed=0; total=0; \
|
||||
total=1; \
|
||||
if ./hltq_test; then \
|
||||
passed=`expr $$passed + 1`; \
|
||||
else \
|
||||
failed=`expr $$failed + 1`; \
|
||||
fi; \
|
||||
for dir in sudo_conf sudo_parseln; do \
|
||||
mkdir -p regress/$$dir; \
|
||||
for t in $(srcdir)/regress/$$dir/*.in; do \
|
||||
@@ -203,13 +214,14 @@ gidlist.lo: $(srcdir)/gidlist.c $(top_builddir)/config.h $(incdir)/gettext.h \
|
||||
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/fatal.h \
|
||||
$(incdir)/sudo_debug.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/gidlist.c
|
||||
hltq_test.lo: $(srcdir)/regress/tailq/hltq_test.c $(top_builddir)/config.h \
|
||||
$(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
|
||||
$(incdir)/fatal.h $(incdir)/queue.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/tailq/hltq_test.c
|
||||
lbuf.lo: $(srcdir)/lbuf.c $(top_builddir)/config.h $(incdir)/missing.h \
|
||||
$(incdir)/alloc.h $(incdir)/fatal.h $(incdir)/lbuf.h \
|
||||
$(incdir)/sudo_debug.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/lbuf.c
|
||||
list.lo: $(srcdir)/list.c $(top_builddir)/config.h $(incdir)/missing.h \
|
||||
$(incdir)/list.h $(incdir)/fatal.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/list.c
|
||||
parseln_test.lo: $(srcdir)/regress/sudo_parseln/parseln_test.c \
|
||||
$(top_builddir)/config.h $(top_srcdir)/compat/stdbool.h \
|
||||
$(incdir)/missing.h $(incdir)/fileops.h
|
||||
|
158
common/list.c
158
common/list.c
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2008, 2010-2012 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.
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#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 "missing.h"
|
||||
#include "list.h"
|
||||
#ifdef DEBUG
|
||||
# include "fatal.h"
|
||||
#endif
|
||||
|
||||
struct list_proto {
|
||||
struct list_proto *prev;
|
||||
struct list_proto *next;
|
||||
};
|
||||
|
||||
struct list_head_proto {
|
||||
struct list_proto *first;
|
||||
struct list_proto *last;
|
||||
};
|
||||
|
||||
/*
|
||||
* Pop the last element off the end of vh.
|
||||
* Returns the popped element.
|
||||
*/
|
||||
void *
|
||||
tq_pop(void *vh)
|
||||
{
|
||||
struct list_head_proto *h = (struct list_head_proto *)vh;
|
||||
void *last = NULL;
|
||||
|
||||
if (!tq_empty(h)) {
|
||||
last = (void *)h->last;
|
||||
if (h->first == h->last) {
|
||||
h->first = NULL;
|
||||
h->last = NULL;
|
||||
} else {
|
||||
h->last = h->last->prev;
|
||||
h->last->next = NULL;
|
||||
}
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from a semi-circle queue to normal doubly-linked list
|
||||
* with a head node.
|
||||
*/
|
||||
void
|
||||
list2tq(void *vh, void *vl)
|
||||
{
|
||||
struct list_head_proto *h = (struct list_head_proto *)vh;
|
||||
struct list_proto *l = (struct list_proto *)vl;
|
||||
|
||||
if (l != NULL) {
|
||||
#ifdef DEBUG
|
||||
if (l->prev == NULL) {
|
||||
warningx_nodebug("list2tq called with non-semicircular list");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
h->first = l;
|
||||
h->last = l->prev; /* l->prev points to the last member of l */
|
||||
l->prev = NULL; /* zero last ptr now that we have a head */
|
||||
} else {
|
||||
h->first = NULL;
|
||||
h->last = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Append one queue (or single entry) to another using the
|
||||
* circular properties of the prev pointer to simplify the logic.
|
||||
*/
|
||||
void
|
||||
list_append(void *vl1, void *vl2)
|
||||
{
|
||||
struct list_proto *l1 = (struct list_proto *)vl1;
|
||||
struct list_proto *l2 = (struct list_proto *)vl2;
|
||||
void *tail = l2->prev;
|
||||
|
||||
l1->prev->next = l2;
|
||||
l2->prev = l1->prev;
|
||||
l1->prev = tail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the list of entries to the head node and convert
|
||||
* from a semi-circle queue to normal doubly-linked list.
|
||||
*/
|
||||
void
|
||||
tq_append(void *vh, void *vl)
|
||||
{
|
||||
struct list_head_proto *h = (struct list_head_proto *)vh;
|
||||
struct list_proto *l = (struct list_proto *)vl;
|
||||
void *tail = l->prev;
|
||||
|
||||
if (h->first == NULL)
|
||||
h->first = l;
|
||||
else
|
||||
h->last->next = l;
|
||||
l->prev = h->last;
|
||||
h->last = tail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove element from the tail_queue
|
||||
*/
|
||||
void
|
||||
tq_remove(void *vh, void *vl)
|
||||
{
|
||||
struct list_head_proto *h = (struct list_head_proto *)vh;
|
||||
struct list_proto *l = (struct list_proto *)vl;
|
||||
|
||||
if (h->first == l && h->last == l) {
|
||||
/* Single element in the list. */
|
||||
h->first = NULL;
|
||||
h->last = NULL;
|
||||
} else {
|
||||
/* At least two elements in the list. */
|
||||
if (h->first == l) {
|
||||
h->first = l->next;
|
||||
h->first->prev = h->first;
|
||||
} else if (h->last == l) {
|
||||
h->last = l->prev;
|
||||
h->last->next = NULL;
|
||||
} else {
|
||||
l->prev->next = l->next;
|
||||
l->next->prev = l->prev;
|
||||
}
|
||||
}
|
||||
}
|
196
common/regress/tailq/hltq_test.c
Normal file
196
common/regress/tailq/hltq_test.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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 */
|
||||
#ifdef HAVE_STRING_H
|
||||
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
#endif /* HAVE_STRING_H */
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
# include "compat/stdbool.h"
|
||||
#endif
|
||||
|
||||
#include "missing.h"
|
||||
#include "fatal.h"
|
||||
#include "queue.h"
|
||||
|
||||
__dso_public int main(int argc, char *argv[]);
|
||||
|
||||
/*
|
||||
* Note: HLTQ_ENTRY is intentionally in the middle of the struct
|
||||
* to catch bad assumptions in the PREV/NEXT macros.
|
||||
*/
|
||||
struct test_data {
|
||||
int a;
|
||||
HLTQ_ENTRY(test_data) entries;
|
||||
char b;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(test_data_list, test_data);
|
||||
|
||||
/*
|
||||
* Simple tests for headless tail queue macros.
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct test_data d1, d2, d3;
|
||||
struct test_data *hltq;
|
||||
struct test_data_list tq;
|
||||
int errors = 0;
|
||||
|
||||
/*
|
||||
* Initialize three data elements and concatenate them in order.
|
||||
*/
|
||||
HLTQ_INIT(&d1, entries);
|
||||
d1.a = 1;
|
||||
d1.b = 'a';
|
||||
if (HLTQ_FIRST(&d1) != &d1) {
|
||||
warningx_nodebug("FAIL: HLTQ_FIRST(1 entry) doesn't return first element: got %p, expected %p", HLTQ_FIRST(&d1), &d1);
|
||||
errors++;
|
||||
}
|
||||
if (HLTQ_LAST(&d1, test_data, entries) != &d1) {
|
||||
warningx_nodebug("FAIL: HLTQ_LAST(1 entry) doesn't return first element: got %p, expected %p", HLTQ_LAST(&d1, test_data, entries), &d1);
|
||||
errors++;
|
||||
}
|
||||
if (HLTQ_PREV(&d1, test_data, entries) != NULL) {
|
||||
warningx_nodebug("FAIL: HLTQ_PREV(1 entry) doesn't return NULL: got %p", HLTQ_PREV(&d1, test_data, entries));
|
||||
errors++;
|
||||
}
|
||||
|
||||
HLTQ_INIT(&d2, entries);
|
||||
d2.a = 2;
|
||||
d2.b = 'b';
|
||||
|
||||
HLTQ_INIT(&d3, entries);
|
||||
d3.a = 3;
|
||||
d3.b = 'c';
|
||||
|
||||
HLTQ_CONCAT(&d1, &d2, entries);
|
||||
HLTQ_CONCAT(&d1, &d3, entries);
|
||||
hltq = &d1;
|
||||
|
||||
/*
|
||||
* Verify that HLTQ_FIRST, HLTQ_LAST, HLTQ_NEXT, HLTQ_PREV
|
||||
* work as expected.
|
||||
*/
|
||||
if (HLTQ_FIRST(hltq) != &d1) {
|
||||
warningx_nodebug("FAIL: HLTQ_FIRST(3 entries) doesn't return first element: got %p, expected %p", HLTQ_FIRST(hltq), &d1);
|
||||
errors++;
|
||||
}
|
||||
if (HLTQ_LAST(hltq, test_data, entries) != &d3) {
|
||||
warningx_nodebug("FAIL: HLTQ_LAST(3 entries) doesn't return third element: got %p, expected %p", HLTQ_LAST(hltq, test_data, entries), &d3);
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (HLTQ_NEXT(&d1, entries) != &d2) {
|
||||
warningx_nodebug("FAIL: HLTQ_NEXT(&d1) doesn't return &d2: got %p, expected %p", HLTQ_NEXT(&d1, entries), &d2);
|
||||
errors++;
|
||||
}
|
||||
if (HLTQ_NEXT(&d2, entries) != &d3) {
|
||||
warningx_nodebug("FAIL: HLTQ_NEXT(&d2) doesn't return &d3: got %p, expected %p", HLTQ_NEXT(&d2, entries), &d3);
|
||||
errors++;
|
||||
}
|
||||
if (HLTQ_NEXT(&d3, entries) != NULL) {
|
||||
warningx_nodebug("FAIL: HLTQ_NEXT(&d3) doesn't return NULL: got %p", HLTQ_NEXT(&d3, entries));
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (HLTQ_PREV(&d1, test_data, entries) != NULL) {
|
||||
warningx_nodebug("FAIL: HLTQ_PREV(&d1) doesn't return NULL: got %p", HLTQ_PREV(&d1, test_data, entries));
|
||||
errors++;
|
||||
}
|
||||
if (HLTQ_PREV(&d2, test_data, entries) != &d1) {
|
||||
warningx_nodebug("FAIL: HLTQ_PREV(&d2) doesn't return &d1: got %p, expected %p", HLTQ_PREV(&d2, test_data, entries), &d1);
|
||||
errors++;
|
||||
}
|
||||
if (HLTQ_PREV(&d3, test_data, entries) != &d2) {
|
||||
warningx_nodebug("FAIL: HLTQ_PREV(&d3) doesn't return &d2: got %p, expected %p", HLTQ_PREV(&d3, test_data, entries), &d2);
|
||||
errors++;
|
||||
}
|
||||
|
||||
/* Test conversion to TAILQ. */
|
||||
HLTQ_TO_TAILQ(&tq, hltq, entries);
|
||||
|
||||
if (TAILQ_FIRST(&tq) != &d1) {
|
||||
warningx_nodebug("FAIL: TAILQ_FIRST(&tq) doesn't return first element: got %p, expected %p", TAILQ_FIRST(&tq), &d1);
|
||||
errors++;
|
||||
}
|
||||
if (TAILQ_LAST(&tq, test_data_list) != &d3) {
|
||||
warningx_nodebug("FAIL: TAILQ_LAST(&tq) doesn't return third element: got %p, expected %p", TAILQ_LAST(&tq, test_data_list), &d3);
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (TAILQ_NEXT(&d1, entries) != &d2) {
|
||||
warningx_nodebug("FAIL: TAILQ_NEXT(&d1) doesn't return &d2: got %p, expected %p", TAILQ_NEXT(&d1, entries), &d2);
|
||||
errors++;
|
||||
}
|
||||
if (TAILQ_NEXT(&d2, entries) != &d3) {
|
||||
warningx_nodebug("FAIL: TAILQ_NEXT(&d2) doesn't return &d3: got %p, expected %p", TAILQ_NEXT(&d2, entries), &d3);
|
||||
errors++;
|
||||
}
|
||||
if (TAILQ_NEXT(&d3, entries) != NULL) {
|
||||
warningx_nodebug("FAIL: TAILQ_NEXT(&d3) doesn't return NULL: got %p", TAILQ_NEXT(&d3, entries));
|
||||
errors++;
|
||||
}
|
||||
|
||||
if (TAILQ_PREV(&d1, test_data_list, entries) != NULL) {
|
||||
warningx_nodebug("FAIL: TAILQ_PREV(&d1) doesn't return NULL: got %p", TAILQ_PREV(&d1, test_data_list, entries));
|
||||
errors++;
|
||||
}
|
||||
if (TAILQ_PREV(&d2, test_data_list, entries) != &d1) {
|
||||
warningx_nodebug("FAIL: TAILQ_PREV(&d2) doesn't return &d1: got %p, expected %p", TAILQ_PREV(&d2, test_data_list, entries), &d1);
|
||||
errors++;
|
||||
}
|
||||
if (TAILQ_PREV(&d3, test_data_list, entries) != &d2) {
|
||||
warningx_nodebug("FAIL: TAILQ_PREV(&d3) doesn't return &d2: got %p, expected %p", TAILQ_PREV(&d3, test_data_list, entries), &d2);
|
||||
errors++;
|
||||
}
|
||||
|
||||
exit(errors);
|
||||
}
|
||||
|
||||
/* STUB */
|
||||
void
|
||||
warning_set_locale(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* STUB */
|
||||
void
|
||||
warning_restore_locale(void)
|
||||
{
|
||||
return;
|
||||
}
|
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2010 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.
|
||||
*/
|
||||
|
||||
#ifndef _SUDO_LIST_H
|
||||
#define _SUDO_LIST_H
|
||||
|
||||
/*
|
||||
* Convenience macro for declaring a list head.
|
||||
*/
|
||||
#define TQ_DECLARE(n) \
|
||||
struct n##_list { \
|
||||
struct n *first; \
|
||||
struct n *last; \
|
||||
};
|
||||
|
||||
/*
|
||||
* Foreach loops: forward and reverse
|
||||
*/
|
||||
#undef tq_foreach_fwd
|
||||
#define tq_foreach_fwd(h, v) \
|
||||
for ((v) = (h)->first; (v) != NULL; (v) = (v)->next)
|
||||
|
||||
#undef tq_foreach_rev
|
||||
#define tq_foreach_rev(h, v) \
|
||||
for ((v) = (h)->last; (v) != NULL; (v) = (v)->prev)
|
||||
|
||||
/*
|
||||
* Init a list head.
|
||||
*/
|
||||
#undef tq_init
|
||||
#define tq_init(h) do { \
|
||||
(h)->first = NULL; \
|
||||
(h)->last = NULL; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Simple macros to avoid exposing first/last and prev/next.
|
||||
*/
|
||||
#undef tq_empty
|
||||
#define tq_empty(h) ((h)->first == NULL)
|
||||
|
||||
#undef tq_first
|
||||
#define tq_first(h) ((h)->first)
|
||||
|
||||
#undef tq_last
|
||||
#define tq_last(h) ((h)->last)
|
||||
|
||||
#undef list_next
|
||||
#define list_next(e) ((e)->next)
|
||||
|
||||
#undef list_prev
|
||||
#define list_prev(e) ((e)->prev)
|
||||
|
||||
/*
|
||||
* Prototypes for list.c
|
||||
*/
|
||||
void *tq_pop(void *);
|
||||
void tq_append(void *, void *);
|
||||
void tq_remove(void *, void *);
|
||||
void list_append(void *, void *);
|
||||
void list2tq(void *, void *);
|
||||
|
||||
#endif /* _SUDO_LIST_H */
|
@@ -72,6 +72,13 @@
|
||||
* after an existing element, at the head of the list, or at the end of
|
||||
* the list. A tail queue may be traversed in either direction.
|
||||
*
|
||||
* A headless tail queue lacks a head structure, The first element acts
|
||||
* as a de facto list head. It uses the same entry struct as a regular
|
||||
* tail queue for easy conversion from headless to headful.
|
||||
* It is capable of concatenating queues as well as individual elements.
|
||||
* Traversing in reverse is more expensive due to lack of a list head.
|
||||
* Note: elements must be initialized before use.
|
||||
*
|
||||
* For details on the use of these macros, see the queue(3) manual page.
|
||||
*
|
||||
*
|
||||
@@ -712,4 +719,88 @@ struct { \
|
||||
(head2)->tqh_last = &(head2)->tqh_first; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Headless Tail queue definitions.
|
||||
*/
|
||||
#undef HLTQ_ENTRY
|
||||
#define HLTQ_ENTRY(type) TAILQ_ENTRY(type)
|
||||
|
||||
#undef HLTQ_INIT
|
||||
#define HLTQ_INIT(entry, field) do { \
|
||||
(entry)->field.tqe_next = NULL; \
|
||||
(entry)->field.tqe_prev = &(entry)->field.tqe_next; \
|
||||
} while (0)
|
||||
|
||||
#undef HLTQ_INITIALIZER
|
||||
#define HLTQ_INITIALIZER(entry, field) \
|
||||
{ NULL, &(entry)->field.tqe_next }
|
||||
|
||||
#undef HLTQ_FIRST
|
||||
#define HLTQ_FIRST(elm) (elm)
|
||||
|
||||
#undef HLTQ_END
|
||||
#define HLTQ_END(elm) NULL
|
||||
|
||||
#undef HLTQ_NEXT
|
||||
#define HLTQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#undef HLTQ_LAST
|
||||
#define HLTQ_LAST(elm, type, field) \
|
||||
((elm)->field.tqe_next == NULL ? (elm) : \
|
||||
__containerof((elm)->field.tqe_prev, struct type, field.tqe_next))
|
||||
|
||||
#undef HLTQ_PREV
|
||||
#define HLTQ_PREV(elm, type, field) \
|
||||
(*(elm)->field.tqe_prev == NULL ? NULL : \
|
||||
__containerof((elm)->field.tqe_prev, struct type, field.tqe_next))
|
||||
|
||||
#undef HLTQ_FOREACH
|
||||
#define HLTQ_FOREACH(var, head, field) \
|
||||
for ((var) = HLTQ_FIRST(head); \
|
||||
(var) != HLTQ_END(head); \
|
||||
(var) = HLTQ_NEXT(var, field))
|
||||
|
||||
#undef HLTQ_FOREACH_SAFE
|
||||
#define HLTQ_FOREACH_SAFE(var, head, field, tvar) \
|
||||
for ((var) = HLTQ_FIRST(head); \
|
||||
(var) != HLTQ_END(head) && \
|
||||
((tvar) = HLTQ_NEXT(var, field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
#undef HLTQ_FOREACH_REVERSE
|
||||
#define HLTQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = HLTQ_LAST(head, headname); \
|
||||
(var) != HLTQ_END(head); \
|
||||
(var) = HLTQ_PREV(var, headname, field))
|
||||
|
||||
#undef HLTQ_FOREACH_REVERSE_SAFE
|
||||
#define HLTQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
|
||||
for ((var) = HLTQ_LAST(head, headname); \
|
||||
(var) != HLTQ_END(head) && \
|
||||
((tvar) = HLTQ_PREV(var, headname, field), 1); \
|
||||
(var) = (tvar))
|
||||
|
||||
/* Concatenate queue2 to the end of queue1. */
|
||||
#undef HLTQ_CONCAT
|
||||
#define HLTQ_CONCAT(queue1, queue2, field) do { \
|
||||
(queue2)->field.tqe_prev = (queue1)->field.tqe_prev; \
|
||||
*(queue1)->field.tqe_prev = (queue2); \
|
||||
(queue1)->field.tqe_prev = &(queue2)->field.tqe_next; \
|
||||
} while (0)
|
||||
|
||||
/* Convert a headless tailq to a headful one. */
|
||||
#define HLTQ_TO_TAILQ(head, hl, field) do { \
|
||||
(head)->tqh_first = (hl); \
|
||||
(head)->tqh_last = (hl)->field.tqe_prev; \
|
||||
(hl)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (0)
|
||||
|
||||
/* Concatenate a headless tail queue to the end of a regular tail queue. */
|
||||
#define TAILQ_CONCAT_HLTQ(head, hl, field) do { \
|
||||
void *last = (hl)->field.tqe_prev; \
|
||||
(hl)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (hl); \
|
||||
(head)->tqh_last = last; \
|
||||
} while (0)
|
||||
|
||||
#endif /* !_SUDO_QUEUE_H_ */
|
||||
|
@@ -450,8 +450,7 @@ alias.lo: $(srcdir)/alias.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||
$(incdir)/queue.h $(incdir)/fileops.h $(srcdir)/defaults.h \
|
||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
|
||||
$(srcdir)/parse.h $(incdir)/list.h $(srcdir)/redblack.h \
|
||||
$(devdir)/gram.h
|
||||
$(srcdir)/parse.h $(srcdir)/redblack.h $(devdir)/gram.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/alias.c
|
||||
audit.lo: $(srcdir)/audit.c $(top_builddir)/config.h \
|
||||
$(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
|
||||
@@ -491,7 +490,7 @@ check_addr.o: $(srcdir)/regress/parser/check_addr.c $(top_builddir)/config.h \
|
||||
$(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
|
||||
$(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/gettext.h $(srcdir)/parse.h \
|
||||
$(incdir)/list.h $(srcdir)/interfaces.h
|
||||
$(srcdir)/interfaces.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/parser/check_addr.c
|
||||
check_base64.o: $(srcdir)/regress/parser/check_base64.c \
|
||||
$(top_builddir)/config.h $(incdir)/missing.h
|
||||
@@ -501,8 +500,8 @@ check_digest.o: $(srcdir)/regress/parser/check_digest.c \
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/parser/check_digest.c
|
||||
check_fill.o: $(srcdir)/regress/parser/check_fill.c $(top_builddir)/config.h \
|
||||
$(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \
|
||||
$(incdir)/list.h $(srcdir)/parse.h $(incdir)/list.h \
|
||||
$(srcdir)/toke.h $(incdir)/sudo_plugin.h $(devdir)/gram.h
|
||||
$(incdir)/queue.h $(srcdir)/parse.h $(srcdir)/toke.h \
|
||||
$(incdir)/sudo_plugin.h $(devdir)/gram.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/regress/parser/check_fill.c
|
||||
check_iolog_path.o: $(srcdir)/regress/iolog_path/check_iolog_path.c \
|
||||
$(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||
@@ -534,8 +533,8 @@ defaults.lo: $(srcdir)/defaults.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||
$(incdir)/queue.h $(incdir)/fileops.h $(srcdir)/defaults.h \
|
||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/gettext.h $(srcdir)/parse.h $(incdir)/list.h \
|
||||
$(devdir)/gram.h $(devdir)/def_data.c
|
||||
$(incdir)/gettext.h $(srcdir)/parse.h $(devdir)/gram.h \
|
||||
$(devdir)/def_data.c
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/defaults.c
|
||||
env.lo: $(srcdir)/env.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
|
||||
@@ -585,7 +584,7 @@ gram.lo: $(devdir)/gram.c $(top_builddir)/config.h $(top_builddir)/config.h \
|
||||
$(incdir)/alloc.h $(incdir)/queue.h $(incdir)/fileops.h \
|
||||
$(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
|
||||
$(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/gettext.h $(srcdir)/parse.h $(incdir)/list.h $(srcdir)/toke.h
|
||||
$(incdir)/gettext.h $(srcdir)/parse.h $(srcdir)/toke.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(devdir)/gram.c
|
||||
group_plugin.lo: $(srcdir)/group_plugin.c $(top_builddir)/config.h \
|
||||
$(top_srcdir)/compat/dlfcn.h $(srcdir)/sudoers.h \
|
||||
@@ -643,7 +642,7 @@ ldap.lo: $(srcdir)/ldap.c $(top_builddir)/config.h \
|
||||
$(incdir)/queue.h $(incdir)/fileops.h $(srcdir)/defaults.h \
|
||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
|
||||
$(srcdir)/parse.h $(incdir)/list.h $(incdir)/lbuf.h
|
||||
$(srcdir)/parse.h $(incdir)/lbuf.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/ldap.c
|
||||
linux_audit.lo: $(srcdir)/linux_audit.c $(top_builddir)/config.h \
|
||||
$(incdir)/missing.h $(incdir)/fatal.h $(incdir)/alloc.h \
|
||||
@@ -678,8 +677,8 @@ match.lo: $(srcdir)/match.c $(top_builddir)/config.h \
|
||||
$(incdir)/alloc.h $(incdir)/queue.h $(incdir)/fileops.h \
|
||||
$(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
|
||||
$(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/gettext.h $(srcdir)/parse.h $(incdir)/list.h \
|
||||
$(srcdir)/sha2.h $(devdir)/gram.h
|
||||
$(incdir)/gettext.h $(srcdir)/parse.h $(srcdir)/sha2.h \
|
||||
$(devdir)/gram.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/match.c
|
||||
match_addr.lo: $(srcdir)/match_addr.c $(top_builddir)/config.h \
|
||||
$(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
|
||||
@@ -708,7 +707,7 @@ parse.lo: $(srcdir)/parse.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||
$(incdir)/queue.h $(incdir)/fileops.h $(srcdir)/defaults.h \
|
||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
|
||||
$(srcdir)/parse.h $(incdir)/list.h $(incdir)/lbuf.h $(devdir)/gram.h
|
||||
$(srcdir)/parse.h $(incdir)/lbuf.h $(devdir)/gram.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/parse.c
|
||||
passwd.lo: $(authdir)/passwd.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
|
||||
@@ -805,8 +804,7 @@ sssd.lo: $(srcdir)/sssd.c $(top_builddir)/config.h \
|
||||
$(incdir)/queue.h $(incdir)/fileops.h $(srcdir)/defaults.h \
|
||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
|
||||
$(srcdir)/parse.h $(incdir)/list.h $(incdir)/lbuf.h \
|
||||
$(incdir)/sudo_debug.h
|
||||
$(srcdir)/parse.h $(incdir)/lbuf.h $(incdir)/sudo_debug.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sssd.c
|
||||
sudo_auth.lo: $(authdir)/sudo_auth.c $(top_builddir)/config.h \
|
||||
$(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
|
||||
@@ -853,8 +851,8 @@ testsudoers.o: $(srcdir)/testsudoers.c $(top_builddir)/config.h \
|
||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/gettext.h $(srcdir)/interfaces.h $(srcdir)/parse.h \
|
||||
$(incdir)/list.h $(incdir)/sudo_conf.h $(incdir)/queue.h \
|
||||
$(incdir)/secure_path.h $(devdir)/gram.h
|
||||
$(incdir)/sudo_conf.h $(incdir)/queue.h $(incdir)/secure_path.h \
|
||||
$(devdir)/gram.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/testsudoers.c
|
||||
timestamp.lo: $(srcdir)/timestamp.c $(top_builddir)/config.h \
|
||||
$(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
|
||||
@@ -872,8 +870,8 @@ toke.lo: $(devdir)/toke.c $(top_builddir)/config.h $(top_builddir)/config.h \
|
||||
$(incdir)/alloc.h $(incdir)/queue.h $(incdir)/fileops.h \
|
||||
$(srcdir)/defaults.h $(devdir)/def_data.h $(srcdir)/logging.h \
|
||||
$(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/gettext.h $(srcdir)/parse.h $(incdir)/list.h \
|
||||
$(srcdir)/toke.h $(devdir)/gram.h $(incdir)/lbuf.h $(srcdir)/sha2.h \
|
||||
$(incdir)/gettext.h $(srcdir)/parse.h $(srcdir)/toke.h \
|
||||
$(devdir)/gram.h $(incdir)/lbuf.h $(srcdir)/sha2.h \
|
||||
$(incdir)/secure_path.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(devdir)/toke.c
|
||||
toke_util.lo: $(srcdir)/toke_util.c $(top_builddir)/config.h \
|
||||
@@ -883,7 +881,7 @@ toke_util.lo: $(srcdir)/toke_util.c $(top_builddir)/config.h \
|
||||
$(incdir)/fileops.h $(srcdir)/defaults.h $(devdir)/def_data.h \
|
||||
$(srcdir)/logging.h $(srcdir)/sudo_nss.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/gettext.h $(srcdir)/parse.h \
|
||||
$(incdir)/list.h $(srcdir)/toke.h $(devdir)/gram.h
|
||||
$(srcdir)/toke.h $(devdir)/gram.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/toke_util.c
|
||||
toke_util.o: toke_util.lo
|
||||
tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(top_builddir)/config.h \
|
||||
@@ -902,7 +900,7 @@ visudo.o: $(srcdir)/visudo.c $(top_builddir)/config.h \
|
||||
$(incdir)/queue.h $(incdir)/fileops.h $(srcdir)/defaults.h \
|
||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
|
||||
$(srcdir)/parse.h $(incdir)/list.h $(srcdir)/redblack.h \
|
||||
$(incdir)/gettext.h $(srcdir)/sudoers_version.h \
|
||||
$(incdir)/sudo_conf.h $(incdir)/queue.h $(devdir)/gram.h
|
||||
$(srcdir)/parse.h $(srcdir)/redblack.h $(incdir)/gettext.h \
|
||||
$(srcdir)/sudoers_version.h $(incdir)/sudo_conf.h $(incdir)/queue.h \
|
||||
$(devdir)/gram.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/visudo.c
|
||||
|
@@ -131,7 +131,7 @@ alias_add(char *name, int type, struct member *members)
|
||||
a->name = name;
|
||||
a->type = type;
|
||||
/* a->used = false; */
|
||||
list2tq(&a->members, members);
|
||||
HLTQ_TO_TAILQ(&a->members, members, entries);
|
||||
if (rbinsert(aliases, a)) {
|
||||
snprintf(errbuf, sizeof(errbuf), N_("Alias `%s' already defined"), name);
|
||||
alias_free(a);
|
||||
@@ -176,8 +176,7 @@ alias_free(void *v)
|
||||
debug_decl(alias_free, SUDO_DEBUG_ALIAS)
|
||||
|
||||
efree(a->name);
|
||||
for (m = a->members.first; m != NULL; m = next) {
|
||||
next = m->next;
|
||||
TAILQ_FOREACH_SAFE(m, &a->members, entries, next) {
|
||||
if (m->type == COMMAND) {
|
||||
c = (struct sudo_command *) m->name;
|
||||
efree(c->cmnd);
|
||||
|
@@ -502,7 +502,7 @@ update_defaults(int what)
|
||||
bool rc = true;
|
||||
debug_decl(update_defaults, SUDO_DEBUG_DEFAULTS)
|
||||
|
||||
tq_foreach_fwd(&defaults, def) {
|
||||
TAILQ_FOREACH(def, &defaults, entries) {
|
||||
switch (def->type) {
|
||||
case DEFAULTS:
|
||||
if (ISSET(what, SETDEF_GENERIC) &&
|
||||
@@ -513,7 +513,7 @@ update_defaults(int what)
|
||||
#if 1
|
||||
if (ISSET(what, SETDEF_USER)) {
|
||||
int m;
|
||||
m = userlist_matches(sudo_user.pw, &def->binding);
|
||||
m = userlist_matches(sudo_user.pw, def->binding);
|
||||
if (m == ALLOW) {
|
||||
if (!set_default(def->var, def->val, def->op))
|
||||
rc = false;
|
||||
@@ -521,26 +521,26 @@ update_defaults(int what)
|
||||
}
|
||||
#else
|
||||
if (ISSET(what, SETDEF_USER) &&
|
||||
userlist_matches(sudo_user.pw, &def->binding) == ALLOW &&
|
||||
userlist_matches(sudo_user.pw, def->binding) == ALLOW &&
|
||||
!set_default(def->var, def->val, def->op))
|
||||
rc = false;
|
||||
#endif
|
||||
break;
|
||||
case DEFAULTS_RUNAS:
|
||||
if (ISSET(what, SETDEF_RUNAS) &&
|
||||
runaslist_matches(&def->binding, NULL, NULL, NULL) == ALLOW &&
|
||||
runaslist_matches(def->binding, NULL, NULL, NULL) == ALLOW &&
|
||||
!set_default(def->var, def->val, def->op))
|
||||
rc = false;
|
||||
break;
|
||||
case DEFAULTS_HOST:
|
||||
if (ISSET(what, SETDEF_HOST) &&
|
||||
hostlist_matches(&def->binding) == ALLOW &&
|
||||
hostlist_matches(def->binding) == ALLOW &&
|
||||
!set_default(def->var, def->val, def->op))
|
||||
rc = false;
|
||||
break;
|
||||
case DEFAULTS_CMND:
|
||||
if (ISSET(what, SETDEF_CMND) &&
|
||||
cmndlist_matches(&def->binding) == ALLOW &&
|
||||
cmndlist_matches(def->binding) == ALLOW &&
|
||||
!set_default(def->var, def->val, def->op))
|
||||
rc = false;
|
||||
break;
|
||||
@@ -561,7 +561,7 @@ check_defaults(int what, bool quiet)
|
||||
bool rc = true;
|
||||
debug_decl(check_defaults, SUDO_DEBUG_DEFAULTS)
|
||||
|
||||
tq_foreach_fwd(&defaults, def) {
|
||||
TAILQ_FOREACH(def, &defaults, entries) {
|
||||
switch (def->type) {
|
||||
case DEFAULTS:
|
||||
if (!ISSET(what, SETDEF_GENERIC))
|
||||
|
@@ -117,8 +117,8 @@ bool parse_error = false;
|
||||
int errorlineno = -1;
|
||||
char *errorfile = NULL;
|
||||
|
||||
struct defaults_list defaults;
|
||||
struct userspec_list userspecs;
|
||||
struct defaults_list defaults = TAILQ_HEAD_INITIALIZER(defaults);
|
||||
struct userspec_list userspecs = TAILQ_HEAD_INITIALIZER(userspecs);
|
||||
|
||||
/*
|
||||
* Local protoypes
|
||||
@@ -699,7 +699,7 @@ short *yyss;
|
||||
short *yysslim;
|
||||
YYSTYPE *yyvs;
|
||||
int yystacksize;
|
||||
#line 681 "gram.y"
|
||||
#line 688 "gram.y"
|
||||
void
|
||||
sudoerserror(const char *s)
|
||||
{
|
||||
@@ -741,11 +741,10 @@ new_default(char *var, char *val, int op)
|
||||
d = ecalloc(1, sizeof(struct defaults));
|
||||
d->var = var;
|
||||
d->val = val;
|
||||
tq_init(&d->binding);
|
||||
/* d->type = 0; */
|
||||
d->op = op;
|
||||
d->prev = d;
|
||||
/* d->next = NULL; */
|
||||
/* d->binding = NULL */
|
||||
HLTQ_INIT(d, entries);
|
||||
|
||||
debug_return_ptr(d);
|
||||
}
|
||||
@@ -759,8 +758,7 @@ new_member(char *name, int type)
|
||||
m = ecalloc(1, sizeof(struct member));
|
||||
m->name = name;
|
||||
m->type = type;
|
||||
m->prev = m;
|
||||
/* m->next = NULL; */
|
||||
HLTQ_INIT(m, entries);
|
||||
|
||||
debug_return_ptr(m);
|
||||
}
|
||||
@@ -787,30 +785,34 @@ static void
|
||||
add_defaults(int type, struct member *bmem, struct defaults *defs)
|
||||
{
|
||||
struct defaults *d;
|
||||
struct member_list binding;
|
||||
struct member_list *binding;
|
||||
debug_decl(add_defaults, SUDO_DEBUG_PARSER)
|
||||
|
||||
/*
|
||||
* We can only call list2tq once on bmem as it will zero
|
||||
* out the prev pointer when it consumes bmem.
|
||||
* We use a single binding for each entry in defs.
|
||||
*/
|
||||
list2tq(&binding, bmem);
|
||||
binding = emalloc(sizeof(*binding));
|
||||
if (bmem != NULL)
|
||||
HLTQ_TO_TAILQ(binding, bmem, entries);
|
||||
else
|
||||
TAILQ_INIT(binding);
|
||||
|
||||
/*
|
||||
* Set type and binding (who it applies to) for new entries.
|
||||
* Then add to the global defaults list.
|
||||
*/
|
||||
for (d = defs; d != NULL; d = d->next) {
|
||||
HLTQ_FOREACH(d, defs, entries) {
|
||||
d->type = type;
|
||||
d->binding = binding;
|
||||
}
|
||||
tq_append(&defaults, defs);
|
||||
TAILQ_CONCAT_HLTQ(&defaults, defs, entries);
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new struct userspec, populate it, and insert it at the
|
||||
* and of the userspecs list.
|
||||
* end of the userspecs list.
|
||||
*/
|
||||
static void
|
||||
add_userspec(struct member *members, struct privilege *privs)
|
||||
@@ -819,11 +821,9 @@ add_userspec(struct member *members, struct privilege *privs)
|
||||
debug_decl(add_userspec, SUDO_DEBUG_PARSER)
|
||||
|
||||
u = ecalloc(1, sizeof(*u));
|
||||
list2tq(&u->users, members);
|
||||
list2tq(&u->privileges, privs);
|
||||
u->prev = u;
|
||||
/* u->next = NULL; */
|
||||
tq_append(&userspecs, u);
|
||||
HLTQ_TO_TAILQ(&u->users, members, entries);
|
||||
HLTQ_TO_TAILQ(&u->privileges, privs, entries);
|
||||
TAILQ_INSERT_TAIL(&userspecs, u, entries);
|
||||
|
||||
debug_return;
|
||||
}
|
||||
@@ -835,21 +835,24 @@ add_userspec(struct member *members, struct privilege *privs)
|
||||
void
|
||||
init_parser(const char *path, bool quiet)
|
||||
{
|
||||
struct member_list *binding;
|
||||
struct member *m;
|
||||
struct defaults *d;
|
||||
struct member *m, *binding;
|
||||
struct userspec *us;
|
||||
struct privilege *priv;
|
||||
struct cmndspec *cs;
|
||||
struct sudo_command *c;
|
||||
debug_decl(init_parser, SUDO_DEBUG_PARSER)
|
||||
|
||||
while ((us = tq_pop(&userspecs)) != NULL) {
|
||||
while ((m = tq_pop(&us->users)) != NULL) {
|
||||
while ((us = TAILQ_FIRST(&userspecs)) != NULL) {
|
||||
TAILQ_REMOVE(&userspecs, us, entries);
|
||||
while ((m = TAILQ_FIRST(&us->users)) != NULL) {
|
||||
TAILQ_REMOVE(&us->users, m, entries);
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
while ((priv = tq_pop(&us->privileges)) != NULL) {
|
||||
struct member *runasuser = NULL, *runasgroup = NULL;
|
||||
while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
|
||||
struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
|
||||
#ifdef HAVE_SELINUX
|
||||
char *role = NULL, *type = NULL;
|
||||
#endif /* HAVE_SELINUX */
|
||||
@@ -857,11 +860,14 @@ init_parser(const char *path, bool quiet)
|
||||
char *privs = NULL, *limitprivs = NULL;
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
|
||||
while ((m = tq_pop(&priv->hostlist)) != NULL) {
|
||||
TAILQ_REMOVE(&us->privileges, priv, entries);
|
||||
while ((m = TAILQ_FIRST(&priv->hostlist)) != NULL) {
|
||||
TAILQ_REMOVE(&priv->hostlist, m, entries);
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
while ((cs = tq_pop(&priv->cmndlist)) != NULL) {
|
||||
while ((cs = TAILQ_FIRST(&priv->cmndlist)) != NULL) {
|
||||
TAILQ_REMOVE(&priv->cmndlist, cs, entries);
|
||||
#ifdef HAVE_SELINUX
|
||||
/* Only free the first instance of a role/type. */
|
||||
if (cs->role != role) {
|
||||
@@ -884,19 +890,24 @@ init_parser(const char *path, bool quiet)
|
||||
efree(cs->limitprivs);
|
||||
}
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
if (tq_last(&cs->runasuserlist) != runasuser) {
|
||||
runasuser = tq_last(&cs->runasuserlist);
|
||||
while ((m = tq_pop(&cs->runasuserlist)) != NULL) {
|
||||
/* Only free the first instance of runas user/group lists. */
|
||||
if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
|
||||
runasuserlist = cs->runasuserlist;
|
||||
while ((m = TAILQ_FIRST(runasuserlist)) != NULL) {
|
||||
TAILQ_REMOVE(runasuserlist, m, entries);
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
efree(runasuserlist);
|
||||
}
|
||||
if (tq_last(&cs->runasgrouplist) != runasgroup) {
|
||||
runasgroup = tq_last(&cs->runasgrouplist);
|
||||
while ((m = tq_pop(&cs->runasgrouplist)) != NULL) {
|
||||
if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
|
||||
runasgrouplist = cs->runasgrouplist;
|
||||
while ((m = TAILQ_FIRST(runasgrouplist)) != NULL) {
|
||||
TAILQ_REMOVE(runasgrouplist, m, entries);
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
efree(runasgrouplist);
|
||||
}
|
||||
if (cs->cmnd->type == COMMAND) {
|
||||
c = (struct sudo_command *) cs->cmnd->name;
|
||||
@@ -911,13 +922,15 @@ init_parser(const char *path, bool quiet)
|
||||
}
|
||||
efree(us);
|
||||
}
|
||||
tq_init(&userspecs);
|
||||
TAILQ_INIT(&userspecs);
|
||||
|
||||
binding = NULL;
|
||||
while ((d = tq_pop(&defaults)) != NULL) {
|
||||
if (tq_last(&d->binding) != binding) {
|
||||
binding = tq_last(&d->binding);
|
||||
while ((m = tq_pop(&d->binding)) != NULL) {
|
||||
while ((d = TAILQ_FIRST(&defaults)) != NULL) {
|
||||
TAILQ_REMOVE(&defaults, d, entries);
|
||||
if (d->binding != binding) {
|
||||
binding = d->binding;
|
||||
while ((m = TAILQ_FIRST(d->binding)) != NULL) {
|
||||
TAILQ_REMOVE(d->binding, m, entries);
|
||||
if (m->type == COMMAND) {
|
||||
c = (struct sudo_command *) m->name;
|
||||
efree(c->cmnd);
|
||||
@@ -926,12 +939,13 @@ init_parser(const char *path, bool quiet)
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
efree(d->binding);
|
||||
}
|
||||
efree(d->var);
|
||||
efree(d->val);
|
||||
efree(d);
|
||||
}
|
||||
tq_init(&defaults);
|
||||
TAILQ_INIT(&defaults);
|
||||
|
||||
init_aliases();
|
||||
|
||||
@@ -947,7 +961,7 @@ init_parser(const char *path, bool quiet)
|
||||
|
||||
debug_return;
|
||||
}
|
||||
#line 898 "gram.c"
|
||||
#line 912 "gram.c"
|
||||
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
|
||||
#if defined(__cplusplus) || defined(__STDC__)
|
||||
static int yygrowstack(void)
|
||||
@@ -1228,7 +1242,7 @@ break;
|
||||
case 18:
|
||||
#line 232 "gram.y"
|
||||
{
|
||||
list_append(yyvsp[-2].defaults, yyvsp[0].defaults);
|
||||
HLTQ_CONCAT(yyvsp[-2].defaults, yyvsp[0].defaults, entries);
|
||||
yyval.defaults = yyvsp[-2].defaults;
|
||||
}
|
||||
break;
|
||||
@@ -1265,7 +1279,7 @@ break;
|
||||
case 25:
|
||||
#line 256 "gram.y"
|
||||
{
|
||||
list_append(yyvsp[-2].privilege, yyvsp[0].privilege);
|
||||
HLTQ_CONCAT(yyvsp[-2].privilege, yyvsp[0].privilege, entries);
|
||||
yyval.privilege = yyvsp[-2].privilege;
|
||||
}
|
||||
break;
|
||||
@@ -1273,108 +1287,116 @@ case 26:
|
||||
#line 262 "gram.y"
|
||||
{
|
||||
struct privilege *p = ecalloc(1, sizeof(*p));
|
||||
list2tq(&p->hostlist, yyvsp[-2].member);
|
||||
list2tq(&p->cmndlist, yyvsp[0].cmndspec);
|
||||
p->prev = p;
|
||||
/* p->next = NULL; */
|
||||
HLTQ_TO_TAILQ(&p->hostlist, yyvsp[-2].member, entries);
|
||||
HLTQ_TO_TAILQ(&p->cmndlist, yyvsp[0].cmndspec, entries);
|
||||
HLTQ_INIT(p, entries);
|
||||
yyval.privilege = p;
|
||||
}
|
||||
break;
|
||||
case 27:
|
||||
#line 272 "gram.y"
|
||||
#line 271 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
yyval.member->negated = false;
|
||||
}
|
||||
break;
|
||||
case 28:
|
||||
#line 276 "gram.y"
|
||||
#line 275 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
yyval.member->negated = true;
|
||||
}
|
||||
break;
|
||||
case 29:
|
||||
#line 282 "gram.y"
|
||||
#line 281 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, ALIAS);
|
||||
}
|
||||
break;
|
||||
case 30:
|
||||
#line 285 "gram.y"
|
||||
#line 284 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(NULL, ALL);
|
||||
}
|
||||
break;
|
||||
case 31:
|
||||
#line 288 "gram.y"
|
||||
#line 287 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, NETGROUP);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
#line 291 "gram.y"
|
||||
#line 290 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, NTWKADDR);
|
||||
}
|
||||
break;
|
||||
case 33:
|
||||
#line 294 "gram.y"
|
||||
#line 293 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, WORD);
|
||||
}
|
||||
break;
|
||||
case 35:
|
||||
#line 300 "gram.y"
|
||||
#line 299 "gram.y"
|
||||
{
|
||||
list_append(yyvsp[-2].cmndspec, yyvsp[0].cmndspec);
|
||||
struct cmndspec *prev;
|
||||
prev = HLTQ_LAST(yyvsp[-2].cmndspec, cmndspec, entries);
|
||||
HLTQ_CONCAT(yyvsp[-2].cmndspec, yyvsp[0].cmndspec, entries);
|
||||
#ifdef HAVE_SELINUX
|
||||
/* propagate role and type */
|
||||
if (yyvsp[0].cmndspec->role == NULL)
|
||||
yyvsp[0].cmndspec->role = yyvsp[0].cmndspec->prev->role;
|
||||
yyvsp[0].cmndspec->role = prev->role;
|
||||
if (yyvsp[0].cmndspec->type == NULL)
|
||||
yyvsp[0].cmndspec->type = yyvsp[0].cmndspec->prev->type;
|
||||
yyvsp[0].cmndspec->type = prev->type;
|
||||
#endif /* HAVE_SELINUX */
|
||||
#ifdef HAVE_PRIV_SET
|
||||
/* propagate privs & limitprivs */
|
||||
if (yyvsp[0].cmndspec->privs == NULL)
|
||||
yyvsp[0].cmndspec->privs = yyvsp[0].cmndspec->prev->privs;
|
||||
yyvsp[0].cmndspec->privs = prev->privs;
|
||||
if (yyvsp[0].cmndspec->limitprivs == NULL)
|
||||
yyvsp[0].cmndspec->limitprivs = yyvsp[0].cmndspec->prev->limitprivs;
|
||||
yyvsp[0].cmndspec->limitprivs = prev->limitprivs;
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
/* propagate tags and runas list */
|
||||
if (yyvsp[0].cmndspec->tags.nopasswd == UNSPEC)
|
||||
yyvsp[0].cmndspec->tags.nopasswd = yyvsp[0].cmndspec->prev->tags.nopasswd;
|
||||
yyvsp[0].cmndspec->tags.nopasswd = prev->tags.nopasswd;
|
||||
if (yyvsp[0].cmndspec->tags.noexec == UNSPEC)
|
||||
yyvsp[0].cmndspec->tags.noexec = yyvsp[0].cmndspec->prev->tags.noexec;
|
||||
yyvsp[0].cmndspec->tags.noexec = prev->tags.noexec;
|
||||
if (yyvsp[0].cmndspec->tags.setenv == UNSPEC &&
|
||||
yyvsp[0].cmndspec->prev->tags.setenv != IMPLIED)
|
||||
yyvsp[0].cmndspec->tags.setenv = yyvsp[0].cmndspec->prev->tags.setenv;
|
||||
prev->tags.setenv != IMPLIED)
|
||||
yyvsp[0].cmndspec->tags.setenv = prev->tags.setenv;
|
||||
if (yyvsp[0].cmndspec->tags.log_input == UNSPEC)
|
||||
yyvsp[0].cmndspec->tags.log_input = yyvsp[0].cmndspec->prev->tags.log_input;
|
||||
yyvsp[0].cmndspec->tags.log_input = prev->tags.log_input;
|
||||
if (yyvsp[0].cmndspec->tags.log_output == UNSPEC)
|
||||
yyvsp[0].cmndspec->tags.log_output = yyvsp[0].cmndspec->prev->tags.log_output;
|
||||
if ((tq_empty(&yyvsp[0].cmndspec->runasuserlist) &&
|
||||
tq_empty(&yyvsp[0].cmndspec->runasgrouplist)) &&
|
||||
(!tq_empty(&yyvsp[0].cmndspec->prev->runasuserlist) ||
|
||||
!tq_empty(&yyvsp[0].cmndspec->prev->runasgrouplist))) {
|
||||
yyvsp[0].cmndspec->runasuserlist = yyvsp[0].cmndspec->prev->runasuserlist;
|
||||
yyvsp[0].cmndspec->runasgrouplist = yyvsp[0].cmndspec->prev->runasgrouplist;
|
||||
yyvsp[0].cmndspec->tags.log_output = prev->tags.log_output;
|
||||
if ((yyvsp[0].cmndspec->runasuserlist == NULL &&
|
||||
yyvsp[0].cmndspec->runasgrouplist == NULL) &&
|
||||
(prev->runasuserlist != NULL ||
|
||||
prev->runasgrouplist != NULL)) {
|
||||
yyvsp[0].cmndspec->runasuserlist = prev->runasuserlist;
|
||||
yyvsp[0].cmndspec->runasgrouplist = prev->runasgrouplist;
|
||||
}
|
||||
yyval.cmndspec = yyvsp[-2].cmndspec;
|
||||
}
|
||||
break;
|
||||
case 36:
|
||||
#line 339 "gram.y"
|
||||
#line 340 "gram.y"
|
||||
{
|
||||
struct cmndspec *cs = ecalloc(1, sizeof(*cs));
|
||||
if (yyvsp[-4].runas != NULL) {
|
||||
list2tq(&cs->runasuserlist, yyvsp[-4].runas->runasusers);
|
||||
list2tq(&cs->runasgrouplist, yyvsp[-4].runas->runasgroups);
|
||||
if (yyvsp[-4].runas->runasusers != NULL) {
|
||||
cs->runasuserlist =
|
||||
emalloc(sizeof(*cs->runasuserlist));
|
||||
HLTQ_TO_TAILQ(cs->runasuserlist,
|
||||
yyvsp[-4].runas->runasusers, entries);
|
||||
}
|
||||
if (yyvsp[-4].runas->runasgroups != NULL) {
|
||||
cs->runasgrouplist =
|
||||
emalloc(sizeof(*cs->runasgrouplist));
|
||||
HLTQ_TO_TAILQ(cs->runasgrouplist,
|
||||
yyvsp[-4].runas->runasgroups, entries);
|
||||
}
|
||||
efree(yyvsp[-4].runas);
|
||||
} else {
|
||||
tq_init(&cs->runasuserlist);
|
||||
tq_init(&cs->runasgrouplist);
|
||||
}
|
||||
#ifdef HAVE_SELINUX
|
||||
cs->role = yyvsp[-3].seinfo.role;
|
||||
@@ -1386,8 +1408,7 @@ case 36:
|
||||
#endif
|
||||
cs->tags = yyvsp[-1].tag;
|
||||
cs->cmnd = yyvsp[0].member;
|
||||
cs->prev = cs;
|
||||
cs->next = NULL;
|
||||
HLTQ_INIT(cs, entries);
|
||||
/* sudo "ALL" implies the SETENV tag */
|
||||
if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
|
||||
cs->tags.setenv == UNSPEC)
|
||||
@@ -1396,37 +1417,37 @@ case 36:
|
||||
}
|
||||
break;
|
||||
case 37:
|
||||
#line 369 "gram.y"
|
||||
#line 376 "gram.y"
|
||||
{
|
||||
yyval.digest = new_digest(SUDO_DIGEST_SHA224, yyvsp[0].string);
|
||||
}
|
||||
break;
|
||||
case 38:
|
||||
#line 372 "gram.y"
|
||||
#line 379 "gram.y"
|
||||
{
|
||||
yyval.digest = new_digest(SUDO_DIGEST_SHA256, yyvsp[0].string);
|
||||
}
|
||||
break;
|
||||
case 39:
|
||||
#line 375 "gram.y"
|
||||
#line 382 "gram.y"
|
||||
{
|
||||
yyval.digest = new_digest(SUDO_DIGEST_SHA384, yyvsp[0].string);
|
||||
}
|
||||
break;
|
||||
case 40:
|
||||
#line 378 "gram.y"
|
||||
#line 385 "gram.y"
|
||||
{
|
||||
yyval.digest = new_digest(SUDO_DIGEST_SHA512, yyvsp[0].string);
|
||||
}
|
||||
break;
|
||||
case 41:
|
||||
#line 383 "gram.y"
|
||||
#line 390 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
}
|
||||
break;
|
||||
case 42:
|
||||
#line 386 "gram.y"
|
||||
#line 393 "gram.y"
|
||||
{
|
||||
/* XXX - yuck */
|
||||
struct sudo_command *c = (struct sudo_command *)(yyvsp[0].member->name);
|
||||
@@ -1435,127 +1456,127 @@ case 42:
|
||||
}
|
||||
break;
|
||||
case 43:
|
||||
#line 394 "gram.y"
|
||||
#line 401 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
yyval.member->negated = false;
|
||||
}
|
||||
break;
|
||||
case 44:
|
||||
#line 398 "gram.y"
|
||||
#line 405 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
yyval.member->negated = true;
|
||||
}
|
||||
break;
|
||||
case 45:
|
||||
#line 404 "gram.y"
|
||||
#line 411 "gram.y"
|
||||
{
|
||||
yyval.string = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 46:
|
||||
#line 409 "gram.y"
|
||||
#line 416 "gram.y"
|
||||
{
|
||||
yyval.string = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 47:
|
||||
#line 414 "gram.y"
|
||||
#line 421 "gram.y"
|
||||
{
|
||||
yyval.seinfo.role = NULL;
|
||||
yyval.seinfo.type = NULL;
|
||||
}
|
||||
break;
|
||||
case 48:
|
||||
#line 418 "gram.y"
|
||||
#line 425 "gram.y"
|
||||
{
|
||||
yyval.seinfo.role = yyvsp[0].string;
|
||||
yyval.seinfo.type = NULL;
|
||||
}
|
||||
break;
|
||||
case 49:
|
||||
#line 422 "gram.y"
|
||||
#line 429 "gram.y"
|
||||
{
|
||||
yyval.seinfo.type = yyvsp[0].string;
|
||||
yyval.seinfo.role = NULL;
|
||||
}
|
||||
break;
|
||||
case 50:
|
||||
#line 426 "gram.y"
|
||||
#line 433 "gram.y"
|
||||
{
|
||||
yyval.seinfo.role = yyvsp[-1].string;
|
||||
yyval.seinfo.type = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 51:
|
||||
#line 430 "gram.y"
|
||||
#line 437 "gram.y"
|
||||
{
|
||||
yyval.seinfo.type = yyvsp[-1].string;
|
||||
yyval.seinfo.role = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 52:
|
||||
#line 436 "gram.y"
|
||||
#line 443 "gram.y"
|
||||
{
|
||||
yyval.string = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 53:
|
||||
#line 440 "gram.y"
|
||||
#line 447 "gram.y"
|
||||
{
|
||||
yyval.string = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 54:
|
||||
#line 445 "gram.y"
|
||||
#line 452 "gram.y"
|
||||
{
|
||||
yyval.privinfo.privs = NULL;
|
||||
yyval.privinfo.limitprivs = NULL;
|
||||
}
|
||||
break;
|
||||
case 55:
|
||||
#line 449 "gram.y"
|
||||
#line 456 "gram.y"
|
||||
{
|
||||
yyval.privinfo.privs = yyvsp[0].string;
|
||||
yyval.privinfo.limitprivs = NULL;
|
||||
}
|
||||
break;
|
||||
case 56:
|
||||
#line 453 "gram.y"
|
||||
#line 460 "gram.y"
|
||||
{
|
||||
yyval.privinfo.privs = NULL;
|
||||
yyval.privinfo.limitprivs = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 57:
|
||||
#line 457 "gram.y"
|
||||
#line 464 "gram.y"
|
||||
{
|
||||
yyval.privinfo.privs = yyvsp[-1].string;
|
||||
yyval.privinfo.limitprivs = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 58:
|
||||
#line 461 "gram.y"
|
||||
#line 468 "gram.y"
|
||||
{
|
||||
yyval.privinfo.limitprivs = yyvsp[-1].string;
|
||||
yyval.privinfo.privs = yyvsp[0].string;
|
||||
}
|
||||
break;
|
||||
case 59:
|
||||
#line 467 "gram.y"
|
||||
#line 474 "gram.y"
|
||||
{
|
||||
yyval.runas = NULL;
|
||||
}
|
||||
break;
|
||||
case 60:
|
||||
#line 470 "gram.y"
|
||||
#line 477 "gram.y"
|
||||
{
|
||||
yyval.runas = yyvsp[-1].runas;
|
||||
}
|
||||
break;
|
||||
case 61:
|
||||
#line 475 "gram.y"
|
||||
#line 482 "gram.y"
|
||||
{
|
||||
yyval.runas = ecalloc(1, sizeof(struct runascontainer));
|
||||
yyval.runas->runasusers = new_member(NULL, MYSELF);
|
||||
@@ -1563,7 +1584,7 @@ case 61:
|
||||
}
|
||||
break;
|
||||
case 62:
|
||||
#line 480 "gram.y"
|
||||
#line 487 "gram.y"
|
||||
{
|
||||
yyval.runas = ecalloc(1, sizeof(struct runascontainer));
|
||||
yyval.runas->runasusers = yyvsp[0].member;
|
||||
@@ -1571,7 +1592,7 @@ case 62:
|
||||
}
|
||||
break;
|
||||
case 63:
|
||||
#line 485 "gram.y"
|
||||
#line 492 "gram.y"
|
||||
{
|
||||
yyval.runas = ecalloc(1, sizeof(struct runascontainer));
|
||||
yyval.runas->runasusers = yyvsp[-2].member;
|
||||
@@ -1579,7 +1600,7 @@ case 63:
|
||||
}
|
||||
break;
|
||||
case 64:
|
||||
#line 490 "gram.y"
|
||||
#line 497 "gram.y"
|
||||
{
|
||||
yyval.runas = ecalloc(1, sizeof(struct runascontainer));
|
||||
/* $$->runasusers = NULL; */
|
||||
@@ -1587,7 +1608,7 @@ case 64:
|
||||
}
|
||||
break;
|
||||
case 65:
|
||||
#line 495 "gram.y"
|
||||
#line 502 "gram.y"
|
||||
{
|
||||
yyval.runas = ecalloc(1, sizeof(struct runascontainer));
|
||||
yyval.runas->runasusers = new_member(NULL, MYSELF);
|
||||
@@ -1595,86 +1616,86 @@ case 65:
|
||||
}
|
||||
break;
|
||||
case 66:
|
||||
#line 502 "gram.y"
|
||||
#line 509 "gram.y"
|
||||
{
|
||||
yyval.tag.nopasswd = yyval.tag.noexec = yyval.tag.setenv =
|
||||
yyval.tag.log_input = yyval.tag.log_output = UNSPEC;
|
||||
}
|
||||
break;
|
||||
case 67:
|
||||
#line 506 "gram.y"
|
||||
#line 513 "gram.y"
|
||||
{
|
||||
yyval.tag.nopasswd = true;
|
||||
}
|
||||
break;
|
||||
case 68:
|
||||
#line 509 "gram.y"
|
||||
#line 516 "gram.y"
|
||||
{
|
||||
yyval.tag.nopasswd = false;
|
||||
}
|
||||
break;
|
||||
case 69:
|
||||
#line 512 "gram.y"
|
||||
#line 519 "gram.y"
|
||||
{
|
||||
yyval.tag.noexec = true;
|
||||
}
|
||||
break;
|
||||
case 70:
|
||||
#line 515 "gram.y"
|
||||
#line 522 "gram.y"
|
||||
{
|
||||
yyval.tag.noexec = false;
|
||||
}
|
||||
break;
|
||||
case 71:
|
||||
#line 518 "gram.y"
|
||||
#line 525 "gram.y"
|
||||
{
|
||||
yyval.tag.setenv = true;
|
||||
}
|
||||
break;
|
||||
case 72:
|
||||
#line 521 "gram.y"
|
||||
#line 528 "gram.y"
|
||||
{
|
||||
yyval.tag.setenv = false;
|
||||
}
|
||||
break;
|
||||
case 73:
|
||||
#line 524 "gram.y"
|
||||
#line 531 "gram.y"
|
||||
{
|
||||
yyval.tag.log_input = true;
|
||||
}
|
||||
break;
|
||||
case 74:
|
||||
#line 527 "gram.y"
|
||||
#line 534 "gram.y"
|
||||
{
|
||||
yyval.tag.log_input = false;
|
||||
}
|
||||
break;
|
||||
case 75:
|
||||
#line 530 "gram.y"
|
||||
#line 537 "gram.y"
|
||||
{
|
||||
yyval.tag.log_output = true;
|
||||
}
|
||||
break;
|
||||
case 76:
|
||||
#line 533 "gram.y"
|
||||
#line 540 "gram.y"
|
||||
{
|
||||
yyval.tag.log_output = false;
|
||||
}
|
||||
break;
|
||||
case 77:
|
||||
#line 538 "gram.y"
|
||||
#line 545 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(NULL, ALL);
|
||||
}
|
||||
break;
|
||||
case 78:
|
||||
#line 541 "gram.y"
|
||||
#line 548 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, ALIAS);
|
||||
}
|
||||
break;
|
||||
case 79:
|
||||
#line 544 "gram.y"
|
||||
#line 551 "gram.y"
|
||||
{
|
||||
struct sudo_command *c = ecalloc(1, sizeof(*c));
|
||||
c->cmnd = yyvsp[0].command.cmnd;
|
||||
@@ -1683,7 +1704,7 @@ case 79:
|
||||
}
|
||||
break;
|
||||
case 82:
|
||||
#line 556 "gram.y"
|
||||
#line 563 "gram.y"
|
||||
{
|
||||
char *s;
|
||||
if ((s = alias_add(yyvsp[-2].string, HOSTALIAS, yyvsp[0].member)) != NULL) {
|
||||
@@ -1693,14 +1714,14 @@ case 82:
|
||||
}
|
||||
break;
|
||||
case 84:
|
||||
#line 566 "gram.y"
|
||||
#line 573 "gram.y"
|
||||
{
|
||||
list_append(yyvsp[-2].member, yyvsp[0].member);
|
||||
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
|
||||
yyval.member = yyvsp[-2].member;
|
||||
}
|
||||
break;
|
||||
case 87:
|
||||
#line 576 "gram.y"
|
||||
#line 583 "gram.y"
|
||||
{
|
||||
char *s;
|
||||
if ((s = alias_add(yyvsp[-2].string, CMNDALIAS, yyvsp[0].member)) != NULL) {
|
||||
@@ -1710,14 +1731,14 @@ case 87:
|
||||
}
|
||||
break;
|
||||
case 89:
|
||||
#line 586 "gram.y"
|
||||
#line 593 "gram.y"
|
||||
{
|
||||
list_append(yyvsp[-2].member, yyvsp[0].member);
|
||||
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
|
||||
yyval.member = yyvsp[-2].member;
|
||||
}
|
||||
break;
|
||||
case 92:
|
||||
#line 596 "gram.y"
|
||||
#line 603 "gram.y"
|
||||
{
|
||||
char *s;
|
||||
if ((s = alias_add(yyvsp[-2].string, RUNASALIAS, yyvsp[0].member)) != NULL) {
|
||||
@@ -1727,7 +1748,7 @@ case 92:
|
||||
}
|
||||
break;
|
||||
case 95:
|
||||
#line 609 "gram.y"
|
||||
#line 616 "gram.y"
|
||||
{
|
||||
char *s;
|
||||
if ((s = alias_add(yyvsp[-2].string, USERALIAS, yyvsp[0].member)) != NULL) {
|
||||
@@ -1737,96 +1758,96 @@ case 95:
|
||||
}
|
||||
break;
|
||||
case 97:
|
||||
#line 619 "gram.y"
|
||||
#line 626 "gram.y"
|
||||
{
|
||||
list_append(yyvsp[-2].member, yyvsp[0].member);
|
||||
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
|
||||
yyval.member = yyvsp[-2].member;
|
||||
}
|
||||
break;
|
||||
case 98:
|
||||
#line 625 "gram.y"
|
||||
#line 632 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
yyval.member->negated = false;
|
||||
}
|
||||
break;
|
||||
case 99:
|
||||
#line 629 "gram.y"
|
||||
#line 636 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
yyval.member->negated = true;
|
||||
}
|
||||
break;
|
||||
case 100:
|
||||
#line 635 "gram.y"
|
||||
#line 642 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, ALIAS);
|
||||
}
|
||||
break;
|
||||
case 101:
|
||||
#line 638 "gram.y"
|
||||
#line 645 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(NULL, ALL);
|
||||
}
|
||||
break;
|
||||
case 102:
|
||||
#line 641 "gram.y"
|
||||
#line 648 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, NETGROUP);
|
||||
}
|
||||
break;
|
||||
case 103:
|
||||
#line 644 "gram.y"
|
||||
#line 651 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, USERGROUP);
|
||||
}
|
||||
break;
|
||||
case 104:
|
||||
#line 647 "gram.y"
|
||||
#line 654 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, WORD);
|
||||
}
|
||||
break;
|
||||
case 106:
|
||||
#line 653 "gram.y"
|
||||
#line 660 "gram.y"
|
||||
{
|
||||
list_append(yyvsp[-2].member, yyvsp[0].member);
|
||||
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
|
||||
yyval.member = yyvsp[-2].member;
|
||||
}
|
||||
break;
|
||||
case 107:
|
||||
#line 659 "gram.y"
|
||||
#line 666 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
yyval.member->negated = false;
|
||||
}
|
||||
break;
|
||||
case 108:
|
||||
#line 663 "gram.y"
|
||||
#line 670 "gram.y"
|
||||
{
|
||||
yyval.member = yyvsp[0].member;
|
||||
yyval.member->negated = true;
|
||||
}
|
||||
break;
|
||||
case 109:
|
||||
#line 669 "gram.y"
|
||||
#line 676 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, ALIAS);
|
||||
}
|
||||
break;
|
||||
case 110:
|
||||
#line 672 "gram.y"
|
||||
#line 679 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(NULL, ALL);
|
||||
}
|
||||
break;
|
||||
case 111:
|
||||
#line 675 "gram.y"
|
||||
#line 682 "gram.y"
|
||||
{
|
||||
yyval.member = new_member(yyvsp[0].string, WORD);
|
||||
}
|
||||
break;
|
||||
#line 1777 "gram.c"
|
||||
#line 1798 "gram.c"
|
||||
}
|
||||
yyssp -= yym;
|
||||
yystate = *yyssp;
|
||||
|
@@ -79,8 +79,8 @@ bool parse_error = false;
|
||||
int errorlineno = -1;
|
||||
char *errorfile = NULL;
|
||||
|
||||
struct defaults_list defaults;
|
||||
struct userspec_list userspecs;
|
||||
struct defaults_list defaults = TAILQ_HEAD_INITIALIZER(defaults);
|
||||
struct userspec_list userspecs = TAILQ_HEAD_INITIALIZER(userspecs);
|
||||
|
||||
/*
|
||||
* Local protoypes
|
||||
@@ -230,7 +230,7 @@ entry : COMMENT {
|
||||
|
||||
defaults_list : defaults_entry
|
||||
| defaults_list ',' defaults_entry {
|
||||
list_append($1, $3);
|
||||
HLTQ_CONCAT($1, $3, entries);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
@@ -254,17 +254,16 @@ defaults_entry : DEFVAR {
|
||||
|
||||
privileges : privilege
|
||||
| privileges ':' privilege {
|
||||
list_append($1, $3);
|
||||
HLTQ_CONCAT($1, $3, entries);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
privilege : hostlist '=' cmndspeclist {
|
||||
struct privilege *p = ecalloc(1, sizeof(*p));
|
||||
list2tq(&p->hostlist, $1);
|
||||
list2tq(&p->cmndlist, $3);
|
||||
p->prev = p;
|
||||
/* p->next = NULL; */
|
||||
HLTQ_TO_TAILQ(&p->hostlist, $1, entries);
|
||||
HLTQ_TO_TAILQ(&p->cmndlist, $3, entries);
|
||||
HLTQ_INIT(p, entries);
|
||||
$$ = p;
|
||||
}
|
||||
;
|
||||
@@ -298,39 +297,41 @@ host : ALIAS {
|
||||
|
||||
cmndspeclist : cmndspec
|
||||
| cmndspeclist ',' cmndspec {
|
||||
list_append($1, $3);
|
||||
struct cmndspec *prev;
|
||||
prev = HLTQ_LAST($1, cmndspec, entries);
|
||||
HLTQ_CONCAT($1, $3, entries);
|
||||
#ifdef HAVE_SELINUX
|
||||
/* propagate role and type */
|
||||
if ($3->role == NULL)
|
||||
$3->role = $3->prev->role;
|
||||
$3->role = prev->role;
|
||||
if ($3->type == NULL)
|
||||
$3->type = $3->prev->type;
|
||||
$3->type = prev->type;
|
||||
#endif /* HAVE_SELINUX */
|
||||
#ifdef HAVE_PRIV_SET
|
||||
/* propagate privs & limitprivs */
|
||||
if ($3->privs == NULL)
|
||||
$3->privs = $3->prev->privs;
|
||||
$3->privs = prev->privs;
|
||||
if ($3->limitprivs == NULL)
|
||||
$3->limitprivs = $3->prev->limitprivs;
|
||||
$3->limitprivs = prev->limitprivs;
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
/* propagate tags and runas list */
|
||||
if ($3->tags.nopasswd == UNSPEC)
|
||||
$3->tags.nopasswd = $3->prev->tags.nopasswd;
|
||||
$3->tags.nopasswd = prev->tags.nopasswd;
|
||||
if ($3->tags.noexec == UNSPEC)
|
||||
$3->tags.noexec = $3->prev->tags.noexec;
|
||||
$3->tags.noexec = prev->tags.noexec;
|
||||
if ($3->tags.setenv == UNSPEC &&
|
||||
$3->prev->tags.setenv != IMPLIED)
|
||||
$3->tags.setenv = $3->prev->tags.setenv;
|
||||
prev->tags.setenv != IMPLIED)
|
||||
$3->tags.setenv = prev->tags.setenv;
|
||||
if ($3->tags.log_input == UNSPEC)
|
||||
$3->tags.log_input = $3->prev->tags.log_input;
|
||||
$3->tags.log_input = prev->tags.log_input;
|
||||
if ($3->tags.log_output == UNSPEC)
|
||||
$3->tags.log_output = $3->prev->tags.log_output;
|
||||
if ((tq_empty(&$3->runasuserlist) &&
|
||||
tq_empty(&$3->runasgrouplist)) &&
|
||||
(!tq_empty(&$3->prev->runasuserlist) ||
|
||||
!tq_empty(&$3->prev->runasgrouplist))) {
|
||||
$3->runasuserlist = $3->prev->runasuserlist;
|
||||
$3->runasgrouplist = $3->prev->runasgrouplist;
|
||||
$3->tags.log_output = prev->tags.log_output;
|
||||
if (($3->runasuserlist == NULL &&
|
||||
$3->runasgrouplist == NULL) &&
|
||||
(prev->runasuserlist != NULL ||
|
||||
prev->runasgrouplist != NULL)) {
|
||||
$3->runasuserlist = prev->runasuserlist;
|
||||
$3->runasgrouplist = prev->runasgrouplist;
|
||||
}
|
||||
$$ = $1;
|
||||
}
|
||||
@@ -339,12 +340,19 @@ cmndspeclist : cmndspec
|
||||
cmndspec : runasspec selinux solarisprivs cmndtag digcmnd {
|
||||
struct cmndspec *cs = ecalloc(1, sizeof(*cs));
|
||||
if ($1 != NULL) {
|
||||
list2tq(&cs->runasuserlist, $1->runasusers);
|
||||
list2tq(&cs->runasgrouplist, $1->runasgroups);
|
||||
if ($1->runasusers != NULL) {
|
||||
cs->runasuserlist =
|
||||
emalloc(sizeof(*cs->runasuserlist));
|
||||
HLTQ_TO_TAILQ(cs->runasuserlist,
|
||||
$1->runasusers, entries);
|
||||
}
|
||||
if ($1->runasgroups != NULL) {
|
||||
cs->runasgrouplist =
|
||||
emalloc(sizeof(*cs->runasgrouplist));
|
||||
HLTQ_TO_TAILQ(cs->runasgrouplist,
|
||||
$1->runasgroups, entries);
|
||||
}
|
||||
efree($1);
|
||||
} else {
|
||||
tq_init(&cs->runasuserlist);
|
||||
tq_init(&cs->runasgrouplist);
|
||||
}
|
||||
#ifdef HAVE_SELINUX
|
||||
cs->role = $2.role;
|
||||
@@ -356,8 +364,7 @@ cmndspec : runasspec selinux solarisprivs cmndtag digcmnd {
|
||||
#endif
|
||||
cs->tags = $4;
|
||||
cs->cmnd = $5;
|
||||
cs->prev = cs;
|
||||
cs->next = NULL;
|
||||
HLTQ_INIT(cs, entries);
|
||||
/* sudo "ALL" implies the SETENV tag */
|
||||
if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
|
||||
cs->tags.setenv == UNSPEC)
|
||||
@@ -564,7 +571,7 @@ hostalias : ALIAS '=' hostlist {
|
||||
|
||||
hostlist : ophost
|
||||
| hostlist ',' ophost {
|
||||
list_append($1, $3);
|
||||
HLTQ_CONCAT($1, $3, entries);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
@@ -584,7 +591,7 @@ cmndalias : ALIAS '=' cmndlist {
|
||||
|
||||
cmndlist : digcmnd
|
||||
| cmndlist ',' digcmnd {
|
||||
list_append($1, $3);
|
||||
HLTQ_CONCAT($1, $3, entries);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
@@ -617,7 +624,7 @@ useralias : ALIAS '=' userlist {
|
||||
|
||||
userlist : opuser
|
||||
| userlist ',' opuser {
|
||||
list_append($1, $3);
|
||||
HLTQ_CONCAT($1, $3, entries);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
@@ -651,7 +658,7 @@ user : ALIAS {
|
||||
|
||||
grouplist : opgroup
|
||||
| grouplist ',' opgroup {
|
||||
list_append($1, $3);
|
||||
HLTQ_CONCAT($1, $3, entries);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
@@ -719,11 +726,10 @@ new_default(char *var, char *val, int op)
|
||||
d = ecalloc(1, sizeof(struct defaults));
|
||||
d->var = var;
|
||||
d->val = val;
|
||||
tq_init(&d->binding);
|
||||
/* d->type = 0; */
|
||||
d->op = op;
|
||||
d->prev = d;
|
||||
/* d->next = NULL; */
|
||||
/* d->binding = NULL */
|
||||
HLTQ_INIT(d, entries);
|
||||
|
||||
debug_return_ptr(d);
|
||||
}
|
||||
@@ -737,8 +743,7 @@ new_member(char *name, int type)
|
||||
m = ecalloc(1, sizeof(struct member));
|
||||
m->name = name;
|
||||
m->type = type;
|
||||
m->prev = m;
|
||||
/* m->next = NULL; */
|
||||
HLTQ_INIT(m, entries);
|
||||
|
||||
debug_return_ptr(m);
|
||||
}
|
||||
@@ -765,30 +770,34 @@ static void
|
||||
add_defaults(int type, struct member *bmem, struct defaults *defs)
|
||||
{
|
||||
struct defaults *d;
|
||||
struct member_list binding;
|
||||
struct member_list *binding;
|
||||
debug_decl(add_defaults, SUDO_DEBUG_PARSER)
|
||||
|
||||
/*
|
||||
* We can only call list2tq once on bmem as it will zero
|
||||
* out the prev pointer when it consumes bmem.
|
||||
* We use a single binding for each entry in defs.
|
||||
*/
|
||||
list2tq(&binding, bmem);
|
||||
binding = emalloc(sizeof(*binding));
|
||||
if (bmem != NULL)
|
||||
HLTQ_TO_TAILQ(binding, bmem, entries);
|
||||
else
|
||||
TAILQ_INIT(binding);
|
||||
|
||||
/*
|
||||
* Set type and binding (who it applies to) for new entries.
|
||||
* Then add to the global defaults list.
|
||||
*/
|
||||
for (d = defs; d != NULL; d = d->next) {
|
||||
HLTQ_FOREACH(d, defs, entries) {
|
||||
d->type = type;
|
||||
d->binding = binding;
|
||||
}
|
||||
tq_append(&defaults, defs);
|
||||
TAILQ_CONCAT_HLTQ(&defaults, defs, entries);
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new struct userspec, populate it, and insert it at the
|
||||
* and of the userspecs list.
|
||||
* end of the userspecs list.
|
||||
*/
|
||||
static void
|
||||
add_userspec(struct member *members, struct privilege *privs)
|
||||
@@ -797,11 +806,9 @@ add_userspec(struct member *members, struct privilege *privs)
|
||||
debug_decl(add_userspec, SUDO_DEBUG_PARSER)
|
||||
|
||||
u = ecalloc(1, sizeof(*u));
|
||||
list2tq(&u->users, members);
|
||||
list2tq(&u->privileges, privs);
|
||||
u->prev = u;
|
||||
/* u->next = NULL; */
|
||||
tq_append(&userspecs, u);
|
||||
HLTQ_TO_TAILQ(&u->users, members, entries);
|
||||
HLTQ_TO_TAILQ(&u->privileges, privs, entries);
|
||||
TAILQ_INSERT_TAIL(&userspecs, u, entries);
|
||||
|
||||
debug_return;
|
||||
}
|
||||
@@ -813,21 +820,24 @@ add_userspec(struct member *members, struct privilege *privs)
|
||||
void
|
||||
init_parser(const char *path, bool quiet)
|
||||
{
|
||||
struct member_list *binding;
|
||||
struct member *m;
|
||||
struct defaults *d;
|
||||
struct member *m, *binding;
|
||||
struct userspec *us;
|
||||
struct privilege *priv;
|
||||
struct cmndspec *cs;
|
||||
struct sudo_command *c;
|
||||
debug_decl(init_parser, SUDO_DEBUG_PARSER)
|
||||
|
||||
while ((us = tq_pop(&userspecs)) != NULL) {
|
||||
while ((m = tq_pop(&us->users)) != NULL) {
|
||||
while ((us = TAILQ_FIRST(&userspecs)) != NULL) {
|
||||
TAILQ_REMOVE(&userspecs, us, entries);
|
||||
while ((m = TAILQ_FIRST(&us->users)) != NULL) {
|
||||
TAILQ_REMOVE(&us->users, m, entries);
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
while ((priv = tq_pop(&us->privileges)) != NULL) {
|
||||
struct member *runasuser = NULL, *runasgroup = NULL;
|
||||
while ((priv = TAILQ_FIRST(&us->privileges)) != NULL) {
|
||||
struct member_list *runasuserlist = NULL, *runasgrouplist = NULL;
|
||||
#ifdef HAVE_SELINUX
|
||||
char *role = NULL, *type = NULL;
|
||||
#endif /* HAVE_SELINUX */
|
||||
@@ -835,11 +845,14 @@ init_parser(const char *path, bool quiet)
|
||||
char *privs = NULL, *limitprivs = NULL;
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
|
||||
while ((m = tq_pop(&priv->hostlist)) != NULL) {
|
||||
TAILQ_REMOVE(&us->privileges, priv, entries);
|
||||
while ((m = TAILQ_FIRST(&priv->hostlist)) != NULL) {
|
||||
TAILQ_REMOVE(&priv->hostlist, m, entries);
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
while ((cs = tq_pop(&priv->cmndlist)) != NULL) {
|
||||
while ((cs = TAILQ_FIRST(&priv->cmndlist)) != NULL) {
|
||||
TAILQ_REMOVE(&priv->cmndlist, cs, entries);
|
||||
#ifdef HAVE_SELINUX
|
||||
/* Only free the first instance of a role/type. */
|
||||
if (cs->role != role) {
|
||||
@@ -862,19 +875,24 @@ init_parser(const char *path, bool quiet)
|
||||
efree(cs->limitprivs);
|
||||
}
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
if (tq_last(&cs->runasuserlist) != runasuser) {
|
||||
runasuser = tq_last(&cs->runasuserlist);
|
||||
while ((m = tq_pop(&cs->runasuserlist)) != NULL) {
|
||||
/* Only free the first instance of runas user/group lists. */
|
||||
if (cs->runasuserlist && cs->runasuserlist != runasuserlist) {
|
||||
runasuserlist = cs->runasuserlist;
|
||||
while ((m = TAILQ_FIRST(runasuserlist)) != NULL) {
|
||||
TAILQ_REMOVE(runasuserlist, m, entries);
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
efree(runasuserlist);
|
||||
}
|
||||
if (tq_last(&cs->runasgrouplist) != runasgroup) {
|
||||
runasgroup = tq_last(&cs->runasgrouplist);
|
||||
while ((m = tq_pop(&cs->runasgrouplist)) != NULL) {
|
||||
if (cs->runasgrouplist && cs->runasgrouplist != runasgrouplist) {
|
||||
runasgrouplist = cs->runasgrouplist;
|
||||
while ((m = TAILQ_FIRST(runasgrouplist)) != NULL) {
|
||||
TAILQ_REMOVE(runasgrouplist, m, entries);
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
efree(runasgrouplist);
|
||||
}
|
||||
if (cs->cmnd->type == COMMAND) {
|
||||
c = (struct sudo_command *) cs->cmnd->name;
|
||||
@@ -889,13 +907,15 @@ init_parser(const char *path, bool quiet)
|
||||
}
|
||||
efree(us);
|
||||
}
|
||||
tq_init(&userspecs);
|
||||
TAILQ_INIT(&userspecs);
|
||||
|
||||
binding = NULL;
|
||||
while ((d = tq_pop(&defaults)) != NULL) {
|
||||
if (tq_last(&d->binding) != binding) {
|
||||
binding = tq_last(&d->binding);
|
||||
while ((m = tq_pop(&d->binding)) != NULL) {
|
||||
while ((d = TAILQ_FIRST(&defaults)) != NULL) {
|
||||
TAILQ_REMOVE(&defaults, d, entries);
|
||||
if (d->binding != binding) {
|
||||
binding = d->binding;
|
||||
while ((m = TAILQ_FIRST(d->binding)) != NULL) {
|
||||
TAILQ_REMOVE(d->binding, m, entries);
|
||||
if (m->type == COMMAND) {
|
||||
c = (struct sudo_command *) m->name;
|
||||
efree(c->cmnd);
|
||||
@@ -904,12 +924,13 @@ init_parser(const char *path, bool quiet)
|
||||
efree(m->name);
|
||||
efree(m);
|
||||
}
|
||||
efree(d->binding);
|
||||
}
|
||||
efree(d->var);
|
||||
efree(d->val);
|
||||
efree(d);
|
||||
}
|
||||
tq_init(&defaults);
|
||||
TAILQ_INIT(&defaults);
|
||||
|
||||
init_aliases();
|
||||
|
||||
|
@@ -91,7 +91,7 @@
|
||||
#include "sha2.h"
|
||||
#include <gram.h>
|
||||
|
||||
static struct member_list empty;
|
||||
static struct member_list empty = TAILQ_HEAD_INITIALIZER(empty);
|
||||
|
||||
static bool command_matches_dir(char *, size_t);
|
||||
#ifndef SUDOERS_NAME_MATCH
|
||||
@@ -117,7 +117,7 @@ userlist_matches(struct passwd *pw, struct member_list *list)
|
||||
int rval, matched = UNSPEC;
|
||||
debug_decl(userlist_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
tq_foreach_rev(list, m) {
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
matched = !m->negated;
|
||||
@@ -169,46 +169,48 @@ runaslist_matches(struct member_list *user_list,
|
||||
|
||||
if (runas_pw != NULL) {
|
||||
/* If no runas user or runas group listed in sudoers, use default. */
|
||||
if (tq_empty(user_list) && tq_empty(group_list))
|
||||
if (user_list == NULL && group_list == NULL)
|
||||
debug_return_int(userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw));
|
||||
|
||||
tq_foreach_rev(user_list, m) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name, NULL, NULL, runas_pw->pw_name))
|
||||
if (user_list != NULL) {
|
||||
TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case USERGROUP:
|
||||
if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
|
||||
rval = runaslist_matches(&a->members, &empty,
|
||||
matching_user, NULL);
|
||||
if (rval != UNSPEC)
|
||||
user_matched = m->negated ? !rval : rval;
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
|
||||
user_matched = !m->negated;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name, NULL, NULL, runas_pw->pw_name))
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case USERGROUP:
|
||||
if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
|
||||
rval = runaslist_matches(&a->members, &empty,
|
||||
matching_user, NULL);
|
||||
if (rval != UNSPEC)
|
||||
user_matched = m->negated ? !rval : rval;
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case MYSELF:
|
||||
if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) ||
|
||||
strcmp(user_name, runas_pw->pw_name) == 0)
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
}
|
||||
if (user_matched != UNSPEC) {
|
||||
if (matching_user != NULL && m->type != ALIAS)
|
||||
*matching_user = m;
|
||||
break;
|
||||
case MYSELF:
|
||||
if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) ||
|
||||
strcmp(user_name, runas_pw->pw_name) == 0)
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
}
|
||||
if (user_matched != UNSPEC) {
|
||||
if (matching_user != NULL && m->type != ALIAS)
|
||||
*matching_user = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,30 +220,32 @@ runaslist_matches(struct member_list *user_list,
|
||||
if (runas_pw == NULL || strcmp(runas_pw->pw_name, user_name) == 0)
|
||||
user_matched = ALLOW; /* only changing group */
|
||||
}
|
||||
tq_foreach_rev(group_list, m) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
group_matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
|
||||
rval = runaslist_matches(&empty, &a->members,
|
||||
NULL, matching_group);
|
||||
if (rval != UNSPEC)
|
||||
group_matched = m->negated ? !rval : rval;
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (group_matches(m->name, runas_gr))
|
||||
if (group_list != NULL) {
|
||||
TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
group_matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
|
||||
rval = runaslist_matches(&empty, &a->members,
|
||||
NULL, matching_group);
|
||||
if (rval != UNSPEC)
|
||||
group_matched = m->negated ? !rval : rval;
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (group_matches(m->name, runas_gr))
|
||||
group_matched = !m->negated;
|
||||
break;
|
||||
}
|
||||
if (group_matched != UNSPEC) {
|
||||
if (matching_group != NULL && m->type != ALIAS)
|
||||
*matching_group = m;
|
||||
break;
|
||||
}
|
||||
if (group_matched != UNSPEC) {
|
||||
if (matching_group != NULL && m->type != ALIAS)
|
||||
*matching_group = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (group_matched == UNSPEC) {
|
||||
@@ -269,7 +273,7 @@ hostlist_matches(struct member_list *list)
|
||||
int rval, matched = UNSPEC;
|
||||
debug_decl(hostlist_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
tq_foreach_rev(list, m) {
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
matched = !m->negated;
|
||||
@@ -313,7 +317,7 @@ cmndlist_matches(struct member_list *list)
|
||||
int matched = UNSPEC;
|
||||
debug_decl(cmndlist_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
tq_foreach_rev(list, m) {
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
matched = cmnd_matches(m);
|
||||
if (matched != UNSPEC)
|
||||
break;
|
||||
|
@@ -181,13 +181,13 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
|
||||
CLR(validated, FLAG_NO_USER);
|
||||
CLR(validated, FLAG_NO_HOST);
|
||||
match = DENY;
|
||||
tq_foreach_fwd(&userspecs, us) {
|
||||
TAILQ_FOREACH(us, &userspecs, entries) {
|
||||
if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
|
||||
continue;
|
||||
tq_foreach_fwd(&us->privileges, priv) {
|
||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||
if (hostlist_matches(&priv->hostlist) != ALLOW)
|
||||
continue;
|
||||
tq_foreach_fwd(&priv->cmndlist, cs) {
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
/* Only check the command when listing another user. */
|
||||
if (user_uid == 0 || list_pw == NULL ||
|
||||
user_uid == list_pw->pw_uid ||
|
||||
@@ -215,20 +215,20 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
|
||||
set_perms(PERM_RUNAS);
|
||||
|
||||
match = UNSPEC;
|
||||
tq_foreach_rev(&userspecs, us) {
|
||||
TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) {
|
||||
if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
|
||||
continue;
|
||||
CLR(validated, FLAG_NO_USER);
|
||||
tq_foreach_rev(&us->privileges, priv) {
|
||||
TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
|
||||
host_match = hostlist_matches(&priv->hostlist);
|
||||
if (host_match == ALLOW)
|
||||
CLR(validated, FLAG_NO_HOST);
|
||||
else
|
||||
continue;
|
||||
tq_foreach_rev(&priv->cmndlist, cs) {
|
||||
TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
|
||||
matching_user = NULL;
|
||||
runas_match = runaslist_matches(&cs->runasuserlist,
|
||||
&cs->runasgrouplist, &matching_user, NULL);
|
||||
runas_match = runaslist_matches(cs->runasuserlist,
|
||||
cs->runasgrouplist, &matching_user, NULL);
|
||||
if (runas_match == ALLOW) {
|
||||
cmnd_match = cmnd_matches(cs->cmnd);
|
||||
if (cmnd_match != UNSPEC) {
|
||||
@@ -340,10 +340,8 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
|
||||
|
||||
#define RUNAS_CHANGED(cs1, cs2) \
|
||||
(cs1 == NULL || cs2 == NULL || \
|
||||
cs1->runasuserlist.first != cs2->runasuserlist.first || \
|
||||
cs1->runasuserlist.last != cs2->runasuserlist.last || \
|
||||
cs1->runasgrouplist.first != cs2->runasgrouplist.first || \
|
||||
cs1->runasgrouplist.last != cs2->runasgrouplist.last)
|
||||
cs1->runasuserlist != cs2->runasuserlist || \
|
||||
cs1->runasgrouplist != cs2->runasgrouplist)
|
||||
|
||||
static int
|
||||
sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
|
||||
@@ -362,30 +360,30 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
|
||||
tags.nopasswd = UNSPEC;
|
||||
tags.log_input = UNSPEC;
|
||||
tags.log_output = UNSPEC;
|
||||
tq_foreach_fwd(&us->privileges, priv) {
|
||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||
if (hostlist_matches(&priv->hostlist) != ALLOW)
|
||||
continue;
|
||||
prev_cs = NULL;
|
||||
tq_foreach_fwd(&priv->cmndlist, cs) {
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
if (RUNAS_CHANGED(cs, prev_cs)) {
|
||||
if (cs != tq_first(&priv->cmndlist))
|
||||
if (cs != TAILQ_FIRST(&priv->cmndlist))
|
||||
lbuf_append(lbuf, "\n");
|
||||
lbuf_append(lbuf, " (");
|
||||
if (!tq_empty(&cs->runasuserlist)) {
|
||||
tq_foreach_fwd(&cs->runasuserlist, m) {
|
||||
if (m != tq_first(&cs->runasuserlist))
|
||||
if (cs->runasuserlist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
||||
if (m != TAILQ_FIRST(cs->runasuserlist))
|
||||
lbuf_append(lbuf, ", ");
|
||||
print_member(lbuf, m, RUNASALIAS);
|
||||
}
|
||||
} else if (tq_empty(&cs->runasgrouplist)) {
|
||||
} else if (cs->runasgrouplist == NULL) {
|
||||
lbuf_append(lbuf, "%s", def_runas_default);
|
||||
} else {
|
||||
lbuf_append(lbuf, "%s", pw->pw_name);
|
||||
}
|
||||
if (!tq_empty(&cs->runasgrouplist)) {
|
||||
if (cs->runasgrouplist != NULL) {
|
||||
lbuf_append(lbuf, " : ");
|
||||
tq_foreach_fwd(&cs->runasgrouplist, m) {
|
||||
if (m != tq_first(&cs->runasgrouplist))
|
||||
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
||||
if (m != TAILQ_FIRST(cs->runasgrouplist))
|
||||
lbuf_append(lbuf, ", ");
|
||||
print_member(lbuf, m, RUNASALIAS);
|
||||
}
|
||||
@@ -396,7 +394,7 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
|
||||
tags.nopasswd = UNSPEC;
|
||||
tags.log_input = UNSPEC;
|
||||
tags.log_output = UNSPEC;
|
||||
} else if (cs != tq_first(&priv->cmndlist)) {
|
||||
} else if (cs != TAILQ_FIRST(&priv->cmndlist)) {
|
||||
lbuf_append(lbuf, ", ");
|
||||
}
|
||||
sudo_file_append_cmnd(cs, &tags, lbuf);
|
||||
@@ -452,30 +450,30 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
|
||||
int nfound = 0, olen;
|
||||
debug_decl(sudo_file_display_priv_long, SUDO_DEBUG_NSS)
|
||||
|
||||
tq_foreach_fwd(&us->privileges, priv) {
|
||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||
if (hostlist_matches(&priv->hostlist) != ALLOW)
|
||||
continue;
|
||||
prev_cs = NULL;
|
||||
tq_foreach_fwd(&priv->cmndlist, cs) {
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
if (new_long_entry(cs, prev_cs)) {
|
||||
lbuf_append(lbuf, _("\nSudoers entry:\n"));
|
||||
lbuf_append(lbuf, _(" RunAsUsers: "));
|
||||
if (!tq_empty(&cs->runasuserlist)) {
|
||||
tq_foreach_fwd(&cs->runasuserlist, m) {
|
||||
if (m != tq_first(&cs->runasuserlist))
|
||||
if (cs->runasuserlist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
||||
if (m != TAILQ_FIRST(cs->runasuserlist))
|
||||
lbuf_append(lbuf, ", ");
|
||||
print_member(lbuf, m, RUNASALIAS);
|
||||
}
|
||||
} else if (tq_empty(&cs->runasgrouplist)) {
|
||||
} else if (cs->runasgrouplist == NULL) {
|
||||
lbuf_append(lbuf, "%s", def_runas_default);
|
||||
} else {
|
||||
lbuf_append(lbuf, "%s", pw->pw_name);
|
||||
}
|
||||
lbuf_append(lbuf, "\n");
|
||||
if (!tq_empty(&cs->runasgrouplist)) {
|
||||
if (cs->runasgrouplist != NULL) {
|
||||
lbuf_append(lbuf, _(" RunAsGroups: "));
|
||||
tq_foreach_fwd(&cs->runasgrouplist, m) {
|
||||
if (m != tq_first(&cs->runasgrouplist))
|
||||
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
||||
if (m != TAILQ_FIRST(cs->runasgrouplist))
|
||||
lbuf_append(lbuf, ", ");
|
||||
print_member(lbuf, m, RUNASALIAS);
|
||||
}
|
||||
@@ -534,7 +532,7 @@ sudo_file_display_privs(struct sudo_nss *nss, struct passwd *pw,
|
||||
if (nss->handle == NULL)
|
||||
goto done;
|
||||
|
||||
tq_foreach_fwd(&userspecs, us) {
|
||||
TAILQ_FOREACH(us, &userspecs, entries) {
|
||||
if (userlist_matches(pw, &us->users) != ALLOW)
|
||||
continue;
|
||||
|
||||
@@ -567,14 +565,14 @@ sudo_file_display_defaults(struct sudo_nss *nss, struct passwd *pw,
|
||||
else
|
||||
prefix = ", ";
|
||||
|
||||
tq_foreach_fwd(&defaults, d) {
|
||||
TAILQ_FOREACH(d, &defaults, entries) {
|
||||
switch (d->type) {
|
||||
case DEFAULTS_HOST:
|
||||
if (hostlist_matches(&d->binding) != ALLOW)
|
||||
if (hostlist_matches(d->binding) != ALLOW)
|
||||
continue;
|
||||
break;
|
||||
case DEFAULTS_USER:
|
||||
if (userlist_matches(pw, &d->binding) != ALLOW)
|
||||
if (userlist_matches(pw, d->binding) != ALLOW)
|
||||
continue;
|
||||
break;
|
||||
case DEFAULTS_RUNAS:
|
||||
@@ -624,7 +622,8 @@ static int
|
||||
display_bound_defaults(int dtype, struct lbuf *lbuf)
|
||||
{
|
||||
struct defaults *d;
|
||||
struct member *m, *binding = NULL;
|
||||
struct member_list *binding = NULL;
|
||||
struct member *m;
|
||||
char *dsep;
|
||||
int atype, nfound = 0;
|
||||
debug_decl(display_bound_defaults, SUDO_DEBUG_NSS)
|
||||
@@ -649,18 +648,18 @@ display_bound_defaults(int dtype, struct lbuf *lbuf)
|
||||
default:
|
||||
debug_return_int(-1);
|
||||
}
|
||||
tq_foreach_fwd(&defaults, d) {
|
||||
TAILQ_FOREACH(d, &defaults, entries) {
|
||||
if (d->type != dtype)
|
||||
continue;
|
||||
|
||||
nfound++;
|
||||
if (binding != tq_first(&d->binding)) {
|
||||
binding = tq_first(&d->binding);
|
||||
if (binding != d->binding) {
|
||||
binding = d->binding;
|
||||
if (nfound != 1)
|
||||
lbuf_append(lbuf, "\n");
|
||||
lbuf_append(lbuf, " Defaults%s", dsep);
|
||||
for (m = binding; m != NULL; m = m->next) {
|
||||
if (m != binding)
|
||||
TAILQ_FOREACH(m, binding, entries) {
|
||||
if (m != TAILQ_FIRST(binding))
|
||||
lbuf_append(lbuf, ",");
|
||||
print_member(lbuf, m, atype);
|
||||
lbuf_append(lbuf, " ");
|
||||
@@ -692,17 +691,17 @@ sudo_file_display_cmnd(struct sudo_nss *nss, struct passwd *pw)
|
||||
goto done;
|
||||
|
||||
match = NULL;
|
||||
tq_foreach_rev(&userspecs, us) {
|
||||
TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) {
|
||||
if (userlist_matches(pw, &us->users) != ALLOW)
|
||||
continue;
|
||||
|
||||
tq_foreach_rev(&us->privileges, priv) {
|
||||
TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
|
||||
host_match = hostlist_matches(&priv->hostlist);
|
||||
if (host_match != ALLOW)
|
||||
continue;
|
||||
tq_foreach_rev(&priv->cmndlist, cs) {
|
||||
runas_match = runaslist_matches(&cs->runasuserlist,
|
||||
&cs->runasgrouplist, NULL, NULL);
|
||||
TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
|
||||
runas_match = runaslist_matches(cs->runasuserlist,
|
||||
cs->runasgrouplist, NULL, NULL);
|
||||
if (runas_match == ALLOW) {
|
||||
cmnd_match = cmnd_matches(cs->cmnd);
|
||||
if (cmnd_match != UNSPEC) {
|
||||
@@ -754,8 +753,8 @@ _print_member(struct lbuf *lbuf, char *name, int type, int negated,
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(name, alias_type)) != NULL) {
|
||||
tq_foreach_fwd(&a->members, m) {
|
||||
if (m != tq_first(&a->members))
|
||||
TAILQ_FOREACH(m, &a->members, entries) {
|
||||
if (m != TAILQ_FIRST(&a->members))
|
||||
lbuf_append(lbuf, "%s", separator);
|
||||
_print_member(lbuf, m->name, m->type,
|
||||
negated ? !m->negated : m->negated, separator,
|
||||
|
@@ -18,8 +18,6 @@
|
||||
#ifndef _SUDOERS_PARSE_H
|
||||
#define _SUDOERS_PARSE_H
|
||||
|
||||
#include "list.h" /* XXX */
|
||||
|
||||
#undef UNSPEC
|
||||
#define UNSPEC -1
|
||||
#undef DENY
|
||||
@@ -86,31 +84,30 @@ struct solaris_privs_info {
|
||||
* modelled after the yacc grammar.
|
||||
*
|
||||
* Other than the alias struct, which is stored in a red-black tree,
|
||||
* the data structure used is basically a doubly-linked tail queue without
|
||||
* a separate head struct--the first entry acts as the head where the prev
|
||||
* pointer does double duty as the tail pointer. This makes it possible
|
||||
* to trivally append sub-lists. In addition, the prev pointer is always
|
||||
* valid (even if it points to itself). Unlike a circle queue, the next
|
||||
* pointer of the last entry is NULL and does not point back to the head.
|
||||
*
|
||||
* Note that each list struct must contain a "prev" and "next" pointer as
|
||||
* the first two members of the struct (in that order).
|
||||
* the data structure used is a doubly-linked tail queue. While sudoers
|
||||
* is being parsed, a headless tail queue is used where the first entry
|
||||
* acts as the head and the prev pointer does double duty as the tail pointer.
|
||||
* This makes it possible to trivally append sub-lists. In addition, the prev
|
||||
* pointer is always valid (even if it points to itself). Unlike a circle
|
||||
* queue, the next pointer of the last entry is NULL and does not point back
|
||||
* to the head. When the tail queue is finalized, it is converted to a
|
||||
* normal BSD tail queue.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Tail queue list head structure.
|
||||
*/
|
||||
TQ_DECLARE(defaults)
|
||||
TQ_DECLARE(userspec)
|
||||
TQ_DECLARE(member)
|
||||
TQ_DECLARE(privilege)
|
||||
TQ_DECLARE(cmndspec)
|
||||
TAILQ_HEAD(defaults_list, defaults);
|
||||
TAILQ_HEAD(userspec_list, userspec);
|
||||
TAILQ_HEAD(member_list, member);
|
||||
TAILQ_HEAD(privilege_list, privilege);
|
||||
TAILQ_HEAD(cmndspec_list, cmndspec);
|
||||
|
||||
/*
|
||||
* Structure describing a user specification and list thereof.
|
||||
*/
|
||||
struct userspec {
|
||||
struct userspec *prev, *next;
|
||||
TAILQ_ENTRY(userspec) entries;
|
||||
struct member_list users; /* list of users */
|
||||
struct privilege_list privileges; /* list of privileges */
|
||||
};
|
||||
@@ -119,7 +116,7 @@ struct userspec {
|
||||
* Structure describing a privilege specification.
|
||||
*/
|
||||
struct privilege {
|
||||
struct privilege *prev, *next;
|
||||
TAILQ_ENTRY(privilege) entries;
|
||||
struct member_list hostlist; /* list of hosts */
|
||||
struct cmndspec_list cmndlist; /* list of Cmnd_Specs */
|
||||
};
|
||||
@@ -128,9 +125,9 @@ struct privilege {
|
||||
* Structure describing a linked list of Cmnd_Specs.
|
||||
*/
|
||||
struct cmndspec {
|
||||
struct cmndspec *prev, *next;
|
||||
struct member_list runasuserlist; /* list of runas users */
|
||||
struct member_list runasgrouplist; /* list of runas groups */
|
||||
TAILQ_ENTRY(cmndspec) entries;
|
||||
struct member_list *runasuserlist; /* list of runas users */
|
||||
struct member_list *runasgrouplist; /* list of runas groups */
|
||||
struct member *cmnd; /* command to allow/deny */
|
||||
char *digest; /* optional command digest */
|
||||
struct cmndtag tags; /* tag specificaion */
|
||||
@@ -146,7 +143,7 @@ struct cmndspec {
|
||||
* Generic structure to hold users, hosts, commands.
|
||||
*/
|
||||
struct member {
|
||||
struct member *prev, *next;
|
||||
TAILQ_ENTRY(member) entries;
|
||||
char *name; /* member name */
|
||||
short type; /* type (see gram.h) */
|
||||
short negated; /* negated via '!'? */
|
||||
@@ -172,10 +169,10 @@ struct alias {
|
||||
* Structure describing a Defaults entry and a list thereof.
|
||||
*/
|
||||
struct defaults {
|
||||
struct defaults *prev, *next;
|
||||
TAILQ_ENTRY(defaults) entries;
|
||||
char *var; /* variable name */
|
||||
char *val; /* variable value */
|
||||
struct member_list binding; /* user/host/runas binding */
|
||||
struct member_list *binding; /* user/host/runas binding */
|
||||
int type; /* DEFAULTS{,_USER,_RUNAS,_HOST} */
|
||||
int op; /* true, false, '+', '-' */
|
||||
};
|
||||
|
@@ -43,7 +43,7 @@
|
||||
#define SUDO_ERROR_WRAP 0
|
||||
|
||||
#include "missing.h"
|
||||
#include "list.h"
|
||||
#include "queue.h"
|
||||
#include "parse.h"
|
||||
#include "toke.h"
|
||||
#include "sudo_plugin.h"
|
||||
|
@@ -304,19 +304,19 @@ main(int argc, char *argv[])
|
||||
/* This loop must match the one in sudo_file_lookup() */
|
||||
printf("\nEntries for user %s:\n", user_name);
|
||||
match = UNSPEC;
|
||||
tq_foreach_rev(&userspecs, us) {
|
||||
TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) {
|
||||
if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
|
||||
continue;
|
||||
tq_foreach_rev(&us->privileges, priv) {
|
||||
TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
|
||||
putchar('\n');
|
||||
print_privilege(priv); /* XXX */
|
||||
print_privilege(priv);
|
||||
putchar('\n');
|
||||
host_match = hostlist_matches(&priv->hostlist);
|
||||
if (host_match == ALLOW) {
|
||||
puts("\thost matched");
|
||||
tq_foreach_rev(&priv->cmndlist, cs) {
|
||||
runas_match = runaslist_matches(&cs->runasuserlist,
|
||||
&cs->runasgrouplist, NULL, NULL);
|
||||
TAILQ_FOREACH_REVERSE(cs, &priv->cmndlist, cmndspec_list, entries) {
|
||||
runas_match = runaslist_matches(cs->runasuserlist,
|
||||
cs->runasgrouplist, NULL, NULL);
|
||||
if (runas_match == ALLOW) {
|
||||
puts("\trunas matched");
|
||||
cmnd_match = cmnd_matches(cs->cmnd);
|
||||
@@ -342,6 +342,8 @@ main(int argc, char *argv[])
|
||||
*/
|
||||
exitcode = parse_error ? 1 : (match == ALLOW ? 0 : match + 3);
|
||||
done:
|
||||
sudo_endpwent();
|
||||
sudo_endgrent();
|
||||
sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode);
|
||||
exit(exitcode);
|
||||
}
|
||||
@@ -492,7 +494,7 @@ print_defaults(void)
|
||||
struct member *m;
|
||||
debug_decl(print_member, SUDO_DEBUG_UTIL)
|
||||
|
||||
tq_foreach_fwd(&defaults, d) {
|
||||
TAILQ_FOREACH(d, &defaults, entries) {
|
||||
(void) fputs("Defaults", stdout);
|
||||
switch (d->type) {
|
||||
case DEFAULTS_HOST:
|
||||
@@ -508,8 +510,8 @@ print_defaults(void)
|
||||
putchar('!');
|
||||
break;
|
||||
}
|
||||
tq_foreach_fwd(&d->binding, m) {
|
||||
if (m != tq_first(&d->binding))
|
||||
TAILQ_FOREACH(m, d->binding, entries) {
|
||||
if (m != TAILQ_FIRST(d->binding))
|
||||
putchar(',');
|
||||
print_member(m);
|
||||
}
|
||||
@@ -545,8 +547,8 @@ print_alias(void *v1, void *v2)
|
||||
(void) printf("Runas_Alias\t%s = ", a->name);
|
||||
break;
|
||||
}
|
||||
tq_foreach_fwd(&a->members, m) {
|
||||
if (m != tq_first(&a->members))
|
||||
TAILQ_FOREACH(m, &a->members, entries) {
|
||||
if (m != TAILQ_FIRST(&a->members))
|
||||
fputs(", ", stdout);
|
||||
if (m->type == COMMAND) {
|
||||
c = (struct sudo_command *) m->name;
|
||||
@@ -567,66 +569,61 @@ print_privilege(struct privilege *priv)
|
||||
{
|
||||
struct cmndspec *cs;
|
||||
struct member *m;
|
||||
struct privilege *p;
|
||||
struct cmndtag tags;
|
||||
debug_decl(print_privilege, SUDO_DEBUG_UTIL)
|
||||
|
||||
for (p = priv; p != NULL; p = p->next) {
|
||||
if (p != priv)
|
||||
fputs(" : ", stdout);
|
||||
tq_foreach_fwd(&p->hostlist, m) {
|
||||
if (m != tq_first(&p->hostlist))
|
||||
fputs(", ", stdout);
|
||||
print_member(m);
|
||||
}
|
||||
fputs(" = ", stdout);
|
||||
tags.nopasswd = UNSPEC;
|
||||
tags.noexec = UNSPEC;
|
||||
tq_foreach_fwd(&p->cmndlist, cs) {
|
||||
if (cs != tq_first(&p->cmndlist))
|
||||
fputs(", ", stdout);
|
||||
if (!tq_empty(&cs->runasuserlist) || !tq_empty(&cs->runasgrouplist)) {
|
||||
fputs("(", stdout);
|
||||
if (!tq_empty(&cs->runasuserlist)) {
|
||||
tq_foreach_fwd(&cs->runasuserlist, m) {
|
||||
if (m != tq_first(&cs->runasuserlist))
|
||||
fputs(", ", stdout);
|
||||
print_member(m);
|
||||
}
|
||||
} else if (tq_empty(&cs->runasgrouplist)) {
|
||||
fputs(def_runas_default, stdout);
|
||||
} else {
|
||||
fputs(sudo_user.pw->pw_name, stdout);
|
||||
TAILQ_FOREACH(m, &priv->hostlist, entries) {
|
||||
if (m != TAILQ_FIRST(&priv->hostlist))
|
||||
fputs(", ", stdout);
|
||||
print_member(m);
|
||||
}
|
||||
fputs(" = ", stdout);
|
||||
tags.nopasswd = UNSPEC;
|
||||
tags.noexec = UNSPEC;
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
if (cs != TAILQ_FIRST(&priv->cmndlist))
|
||||
fputs(", ", stdout);
|
||||
if (cs->runasuserlist != NULL || cs->runasgrouplist != NULL) {
|
||||
fputs("(", stdout);
|
||||
if (cs->runasuserlist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
||||
if (m != TAILQ_FIRST(cs->runasuserlist))
|
||||
fputs(", ", stdout);
|
||||
print_member(m);
|
||||
}
|
||||
if (!tq_empty(&cs->runasgrouplist)) {
|
||||
fputs(" : ", stdout);
|
||||
tq_foreach_fwd(&cs->runasgrouplist, m) {
|
||||
if (m != tq_first(&cs->runasgrouplist))
|
||||
fputs(", ", stdout);
|
||||
print_member(m);
|
||||
}
|
||||
}
|
||||
fputs(") ", stdout);
|
||||
} else if (cs->runasgrouplist == NULL) {
|
||||
fputs(def_runas_default, stdout);
|
||||
} else {
|
||||
fputs(sudo_user.pw->pw_name, stdout);
|
||||
}
|
||||
if (cs->runasgrouplist != NULL) {
|
||||
fputs(" : ", stdout);
|
||||
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
||||
if (m != TAILQ_FIRST(cs->runasgrouplist))
|
||||
fputs(", ", stdout);
|
||||
print_member(m);
|
||||
}
|
||||
}
|
||||
fputs(") ", stdout);
|
||||
}
|
||||
#ifdef HAVE_SELINUX
|
||||
if (cs->role)
|
||||
printf("ROLE=%s ", cs->role);
|
||||
if (cs->type)
|
||||
printf("TYPE=%s ", cs->type);
|
||||
if (cs->role)
|
||||
printf("ROLE=%s ", cs->role);
|
||||
if (cs->type)
|
||||
printf("TYPE=%s ", cs->type);
|
||||
#endif /* HAVE_SELINUX */
|
||||
#ifdef HAVE_PRIV_SET
|
||||
if (cs->privs)
|
||||
printf("PRIVS=%s ", cs->privs);
|
||||
if (cs->limitprivs)
|
||||
printf("LIMITPRIVS=%s ", cs->limitprivs);
|
||||
if (cs->privs)
|
||||
printf("PRIVS=%s ", cs->privs);
|
||||
if (cs->limitprivs)
|
||||
printf("LIMITPRIVS=%s ", cs->limitprivs);
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != tags.nopasswd)
|
||||
printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : "");
|
||||
if (cs->tags.noexec != UNSPEC && cs->tags.noexec != tags.noexec)
|
||||
printf("%sEXEC: ", cs->tags.noexec ? "NO" : "");
|
||||
print_member(cs->cmnd);
|
||||
memcpy(&tags, &cs->tags, sizeof(tags));
|
||||
}
|
||||
if (cs->tags.nopasswd != UNSPEC && cs->tags.nopasswd != tags.nopasswd)
|
||||
printf("%sPASSWD: ", cs->tags.nopasswd ? "NO" : "");
|
||||
if (cs->tags.noexec != UNSPEC && cs->tags.noexec != tags.noexec)
|
||||
printf("%sEXEC: ", cs->tags.noexec ? "NO" : "");
|
||||
print_member(cs->cmnd);
|
||||
memcpy(&tags, &cs->tags, sizeof(tags));
|
||||
}
|
||||
debug_return;
|
||||
}
|
||||
@@ -636,16 +633,21 @@ print_userspecs(void)
|
||||
{
|
||||
struct member *m;
|
||||
struct userspec *us;
|
||||
struct privilege *priv;
|
||||
debug_decl(print_userspecs, SUDO_DEBUG_UTIL)
|
||||
|
||||
tq_foreach_fwd(&userspecs, us) {
|
||||
tq_foreach_fwd(&us->users, m) {
|
||||
if (m != tq_first(&us->users))
|
||||
TAILQ_FOREACH(us, &userspecs, entries) {
|
||||
TAILQ_FOREACH(m, &us->users, entries) {
|
||||
if (m != TAILQ_FIRST(&us->users))
|
||||
fputs(", ", stdout);
|
||||
print_member(m);
|
||||
}
|
||||
putchar('\t');
|
||||
print_privilege(us->privileges.first); /* XXX */
|
||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||
if (priv != TAILQ_FIRST(&us->privileges))
|
||||
fputs(" : ", stdout);
|
||||
print_privilege(priv);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
debug_return;
|
||||
|
@@ -1085,7 +1085,7 @@ alias_remove_recursive(char *name, int type)
|
||||
debug_decl(alias_remove_recursive, SUDO_DEBUG_ALIAS)
|
||||
|
||||
if ((a = alias_remove(name, type)) != NULL) {
|
||||
tq_foreach_fwd(&a->members, m) {
|
||||
TAILQ_FOREACH(m, &a->members, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, type))
|
||||
rval = false;
|
||||
@@ -1106,7 +1106,7 @@ check_alias(char *name, int type, int strict, int quiet)
|
||||
|
||||
if ((a = alias_get(name, type)) != NULL) {
|
||||
/* check alias contents */
|
||||
tq_foreach_fwd(&a->members, m) {
|
||||
TAILQ_FOREACH(m, &a->members, entries) {
|
||||
if (m->type == ALIAS)
|
||||
errors += check_alias(m->name, type, strict, quiet);
|
||||
}
|
||||
@@ -1143,7 +1143,7 @@ static int
|
||||
check_aliases(bool strict, bool quiet)
|
||||
{
|
||||
struct cmndspec *cs;
|
||||
struct member *m, *binding;
|
||||
struct member *m;
|
||||
struct privilege *priv;
|
||||
struct userspec *us;
|
||||
struct defaults *d;
|
||||
@@ -1153,22 +1153,31 @@ check_aliases(bool strict, bool quiet)
|
||||
alias_freelist = rbcreate(alias_compare);
|
||||
|
||||
/* Forward check. */
|
||||
tq_foreach_fwd(&userspecs, us) {
|
||||
tq_foreach_fwd(&us->users, m) {
|
||||
TAILQ_FOREACH(us, &userspecs, entries) {
|
||||
TAILQ_FOREACH(m, &us->users, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, USERALIAS, strict, quiet);
|
||||
}
|
||||
}
|
||||
tq_foreach_fwd(&us->privileges, priv) {
|
||||
tq_foreach_fwd(&priv->hostlist, m) {
|
||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||
TAILQ_FOREACH(m, &priv->hostlist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, HOSTALIAS, strict, quiet);
|
||||
}
|
||||
}
|
||||
tq_foreach_fwd(&priv->cmndlist, cs) {
|
||||
tq_foreach_fwd(&cs->runasuserlist, m) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, RUNASALIAS, strict, quiet);
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
if (cs->runasuserlist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, RUNASALIAS, strict, quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cs->runasgrouplist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, RUNASALIAS, strict, quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((m = cs->cmnd)->type == ALIAS) {
|
||||
@@ -1179,31 +1188,35 @@ check_aliases(bool strict, bool quiet)
|
||||
}
|
||||
|
||||
/* Reverse check (destructive) */
|
||||
tq_foreach_fwd(&userspecs, us) {
|
||||
tq_foreach_fwd(&us->users, m) {
|
||||
TAILQ_FOREACH(us, &userspecs, entries) {
|
||||
TAILQ_FOREACH(m, &us->users, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, USERALIAS))
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
tq_foreach_fwd(&us->privileges, priv) {
|
||||
tq_foreach_fwd(&priv->hostlist, m) {
|
||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||
TAILQ_FOREACH(m, &priv->hostlist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, HOSTALIAS))
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
tq_foreach_fwd(&priv->cmndlist, cs) {
|
||||
tq_foreach_fwd(&cs->runasuserlist, m) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, RUNASALIAS))
|
||||
errors++;
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
if (cs->runasuserlist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, RUNASALIAS))
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
tq_foreach_fwd(&cs->runasgrouplist, m) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, RUNASALIAS))
|
||||
errors++;
|
||||
if (cs->runasgrouplist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, RUNASALIAS))
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((m = cs->cmnd)->type == ALIAS) {
|
||||
@@ -1213,7 +1226,7 @@ check_aliases(bool strict, bool quiet)
|
||||
}
|
||||
}
|
||||
}
|
||||
tq_foreach_fwd(&defaults, d) {
|
||||
TAILQ_FOREACH(d, &defaults, entries) {
|
||||
switch (d->type) {
|
||||
case DEFAULTS_HOST:
|
||||
atype = HOSTALIAS;
|
||||
@@ -1230,12 +1243,10 @@ check_aliases(bool strict, bool quiet)
|
||||
default:
|
||||
continue; /* not an alias */
|
||||
}
|
||||
tq_foreach_fwd(&d->binding, binding) {
|
||||
for (m = binding; m != NULL; m = m->next) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, atype))
|
||||
errors++;
|
||||
}
|
||||
TAILQ_FOREACH(m, d->binding, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
if (!alias_remove_recursive(m->name, atype))
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user