diff --git a/.gitignore b/.gitignore index c6271d0..59b3a3b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/sudo-1.8.6p7.tar.gz +SOURCES/sudo-1.8.19p2.tar.gz diff --git a/.sudo.metadata b/.sudo.metadata index 5a18089..e9bab31 100644 --- a/.sudo.metadata +++ b/.sudo.metadata @@ -1 +1 @@ -5dec7216d8d70c5ead869479729fba924c7d3818 SOURCES/sudo-1.8.6p7.tar.gz +78868ef825e7b6db246d99160ec16fd4e4c93f3f SOURCES/sudo-1.8.19p2.tar.gz diff --git a/SOURCES/sudo-1.6.7p5-strip.patch b/SOURCES/sudo-1.6.7p5-strip.patch index f9e2faa..ba00efc 100644 --- a/SOURCES/sudo-1.6.7p5-strip.patch +++ b/SOURCES/sudo-1.6.7p5-strip.patch @@ -1,6 +1,19 @@ ---- sudo-1.6.7p5/install-sh.strip 2005-07-21 14:28:25.000000000 +0200 -+++ sudo-1.6.7p5/install-sh 2005-07-21 14:29:18.000000000 +0200 -@@ -138,7 +138,7 @@ +From 8a045c3880e06f5fcf69a73c4029d6725e17f7bc Mon Sep 17 00:00:00 2001 +From: Tomas Sykora +Date: Fri, 19 Aug 2016 13:49:25 +0200 +Subject: [PATCH 01/10] We do not strip + +rebased from: +Patch1: sudo-1.6.7p5-strip.patch +--- + install-sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/install-sh b/install-sh +index 6944fba..49d383a 100755 +--- a/install-sh ++++ b/install-sh +@@ -147,7 +147,7 @@ while ${MORETODO} ; do fi ;; X-s) @@ -9,3 +22,6 @@ ;; X--) shift +-- +2.7.4 + diff --git a/SOURCES/sudo-1.7.2p1-envdebug.patch b/SOURCES/sudo-1.7.2p1-envdebug.patch index e189c98..94c719a 100644 --- a/SOURCES/sudo-1.7.2p1-envdebug.patch +++ b/SOURCES/sudo-1.7.2p1-envdebug.patch @@ -1,7 +1,19 @@ -diff -up sudo-1.7.2p1/configure.in.envdebug sudo-1.7.2p1/configure.in ---- sudo-1.7.2p1/configure.in.envdebug 2009-10-30 12:18:09.000000000 +0100 -+++ sudo-1.7.2p1/configure.in 2009-10-30 12:19:01.000000000 +0100 -@@ -1214,7 +1214,7 @@ AC_ARG_ENABLE(env_debug, +From 44a602b49365969e56c63c9f12eda197e951302f Mon Sep 17 00:00:00 2001 +From: Tomas Sykora +Date: Fri, 19 Aug 2016 14:07:35 +0200 +Subject: [PATCH 02/10] Added "Enviroment debugging" message + +rebased from: +Patch2: sudo-1.7.2p1-envdebug.patch +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 9feddfd..39a2d86 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1390,7 +1390,7 @@ AC_ARG_ENABLE(env_debug, [AS_HELP_STRING([--enable-env-debug], [Whether to enable environment debugging.])], [ case "$enableval" in yes) AC_MSG_RESULT(yes) @@ -10,3 +22,6 @@ diff -up sudo-1.7.2p1/configure.in.envdebug sudo-1.7.2p1/configure.in ;; no) AC_MSG_RESULT(no) ;; +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.18-testsuitefix.patch b/SOURCES/sudo-1.8.18-testsuitefix.patch new file mode 100644 index 0000000..6c60292 --- /dev/null +++ b/SOURCES/sudo-1.8.18-testsuitefix.patch @@ -0,0 +1,189 @@ +From ea44d916b9dffe0f33c3c62d1677567bf64a26b8 Mon Sep 17 00:00:00 2001 +From: Radovan Sroka +Date: Tue, 20 Sep 2016 15:07:53 +0200 +Subject: [PATCH 10/10] Fix upstream testsuite + +--- + plugins/sudoers/regress/sudoers/test2.in | 60 --------------------------- + plugins/sudoers/regress/sudoers/test2.in_ | 60 +++++++++++++++++++++++++++ + plugins/sudoers/regress/testsudoers/test3.sh | 13 ------ + plugins/sudoers/regress/testsudoers/test3.sh_ | 13 ++++++ + 4 files changed, 73 insertions(+), 73 deletions(-) + delete mode 100644 plugins/sudoers/regress/sudoers/test2.in + create mode 100644 plugins/sudoers/regress/sudoers/test2.in_ + delete mode 100755 plugins/sudoers/regress/testsudoers/test3.sh + create mode 100755 plugins/sudoers/regress/testsudoers/test3.sh_ + +diff --git a/plugins/sudoers/regress/sudoers/test2.in b/plugins/sudoers/regress/sudoers/test2.in +deleted file mode 100644 +index cfdfaa3..0000000 +--- a/plugins/sudoers/regress/sudoers/test2.in ++++ /dev/null +@@ -1,60 +0,0 @@ +-# Check quoted user name in User_Alias +-User_Alias UA1 = "foo" +-User_Alias UA2 = "foo.bar" +-User_Alias UA3 = "foo\"" +-User_Alias UA4 = "foo:bar" +-User_Alias UA5 = "foo:bar\"" +- +-# Check quoted group name in User_Alias +-User_Alias UA6 = "%baz" +-User_Alias UA7 = "%baz.biz" +- +-# Check quoted non-Unix group name in User_Alias +-User_Alias UA8 = "%:C/non UNIX 0 c" +-User_Alias UA9 = "%:C/non\'UNIX\'1 c" +-User_Alias UA10 = "%:C/non\"UNIX\"0 c" +-User_Alias UA11 = "%:C/non_UNIX_0 c" +-User_Alias UA12 = "%:C/non\'UNIX_3 c" +- +-# Check quoted user name in Runas_Alias +-Runas_Alias RA1 = "foo" +-Runas_Alias RA2 = "foo\"" +-Runas_Alias RA3 = "foo:bar" +-Runas_Alias RA4 = "foo:bar\"" +- +-# Check quoted host name in Defaults +-Defaults@"somehost" set_home +-Defaults@"quoted\"" set_home +- +-# Check quoted user name in Defaults +-Defaults:"you" set_home +-Defaults:"us\"" set_home +-Defaults:"%them" set_home +-Defaults:"%: non UNIX 0 c" set_home +-Defaults:"+net" set_home +- +-# Check quoted runas name in Defaults +-Defaults>"someone" set_home +-Defaults>"some one" set_home +- +-# Check quoted command in Defaults +-# XXX - not currently supported +-#Defaults!"/bin/ls -l" set_home +-#Defaults!"/bin/ls -l \"foo\"" set_home +- +-# Check quoted user, runas and host name in Cmnd_Spec +-"foo" "hosta" = ("root") ALL +-"foo.bar" "hostb" = ("root") ALL +-"foo\"" "hostc" = ("root") ALL +-"foo:bar" "hostd" = ("root") ALL +-"foo:bar\"" "hoste" = ("root") ALL +- +-# Check quoted group/netgroup name in Cmnd_Spec +-"%baz" "hosta" = ("root") ALL +-"%baz.biz" "hostb" = ("root") ALL +-"%:C/non UNIX 0 c" "hostc" = ("root") ALL +-"%:C/non\'UNIX\'1 c" "hostd" = ("root") ALL +-"%:C/non\"UNIX\"0 c" "hoste" = ("root") ALL +-"%:C/non_UNIX_0 c" "hostf" = ("root") ALL +-"%:C/non\'UNIX_3 c" "hostg" = ("root") ALL +-"+netgr" "hosth" = ("root") ALL +diff --git a/plugins/sudoers/regress/sudoers/test2.in_ b/plugins/sudoers/regress/sudoers/test2.in_ +new file mode 100644 +index 0000000..cfdfaa3 +--- /dev/null ++++ b/plugins/sudoers/regress/sudoers/test2.in_ +@@ -0,0 +1,60 @@ ++# Check quoted user name in User_Alias ++User_Alias UA1 = "foo" ++User_Alias UA2 = "foo.bar" ++User_Alias UA3 = "foo\"" ++User_Alias UA4 = "foo:bar" ++User_Alias UA5 = "foo:bar\"" ++ ++# Check quoted group name in User_Alias ++User_Alias UA6 = "%baz" ++User_Alias UA7 = "%baz.biz" ++ ++# Check quoted non-Unix group name in User_Alias ++User_Alias UA8 = "%:C/non UNIX 0 c" ++User_Alias UA9 = "%:C/non\'UNIX\'1 c" ++User_Alias UA10 = "%:C/non\"UNIX\"0 c" ++User_Alias UA11 = "%:C/non_UNIX_0 c" ++User_Alias UA12 = "%:C/non\'UNIX_3 c" ++ ++# Check quoted user name in Runas_Alias ++Runas_Alias RA1 = "foo" ++Runas_Alias RA2 = "foo\"" ++Runas_Alias RA3 = "foo:bar" ++Runas_Alias RA4 = "foo:bar\"" ++ ++# Check quoted host name in Defaults ++Defaults@"somehost" set_home ++Defaults@"quoted\"" set_home ++ ++# Check quoted user name in Defaults ++Defaults:"you" set_home ++Defaults:"us\"" set_home ++Defaults:"%them" set_home ++Defaults:"%: non UNIX 0 c" set_home ++Defaults:"+net" set_home ++ ++# Check quoted runas name in Defaults ++Defaults>"someone" set_home ++Defaults>"some one" set_home ++ ++# Check quoted command in Defaults ++# XXX - not currently supported ++#Defaults!"/bin/ls -l" set_home ++#Defaults!"/bin/ls -l \"foo\"" set_home ++ ++# Check quoted user, runas and host name in Cmnd_Spec ++"foo" "hosta" = ("root") ALL ++"foo.bar" "hostb" = ("root") ALL ++"foo\"" "hostc" = ("root") ALL ++"foo:bar" "hostd" = ("root") ALL ++"foo:bar\"" "hoste" = ("root") ALL ++ ++# Check quoted group/netgroup name in Cmnd_Spec ++"%baz" "hosta" = ("root") ALL ++"%baz.biz" "hostb" = ("root") ALL ++"%:C/non UNIX 0 c" "hostc" = ("root") ALL ++"%:C/non\'UNIX\'1 c" "hostd" = ("root") ALL ++"%:C/non\"UNIX\"0 c" "hoste" = ("root") ALL ++"%:C/non_UNIX_0 c" "hostf" = ("root") ALL ++"%:C/non\'UNIX_3 c" "hostg" = ("root") ALL ++"+netgr" "hosth" = ("root") ALL +diff --git a/plugins/sudoers/regress/testsudoers/test3.sh b/plugins/sudoers/regress/testsudoers/test3.sh +deleted file mode 100755 +index c1251b9..0000000 +--- a/plugins/sudoers/regress/testsudoers/test3.sh ++++ /dev/null +@@ -1,13 +0,0 @@ +-#!/bin/sh +-# +-# Test #include facility +-# +- +-MYUID=`\ls -lnd $TESTDIR/test3.d | awk '{print $3}'` +-MYGID=`\ls -lnd $TESTDIR/test3.d | awk '{print $4}'` +-exec 2>&1 +-./testsudoers -U $MYUID -G $MYGID root id <&1 ++./testsudoers -U $MYUID -G $MYGID root id <= buf + sizeof(buf)) ++ break; ++ } ++ if (nread == 0 && memchr(buf, '\0', cp - buf) == NULL) { + /* + * Field 7 is the tty dev (0 if no tty). +- * Since the process name at field 2 "(comm)" may include spaces, +- * start at the last ')' found. ++ * Since the process name at field 2 "(comm)" may include ++ * whitespace (including newlines), start at the last ')' found. + */ +- char *cp = strrchr(line, ')'); ++ *cp = '\0'; ++ cp = strrchr(buf, ')'); + if (cp != NULL) { + char *ep = cp; + const char *errstr; +@@ -527,7 +539,8 @@ get_process_ttyname(char *name, size_t namelen) + errno = ENOENT; + + done: +- free(line); ++ if (fd != -1) ++ close(fd); + if (ret == NULL) + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, + "unable to resolve tty via %s", path); diff --git a/SOURCES/sudo-1.8.19p2-error-warning-visudo-message.patch b/SOURCES/sudo-1.8.19p2-error-warning-visudo-message.patch new file mode 100644 index 0000000..6d52342 --- /dev/null +++ b/SOURCES/sudo-1.8.19p2-error-warning-visudo-message.patch @@ -0,0 +1,53 @@ +From daa728fd889680cf5294fbb0e836cade9fe1a6d8 Mon Sep 17 00:00:00 2001 +From: "Todd C. Miller" +Date: Wed, 22 Feb 2017 06:38:33 -0700 +Subject: [PATCH] Go back to using a Warning/Error prefix in the message + printed to stderr for alias problems. Requested by Tomas Sykora. + +--- + doc/visudo.cat | 10 +++++----- + doc/visudo.man.in | 12 ++++++------ + doc/visudo.mdoc.in | 12 ++++++------ + plugins/sudoers/regress/visudo/test2.err.ok | 2 +- + plugins/sudoers/regress/visudo/test3.err.ok | 4 ++-- + plugins/sudoers/visudo.c | 14 ++++++++++---- + 6 files changed, 30 insertions(+), 24 deletions(-) + +diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c +index 4f192b2..4793d54 100644 +--- a/plugins/sudoers/visudo.c ++++ b/plugins/sudoers/visudo.c +@@ -1137,12 +1137,17 @@ check_alias(char *name, int type, char *file, int lineno, bool strict, bool quie + } else { + if (!quiet) { + if (errno == ELOOP) { +- sudo_warnx(U_("%s:%d cycle in %s \"%s\""), ++ fprintf(stderr, strict ? ++ U_("Error: %s:%d cycle in %s \"%s\"") : ++ U_("Warning: %s:%d cycle in %s \"%s\""), + file, lineno, alias_type_to_string(type), name); + } else { +- sudo_warnx(U_("%s:%d %s \"%s\" referenced but not defined"), ++ fprintf(stderr, strict ? ++ U_("Error: %s:%d %s \"%s\" referenced but not defined") : ++ U_("Warning: %s:%d %s \"%s\" referenced but not defined"), + file, lineno, alias_type_to_string(type), name); + } ++ fputc('\n', stderr); + if (strict && errorfile == NULL) { + errorfile = rcstr_addref(file); + errorlineno = lineno; +@@ -1292,8 +1297,9 @@ print_unused(void *v1, void *v2) + { + struct alias *a = (struct alias *)v1; + +- sudo_warnx_nodebug(U_("%s:%d unused %s \"%s\""), ++ fprintf(stderr, U_("Warning: %s:%d unused %s \"%s\""), + a->file, a->lineno, alias_type_to_string(a->type), a->name); ++ fputc('\n', stderr); + return 0; + } + +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.19p2-fqdn-use-after-free.patch b/SOURCES/sudo-1.8.19p2-fqdn-use-after-free.patch new file mode 100644 index 0000000..1c44dcc --- /dev/null +++ b/SOURCES/sudo-1.8.19p2-fqdn-use-after-free.patch @@ -0,0 +1,124 @@ +diff -up ./plugins/sudoers/sssd.c.fqdnafterfree ./plugins/sudoers/sssd.c +--- ./plugins/sudoers/sssd.c.fqdnafterfree 2017-01-14 05:30:15.000000000 +0100 ++++ ./plugins/sudoers/sssd.c 2017-04-25 14:23:39.655649726 +0200 +@@ -82,8 +82,8 @@ typedef void (*sss_sudo_free_values_t)(c + + struct sudo_sss_handle { + char *domainname; +- char *host; +- char *shost; ++ char *ipa_host; ++ char *ipa_shost; + struct passwd *pw; + void *ssslib; + sss_sudo_send_recv_t fn_send_recv; +@@ -385,7 +385,7 @@ sudo_sss_open(struct sudo_nss *nss) + debug_decl(sudo_sss_open, SUDOERS_DEBUG_SSSD); + + /* Create a handle container. */ +- handle = malloc(sizeof(struct sudo_sss_handle)); ++ handle = calloc(1, sizeof(struct sudo_sss_handle)); + if (handle == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + debug_return_int(ENOMEM); +@@ -447,9 +447,6 @@ sudo_sss_open(struct sudo_nss *nss) + debug_return_int(EFAULT); + } + +- handle->domainname = NULL; +- handle->host = user_runhost; +- handle->shost = user_srunhost; + handle->pw = sudo_user.pw; + nss->handle = handle; + +@@ -458,7 +455,7 @@ sudo_sss_open(struct sudo_nss *nss) + * in sssd.conf and use it in preference to user_runhost. + */ + if (strcmp(user_runhost, user_host) == 0) { +- if (get_ipa_hostname(&handle->shost, &handle->host) == -1) { ++ if (get_ipa_hostname(&handle->ipa_shost, &handle->ipa_host) == -1) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + free(handle); + debug_return_int(ENOMEM); +@@ -480,7 +477,10 @@ sudo_sss_close(struct sudo_nss *nss) + if (nss && nss->handle) { + handle = nss->handle; + sudo_dso_unload(handle->ssslib); +- free(nss->handle); ++ free(handle->ipa_host); ++ free(handle->ipa_shost); ++ free(handle); ++ nss->handle = NULL; + } + debug_return_int(0); + } +@@ -585,8 +585,9 @@ sudo_sss_checkpw(struct sudo_nss *nss, s + static int + sudo_sss_check_runas_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *sss_rule, int group_matched) + { +- char **val_array = NULL; +- char *val; ++ const char *host = handle->ipa_host ? handle->ipa_host : user_runhost; ++ const char *shost = handle->ipa_shost ? handle->ipa_shost : user_srunhost; ++ char *val, **val_array = NULL; + int ret = false, i; + debug_decl(sudo_sss_check_runas_user, SUDOERS_DEBUG_SSSD); + +@@ -656,8 +657,8 @@ sudo_sss_check_runas_user(struct sudo_ss + switch (val[0]) { + case '+': + sudo_debug_printf(SUDO_DEBUG_DEBUG, "netgr_"); +- if (netgr_matches(val, def_netgroup_tuple ? handle->host : NULL, +- def_netgroup_tuple ? handle->shost : NULL, runas_pw->pw_name)) { ++ if (netgr_matches(val, def_netgroup_tuple ? host : NULL, ++ def_netgroup_tuple ? shost : NULL, runas_pw->pw_name)) { + sudo_debug_printf(SUDO_DEBUG_DEBUG, "=> match"); + ret = true; + } +@@ -762,7 +763,9 @@ sudo_sss_check_runas(struct sudo_sss_han + static bool + sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) + { +- char **val_array, *val; ++ const char *host = handle->ipa_host ? handle->ipa_host : user_runhost; ++ const char *shost = handle->ipa_shost ? handle->ipa_shost : user_srunhost; ++ char *val, **val_array; + int matched = UNSPEC; + bool negated; + int i; +@@ -792,9 +795,9 @@ sudo_sss_check_host(struct sudo_sss_hand + + /* match any or address or netgroup or hostname */ + if (strcmp(val, "ALL") == 0 || addr_matches(val) || +- netgr_matches(val, handle->host, handle->shost, ++ netgr_matches(val, host, shost, + def_netgroup_tuple ? handle->pw->pw_name : NULL) || +- hostname_matches(handle->shost, handle->host, val)) { ++ hostname_matches(shost, host, val)) { + + matched = negated ? false : true; + } +@@ -816,9 +819,10 @@ sudo_sss_check_host(struct sudo_sss_hand + static bool + sudo_sss_check_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) + { +- int ret = false; ++ const char *host = handle->ipa_host ? handle->ipa_host : user_runhost; ++ const char *shost = handle->ipa_shost ? handle->ipa_shost : user_srunhost; + char **val_array; +- int i; ++ int i, ret = false; + debug_decl(sudo_sss_check_user, SUDOERS_DEBUG_SSSD); + + if (!handle || !rule) +@@ -844,8 +848,8 @@ sudo_sss_check_user(struct sudo_sss_hand + switch (*val) { + case '+': + /* Netgroup spec found, check membership. */ +- if (netgr_matches(val, def_netgroup_tuple ? handle->host : NULL, +- def_netgroup_tuple ? handle->shost : NULL, handle->pw->pw_name)) { ++ if (netgr_matches(val, def_netgroup_tuple ? host : NULL, ++ def_netgroup_tuple ? shost : NULL, handle->pw->pw_name)) { + ret = true; + } + break; diff --git a/SOURCES/sudo-1.8.19p2-get_process_ttyname.patch b/SOURCES/sudo-1.8.19p2-get_process_ttyname.patch new file mode 100644 index 0000000..8d304d5 --- /dev/null +++ b/SOURCES/sudo-1.8.19p2-get_process_ttyname.patch @@ -0,0 +1,76 @@ +diff -ru sudo-1.8.20/src/ttyname.c sudo-1.8.20-Q/src/ttyname.c +--- sudo-1.8.20/src/ttyname.c 2017-05-10 08:38:44.000000000 -0700 ++++ sudo-1.8.20-Q/src/ttyname.c 2017-05-19 02:15:48.442705049 -0700 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2012-2016 Todd C. Miller ++ * Copyright (c) 2012-2017 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above +@@ -159,6 +159,8 @@ + + static char *ignore_devs[] = { + "/dev/fd/", ++ "/dev/mqueue/", ++ "/dev/shm/", + "/dev/stdin", + "/dev/stdout", + "/dev/stderr", +@@ -493,28 +495,35 @@ + len = getline(&line, &linesize, fp); + fclose(fp); + if (len != -1) { +- /* Field 7 is the tty dev (0 if no tty) */ +- char *cp = line; +- char *ep = line; +- const char *errstr; +- int field = 0; +- while (*++ep != '\0') { +- if (*ep == ' ') { +- *ep = '\0'; +- if (++field == 7) { +- dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr); +- if (errstr) { +- sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, +- "%s: tty device %s: %s", path, cp, errstr); ++ /* ++ * Field 7 is the tty dev (0 if no tty). ++ * Since the process name at field 2 "(comm)" may include spaces, ++ * start at the last ')' found. ++ */ ++ char *cp = strrchr(line, ')'); ++ if (cp != NULL) { ++ char *ep = cp; ++ const char *errstr; ++ int field = 1; ++ ++ while (*++ep != '\0') { ++ if (*ep == ' ') { ++ *ep = '\0'; ++ if (++field == 7) { ++ dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr); ++ if (errstr) { ++ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, ++ "%s: tty device %s: %s", path, cp, errstr); ++ } ++ if (tdev > 0) { ++ errno = serrno; ++ ret = sudo_ttyname_dev(tdev, name, namelen); ++ goto done; ++ } ++ break; + } +- if (tdev > 0) { +- errno = serrno; +- ret = sudo_ttyname_dev(tdev, name, namelen); +- goto done; +- } +- break; ++ cp = ep + 1; + } +- cp = ep + 1; + } + } + } + diff --git a/SOURCES/sudo-1.8.19p2-ignore-unknown-defaults.patch b/SOURCES/sudo-1.8.19p2-ignore-unknown-defaults.patch new file mode 100644 index 0000000..aadb45d --- /dev/null +++ b/SOURCES/sudo-1.8.19p2-ignore-unknown-defaults.patch @@ -0,0 +1,142 @@ +From 93cef1efac4e2b4930c23cdc35c0b916365ccabc Mon Sep 17 00:00:00 2001 +From: Tomas Sykora +Date: Tue, 21 Feb 2017 14:56:24 +0100 +Subject: [PATCH] Add ignore_unknown_defaults flag to ignore unknown Defaults + entries in sudoers instead of producing a warning. + +Patch: sudo-1.8.19p2-ignore-unknown-defaults.patch +Resolves: +rhbz#1413160 +--- + doc/sudoers.cat | 6 ++++++ + doc/sudoers.man.in | 11 +++++++++++ + doc/sudoers.mdoc.in | 10 ++++++++++ + plugins/sudoers/def_data.c | 4 ++++ + plugins/sudoers/def_data.h | 2 ++ + plugins/sudoers/def_data.in | 3 +++ + plugins/sudoers/defaults.c | 3 ++- + 7 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/doc/sudoers.cat b/doc/sudoers.cat +index 76dbf28..50cf78a 100644 +--- a/doc/sudoers.cat ++++ b/doc/sudoers.cat +@@ -1071,6 +1071,12 @@ SSUUDDOOEERRSS OOPPTTIIOONNSS + meaningful for the cn=defaults section. This flag is + _o_f_f by default. + ++ ignore_unknown_defaults ++ If set, ssuuddoo will not produce a warning if it ++ encounters an unknown Defaults entry in the _^Hs_^Hu_^Hd_^Ho_^He_^Hr_^Hs ++ file or an unknown sudoOption in LDAP. This flag is ++ _o_f_f by default. ++ + insults If set, ssuuddoo will insult users when they enter an + incorrect password. This flag is _o_f_f by default. + +diff --git a/doc/sudoers.man.in b/doc/sudoers.man.in +index 8673da0..4be3760 100644 +--- a/doc/sudoers.man.in ++++ b/doc/sudoers.man.in +@@ -2266,6 +2266,17 @@ This flag is + \fIoff\fR + by default. + .TP 18n ++ignore_unknown_defaults ++If set, ++\fBsudo\fR ++will not produce a warning if it encounters an unknown Defaults entry ++in the ++\fIsudoers\fR ++file or an unknown sudoOption in LDAP. ++This flag is ++\fIoff\fR ++by default. ++.TP 18n + insults + If set, + \fBsudo\fR +diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in +index 74b6f01..f3fe5e6 100644 +--- a/doc/sudoers.mdoc.in ++++ b/doc/sudoers.mdoc.in +@@ -2124,6 +2124,16 @@ section. + This flag is + .Em off + by default. ++.It ignore_unknown_defaults ++If set, ++.Nm sudo ++will not produce a warning if it encounters an unknown Defaults entry ++in the ++.Em sudoers ++file or an unknown sudoOption in LDAP. ++This flag is ++.Em off ++by default. + .It insults + If set, + .Nm sudo +diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c +index 3926fed..3d787c2 100644 +--- a/plugins/sudoers/def_data.c ++++ b/plugins/sudoers/def_data.c +@@ -443,6 +443,10 @@ struct sudo_defs_types sudo_defs_table[] = { + N_("Don't pre-resolve all group names"), + NULL, + }, { ++ "ignore_unknown_defaults", T_FLAG, ++ N_("Ignore unknown Defaults entries in sudoers instead of producing a warning"), ++ NULL, ++ }, { + NULL, 0, NULL + } + }; +diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h +index b5e61b4..f5773a3 100644 +--- a/plugins/sudoers/def_data.h ++++ b/plugins/sudoers/def_data.h +@@ -208,6 +208,8 @@ + #define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag) + #define I_LEGACY_GROUP_PROCESSING 104 + #define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag) ++#define I_IGNORE_UNKNOWN_DEFAULTS 105 ++#define def_ignore_unknown_defaults (sudo_defs_table[I_IGNORE_UNKNOWN_DEFAULTS].sd_un.flag) + + enum def_tuple { + never, +diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in +index f1c9265..8f63d70 100644 +--- a/plugins/sudoers/def_data.in ++++ b/plugins/sudoers/def_data.in +@@ -328,3 +328,6 @@ cmnd_no_wait + legacy_group_processing + T_FLAG + "Don't pre-resolve all group names" ++ignore_unknown_defaults ++ T_FLAG ++ "Ignore unknown Defaults entries in sudoers instead of producing a warning" +diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c +index 9e60d94..5f93f80 100644 +--- a/plugins/sudoers/defaults.c ++++ b/plugins/sudoers/defaults.c +@@ -79,6 +79,7 @@ static struct strmap priorities[] = { + }; + + static struct early_default early_defaults[] = { ++ { I_IGNORE_UNKNOWN_DEFAULTS }, + #ifdef FQDN + { I_FQDN, true }, + #else +@@ -206,7 +207,7 @@ find_default(const char *name, const char *file, int lineno, bool quiet) + if (strcmp(name, sudo_defs_table[i].name) == 0) + debug_return_int(i); + } +- if (!quiet) { ++ if (!quiet && !def_ignore_unknown_defaults) { + if (lineno > 0) { + sudo_warnx(U_("%s:%d unknown defaults entry \"%s\""), + file, lineno, name); +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.19p2-iologflush.patch b/SOURCES/sudo-1.8.19p2-iologflush.patch new file mode 100644 index 0000000..213566f --- /dev/null +++ b/SOURCES/sudo-1.8.19p2-iologflush.patch @@ -0,0 +1,317 @@ +diff -up ./doc/sudoers.cat.orig ./doc/sudoers.cat +--- ./doc/sudoers.cat.orig 2017-03-21 13:31:00.953951199 +0100 ++++ ./doc/sudoers.cat 2017-03-21 14:14:18.679116865 +0100 +@@ -1549,6 +1549,16 @@ SSUUDDOOEERRSS OOPPTTIIOONN + will be truncated and overwritten unless _i_o_l_o_g___f_i_l_e + ends in six or more Xs. + ++ iolog_flush If set, ssuuddoo will flush I/O log data to disk after each ++ write instead of buffering it. This makes it possible ++ to view the logs in real-time as the program is ++ executing but may significantly reduce the ++ effectiveness of I/O log compression. This flag is _o_f_f ++ by default. ++ ++ This setting is only supported by version 1.8.20 or ++ higher. ++ + iolog_group The group name to look up when setting the group ID on + new I/O log files and directories. By default, I/O log + files and directories inherit the group ID of the +@@ -2141,10 +2151,14 @@ II//OO LLOOGG FFIILLEESS + _s_t_d_e_r_r standard error to a pipe or redirected to a file + + All files other than _l_o_g are compressed in gzip format unless the +- _c_o_m_p_r_e_s_s___i_o option has been disabled. Due to buffering, the I/O log data +- will not be complete until the ssuuddoo command has completed. The output +- portion of an I/O log file can be viewed with the sudoreplay(1m) utility, +- which can also be used to list or search the available logs. ++ _c_o_m_p_r_e_s_s___i_o flag has been disabled. Due to buffering, it is not normally ++ possible to display the I/O logs in real-time as the program is executing ++ The I/O log data will not be complete until the program run by ssuuddoo has ++ exited or has been terminated by a signal. The _i_o_l_o_g___f_l_u_s_h flag can be ++ used to disable buffering, in which case I/O log data is written to disk ++ as soon as it is available. The output portion of an I/O log file can be ++ viewed with the sudoreplay(1m) utility, which can also be used to list or ++ search the available logs. + + Note that user input may contain sensitive information such as passwords + (even if they are not echoed to the screen), which will be stored in the +diff -up ./doc/sudoers.man.in.orig ./doc/sudoers.man.in +--- ./doc/sudoers.man.in.orig 2017-03-21 14:22:33.804283190 +0100 ++++ ./doc/sudoers.man.in 2017-03-21 14:22:21.136664667 +0100 +@@ -3199,6 +3199,19 @@ ends in six or + more + \fRX\fRs. + .TP 18n ++iolog_flush ++If set, ++\fBsudo\fR ++will flush I/O log data to disk after each write instead of buffering it. ++This makes it possible to view the logs in real-time as the program ++is executing but may significantly reduce the effectiveness of I/O ++log compression. ++This flag is ++\fIoff\fR ++by default. ++.sp ++This setting is only supported by version 1.8.20 or higher. ++.TP 18n + iolog_group + The group name to look up when setting the group ID on new I/O log + files and directories. +@@ -4298,10 +4311,16 @@ All files other than + \fIlog\fR + are compressed in gzip format unless the + \fIcompress_io\fR +-option has been disabled. +-Due to buffering, the I/O log data will not be complete until the ++flag has been disabled. ++Due to buffering, it is not normally possible to display the I/O logs in ++real-time as the program is executing ++The I/O log data will not be complete until the program run by + \fBsudo\fR +-command has completed. ++has exited or has been terminated by a signal. ++The ++\fIiolog_flush\fR ++flag can be used to disable buffering, in which case I/O log data ++is written to disk as soon as it is available. + The output portion of an I/O log file can be viewed with the + sudoreplay(@mansectsu@) + utility, which can also be used to list or search the available logs. +diff -up ./doc/sudoers.mdoc.in.orig ./doc/sudoers.mdoc.in +--- ./doc/sudoers.mdoc.in.orig 2017-03-21 14:23:46.652089432 +0100 ++++ ./doc/sudoers.mdoc.in 2017-03-21 14:26:43.686758162 +0100 +@@ -2998,6 +2998,18 @@ overwritten unless + ends in six or + more + .Li X Ns s . ++.It iolog_flush ++If set, ++.Nm sudo ++will flush I/O log data to disk after each write instead of buffering it. ++This makes it possible to view the logs in real-time as the program ++is executing but may significantly reduce the effectiveness of I/O ++log compression. ++This flag is ++.Em off ++by default. ++.Pp ++This setting is only supported by version 1.8.20 or higher. + .It iolog_group + The group name to look up when setting the group ID on new I/O log + files and directories. +@@ -3991,10 +4003,16 @@ All files other than + .Pa log + are compressed in gzip format unless the + .Em compress_io +-option has been disabled. +-Due to buffering, the I/O log data will not be complete until the +-.Nm sudo +-command has completed. ++flag has been disabled. ++Due to buffering, it is not normally possible to display the I/O logs in ++real-time as the program is executing ++The I/O log data will not be complete until the program run by ++.Nm sudo ++has exited or has been terminated by a signal. ++The ++.Em iolog_flush ++flag can be used to disable buffering, in which case I/O log data ++is written to disk as soon as it is available. + The output portion of an I/O log file can be viewed with the + .Xr sudoreplay @mansectsu@ + utility, which can also be used to list or search the available logs. +diff -up ./plugins/sudoers/def_data.c.orig ./plugins/sudoers/def_data.c +--- ./plugins/sudoers/def_data.c.orig 2017-03-21 13:24:10.682064806 +0100 ++++ ./plugins/sudoers/def_data.c 2017-03-21 13:25:09.805322057 +0100 +@@ -447,6 +447,10 @@ struct sudo_defs_types sudo_defs_table[] + N_("Ignore unknown Defaults entries in sudoers instead of producing a warning"), + NULL, + }, { ++ "iolog_flush", T_FLAG, ++ N_("Flush I/O log data to disk immediately instead of buffering it"), ++ NULL, ++ }, { + NULL, 0, NULL + } + }; +diff -up ./plugins/sudoers/def_data.h.orig ./plugins/sudoers/def_data.h +--- ./plugins/sudoers/def_data.h.orig 2017-03-21 13:25:20.489006524 +0100 ++++ ./plugins/sudoers/def_data.h 2017-03-21 13:28:09.251022290 +0100 +@@ -210,6 +210,8 @@ + #define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag) + #define I_IGNORE_UNKNOWN_DEFAULTS 105 + #define def_ignore_unknown_defaults (sudo_defs_table[I_IGNORE_UNKNOWN_DEFAULTS].sd_un.flag) ++#define I_IOLOG_FLUSH 106 ++#define def_iolog_flush (sudo_defs_table[I_IOLOG_FLUSH].sd_un.flag) + + enum def_tuple { + never, +diff -up ./plugins/sudoers/def_data.in.orig ./plugins/sudoers/def_data.in +--- ./plugins/sudoers/def_data.in.orig 2017-03-21 13:28:35.115258413 +0100 ++++ ./plugins/sudoers/def_data.in 2017-03-21 13:30:03.239655739 +0100 +@@ -331,3 +331,6 @@ legacy_group_processing + ignore_unknown_defaults + T_FLAG + "Ignore unknown Defaults entries in sudoers instead of producing a warning" ++iolog_flush ++ T_FLAG ++ "Flush I/O log data to disk immediately instead of buffering it" +diff -up ./plugins/sudoers/iolog.c.orig ./plugins/sudoers/iolog.c +--- ./plugins/sudoers/iolog.c.orig 2017-03-21 13:12:39.471464160 +0100 ++++ ./plugins/sudoers/iolog.c 2017-03-21 13:21:49.279230759 +0100 +@@ -709,6 +709,7 @@ iolog_deserialize_info(struct iolog_deta + + /* + * Write the "/log" file that contains the user and command info. ++ * This file is not compressed. + */ + static bool + write_info_log(char *pathbuf, size_t len, struct iolog_details *details, +@@ -747,6 +748,57 @@ write_info_log(char *pathbuf, size_t len + debug_return_bool(ret); + } + ++#ifdef HAVE_ZLIB_H ++static const char * ++gzstrerror(gzFile file) ++{ ++ int errnum; ++ ++ return gzerror(file, &errnum); ++} ++#endif /* HAVE_ZLIB_H */ ++ ++/* ++ * Write to an I/O log, compressing if iolog_compress is enabled. ++ * If def_iolog_flush is true, flush the buffer immediately. ++ */ ++static const char * ++iolog_write(const void *buf, unsigned int len, int idx) ++{ ++ const char *errstr = NULL; ++ debug_decl(iolog_write, SUDOERS_DEBUG_PLUGIN) ++ ++#ifdef HAVE_ZLIB_H ++ if (iolog_compress) { ++ if (gzwrite(io_log_files[idx].fd.g, buf, len) != (int)len) { ++ errstr = gzstrerror(io_log_files[idx].fd.g); ++ goto done; ++ } ++ if (def_iolog_flush) { ++ if (gzflush(io_log_files[idx].fd.g, Z_SYNC_FLUSH) != Z_OK) { ++ errstr = gzstrerror(io_log_files[idx].fd.g); ++ goto done; ++ } ++ } ++ } else ++#endif ++ { ++ if (fwrite(buf, 1, len, io_log_files[idx].fd.f) != len) { ++ errstr = strerror(errno); ++ goto done; ++ } ++ if (def_iolog_flush) { ++ if (fflush(io_log_files[idx].fd.f) != 0) { ++ errstr = strerror(errno); ++ goto done; ++ } ++ } ++ } ++ ++done: ++ debug_return_const_str(errstr); ++} ++ + static int + sudoers_io_open(unsigned int version, sudo_conv_t conversation, + sudo_printf_t plugin_printf, char * const settings[], +@@ -914,13 +966,15 @@ sudoers_io_version(int verbose) + + /* + * Generic I/O logging function. Called by the I/O logging entry points. ++ * Returns 1 on success and -1 on error. + */ + static int + sudoers_io_log(const char *buf, unsigned int len, int idx) + { + struct timeval now, delay; ++ char tbuf[1024]; + const char *errstr = NULL; +- int ret = true; ++ int ret = -1; + debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN) + + if (io_log_files[idx].fd.v == NULL) { +@@ -931,41 +985,28 @@ sudoers_io_log(const char *buf, unsigned + + gettimeofday(&now, NULL); + +-#ifdef HAVE_ZLIB_H +- if (iolog_compress) { +- if (gzwrite(io_log_files[idx].fd.g, (const voidp)buf, len) != (int)len) { +- int errnum; ++ /* Write I/O log file entry. */ ++ errstr = iolog_write(buf, len, idx); ++ if (errstr != NULL) ++ goto done; + +- errstr = gzerror(io_log_files[idx].fd.g, &errnum); +- ret = -1; +- } +- } else +-#endif +- { +- if (fwrite(buf, 1, len, io_log_files[idx].fd.f) != len) { +- errstr = strerror(errno); +- ret = -1; +- } +- } ++ /* Write timing file entry. */ + sudo_timevalsub(&now, &last_time, &delay); +-#ifdef HAVE_ZLIB_H +- if (iolog_compress) { +- if (gzprintf(io_log_files[IOFD_TIMING].fd.g, "%d %f %u\n", idx, +- delay.tv_sec + ((double)delay.tv_usec / 1000000), len) == 0) { +- int errnum; +- +- errstr = gzerror(io_log_files[IOFD_TIMING].fd.g, &errnum); +- ret = -1; +- } +- } else +-#endif +- { +- if (fprintf(io_log_files[IOFD_TIMING].fd.f, "%d %f %u\n", idx, +- delay.tv_sec + ((double)delay.tv_usec / 1000000), len) < 0) { +- errstr = strerror(errno); +- ret = -1; +- } ++ len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %f %u\n", idx, ++ delay.tv_sec + ((double)delay.tv_usec / 1000000), len); ++ if (len >= sizeof(tbuf)) { ++ /* Not actually possible due to the size of tbuf[]. */ ++ errstr = strerror(EOVERFLOW); ++ goto done; + } ++ errstr = iolog_write(tbuf, len, IOFD_TIMING); ++ if (errstr != NULL) ++ goto done; ++ ++ /* Success. */ ++ ret = 1; ++ ++done: + last_time.tv_sec = now.tv_sec; + last_time.tv_usec = now.tv_usec; + +@@ -979,7 +1020,7 @@ sudoers_io_log(const char *buf, unsigned + + /* Ignore errors if they occur if the policy says so. */ + if (iolog_details.ignore_iolog_errors) +- ret = true; ++ ret = 1; + } + + debug_return_int(ret); diff --git a/SOURCES/sudo-1.8.19p2-lecture-boolean.patch b/SOURCES/sudo-1.8.19p2-lecture-boolean.patch new file mode 100644 index 0000000..482bc6b --- /dev/null +++ b/SOURCES/sudo-1.8.19p2-lecture-boolean.patch @@ -0,0 +1,54 @@ +commit 631d458b6fc7341363a121c390e086cf676ecc83 +Author: Todd C. Miller +Date: Wed May 3 09:28:36 2017 -0600 + + Allow a tuple to be set to boolean true. Regression introduced by + refactor of set_default_entry() in sudo 1.8.18. + +diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c +index 89788477..91b47eeb 100644 +--- a/plugins/sudoers/defaults.c ++++ b/plugins/sudoers/defaults.c +@@ -238,19 +238,31 @@ parse_default_entry(struct sudo_defs_types *def, const char *val, int op, + int rc; + debug_decl(parse_default_entry, SUDOERS_DEBUG_DEFAULTS) + +- if (val == NULL && !ISSET(def->type, T_FLAG)) { +- /* Check for bogus boolean usage or missing value if non-boolean. */ +- if (!ISSET(def->type, T_BOOL) || op != false) { +- if (!quiet) { +- if (lineno > 0) { +- sudo_warnx(U_("%s:%d no value specified for \"%s\""), +- file, lineno, def->name); +- } else { +- sudo_warnx(U_("%s: no value specified for \"%s\""), +- file, def->name); ++ /* ++ * If no value specified, the boolean flag must be set for non-flags. ++ * Only flags and tuples support boolean "true". ++ */ ++ if (val == NULL) { ++ switch (def->type & T_MASK) { ++ case T_FLAG: ++ break; ++ case T_TUPLE: ++ if (ISSET(def->type, T_BOOL)) ++ break; ++ /* FALLTHROUGH */ ++ default: ++ if (!ISSET(def->type, T_BOOL) || op != false) { ++ if (!quiet) { ++ if (lineno > 0) { ++ sudo_warnx(U_("%s:%d no value specified for \"%s\""), ++ file, lineno, def->name); ++ } else { ++ sudo_warnx(U_("%s: no value specified for \"%s\""), ++ file, def->name); ++ } + } ++ debug_return_bool(false); + } +- debug_return_bool(false); + } + } + diff --git a/SOURCES/sudo-1.8.19p2-lookup-issue-doc.patch b/SOURCES/sudo-1.8.19p2-lookup-issue-doc.patch new file mode 100644 index 0000000..af85676 --- /dev/null +++ b/SOURCES/sudo-1.8.19p2-lookup-issue-doc.patch @@ -0,0 +1,164 @@ +diff -up ./doc/sudoers.cat.lookup ./doc/sudoers.cat +--- ./doc/sudoers.cat.lookup 2017-04-25 13:17:51.073190114 +0200 ++++ ./doc/sudoers.cat 2017-04-25 13:17:51.081190069 +0200 +@@ -1140,24 +1140,39 @@ SSUUDDOOEERRSS OOPPTTIIOONN + _o_n by default. + + match_group_by_gid +- By default, when matching groups, ssuuddooeerrss will first +- resolve all the user's group IDs to group names and +- then compare those group names to any group names +- listed in the _s_u_d_o_e_r_s file. This works well on systems +- where the number of groups listed in the _s_u_d_o_e_r_s file +- is larger than the number of groups a typical user +- belongs to. On systems where group lookups are slow, +- where users may belong to a large number of groups, and +- where the number of groups listed in the _s_u_d_o_e_r_s file +- is relatively small, it may be prohibitively expensive +- and running commands via ssuuddoo may take longer than +- normal. On such systems it may be faster to use the ++ By default, ssuuddooeerrss will look up each group the user is ++ a member of by group ID to determine the group name ++ (this is only done once). The resulting list of the ++ user's group names is used when matching groups listed ++ in the _s_u_d_o_e_r_s file. This works well on systems where ++ the number of groups listed in the _s_u_d_o_e_r_s file is ++ larger than the number of groups a typical user belongs ++ to. On systems where group lookups are slow, where ++ users may belong to a large number of groups, and where ++ the number of groups listed in the _s_u_d_o_e_r_s file is ++ relatively small, it may be prohibitively expensive and ++ running commands via ssuuddoo may take longer than normal. ++ On such systems it may be faster to use the + _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d flag to avoid resolving the user's +- group IDs to group names and instead resolve all group +- names listed in the _s_u_d_o_e_r_s file, matching by group ID +- instead of by group name. The _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d flag +- has no effect when _s_u_d_o_e_r_s data is stored in LDAP. +- This flag is _o_f_f by default. ++ group IDs to group names. In this case, ssuuddooeerrss must ++ look up any group name listed in the _s_u_d_o_e_r_s file and ++ use the group ID instead of the group name when ++ determining whether the user is a member of the group. ++ ++ Note that if _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d is enabled, group ++ database lookups performed by ssuuddooeerrss will be keyed by ++ group name as opposed to group ID. On systems where ++ there are multiple sources for the group database, it ++ is possible to have conflicting group names or group ++ IDs in the local _/_e_t_c_/_g_r_o_u_p file and the remote group ++ database. On such systems, enabling or disabling ++ _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d can be used to choose whether group ++ database queries are performed by name (enabled) or ID ++ (disabled), which may aid in working around group entry ++ conflicts. ++ ++ The _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d flag has no effect when _s_u_d_o_e_r_s ++ data is stored in LDAP. This flag is _o_f_f by default. + + This setting is only supported by version 1.8.18 or + higher. +diff -up ./doc/sudoers.man.in.lookup ./doc/sudoers.man.in +--- ./doc/sudoers.man.in.lookup 2017-04-25 13:17:51.074190108 +0200 ++++ ./doc/sudoers.man.in 2017-04-25 13:17:51.082190064 +0200 +@@ -2423,10 +2423,12 @@ This flag is + by default. + .TP 18n + match_group_by_gid +-By default, when matching groups, ++By default, + \fBsudoers\fR +-will first resolve all the user's group IDs to group names and then +-compare those group names to any group names listed in the ++will look up each group the user is a member of by group ID to ++determine the group name (this is only done once). ++The resulting list of the user's group names is used when matching ++groups listed in the + \fIsudoers\fR + file. + This works well on systems where the number of groups listed in the +@@ -2442,10 +2444,29 @@ running commands via + may take longer than normal. + On such systems it may be faster to use the + \fImatch_group_by_gid\fR +-flag to avoid resolving the user's group IDs to group names and +-instead resolve all group names listed in the ++flag to avoid resolving the user's group IDs to group names. ++In this case, ++\fBsudoers\fR ++must look up any group name listed in the + \fIsudoers\fR +-file, matching by group ID instead of by group name. ++file and use the group ID instead of the group name when determining ++whether the user is a member of the group. ++.sp ++Note that if ++\fImatch_group_by_gid\fR ++is enabled, group database lookups performed by ++\fBsudoers\fR ++will be keyed by group name as opposed to group ID. ++On systems where there are multiple sources for the group database, ++it is possible to have conflicting group names or group IDs in the local ++\fI/etc/group\fR ++file and the remote group database. ++On such systems, enabling or disabling ++\fImatch_group_by_gid\fR ++can be used to choose whether group database queries are performed ++by name (enabled) or ID (disabled), which may aid in working around ++group entry conflicts. ++.sp + The + \fImatch_group_by_gid\fR + flag has no effect when +diff -up ./doc/sudoers.mdoc.in.lookup ./doc/sudoers.mdoc.in +--- ./doc/sudoers.mdoc.in.lookup 2017-04-25 13:17:51.075190102 +0200 ++++ ./doc/sudoers.mdoc.in 2017-04-25 13:17:51.082190064 +0200 +@@ -2268,10 +2268,12 @@ This flag is + .Em @mail_no_user@ + by default. + .It match_group_by_gid +-By default, when matching groups, ++By default, + .Nm +-will first resolve all the user's group IDs to group names and then +-compare those group names to any group names listed in the ++will look up each group the user is a member of by group ID to ++determine the group name (this is only done once). ++The resulting list of the user's group names is used when matching ++groups listed in the + .Em sudoers + file. + This works well on systems where the number of groups listed in the +@@ -2287,10 +2289,29 @@ running commands via + may take longer than normal. + On such systems it may be faster to use the + .Em match_group_by_gid +-flag to avoid resolving the user's group IDs to group names and +-instead resolve all group names listed in the ++flag to avoid resolving the user's group IDs to group names. ++In this case, ++.Nm ++must look up any group name listed in the + .Em sudoers +-file, matching by group ID instead of by group name. ++file and use the group ID instead of the group name when determining ++whether the user is a member of the group. ++.Pp ++Note that if ++.Em match_group_by_gid ++is enabled, group database lookups performed by ++.Nm ++will be keyed by group name as opposed to group ID. ++On systems where there are multiple sources for the group database, ++it is possible to have conflicting group names or group IDs in the local ++.Pa /etc/group ++file and the remote group database. ++On such systems, enabling or disabling ++.Em match_group_by_gid ++can be used to choose whether group database queries are performed ++by name (enabled) or ID (disabled), which may aid in working around ++group entry conflicts. ++.Pp + The + .Em match_group_by_gid + flag has no effect when diff --git a/SOURCES/sudo-1.8.19p2-upstream-testsuitefix.patch b/SOURCES/sudo-1.8.19p2-upstream-testsuitefix.patch new file mode 100644 index 0000000..ef2946c --- /dev/null +++ b/SOURCES/sudo-1.8.19p2-upstream-testsuitefix.patch @@ -0,0 +1,14 @@ +diff -up ./plugins/sudoers/regress/visudo/test2.err.ok.orig ./plugins/sudoers/regress/visudo/test2.err.ok +--- ./plugins/sudoers/regress/visudo/test2.err.ok.orig 2017-04-10 10:12:53.003000000 -0400 ++++ ./plugins/sudoers/regress/visudo/test2.err.ok 2017-04-10 10:13:36.771000000 -0400 +@@ -1 +1 @@ +-visudo: stdin:1 cycle in User_Alias "FOO" ++Error: stdin:1 cycle in User_Alias "FOO" +diff -up ./plugins/sudoers/regress/visudo/test3.err.ok.orig ./plugins/sudoers/regress/visudo/test3.err.ok +--- ./plugins/sudoers/regress/visudo/test3.err.ok.orig 2017-04-10 10:13:12.141000000 -0400 ++++ ./plugins/sudoers/regress/visudo/test3.err.ok 2017-04-10 10:13:56.842000000 -0400 +@@ -1,2 +1,2 @@ +-visudo: stdin:1 unused User_Alias "A" +-visudo: stdin:2 unused User_Alias "B" ++Warning: stdin:1 unused User_Alias "A" ++Warning: stdin:2 unused User_Alias "B" diff --git a/SOURCES/sudo-1.8.6p3-ALL-with-negation-manupdate.patch b/SOURCES/sudo-1.8.6p3-ALL-with-negation-manupdate.patch deleted file mode 100644 index ef468e3..0000000 --- a/SOURCES/sudo-1.8.6p3-ALL-with-negation-manupdate.patch +++ /dev/null @@ -1,113 +0,0 @@ -diff -up sudo-1.8.6p3/doc/sudoers.cat.orig sudo-1.8.6p3/doc/sudoers.cat ---- sudo-1.8.6p3/doc/sudoers.cat.orig 2012-09-18 15:57:43.000000000 +0200 -+++ sudo-1.8.6p3/doc/sudoers.cat 2013-07-10 14:57:53.791093835 +0200 -@@ -668,11 +668,24 @@ SSUUDDOOEERRSS FFIILLEE FFO - since in a command context, it allows the user to run aannyy command on the - system. - -- An exclamation point (`!') can be used as a logical _n_o_t operator both in -- an _a_l_i_a_s and in front of a Cmnd. This allows one to exclude certain -- values. Note, however, that using a `!' in conjunction with the built-in -- AALLLL alias to allow a user to run ``all but a few'' commands rarely works -- as intended (see _S_E_C_U_R_I_T_Y _N_O_T_E_S below). -+ An exclamation point (`!') can be used as a logical _n_o_t operator in a -+ list or _a_l_i_a_s as well as in front of a Cmnd. This allows one to exclude -+ certain values. For the `!' operator to be effective, there must be -+ something for it to exclude. For example, to match all users except for -+ root one would use: -+ -+ ALL,!root -+ -+ If the AALLLL, is omitted, as in: -+ -+ !root -+ -+ it would explicitly deny root but not match any other users. This is -+ different from a true ``negation'' operator. -+ -+ Note, however, that using a `!' in conjunction with the built-in AALLLL -+ alias to allow a user to run ``all but a few'' commands rarely works as -+ intended (see _S_E_C_U_R_I_T_Y _N_O_T_E_S below). - - Long lines can be continued with a backslash (`\') as the last character - on the line. -diff -up sudo-1.8.6p3/doc/sudoers.man.in.orig sudo-1.8.6p3/doc/sudoers.man.in ---- sudo-1.8.6p3/doc/sudoers.man.in.orig 2013-07-10 13:00:20.987336061 +0200 -+++ sudo-1.8.6p3/doc/sudoers.man.in 2013-07-10 14:57:53.792093837 +0200 -@@ -1490,11 +1490,37 @@ An exclamation point - (`\&!') - can be used as a logical - \fInot\fR --operator both in an -+operator in a list or - \fIalias\fR --and in front of a -+as well as in front of a - \fRCmnd\fR. - This allows one to exclude certain values. -+For the -+`\&!' -+operator to be effective, there must be something for it to exclude. -+For example, to match all users except for root one would use: -+.nf -+.sp -+.RS 4n -+ALL,!root -+.RE -+.fi -+.PP -+If the -+\fBALL\fR, -+is omitted, as in: -+.nf -+.sp -+.RS 4n -+!root -+.RE -+.fi -+.PP -+it would explicitly deny root but not match any other users. -+This is different from a true -+``negation'' -+operator. -+.PP - Note, however, that using a - `\&!' - in conjunction with the built-in -diff -up sudo-1.8.6p3/doc/sudoers.mdoc.in.orig sudo-1.8.6p3/doc/sudoers.mdoc.in ---- sudo-1.8.6p3/doc/sudoers.mdoc.in.orig 2012-09-18 15:57:43.000000000 +0200 -+++ sudo-1.8.6p3/doc/sudoers.mdoc.in 2013-07-10 14:57:53.793093839 +0200 -@@ -1393,11 +1393,31 @@ An exclamation point - .Pq Ql \&! - can be used as a logical - .Em not --operator both in an -+operator in a list or - .Em alias --and in front of a -+as well as in front of a - .Li Cmnd . - This allows one to exclude certain values. -+For the -+.Ql \&! -+operator to be effective, there must be something for it to exclude. -+For example, to match all users except for root one would use: -+.Bd -literal -offset 4n -+ALL,!root -+.Ed -+.Pp -+If the -+.Sy ALL , -+is omitted, as in: -+.Bd -literal -offset 4n -+!root -+.Ed -+.Pp -+it would explicitly deny root but not match any other users. -+This is different from a true -+.Dq negation -+operator. -+.Pp - Note, however, that using a - .Ql \&! - in conjunction with the built-in diff --git a/SOURCES/sudo-1.8.6p3-aliaswarnonly.patch b/SOURCES/sudo-1.8.6p3-aliaswarnonly.patch deleted file mode 100644 index 4f2a13b..0000000 --- a/SOURCES/sudo-1.8.6p3-aliaswarnonly.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/visudo.c.aliaswarnonly sudo-1.8.6p3/plugins/sudoers/visudo.c ---- sudo-1.8.6p3/plugins/sudoers/visudo.c.aliaswarnonly 2012-09-25 16:19:04.995831784 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/visudo.c 2012-09-25 16:20:15.768964400 +0200 -@@ -1238,7 +1238,7 @@ check_aliases(bool strict, bool quiet) - - /* If all aliases were referenced we will have an empty tree. */ - if (!no_aliases() && !quiet) -- alias_apply(print_unused, strict ? "Error" : "Warning"); -+ alias_apply(print_unused, "Warning"); - - debug_return_int(strict ? errors : 0); - } diff --git a/SOURCES/sudo-1.8.6p3-auditeditor.patch b/SOURCES/sudo-1.8.6p3-auditeditor.patch deleted file mode 100644 index db2c96f..0000000 --- a/SOURCES/sudo-1.8.6p3-auditeditor.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/sudoers.c.auditeditor sudo-1.8.6p3/plugins/sudoers/sudoers.c ---- sudo-1.8.6p3/plugins/sudoers/sudoers.c.auditeditor 2012-09-24 16:16:07.577331344 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/sudoers.c 2012-09-24 16:30:16.738174293 +0200 -@@ -709,7 +709,24 @@ sudoers_policy_main(int argc, char * con - #endif /* HAVE_SELINUX */ - - /* Must audit before uid change. */ -- audit_success(NewArgv); -+ if (ISSET(sudo_mode, MODE_EDIT)) { -+ /* -+ * Build a new argv, argc for the audit system -+ * so that the editor being invoked is visible -+ * in audit messages. -+ */ -+ char *editor = NULL; -+ char **editor_argv = NULL; -+ -+ editor = find_editor(NewArgc - 1, NewArgv + 1, &editor_argv); -+ -+ if (editor) { -+ audit_success(editor_argv); -+ efree(editor_argv); -+ } else -+ errorx(1, _("Can't find an editor")); -+ } else -+ audit_success(NewArgv); - - *command_infop = command_info; - diff --git a/SOURCES/sudo-1.8.6p3-auditrolechange.patch b/SOURCES/sudo-1.8.6p3-auditrolechange.patch deleted file mode 100644 index 90e7331..0000000 --- a/SOURCES/sudo-1.8.6p3-auditrolechange.patch +++ /dev/null @@ -1,45 +0,0 @@ -diff -up sudo-1.8.6p3/src/selinux.c.auditrolechange sudo-1.8.6p3/src/selinux.c ---- sudo-1.8.6p3/src/selinux.c.auditrolechange 2012-09-25 16:29:58.090826474 +0200 -+++ sudo-1.8.6p3/src/selinux.c 2012-09-25 16:33:53.953084178 +0200 -@@ -63,7 +63,7 @@ static struct selinux_state { - #ifdef HAVE_LINUX_AUDIT - static int - audit_role_change(const security_context_t old_context, -- const security_context_t new_context, const char *ttyn) -+ const security_context_t new_context, const char *ttyn, int result) - { - int au_fd, rc = -1; - char *message; -@@ -80,7 +80,7 @@ audit_role_change(const security_context - easprintf(&message, "newrole: old-context=%s new-context=%s", - old_context, new_context); - rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE, -- message, NULL, NULL, ttyn, 1); -+ message, NULL, NULL, ttyn, result); - if (rc <= 0) - warning(_("unable to send audit message")); - efree(message); -@@ -335,8 +335,13 @@ selinux_setup(const char *role, const ch - warningx("your old context was %s", se_state.old_context); - #endif - se_state.new_context = get_exec_context(se_state.old_context, role, type); -- if (!se_state.new_context) -+ if (!se_state.new_context) { -+#ifdef HAVE_LINUX_AUDIT -+ audit_role_change(se_state.old_context, "?", -+ se_state.ttyn, 0); -+#endif - goto done; -+ } - - if (relabel_tty(ttyn, ptyfd) < 0) { - warning(_("unable to setup tty context for %s"), se_state.new_context); -@@ -352,7 +357,7 @@ selinux_setup(const char *role, const ch - - #ifdef HAVE_LINUX_AUDIT - audit_role_change(se_state.old_context, se_state.new_context, -- se_state.ttyn); -+ se_state.ttyn, 1); - #endif - - rval = 0; diff --git a/SOURCES/sudo-1.8.6p3-authinterrupt.patch b/SOURCES/sudo-1.8.6p3-authinterrupt.patch deleted file mode 100644 index 18923d4..0000000 --- a/SOURCES/sudo-1.8.6p3-authinterrupt.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/auth/pam.c.authinterrupt sudo-1.8.6p3/plugins/sudoers/auth/pam.c ---- sudo-1.8.6p3/plugins/sudoers/auth/pam.c.authinterrupt 2014-05-22 13:46:31.204706184 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/auth/pam.c 2014-05-22 13:47:06.729830043 +0200 -@@ -167,13 +167,13 @@ sudo_pam_verify(struct passwd *pw, char - /* FALLTHROUGH */ - case PAM_AUTH_ERR: - case PAM_AUTHINFO_UNAVAIL: -+ case PAM_PERM_DENIED: - if (getpass_error) { - /* error or ^C from tgetpass() */ - debug_return_int(AUTH_INTR); - } - /* FALLTHROUGH */ - case PAM_MAXTRIES: -- case PAM_PERM_DENIED: - debug_return_int(AUTH_FAILURE); - default: - if ((s = pam_strerror(pamh, *pam_status))) -@@ -343,6 +343,7 @@ converse(int num_msg, PAM_CONST struct p - if (pass == NULL) { - /* Error (or ^C) reading password, don't try again. */ - getpass_error = 1; -+ ret = PAM_CONV_ERR; - #if (defined(__darwin__) || defined(__APPLE__)) && !defined(OPENPAM_VERSION) - pass = ""; - #else diff --git a/SOURCES/sudo-1.8.6p3-cycledetect.patch b/SOURCES/sudo-1.8.6p3-cycledetect.patch deleted file mode 100644 index e2c9b87..0000000 --- a/SOURCES/sudo-1.8.6p3-cycledetect.patch +++ /dev/null @@ -1,477 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/alias.c.cycledetect sudo-1.8.6p3/plugins/sudoers/alias.c ---- sudo-1.8.6p3/plugins/sudoers/alias.c.cycledetect 2012-09-18 15:56:29.000000000 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/alias.c 2013-08-09 10:52:04.785860905 +0200 -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2004-2005, 2007-2011 -+ * Copyright (c) 2004-2005, 2007-2013 - * Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any -@@ -50,7 +50,6 @@ - * Globals - */ - struct rbtree *aliases; --unsigned int alias_seqno; - - /* - * Comparison function for the red-black tree. -@@ -76,29 +75,31 @@ alias_compare(const void *v1, const void - /* - * Search the tree for an alias with the specified name and type. - * Returns a pointer to the alias structure or NULL if not found. -+ * Caller is responsible for calling alias_put() on the returned -+ * alias to mark it as unused. - */ - struct alias * --alias_find(char *name, int type) -+alias_get(char *name, int type) - { - struct alias key; - struct rbnode *node; - struct alias *a = NULL; -- debug_decl(alias_find, SUDO_DEBUG_ALIAS) -+ debug_decl(alias_get, SUDO_DEBUG_ALIAS) - - key.name = name; - key.type = type; - if ((node = rbfind(aliases, &key)) != NULL) { - /* -- * Compare the global sequence number with the one stored -- * in the alias. If they match then we've seen this alias -- * before and found a loop. -+ * Check whether this alias is already in use. -+ * If so, we've detected a loop. If not, set the flag, -+ * which the caller should clear with a call to alias_put(). - */ - a = node->data; -- if (a->seqno == alias_seqno) { -+ if (a->used) { - errno = ELOOP; - debug_return_ptr(NULL); - } -- a->seqno = alias_seqno; -+ a->used = true; - } else { - errno = ENOENT; - } -@@ -106,6 +107,17 @@ alias_find(char *name, int type) - } - - /* -+ * Clear the "used" flag in an alias once the caller is done with it. -+ */ -+void -+alias_put(struct alias *a) -+{ -+ debug_decl(alias_put, SUDO_DEBUG_ALIAS) -+ a->used = false; -+ debug_return; -+} -+ -+/* - * Add an alias to the aliases redblack tree. - * Returns NULL on success and an error string on failure. - */ -@@ -119,7 +131,7 @@ alias_add(char *name, int type, struct m - a = ecalloc(1, sizeof(*a)); - a->name = name; - a->type = type; -- /* a->seqno = 0; */ -+ /* a->used = false; */ - list2tq(&a->members, members); - if (rbinsert(aliases, a)) { - snprintf(errbuf, sizeof(errbuf), _("Alias `%s' already defined"), name); -diff -up sudo-1.8.6p3/plugins/sudoers/match.c.cycledetect sudo-1.8.6p3/plugins/sudoers/match.c ---- sudo-1.8.6p3/plugins/sudoers/match.c.cycledetect 2013-08-09 10:52:04.783860895 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/match.c 2013-08-09 10:52:04.785860905 +0200 -@@ -101,13 +101,13 @@ static bool command_matches_normal(char - * Check for user described by pw in a list of members. - * Returns ALLOW, DENY or UNSPEC. - */ --static int --_userlist_matches(struct passwd *pw, struct member_list *list) -+int -+userlist_matches(struct passwd *pw, struct member_list *list) - { - struct member *m; - struct alias *a; - int rval, matched = UNSPEC; -- debug_decl(_userlist_matches, SUDO_DEBUG_MATCH) -+ debug_decl(userlist_matches, SUDO_DEBUG_MATCH) - - tq_foreach_rev(list, m) { - switch (m->type) { -@@ -123,10 +123,11 @@ _userlist_matches(struct passwd *pw, str - matched = !m->negated; - break; - case ALIAS: -- if ((a = alias_find(m->name, USERALIAS)) != NULL) { -- rval = _userlist_matches(pw, &a->members); -+ if ((a = alias_get(m->name, USERALIAS)) != NULL) { -+ rval = userlist_matches(pw, &a->members); - if (rval != UNSPEC) - matched = m->negated ? !rval : rval; -+ alias_put(a); - break; - } - /* FALLTHROUGH */ -@@ -141,20 +142,13 @@ _userlist_matches(struct passwd *pw, str - debug_return_bool(matched); - } - --int --userlist_matches(struct passwd *pw, struct member_list *list) --{ -- alias_seqno++; -- return _userlist_matches(pw, list); --} -- - /* - * Check for user described by pw in a list of members. - * If both lists are empty compare against def_runas_default. - * Returns ALLOW, DENY or UNSPEC. - */ --static int --_runaslist_matches(struct member_list *user_list, -+int -+runaslist_matches(struct member_list *user_list, - struct member_list *group_list, struct member **matching_user, - struct member **matching_group) - { -@@ -163,7 +157,7 @@ _runaslist_matches(struct member_list *u - int rval; - int user_matched = UNSPEC; - int group_matched = UNSPEC; -- debug_decl(_runaslist_matches, SUDO_DEBUG_MATCH) -+ debug_decl(runaslist_matches, SUDO_DEBUG_MATCH) - - if (runas_pw != NULL) { - /* If no runas user or runas group listed in sudoers, use default. */ -@@ -184,11 +178,12 @@ _runaslist_matches(struct member_list *u - user_matched = !m->negated; - break; - case ALIAS: -- if ((a = alias_find(m->name, RUNASALIAS)) != NULL) { -- rval = _runaslist_matches(&a->members, &empty, -+ 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 */ -@@ -221,11 +216,12 @@ _runaslist_matches(struct member_list *u - group_matched = !m->negated; - break; - case ALIAS: -- if ((a = alias_find(m->name, RUNASALIAS)) != NULL) { -- rval = _runaslist_matches(&empty, &a->members, -+ 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 */ -@@ -253,27 +249,17 @@ _runaslist_matches(struct member_list *u - debug_return_int(UNSPEC); - } - --int --runaslist_matches(struct member_list *user_list, -- struct member_list *group_list, struct member **matching_user, -- struct member **matching_group) --{ -- alias_seqno++; -- return _runaslist_matches(user_list ? user_list : &empty, -- group_list ? group_list : &empty, matching_user, matching_group); --} -- - /* - * Check for host and shost in a list of members. - * Returns ALLOW, DENY or UNSPEC. - */ --static int --_hostlist_matches(struct member_list *list) -+int -+hostlist_matches(struct member_list *list) - { - struct member *m; - struct alias *a; - int rval, matched = UNSPEC; -- debug_decl(_hostlist_matches, SUDO_DEBUG_MATCH) -+ debug_decl(hostlist_matches, SUDO_DEBUG_MATCH) - - tq_foreach_rev(list, m) { - switch (m->type) { -@@ -289,10 +275,11 @@ _hostlist_matches(struct member_list *li - matched = !m->negated; - break; - case ALIAS: -- if ((a = alias_find(m->name, HOSTALIAS)) != NULL) { -- rval = _hostlist_matches(&a->members); -+ if ((a = alias_get(m->name, HOSTALIAS)) != NULL) { -+ rval = hostlist_matches(&a->members); - if (rval != UNSPEC) - matched = m->negated ? !rval : rval; -+ alias_put(a); - break; - } - /* FALLTHROUGH */ -@@ -307,23 +294,16 @@ _hostlist_matches(struct member_list *li - debug_return_bool(matched); - } - --int --hostlist_matches(struct member_list *list) --{ -- alias_seqno++; -- return _hostlist_matches(list); --} -- - /* - * Check for cmnd and args in a list of members. - * Returns ALLOW, DENY or UNSPEC. - */ --static int --_cmndlist_matches(struct member_list *list) -+int -+cmndlist_matches(struct member_list *list) - { - struct member *m; - int matched = UNSPEC; -- debug_decl(_cmndlist_matches, SUDO_DEBUG_MATCH) -+ debug_decl(cmndlist_matches, SUDO_DEBUG_MATCH) - - tq_foreach_rev(list, m) { - matched = cmnd_matches(m); -@@ -333,13 +313,6 @@ _cmndlist_matches(struct member_list *li - debug_return_bool(matched); - } - --int --cmndlist_matches(struct member_list *list) --{ -- alias_seqno++; -- return _cmndlist_matches(list); --} -- - /* - * Check cmnd and args. - * Returns ALLOW, DENY or UNSPEC. -@@ -357,11 +330,11 @@ cmnd_matches(struct member *m) - matched = !m->negated; - break; - case ALIAS: -- alias_seqno++; -- if ((a = alias_find(m->name, CMNDALIAS)) != NULL) { -- rval = _cmndlist_matches(&a->members); -+ if ((a = alias_get(m->name, CMNDALIAS)) != NULL) { -+ rval = cmndlist_matches(&a->members); - if (rval != UNSPEC) - matched = m->negated ? !rval : rval; -+ alias_put(a); - } - break; - case COMMAND: -diff -up sudo-1.8.6p3/plugins/sudoers/parse.c.cycledetect sudo-1.8.6p3/plugins/sudoers/parse.c ---- sudo-1.8.6p3/plugins/sudoers/parse.c.cycledetect 2012-09-18 15:57:43.000000000 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/parse.c 2013-08-09 10:52:04.785860905 +0200 -@@ -676,13 +676,14 @@ _print_member(struct lbuf *lbuf, char *n - } - break; - case ALIAS: -- if ((a = alias_find(name, alias_type)) != NULL) { -+ if ((a = alias_get(name, alias_type)) != NULL) { - tq_foreach_fwd(&a->members, m) { - if (m != tq_first(&a->members)) - lbuf_append(lbuf, ", "); - _print_member(lbuf, m->name, m->type, - negated ? !m->negated : m->negated, alias_type); - } -+ alias_put(a); - break; - } - /* FALLTHROUGH */ -@@ -697,6 +698,5 @@ static void - print_member(struct lbuf *lbuf, char *name, int type, int negated, - int alias_type) - { -- alias_seqno++; - _print_member(lbuf, name, type, negated, alias_type); - } -diff -up sudo-1.8.6p3/plugins/sudoers/parse.h.cycledetect sudo-1.8.6p3/plugins/sudoers/parse.h ---- sudo-1.8.6p3/plugins/sudoers/parse.h.cycledetect 2012-09-18 15:56:29.000000000 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/parse.h 2013-08-09 10:54:30.984565529 +0200 -@@ -148,7 +148,7 @@ struct runascontainer { - struct alias { - char *name; /* alias name */ - unsigned short type; /* {USER,HOST,RUNAS,CMND}ALIAS */ -- unsigned short seqno; /* sequence number */ -+ bool used; /* "used" flag for cycle detection */ - struct member_list members; /* list of alias members */ - }; - -@@ -170,35 +170,39 @@ struct defaults { - extern struct userspec_list userspecs; - extern struct defaults_list defaults; - --/* -- * Alias sequence number to avoid loops. -- */ --extern unsigned int alias_seqno; -- --/* -- * Prototypes -- */ --char *alias_add(char *, int, struct member *); --bool addr_matches(char *); --int cmnd_matches(struct member *); --int cmndlist_matches(struct member_list *); --bool command_matches(char *, char *); --int hostlist_matches(struct member_list *); --bool hostname_matches(char *, char *, char *); --bool netgr_matches(char *, char *, char *, char *); -+/* alias.c */ - bool no_aliases(void); --int runaslist_matches(struct member_list *, struct member_list *, struct member **, struct member **); --int userlist_matches(struct passwd *, struct member_list *); --bool usergr_matches(char *, char *, struct passwd *); --bool userpw_matches(char *, char *, struct passwd *); --bool group_matches(char *, struct group *); --struct alias *alias_find(char *, int); --struct alias *alias_remove(char *, int); --void alias_free(void *); --void alias_apply(int (*)(void *, void *), void *); -+char *alias_add(char *name, int type, struct member *members); -+int alias_compare(const void *a1, const void *a2); -+struct alias *alias_get(char *name, int type); -+struct alias *alias_remove(char *name, int type); -+void alias_apply(int (*func)(void *, void *), void *cookie); -+void alias_free(void *a); -+void alias_put(struct alias *a); - void init_aliases(void); --void init_lexer(void); -+/* gram.c */ - void init_parser(const char *, bool); --int alias_compare(const void *, const void *); -+ -+/* match_addr.c */ -+bool addr_matches(char *n); -+ -+/* match.c */ -+bool command_matches(char *sudoers_cmnd, char *sudoers_args); -+bool group_matches(char *sudoers_group, struct group *gr); -+bool hostname_matches(char *shost, char *lhost, char *pattern); -+bool netgr_matches(char *netgr, char *lhost, char *shost, char *user); -+bool usergr_matches(char *group, char *user, struct passwd *pw); -+bool userpw_matches(char *sudoers_user, char *user, struct passwd *pw); -+int cmnd_matches(struct member *m); -+int cmndlist_matches(struct member_list *list); -+int hostlist_matches(struct member_list *list); -+int runaslist_matches(struct member_list *user_list, struct member_list *group_list, struct member **matching_user, struct member **matching_group); -+int userlist_matches(struct passwd *pw, struct member_list *list); -+ -+/* toke.c */ -+ void init_lexer(void); -+ -+/* base64.c */ -+ size_t base64_decode(const char *str, unsigned char *dst, size_t dsize); - - #endif /* _SUDO_PARSE_H */ -diff -up sudo-1.8.6p3/plugins/sudoers/visudo.c.cycledetect sudo-1.8.6p3/plugins/sudoers/visudo.c ---- sudo-1.8.6p3/plugins/sudoers/visudo.c.cycledetect 2013-08-09 10:52:04.759860779 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/visudo.c 2013-08-09 10:52:04.786860910 +0200 -@@ -1084,7 +1084,6 @@ alias_remove_recursive(char *name, int t - } - rbinsert(alias_freelist, a); - } -- alias_seqno++; - debug_return_bool(rval); - } - -@@ -1096,12 +1095,13 @@ check_alias(char *name, int type, int st - int errors = 0; - debug_decl(check_alias, SUDO_DEBUG_ALIAS) - -- if ((a = alias_find(name, type)) != NULL) { -+ if ((a = alias_get(name, type)) != NULL) { - /* check alias contents */ - tq_foreach_fwd(&a->members, m) { - if (m->type == ALIAS) - errors += check_alias(m->name, type, strict, quiet); - } -+ alias_put(a); - } else { - if (!quiet) { - char *fmt; -@@ -1146,26 +1146,22 @@ check_aliases(bool strict, bool quiet) - tq_foreach_fwd(&userspecs, us) { - tq_foreach_fwd(&us->users, m) { - if (m->type == ALIAS) { -- alias_seqno++; - errors += check_alias(m->name, USERALIAS, strict, quiet); - } - } - tq_foreach_fwd(&us->privileges, priv) { - tq_foreach_fwd(&priv->hostlist, m) { - if (m->type == ALIAS) { -- alias_seqno++; - errors += check_alias(m->name, HOSTALIAS, strict, quiet); - } - } - tq_foreach_fwd(&priv->cmndlist, cs) { - tq_foreach_fwd(&cs->runasuserlist, m) { - if (m->type == ALIAS) { -- alias_seqno++; - errors += check_alias(m->name, RUNASALIAS, strict, quiet); - } - } - if ((m = cs->cmnd)->type == ALIAS) { -- alias_seqno++; - errors += check_alias(m->name, CMNDALIAS, strict, quiet); - } - } -@@ -1176,7 +1172,6 @@ check_aliases(bool strict, bool quiet) - tq_foreach_fwd(&userspecs, us) { - tq_foreach_fwd(&us->users, m) { - if (m->type == ALIAS) { -- alias_seqno++; - if (!alias_remove_recursive(m->name, USERALIAS)) - errors++; - } -@@ -1184,7 +1179,6 @@ check_aliases(bool strict, bool quiet) - tq_foreach_fwd(&us->privileges, priv) { - tq_foreach_fwd(&priv->hostlist, m) { - if (m->type == ALIAS) { -- alias_seqno++; - if (!alias_remove_recursive(m->name, HOSTALIAS)) - errors++; - } -@@ -1192,13 +1186,11 @@ check_aliases(bool strict, bool quiet) - tq_foreach_fwd(&priv->cmndlist, cs) { - tq_foreach_fwd(&cs->runasuserlist, m) { - if (m->type == ALIAS) { -- alias_seqno++; - if (!alias_remove_recursive(m->name, RUNASALIAS)) - errors++; - } - } - if ((m = cs->cmnd)->type == ALIAS) { -- alias_seqno++; - if (!alias_remove_recursive(m->name, CMNDALIAS)) - errors++; - } -@@ -1225,7 +1217,6 @@ check_aliases(bool strict, bool quiet) - tq_foreach_fwd(&d->binding, binding) { - for (m = binding; m != NULL; m = m->next) { - if (m->type == ALIAS) { -- alias_seqno++; - if (!alias_remove_recursive(m->name, atype)) - errors++; - } diff --git a/SOURCES/sudo-1.8.6p3-doublequotefix.patch b/SOURCES/sudo-1.8.6p3-doublequotefix.patch index 4ac2d50..c028017 100644 --- a/SOURCES/sudo-1.8.6p3-doublequotefix.patch +++ b/SOURCES/sudo-1.8.6p3-doublequotefix.patch @@ -1,24 +1,46 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/toke.c.doublequotefix sudo-1.8.6p3/plugins/sudoers/toke.c ---- sudo-1.8.6p3/plugins/sudoers/toke.c.doublequotefix 2014-05-19 14:28:27.536399410 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/toke.c 2014-05-19 14:29:51.084714355 +0200 -@@ -1851,7 +1851,7 @@ YY_RULE_SETUP +From 1b16310c7ec5ba23fbe066c7d000016e534b4448 Mon Sep 17 00:00:00 2001 +From: Tomas Sykora +Date: Tue, 16 Aug 2016 09:54:06 +0200 +Subject: [PATCH] Double quotes are not accepted in sudoers + +Regression in sudo 1.8.6p3-7 package, double quotes are not accepted in sudoers + +Rebased from: +Patch25: sudo-1.8.6p3-doublequotefix.patch + +Resolves: +rhbz#1092499 +--- + plugins/sudoers/toke.c | 2 +- + plugins/sudoers/toke.l | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c +index e5b4d97..3b510bb 100644 +--- a/plugins/sudoers/toke.c ++++ b/plugins/sudoers/toke.c +@@ -2385,7 +2385,7 @@ YY_RULE_SETUP LEXTRACE("ERROR "); /* empty string */ LEXRETURN(ERROR); } - if (prev_state == INITIAL) { + if (prev_state == INITIAL || prev_state == GOTDEFS) { - switch (yylval.string[0]) { + switch (sudoerslval.string[0]) { case '%': - if (yylval.string[1] == '\0' || -diff -up sudo-1.8.6p3/plugins/sudoers/toke.l.doublequotefix sudo-1.8.6p3/plugins/sudoers/toke.l ---- sudo-1.8.6p3/plugins/sudoers/toke.l.doublequotefix 2014-05-19 14:28:36.932438977 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/toke.l 2014-05-19 14:29:27.769626995 +0200 -@@ -197,7 +197,7 @@ DEFVAR [a-z_]+ + if (sudoerslval.string[1] == '\0' || +diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l +index b63edd0..82724aa 100644 +--- a/plugins/sudoers/toke.l ++++ b/plugins/sudoers/toke.l +@@ -185,7 +185,7 @@ DEFVAR [a-z_]+ LEXTRACE("ERROR "); /* empty string */ LEXRETURN(ERROR); } - if (prev_state == INITIAL) { + if (prev_state == INITIAL || prev_state == GOTDEFS) { - switch (yylval.string[0]) { + switch (sudoerslval.string[0]) { case '%': - if (yylval.string[1] == '\0' || + if (sudoerslval.string[1] == '\0' || +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.6p3-emallocfail.patch b/SOURCES/sudo-1.8.6p3-emallocfail.patch deleted file mode 100644 index 91792df..0000000 --- a/SOURCES/sudo-1.8.6p3-emallocfail.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.emallocfail sudo-1.8.6p3/plugins/sudoers/sssd.c ---- sudo-1.8.6p3/plugins/sudoers/sssd.c.emallocfail 2012-11-23 15:58:20.139417659 +0100 -+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2012-11-23 15:58:26.732437421 +0100 -@@ -212,7 +212,12 @@ sudo_sss_filter_result(struct sudo_sss_h - sudo_debug_printf(SUDO_DEBUG_DEBUG, - "reallocating result: %p (count: %u -> %u)", out_res->rules, - in_res->num_rules, l); -- out_res->rules = erealloc3(out_res->rules, l, sizeof(struct sss_sudo_rule)); -+ if (l > 0) -+ out_res->rules = erealloc3(out_res->rules, l, sizeof(struct sss_sudo_rule)); -+ else { -+ efree(out_res->rules); -+ out_res->rules = NULL; -+ } - } - - out_res->num_rules = l; diff --git a/SOURCES/sudo-1.8.6p3-lbufexpandcode.patch b/SOURCES/sudo-1.8.6p3-lbufexpandcode.patch deleted file mode 100644 index 70a4c13..0000000 --- a/SOURCES/sudo-1.8.6p3-lbufexpandcode.patch +++ /dev/null @@ -1,138 +0,0 @@ -diff -up sudo-1.8.6p3/common/lbuf.c.lbufexpandcode sudo-1.8.6p3/common/lbuf.c ---- sudo-1.8.6p3/common/lbuf.c.lbufexpandcode 2013-08-12 17:28:52.429562473 +0200 -+++ sudo-1.8.6p3/common/lbuf.c 2013-08-12 17:29:21.486668465 +0200 -@@ -77,6 +77,17 @@ lbuf_destroy(struct lbuf *lbuf) - debug_return; - } - -+static void -+lbuf_expand(struct lbuf *lbuf, size_t extra) -+{ -+ if (lbuf->len + extra + 1 >= lbuf->size) { -+ do { -+ lbuf->size += 256; -+ } while (lbuf->len + extra + 1 >= lbuf->size); -+ lbuf->buf = erealloc(lbuf->buf, lbuf->size); -+ } -+} -+ - /* - * Parse the format and append strings, only %s and %% escapes are supported. - * Any characters in set are quoted with a backslash. -@@ -86,47 +97,40 @@ lbuf_append_quoted(struct lbuf *lbuf, co - { - va_list ap; - int len; -- char *cp, *s = NULL; -+ char *cp, *s; - debug_decl(lbuf_append_quoted, SUDO_DEBUG_UTIL) - - va_start(ap, fmt); - while (*fmt != '\0') { -- len = 1; - if (fmt[0] == '%' && fmt[1] == 's') { -- s = va_arg(ap, char *); -- len = strlen(s); -- } -- /* Assume worst case that all chars must be escaped. */ -- if (lbuf->len + (len * 2) + 1 >= lbuf->size) { -- do { -- lbuf->size += 256; -- } while (lbuf->len + len + 1 >= lbuf->size); -- lbuf->buf = erealloc(lbuf->buf, lbuf->size); -- } -- if (*fmt == '%') { -- if (*(++fmt) == 's') { -- while ((cp = strpbrk(s, set)) != NULL) { -- len = (int)(cp - s); -- memcpy(lbuf->buf + lbuf->len, s, len); -- lbuf->len += len; -- lbuf->buf[lbuf->len++] = '\\'; -- lbuf->buf[lbuf->len++] = *cp; -- s = cp + 1; -- } -- if (*s != '\0') { -- len = strlen(s); -- memcpy(lbuf->buf + lbuf->len, s, len); -- lbuf->len += len; -- } -- fmt++; -- continue; -+ if ((s = va_arg(ap, char *)) == NULL) -+ goto done; -+ while ((cp = strpbrk(s, set)) != NULL) { -+ len = (int)(cp - s); -+ lbuf_expand(lbuf, len + 2); -+ memcpy(lbuf->buf + lbuf->len, s, len); -+ lbuf->len += len; -+ lbuf->buf[lbuf->len++] = '\\'; -+ lbuf->buf[lbuf->len++] = *cp; -+ s = cp + 1; - } -+ if (*s != '\0') { -+ len = strlen(s); -+ lbuf_expand(lbuf, len); -+ memcpy(lbuf->buf + lbuf->len, s, len); -+ lbuf->len += len; -+ } -+ fmt += 2; -+ continue; - } -+ lbuf_expand(lbuf, 2); - if (strchr(set, *fmt) != NULL) - lbuf->buf[lbuf->len++] = '\\'; - lbuf->buf[lbuf->len++] = *fmt++; - } -- lbuf->buf[lbuf->len] = '\0'; -+done: -+ if (lbuf->size != 0) -+ lbuf->buf[lbuf->len] = '\0'; - va_end(ap); - - debug_return; -@@ -140,33 +144,27 @@ lbuf_append(struct lbuf *lbuf, const cha - { - va_list ap; - int len; -- char *s = NULL; -+ char *s; - debug_decl(lbuf_append, SUDO_DEBUG_UTIL) - - va_start(ap, fmt); - while (*fmt != '\0') { -- len = 1; - if (fmt[0] == '%' && fmt[1] == 's') { -- s = va_arg(ap, char *); -+ if ((s = va_arg(ap, char *)) == NULL) -+ goto done; - len = strlen(s); -+ lbuf_expand(lbuf, len); -+ memcpy(lbuf->buf + lbuf->len, s, len); -+ lbuf->len += len; -+ fmt += 2; -+ continue; - } -- if (lbuf->len + len + 1 >= lbuf->size) { -- do { -- lbuf->size += 256; -- } while (lbuf->len + len + 1 >= lbuf->size); -- lbuf->buf = erealloc(lbuf->buf, lbuf->size); -- } -- if (*fmt == '%') { -- if (*(++fmt) == 's') { -- memcpy(lbuf->buf + lbuf->len, s, len); -- lbuf->len += len; -- fmt++; -- continue; -- } -- } -+ lbuf_expand(lbuf, 1); - lbuf->buf[lbuf->len++] = *fmt++; - } -- lbuf->buf[lbuf->len] = '\0'; -+done: -+ if (lbuf->size != 0) -+ lbuf->buf[lbuf->len] = '\0'; - va_end(ap); - - debug_return; diff --git a/SOURCES/sudo-1.8.6p3-ldap-sssd-usermatch.patch b/SOURCES/sudo-1.8.6p3-ldap-sssd-usermatch.patch deleted file mode 100644 index 1058cd2..0000000 --- a/SOURCES/sudo-1.8.6p3-ldap-sssd-usermatch.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/ldap.c.usermatch sudo-1.8.6p3/plugins/sudoers/ldap.c ---- sudo-1.8.6p3/plugins/sudoers/ldap.c.usermatch 2012-11-23 15:57:00.084176086 +0100 -+++ sudo-1.8.6p3/plugins/sudoers/ldap.c 2012-11-23 15:57:21.491239877 +0100 -@@ -742,7 +742,7 @@ sudo_ldap_check_runas_user(LDAP *ld, LDA - } - /* FALLTHROUGH */ - default: -- if (strcasecmp(val, runas_pw->pw_name) == 0) -+ if (userpw_matches(val, runas_pw->pw_name, runas_pw)) - ret = true; - break; - } -diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.usermatch sudo-1.8.6p3/plugins/sudoers/sssd.c ---- sudo-1.8.6p3/plugins/sudoers/sssd.c.usermatch 2012-11-23 15:57:12.234211662 +0100 -+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2012-11-23 15:57:21.492239881 +0100 -@@ -466,7 +466,7 @@ sudo_sss_check_runas_user(struct sudo_ss - /* FALLTHROUGH */ - sudo_debug_printf(SUDO_DEBUG_DEBUG, "FALLTHROUGH"); - default: -- if (strcasecmp(val, runas_pw->pw_name) == 0) { -+ if (userpw_matches(val, runas_pw->pw_name, runas_pw)) { - sudo_debug_printf(SUDO_DEBUG_DEBUG, - "%s == %s (pw_name) => match", val, runas_pw->pw_name); - ret = true; diff --git a/SOURCES/sudo-1.8.6p3-ldapconfparse.patch b/SOURCES/sudo-1.8.6p3-ldapconfparse.patch deleted file mode 100644 index b73ae0f..0000000 --- a/SOURCES/sudo-1.8.6p3-ldapconfparse.patch +++ /dev/null @@ -1,45 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/ldap.c.confparse sudo-1.8.6p3/plugins/sudoers/ldap.c ---- sudo-1.8.6p3/plugins/sudoers/ldap.c.confparse 2012-11-23 15:46:41.801008370 +0100 -+++ sudo-1.8.6p3/plugins/sudoers/ldap.c 2012-11-23 15:46:07.903885738 +0100 -@@ -1343,6 +1343,32 @@ sudo_ldap_parse_keyword(const char *keyw - debug_return_bool(false); - } - -+/* -+ * Read a line of input, remove whole line comments and strip off leading -+ * and trailing spaces. Returns static storage that is reused. -+ */ -+static char * -+sudo_ldap_parseln(FILE *fp) -+{ -+ size_t len; -+ char *cp = NULL; -+ static char buf[LINE_MAX]; -+ -+ if (fgets(buf, sizeof(buf), fp) != NULL) { -+ /* Remove comments */ -+ if (*buf == '#') -+ *buf = '\0'; -+ -+ /* Trim leading and trailing whitespace/newline */ -+ len = strlen(buf); -+ while (len > 0 && isspace((unsigned char)buf[len - 1])) -+ buf[--len] = '\0'; -+ for (cp = buf; isblank(*cp); cp++) -+ continue; -+ } -+ return(cp); -+} -+ - static bool - sudo_ldap_read_config(void) - { -@@ -1364,7 +1390,7 @@ sudo_ldap_read_config(void) - if ((fp = fopen(_PATH_LDAP_CONF, "r")) == NULL) - debug_return_bool(false); - -- while ((cp = sudo_parseln(fp)) != NULL) { -+ while ((cp = sudo_ldap_parseln(fp)) != NULL) { - if (*cp == '\0') - continue; /* skip empty line */ - diff --git a/SOURCES/sudo-1.8.6p3-mantypo.patch b/SOURCES/sudo-1.8.6p3-mantypo.patch deleted file mode 100644 index 8b79d91..0000000 --- a/SOURCES/sudo-1.8.6p3-mantypo.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up sudo-1.8.6p3/doc/sudoers.man.in.mantypo sudo-1.8.6p3/doc/sudoers.man.in ---- sudo-1.8.6p3/doc/sudoers.man.in.mantypo 2012-09-24 16:38:33.946465411 +0200 -+++ sudo-1.8.6p3/doc/sudoers.man.in 2012-09-24 16:39:01.400941691 +0200 -@@ -1408,7 +1408,7 @@ to include the file - The - \fR#includedir\fR - directive can be used to create a --\fIsudo.d\fR -+\fIsudoers.d\fR - directory that the system package manager can drop - \fIsudoers\fR - rules diff --git a/SOURCES/sudo-1.8.6p3-mantypos-ldap.patch b/SOURCES/sudo-1.8.6p3-mantypos-ldap.patch deleted file mode 100644 index 57fbfba..0000000 --- a/SOURCES/sudo-1.8.6p3-mantypos-ldap.patch +++ /dev/null @@ -1,74 +0,0 @@ -diff -up sudo-1.8.6p3/doc/sudoers.ldap.cat.mantypos-ldap sudo-1.8.6p3/doc/sudoers.ldap.cat ---- sudo-1.8.6p3/doc/sudoers.ldap.cat.mantypos-ldap 2012-09-18 15:57:43.000000000 +0200 -+++ sudo-1.8.6p3/doc/sudoers.ldap.cat 2015-04-16 11:24:08.277692534 +0200 -@@ -119,7 +119,7 @@ DDEESSCCRRIIPPTTIIOONN - ssuuddooNNoottAAfftteerr - A timestamp in the form yyyymmddHHMMSSZ that indicates an - expiration date/time, after which the sudoRole will no longer be -- valid. If multiple sudoNotBefore entries are present, the last one -+ valid. If multiple sudoNotAfter entries are present, the last one - is used. Note that timestamps must be in Coordinated Universal - Time (UTC), not the local timezone. The minute and seconds - portions are optional, but some LDAP servers require that they be -@@ -134,8 +134,8 @@ DDEESSCCRRIIPPTTIIOONN - inherent order. The sudoOrder attribute is an integer (or floating - point value for LDAP servers that support it) that is used to sort - the matching entries. This allows LDAP-based sudoers entries to -- more closely mimic the behaviour of the sudoers file, where the of -- the entries influences the result. If multiple entries match, the -+ more closely mimic the behaviour of the sudoers file, where the order -+ of the entries influences the result. If multiple entries match, the - entry with the highest sudoOrder attribute is chosen. This - corresponds to the ``last match'' behavior of the sudoers file. If - the sudoOrder attribute is not present, a value of 0 is assumed. -diff -up sudo-1.8.6p3/doc/sudoers.ldap.man.in.mantypos-ldap sudo-1.8.6p3/doc/sudoers.ldap.man.in ---- sudo-1.8.6p3/doc/sudoers.ldap.man.in.mantypos-ldap 2012-09-18 15:57:43.000000000 +0200 -+++ sudo-1.8.6p3/doc/sudoers.ldap.man.in 2015-04-16 11:24:08.277692534 +0200 -@@ -238,7 +238,7 @@ that indicates an expiration date/time, - \fRsudoRole\fR - will no longer be valid. - If multiple --\fRsudoNotBefore\fR -+\fRsudoNotAfter\fR - entries are present, the last one is used. - Note that timestamps must be in Coordinated Universal Time (UTC), - not the local timezone. -@@ -264,7 +264,7 @@ The - attribute is an integer (or floating point value for LDAP servers - that support it) that is used to sort the matching entries. - This allows LDAP-based sudoers entries to more closely mimic the behaviour --of the sudoers file, where the of the entries influences the result. -+of the sudoers file, where the order of the entries influences the result. - If multiple entries match, the entry with the highest - \fRsudoOrder\fR - attribute is chosen. -diff -up sudo-1.8.6p3/doc/sudoers.ldap.mdoc.in.mantypos-ldap sudo-1.8.6p3/doc/sudoers.ldap.mdoc.in ---- sudo-1.8.6p3/doc/sudoers.ldap.mdoc.in.mantypos-ldap 2012-09-18 15:57:43.000000000 +0200 -+++ sudo-1.8.6p3/doc/sudoers.ldap.mdoc.in 2015-04-16 11:32:51.574469447 +0200 -@@ -15,7 +15,7 @@ - .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - .\" - .Dd July 12, 2012 --.Dt SUDOERS.LDAP @mansectsu@ -+.Dt SUDOERS.LDAP @mansectform@ - .Os Sudo @PACKAGE_VERSION@ - .Sh NAME - .Nm sudoers.ldap -@@ -224,7 +224,7 @@ that indicates an expiration date/time, - .Li sudoRole - will no longer be valid. - If multiple --.Li sudoNotBefore -+.Li sudoNotAfter - entries are present, the last one is used. - Note that timestamps must be in Coordinated Universal Time (UTC), - not the local timezone. -@@ -249,7 +249,7 @@ The - attribute is an integer (or floating point value for LDAP servers - that support it) that is used to sort the matching entries. - This allows LDAP-based sudoers entries to more closely mimic the behaviour --of the sudoers file, where the of the entries influences the result. -+of the sudoers file, where the order of the entries influences the result. - If multiple entries match, the entry with the highest - .Li sudoOrder - attribute is chosen. diff --git a/SOURCES/sudo-1.8.6p3-netgrfilterfix.patch b/SOURCES/sudo-1.8.6p3-netgrfilterfix.patch deleted file mode 100644 index 0118511..0000000 --- a/SOURCES/sudo-1.8.6p3-netgrfilterfix.patch +++ /dev/null @@ -1,92 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.netgrfilterfix sudo-1.8.6p3/plugins/sudoers/sssd.c ---- sudo-1.8.6p3/plugins/sudoers/sssd.c.netgrfilterfix 2014-07-30 13:29:47.713823996 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2014-07-30 13:30:08.917436088 +0200 -@@ -614,16 +615,13 @@ sudo_sss_check_host(struct sudo_sss_hand - } - - /* -- * Look for netgroup specifcations in the sudoUser attribute and -- * if found, filter according to netgroup membership. -- * returns: -- * true -> netgroup spec found && negroup member -- * false -> netgroup spec found && not a meber of netgroup -- * true -> netgroup spec not found (filtered by SSSD already, netgroups are an exception) -+ * SSSD doesn't handle netgroups, we have to ensure they are correctly filtered -+ * in sudo. The rules may contain mixed sudoUser specification so we have to check -+ * not only for netgroup membership but also for user and group matches. - */ --bool sudo_sss_filter_user_netgroup(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) -+bool sudo_sss_filter_sudoUser(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) - { -- bool ret = false, netgroup_spec_found = false; -+ bool ret = false; - char **val_array, *val; - int i; - debug_decl(sudo_sss_check_user_netgroup, SUDO_DEBUG_SSSD); -@@ -641,21 +639,48 @@ bool sudo_sss_filter_user_netgroup(struc - sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoUser): != 0"); - debug_return_bool(ret); - } -- -+ /* -+ * Scan sudoUser values and look for netgroup specs. -+ * Netgroup-only rule specification should be filtered -+ * out if the user isn't member of any specified netgroup. -+ */ - for (i = 0; val_array[i] != NULL && !ret; ++i) { - val = val_array[i]; -- if (*val == '+') { -- netgroup_spec_found = true; -- } - sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val); -- if (strcmp(val, "ALL") == 0 || netgr_matches(val, NULL, NULL, user_name)) { -- ret = true; -- sudo_debug_printf(SUDO_DEBUG_DIAG, -- "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, user_name); -+ if (*val == '+') { -+ /* Netgroup spec found, check netgroup membership */ -+ if (netgr_matches(val, NULL, NULL, handle->pw->pw_name)) { -+ ret = true; -+ sudo_debug_printf(SUDO_DEBUG_DIAG, -+ "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, handle->pw->pw_name); -+ } -+ } else { -+ /* -+ * Non-netgroup sudoUser value -+ */ -+ if (strcmp(val, "ALL") == 0) { -+ ret = true; -+ } else { -+ const char *match_val = (*val == '!' ? val + 1 : val); -+ const bool negated = (*val == '!' ? true : false); -+ const bool group_spec = (*match_val == '%' ? true : false); -+ -+ if (group_spec) { -+ if (usergr_matches(match_val, -+ handle->pw->pw_name, handle->pw)) { -+ ret = !negated; -+ } -+ } else { -+ if (userpw_matches(match_val, -+ handle->pw->pw_name, handle->pw)) { -+ ret = !negated; -+ } -+ } -+ } - } - } - handle->fn_free_values(val_array); -- debug_return_bool(netgroup_spec_found ? ret : true); -+ debug_return_bool(ret); - } - - static int -@@ -666,7 +691,7 @@ sudo_sss_result_filterp(struct sudo_sss_ - debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD); - - if (sudo_sss_check_host(handle, rule) && -- sudo_sss_filter_user_netgroup(handle, rule)) -+ sudo_sss_filter_sudoUser(handle, rule)) - debug_return_int(1); - else - debug_return_int(0); diff --git a/SOURCES/sudo-1.8.6p3-netgrmatchtrace.patch b/SOURCES/sudo-1.8.6p3-netgrmatchtrace.patch deleted file mode 100644 index 010699d..0000000 --- a/SOURCES/sudo-1.8.6p3-netgrmatchtrace.patch +++ /dev/null @@ -1,56 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/match.c.netgrmatchtrace sudo-1.8.6p3/plugins/sudoers/match.c ---- sudo-1.8.6p3/plugins/sudoers/match.c.netgrmatchtrace 2013-08-12 14:42:56.498247674 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/match.c 2013-08-12 14:43:01.009264127 +0200 -@@ -713,6 +713,10 @@ netgr_matches(char *netgr, char *lhost, - #ifdef HAVE_GETDOMAINNAME - static int initialized; - #endif -+#ifdef HAVE_INNETGR -+ bool innetgr_lhost = false; -+ bool innetgr_shost = false; -+#endif - debug_decl(netgr_matches, SUDO_DEBUG_MATCH) - - /* make sure we have a valid netgroup, sudo style */ -@@ -733,9 +737,39 @@ netgr_matches(char *netgr, char *lhost, - - #ifdef HAVE_INNETGR - if (innetgr(netgr, lhost, user, domain)) -- debug_return_bool(true); -+ innetgr_lhost = true; - else if (lhost != shost && innetgr(netgr, shost, user, domain)) -- debug_return_bool(true); -+ innetgr_shost = true; -+ -+ if (innetgr_lhost) { -+ sudo_debug_printf(SUDO_DEBUG_TRACE, -+ "(%s, %s, %s) found in netgroup %s\n", -+ shost ? shost : "*", -+ user ? user : "*", -+ domain ? domain : "*", -+ netgr); -+ } else if (innetgr_shost) { -+ sudo_debug_printf(SUDO_DEBUG_TRACE, -+ "(%s, %s, %s) found in netgroup %s\n", -+ lhost ? lhost : "*", -+ user ? user : "*", -+ domain ? domain : "*", -+ netgr); -+ } else { -+ sudo_debug_printf(SUDO_DEBUG_TRACE, -+ "(%s, %s, %s) NOT found in netgroup %s\n", -+ shost ? shost : "*", -+ user ? user : "*", -+ domain ? domain : "*", -+ netgr); -+ sudo_debug_printf(SUDO_DEBUG_TRACE, -+ "(%s, %s, %s) NOT found in netgroup %s\n", -+ lhost ? lhost : "*", -+ user ? user : "*", -+ domain ? domain : "*", -+ netgr); -+ } -+ debug_return_bool(innetgr_lhost || innetgr_shost); - #endif /* HAVE_INNETGR */ - - debug_return_bool(false); diff --git a/SOURCES/sudo-1.8.6p3-nonehostname.patch b/SOURCES/sudo-1.8.6p3-nonehostname.patch deleted file mode 100644 index 5e170d2..0000000 --- a/SOURCES/sudo-1.8.6p3-nonehostname.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/match.c.nonehostname sudo-1.8.6p3/plugins/sudoers/match.c ---- sudo-1.8.6p3/plugins/sudoers/match.c.nonehostname 2014-05-19 12:50:08.412313041 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/match.c 2014-05-19 12:50:17.787348134 +0200 -@@ -727,7 +727,8 @@ netgr_matches(char *netgr, char *lhost, - /* get the domain name (if any) */ - if (!initialized) { - domain = (char *) emalloc(MAXHOSTNAMELEN + 1); -- if (getdomainname(domain, MAXHOSTNAMELEN + 1) == -1 || *domain == '\0') { -+ if (getdomainname(domain, MAXHOSTNAMELEN + 1) == -1 || *domain == '\0' -+ || strncmp (domain, "(none)", 7) == 0) { - efree(domain); - domain = NULL; - } diff --git a/SOURCES/sudo-1.8.6p3-nowaitopt.patch b/SOURCES/sudo-1.8.6p3-nowaitopt.patch index db4146c..df51500 100644 --- a/SOURCES/sudo-1.8.6p3-nowaitopt.patch +++ b/SOURCES/sudo-1.8.6p3-nowaitopt.patch @@ -1,45 +1,92 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/def_data.c.nowaitopt sudo-1.8.6p3/plugins/sudoers/def_data.c ---- sudo-1.8.6p3/plugins/sudoers/def_data.c.nowaitopt 2012-09-26 14:05:10.088862635 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/def_data.c 2012-09-26 13:36:07.750215749 +0200 -@@ -351,6 +351,10 @@ struct sudo_defs_types sudo_defs_table[] - N_("Set of limit privileges"), +From 9b1f0f16bfe7552810b4adb6b17ac3674da660f9 Mon Sep 17 00:00:00 2001 +From: Tomas Sykora +Date: Mon, 15 Aug 2016 15:13:31 +0200 +Subject: [PATCH] Backport direct exec of command from sudo + +Added cmnd_no_wait option +Sudo does not run command in a new child process, +when cmnd_no_wait is enabled. + +!!! +Upstream can do that too now in 1.8.17 with combination of +pam_session, pam_setcred and use_pty option. +They must be disabled and I/O logging must not be configured. +See "man sudoers". + +rebased from: +Patch8: sudo-1.8.6p3-nowaitopt.patch + +Resolves: +rhbz#840980 +--- + plugins/sudoers/def_data.c | 4 ++++ + plugins/sudoers/def_data.h | 2 ++ + plugins/sudoers/def_data.in | 3 +++ + plugins/sudoers/policy.c | 4 ++++ + src/exec.c | 34 ++++++++++++++++++++++++++++++++++ + src/sudo.c | 5 +++++ + src/sudo.h | 1 + + 7 files changed, 53 insertions(+) + +diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c +index 00caa8b..d8b1ada 100644 +--- a/plugins/sudoers/def_data.c ++++ b/plugins/sudoers/def_data.c +@@ -435,6 +435,10 @@ struct sudo_defs_types sudo_defs_table[] = { + N_("File mode to use for the I/O log files: 0%o"), NULL, }, { -+ "cmnd_no_wait", T_FLAG, -+ N_("Don't fork and wait for the command to finish, just exec it"), -+ NULL, ++ "cmnd_no_wait", T_FLAG, ++ N_("Don't fork and wait for the command to finish, just exec it"), ++ NULL, + }, { NULL, 0, NULL } }; -diff -up sudo-1.8.6p3/plugins/sudoers/def_data.h.nowaitopt sudo-1.8.6p3/plugins/sudoers/def_data.h ---- sudo-1.8.6p3/plugins/sudoers/def_data.h.nowaitopt 2012-09-26 14:05:03.280859958 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/def_data.h 2012-09-26 13:37:05.320329089 +0200 -@@ -162,6 +162,8 @@ - #define I_PRIVS 80 - #define def_limitprivs (sudo_defs_table[81].sd_un.str) - #define I_LIMITPRIVS 81 -+#define def_cmnd_no_wait (sudo_defs_table[82].sd_un.flag) -+#define I_CMND_NO_WAIT 82 +diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h +index d83d2c3..1b6be3d 100644 +--- a/plugins/sudoers/def_data.h ++++ b/plugins/sudoers/def_data.h +@@ -204,6 +204,8 @@ + #define def_iolog_group (sudo_defs_table[I_IOLOG_GROUP].sd_un.str) + #define I_IOLOG_MODE 102 + #define def_iolog_mode (sudo_defs_table[I_IOLOG_MODE].sd_un.mode) ++#define I_CMND_NO_WAIT 103 ++#define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag) enum def_tuple { never, -diff -up sudo-1.8.6p3/plugins/sudoers/sudoers.c.nowaitopt sudo-1.8.6p3/plugins/sudoers/sudoers.c ---- sudo-1.8.6p3/plugins/sudoers/sudoers.c.nowaitopt 2012-09-26 14:04:47.223854171 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/sudoers.c 2012-09-26 13:39:05.590552887 +0200 -@@ -689,6 +689,8 @@ sudoers_policy_main(int argc, char * con - command_info[info_len++] = estrdup("set_utmp=true"); - if (def_use_pty) - command_info[info_len++] = estrdup("use_pty=true"); -+ if (def_cmnd_no_wait) -+ command_info[info_len++] = estrdup("cmnd_no_wait=true"); - if (def_utmp_runas) - command_info[info_len++] = fmt_string("utmp_user", runas_pw->pw_name); - #ifdef HAVE_LOGIN_CAP_H -diff -up sudo-1.8.6p3/src/exec.c.nowaitopt sudo-1.8.6p3/src/exec.c ---- sudo-1.8.6p3/src/exec.c.nowaitopt 2012-09-26 14:06:08.505887008 +0200 -+++ sudo-1.8.6p3/src/exec.c 2012-09-26 13:29:19.786240447 +0200 -@@ -281,6 +281,45 @@ sudo_execute(struct command_details *det +diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in +index 9f069f1..5200fe3 100644 +--- a/plugins/sudoers/def_data.in ++++ b/plugins/sudoers/def_data.in +@@ -322,3 +322,6 @@ iolog_group + iolog_mode + T_MODE + "File mode to use for the I/O log files: 0%o" ++cmnd_no_wait ++ T_FLAG ++ "Don't fork and wait for the command to finish, just exec it" +diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c +index 4ee1e28..93df1dd 100644 +--- a/plugins/sudoers/policy.c ++++ b/plugins/sudoers/policy.c +@@ -564,6 +564,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask, + if ((command_info[info_len++] = strdup("use_pty=true")) == NULL) + goto oom; + } ++ if (def_cmnd_no_wait) { ++ if ((command_info[info_len++] = strdup("cmnd_no_wait=true")) == NULL) ++ goto oom; ++ } + if (def_utmp_runas) { + if ((command_info[info_len++] = sudo_new_key_val("utmp_user", runas_pw->pw_name)) == NULL) + goto oom; +diff --git a/src/exec.c b/src/exec.c +index 56da013..08bc86d 100644 +--- a/src/exec.c ++++ b/src/exec.c +@@ -384,6 +384,41 @@ sudo_execute(struct command_details *details, struct command_status *cstat) } /* @@ -51,26 +98,21 @@ diff -up sudo-1.8.6p3/src/exec.c.nowaitopt sudo-1.8.6p3/src/exec.c + */ + if (details->flags & CD_DONTWAIT) { + if (exec_setup(details, NULL, -1) == true) { ++ restore_signals(); + /* headed for execve() */ + sudo_debug_execve(SUDO_DEBUG_INFO, details->command, + details->argv, details->envp); + if (details->closefrom >= 0) { -+ int maxfd = details->closefrom; -+ dup2(sv[1], maxfd); -+ (void)fcntl(maxfd, F_SETFD, FD_CLOEXEC); -+ sv[1] = maxfd++; -+ if (sudo_debug_fd_set(maxfd) != -1) -+ maxfd++; -+ closefrom(maxfd); ++ closefrom(details->closefrom); + } +#ifdef HAVE_SELINUX + if (ISSET(details->flags, CD_RBAC_ENABLED)) { -+ selinux_execve(details->command, details->argv, details->envp, ++ selinux_execve(-1, details->command, details->argv, details->envp, + ISSET(details->flags, CD_NOEXEC)); + } else +#endif + { -+ sudo_execve(details->command, details->argv, details->envp, ++ sudo_execve(-1, details->command, details->argv, details->envp, + ISSET(details->flags, CD_NOEXEC)); + } + sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s", @@ -78,36 +120,42 @@ diff -up sudo-1.8.6p3/src/exec.c.nowaitopt sudo-1.8.6p3/src/exec.c + } + cstat->type = CMD_ERRNO; + cstat->val = errno; -+ return 127; ++ return 127; + } -+ ++ ++ + /* * We communicate with the child over a bi-directional pair of sockets. * Parent sends signal info to child and child sends back wait status. */ -diff -up sudo-1.8.6p3/src/sudo.c.nowaitopt sudo-1.8.6p3/src/sudo.c ---- sudo-1.8.6p3/src/sudo.c.nowaitopt 2012-09-26 14:06:25.504894811 +0200 -+++ sudo-1.8.6p3/src/sudo.c 2012-09-26 13:33:34.306889223 +0200 -@@ -552,6 +552,11 @@ command_info_to_details(char * const inf - } +diff --git a/src/sudo.c b/src/sudo.c +index 5dd090d..0606a19 100644 +--- a/src/sudo.c ++++ b/src/sudo.c +@@ -670,6 +670,11 @@ command_info_to_details(char * const info[], struct command_details *details) + sudo_fatalx(U_("%s: %s"), info[i], U_(errstr)); break; } + if (strncmp("cmnd_no_wait=", info[i], sizeof("cmnd_no_wait=") - 1) == 0) { -+ if (atobool(info[i] + sizeof("cmnd_no_wait=") - 1) == true) -+ SET(details->flags, CD_DONTWAIT); -+ break; -+ } ++ if (sudo_strtobool(info[i] + sizeof("cmnd_no_wait=") - 1) == true) ++ SET(details->flags, CD_DONTWAIT); ++ break; ++ } break; - case 'l': - SET_STRING("login_class=", login_class) -diff -up sudo-1.8.6p3/src/sudo.h.nowaitopt sudo-1.8.6p3/src/sudo.h ---- sudo-1.8.6p3/src/sudo.h.nowaitopt 2012-09-26 14:06:20.856892631 +0200 -+++ sudo-1.8.6p3/src/sudo.h 2012-09-26 13:19:11.697482212 +0200 -@@ -131,6 +131,7 @@ struct user_details { - #define CD_USE_PTY 0x1000 - #define CD_SET_UTMP 0x2000 - #define CD_SUDOEDIT_COPY 0x4000 -+#define CD_DONTWAIT 0x8000 + case 'e': + SET_FLAG("exec_background=", CD_EXEC_BG) +diff --git a/src/sudo.h b/src/sudo.h +index 3ac2c9d..f07ba11 100644 +--- a/src/sudo.h ++++ b/src/sudo.h +@@ -130,6 +130,7 @@ struct user_details { + #define CD_SUDOEDIT_FOLLOW 0x10000 + #define CD_SUDOEDIT_CHECKDIR 0x20000 + #define CD_SET_GROUPS 0x40000 ++#define CD_DONTWAIT 0x80000 - struct command_details { - uid_t uid; + struct preserved_fd { + TAILQ_ENTRY(preserved_fd) entries; +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.6p3-nprocfix.patch b/SOURCES/sudo-1.8.6p3-nprocfix.patch deleted file mode 100644 index 5ffd56b..0000000 --- a/SOURCES/sudo-1.8.6p3-nprocfix.patch +++ /dev/null @@ -1,117 +0,0 @@ -diff -up sudo-1.8.6p3/src/exec.c.nprocfix sudo-1.8.6p3/src/exec.c ---- sudo-1.8.6p3/src/exec.c.nprocfix 2013-07-11 12:55:10.686308050 +0200 -+++ sudo-1.8.6p3/src/exec.c 2013-07-11 12:54:21.159160553 +0200 -@@ -132,6 +132,15 @@ static int fork_cmnd(struct command_deta - if (policy_init_session(details) != true) - errorx(1, _("policy plugin failed session initialization")); - -+ /* -+ * See the comment in unlimit_nproc. It is important to call -+ * this function AFTER policy_init_session, because the PAM -+ * subsystem, if used, may change the RLIMIT_NPROC limit to -+ * unlimited (infinity) and we would not be able to distinguish -+ * between our temporary change and the change done by PAM. -+ */ -+ unlimit_nproc(); -+ - cmnd_pid = sudo_debug_fork(); - switch (cmnd_pid) { - case -1: -diff -up sudo-1.8.6p3/src/exec_pty.c.nprocfix sudo-1.8.6p3/src/exec_pty.c ---- sudo-1.8.6p3/src/exec_pty.c.nprocfix 2012-09-18 15:57:43.000000000 +0200 -+++ sudo-1.8.6p3/src/exec_pty.c 2013-07-11 12:37:41.811202301 +0200 -@@ -678,6 +678,15 @@ fork_pty(struct command_details *details - errorx(1, _("policy plugin failed session initialization")); - - /* -+ * See the comment in unlimit_nproc. It is important to call -+ * this function AFTER policy_init_session, because the PAM -+ * subsystem, if used, may change the RLIMIT_NPROC limit to -+ * unlimited (infinity) and we would not be able to distinguish -+ * between our temporary change and the change done by PAM. -+ */ -+ unlimit_nproc(); -+ -+ /* - * Block some signals until cmnd_pid is set in the parent to avoid a - * race between exec of the command and receipt of a fatal signal from it. - */ -diff -up sudo-1.8.6p3/src/sudo.c.nprocfix sudo-1.8.6p3/src/sudo.c ---- sudo-1.8.6p3/src/sudo.c.nprocfix 2013-07-11 12:37:41.767202170 +0200 -+++ sudo-1.8.6p3/src/sudo.c 2013-07-11 12:37:41.811202301 +0200 -@@ -808,25 +808,11 @@ sudo_check_suid(const char *path) - static void - disable_coredumps(void) - { --#if defined(__linux__) || defined(RLIMIT_CORE) -- struct rlimit rl; -+#if defined(RLIMIT_CORE) -+ struct rlimit rl; - #endif - debug_decl(disable_coredumps, SUDO_DEBUG_UTIL) - --#if defined(__linux__) -- /* -- * Unlimit the number of processes since Linux's setuid() will -- * apply resource limits when changing uid and return EAGAIN if -- * nproc would be violated by the uid switch. -- */ -- (void) getrlimit(RLIMIT_NPROC, &nproclimit); -- rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; -- if (setrlimit(RLIMIT_NPROC, &rl)) { -- memcpy(&rl, &nproclimit, sizeof(struct rlimit)); -- rl.rlim_cur = rl.rlim_max; -- (void)setrlimit(RLIMIT_NPROC, &rl); -- } --#endif /* __linux__ */ - #ifdef RLIMIT_CORE - /* - * Turn off core dumps? -@@ -841,6 +827,28 @@ disable_coredumps(void) - debug_return; - } - -+void -+unlimit_nproc(void) -+{ -+ debug_decl(unlimit_nproc, SUDO_DEBUG_UTIL) -+#if defined(__linux__) -+ struct rlimit rl; -+ /* -+ * Unlimit the number of processes since Linux's setuid() will -+ * apply resource limits when changing uid and return EAGAIN if -+ * nproc would be violated by the uid switch. -+ */ -+ (void) getrlimit(RLIMIT_NPROC, &nproclimit); -+ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; -+ if (setrlimit(RLIMIT_NPROC, &rl)) { -+ memcpy(&rl, &nproclimit, sizeof(struct rlimit)); -+ rl.rlim_cur = rl.rlim_max; -+ (void)setrlimit(RLIMIT_NPROC, &rl); -+ } -+#endif /* __linux__ */ -+ debug_return; -+} -+ - #ifdef HAVE_PROJECT_H - static void - set_project(struct passwd *pw) -@@ -1082,7 +1090,6 @@ exec_setup(struct command_details *detai - errno = 0; - l = sysconf(_SC_CHILD_MAX); - if (l == -1 && errno == 0 && getrlimit(RLIMIT_NPROC, &rl) == 0) { -- if (rl.rlim_cur == RLIM_INFINITY && rl.rlim_max == RLIM_INFINITY) - (void) setrlimit(RLIMIT_NPROC, &nproclimit); - } - } -diff -up sudo-1.8.6p3/src/sudo.h.nprocfix sudo-1.8.6p3/src/sudo.h ---- sudo-1.8.6p3/src/sudo.h.nprocfix 2013-07-11 12:37:41.768202173 +0200 -+++ sudo-1.8.6p3/src/sudo.h 2013-07-11 12:37:41.811202301 +0200 -@@ -219,6 +219,7 @@ int policy_init_session(struct command_d - int run_command(struct command_details *details); - extern const char *list_user, *runas_user, *runas_group; - extern struct user_details user_details; -+void unlimit_nproc(void); - - /* sudo_edit.c */ - int sudo_edit(struct command_details *details); diff --git a/SOURCES/sudo-1.8.6p3-sigpipefix.patch b/SOURCES/sudo-1.8.6p3-sigpipefix.patch deleted file mode 100644 index ce4886b..0000000 --- a/SOURCES/sudo-1.8.6p3-sigpipefix.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up sudo-1.8.6p3/src/tgetpass.c.sigpipefix sudo-1.8.6p3/src/tgetpass.c ---- sudo-1.8.6p3/src/tgetpass.c.sigpipefix 2015-03-03 10:23:23.219038693 +0100 -+++ sudo-1.8.6p3/src/tgetpass.c 2015-03-03 10:23:43.089813184 +0100 -@@ -173,7 +173,7 @@ restore: - (void) sigaction(SIGTSTP, &savetstp, NULL); - (void) sigaction(SIGTTIN, &savettin, NULL); - (void) sigaction(SIGTTOU, &savettou, NULL); -- (void) sigaction(SIGTTOU, &savepipe, NULL); -+ (void) sigaction(SIGPIPE, &savepipe, NULL); - if (input != STDIN_FILENO) - (void) close(input); - diff --git a/SOURCES/sudo-1.8.6p3-sssd-noise.patch b/SOURCES/sudo-1.8.6p3-sssd-noise.patch deleted file mode 100644 index dd7bed0..0000000 --- a/SOURCES/sudo-1.8.6p3-sssd-noise.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.sssd-noise sudo-1.8.6p3/plugins/sudoers/sssd.c ---- sudo-1.8.6p3/plugins/sudoers/sssd.c.sssd-noise 2012-11-29 13:23:43.332760956 +0100 -+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2012-11-29 13:23:57.548816054 +0100 -@@ -350,7 +350,7 @@ static int sudo_sss_setdefs(struct sudo_ - - if (sss_error == ENOENT) { - sudo_debug_printf(SUDO_DEBUG_INFO, "The user was not found in SSSD."); -- debug_return_int(-1); -+ debug_return_int(0); - } else if(sss_error != 0) { - sudo_debug_printf(SUDO_DEBUG_INFO, "sss_error=%u\n", sss_error); - debug_return_int(-1); diff --git a/SOURCES/sudo-1.8.6p3-sssdfixes.patch b/SOURCES/sudo-1.8.6p3-sssdfixes.patch deleted file mode 100644 index 07062e3..0000000 --- a/SOURCES/sudo-1.8.6p3-sssdfixes.patch +++ /dev/null @@ -1,119 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.sssdfixes sudo-1.8.6p3/plugins/sudoers/sssd.c ---- sudo-1.8.6p3/plugins/sudoers/sssd.c.sssdfixes 2013-08-13 15:20:39.558187669 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2013-08-13 16:24:27.209064162 +0200 -@@ -534,30 +534,31 @@ sudo_sss_check_runas_group(struct sudo_s - * Walk through search results and return true if we have a runas match, - * else false. RunAs info is optional. - */ --static int -+static bool - sudo_sss_check_runas(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) - { -- int ret; -+ bool ret; - debug_decl(sudo_sss_check_runas, SUDO_DEBUG_SSSD); - - if (rule == NULL) -- debug_return_int(false); -+ debug_return_bool(false); - - ret = sudo_sss_check_runas_user(handle, rule) != false && - sudo_sss_check_runas_group(handle, rule) != false; - -- debug_return_int(ret); -+ debug_return_bool(ret); - } - --static int -+static bool - sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) - { - char **val_array, *val; -- int ret = false, i; -+ bool ret = false; -+ int i; - debug_decl(sudo_sss_check_host, SUDO_DEBUG_SSSD); - - if (rule == NULL) -- debug_return_int(ret); -+ debug_return_bool(ret); - - /* get the values from the rule */ - switch (handle->fn_get_values(rule, "sudoHost", &val_array)) -@@ -566,10 +567,10 @@ sudo_sss_check_host(struct sudo_sss_hand - break; - case ENOENT: - sudo_debug_printf(SUDO_DEBUG_INFO, "No result."); -- debug_return_int(false); -+ debug_return_bool(false); - default: - sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoHost): != 0"); -- debug_return_int(ret); -+ debug_return_bool(ret); - } - - /* walk through values */ -@@ -589,7 +590,52 @@ sudo_sss_check_host(struct sudo_sss_hand - - handle->fn_free_values(val_array); - -- debug_return_int(ret); -+ debug_return_bool(ret); -+} -+ -+/* -+ * Look for netgroup specifcations in the sudoUser attribute and -+ * if found, filter according to netgroup membership. -+ * returns: -+ * true -> netgroup spec found && negroup member -+ * false -> netgroup spec found && not a meber of netgroup -+ * true -> netgroup spec not found (filtered by SSSD already, netgroups are an exception) -+ */ -+bool sudo_sss_filter_user_netgroup(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) -+{ -+ bool ret = false, netgroup_spec_found = false; -+ char **val_array, *val; -+ int i; -+ debug_decl(sudo_sss_check_user_netgroup, SUDO_DEBUG_SSSD); -+ -+ if (!handle || !rule) -+ debug_return_bool(ret); -+ -+ switch (handle->fn_get_values(rule, "sudoUser", &val_array)) { -+ case 0: -+ break; -+ case ENOENT: -+ sudo_debug_printf(SUDO_DEBUG_INFO, "No result."); -+ debug_return_bool(ret); -+ default: -+ sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoUser): != 0"); -+ debug_return_bool(ret); -+ } -+ -+ for (i = 0; val_array[i] != NULL && !ret; ++i) { -+ val = val_array[i]; -+ if (*val == '+') { -+ netgroup_spec_found = true; -+ } -+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val); -+ if (strcmp(val, "ALL") == 0 || netgr_matches(val, NULL, NULL, user_name)) { -+ ret = true; -+ sudo_debug_printf(SUDO_DEBUG_DIAG, -+ "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, user_name); -+ } -+ } -+ handle->fn_free_values(val_array); -+ debug_return_bool(netgroup_spec_found ? ret : true); - } - - static int -@@ -599,7 +645,8 @@ sudo_sss_result_filterp(struct sudo_sss_ - (void)unused; - debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD); - -- if (sudo_sss_check_host(handle, rule)) -+ if (sudo_sss_check_host(handle, rule) && -+ sudo_sss_filter_user_netgroup(handle, rule)) - debug_return_int(1); - else - debug_return_int(0); diff --git a/SOURCES/sudo-1.8.6p3-sssdrulenames.patch b/SOURCES/sudo-1.8.6p3-sssdrulenames.patch deleted file mode 100644 index 84081d1..0000000 --- a/SOURCES/sudo-1.8.6p3-sssdrulenames.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.rulenames sudo-1.8.6p3/plugins/sudoers/sssd.c ---- sudo-1.8.6p3/plugins/sudoers/sssd.c.rulenames 2014-05-21 12:33:21.000768420 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2014-05-21 12:38:13.779864718 +0200 -@@ -1180,6 +1180,18 @@ sudo_sss_display_entry_long(struct sudo_ - int count = 0, i; - debug_decl(sudo_sss_display_entry_long, SUDO_DEBUG_SSSD); - -+ switch(handle->fn_get_values(rule, "cn", &val_array)) { -+ case 0: -+ if (val_array[0]) { -+ lbuf_append(lbuf, _("\nSSSD Role: %s\n"), val_array[0]); -+ } -+ handle->fn_free_values(val_array); -+ val_array = NULL; -+ break; -+ default: -+ lbuf_append(lbuf, _("\nSSSD Role: UNKNOWN\n")); -+ } -+ - /* get the RunAsUser Values from the entry */ - lbuf_append(lbuf, " RunAsUsers: "); - switch (handle->fn_get_values(rule, "sudoRunAsUser", &val_array)) { diff --git a/SOURCES/sudo-1.8.6p3-strictuidgid.patch b/SOURCES/sudo-1.8.6p3-strictuidgid.patch deleted file mode 100644 index 0553cd7..0000000 --- a/SOURCES/sudo-1.8.6p3-strictuidgid.patch +++ /dev/null @@ -1,53 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/match.c.strictuidgid sudo-1.8.6p3/plugins/sudoers/match.c ---- sudo-1.8.6p3/plugins/sudoers/match.c.strictuidgid 2012-09-18 15:56:29.000000000 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/match.c 2013-08-08 16:22:00.413281960 +0200 -@@ -650,14 +650,16 @@ hostname_matches(char *shost, char *lhos - bool - userpw_matches(char *sudoers_user, char *user, struct passwd *pw) - { -- debug_decl(userpw_matches, SUDO_DEBUG_MATCH) -- -- if (pw != NULL && *sudoers_user == '#') { -- uid_t uid = (uid_t) atoi(sudoers_user + 1); -- if (uid == pw->pw_uid) -- debug_return_bool(true); -- } -- debug_return_bool(strcmp(sudoers_user, user) == 0); -+ debug_decl(userpw_matches, SUDO_DEBUG_MATCH) -+ if (pw != NULL && *sudoers_user == '#') { -+ char *end = NULL; -+ uid_t uid = (uid_t) strtol(sudoers_user + 1, &end, 10); -+ if (end != NULL && (sudoers_user[1] != '\0' && *end == '\0')) { -+ if (uid == pw->pw_uid) -+ debug_return_bool(true); -+ } -+ } -+ debug_return_bool(strcmp(sudoers_user, user) == 0); - } - - /* -@@ -667,14 +669,16 @@ userpw_matches(char *sudoers_user, char - bool - group_matches(char *sudoers_group, struct group *gr) - { -- debug_decl(group_matches, SUDO_DEBUG_MATCH) -- -- if (*sudoers_group == '#') { -- gid_t gid = (gid_t) atoi(sudoers_group + 1); -- if (gid == gr->gr_gid) -- debug_return_bool(true); -- } -- debug_return_bool(strcmp(gr->gr_name, sudoers_group) == 0); -+ debug_decl(group_matches, SUDO_DEBUG_MATCH) -+ if (*sudoers_group == '#') { -+ char *end = NULL; -+ gid_t gid = (gid_t) strtol(sudoers_group + 1, &end, 10); -+ if (end != NULL && (sudoers_group[1] != '\0' && *end == '\0')) { -+ if (gid == gr->gr_gid) -+ debug_return_bool(true); -+ } -+ } -+ debug_return_bool(strcmp(gr->gr_name, sudoers_group) == 0); - } - - /* diff --git a/SOURCES/sudo-1.8.6p3-sudoedit-selinux.patch b/SOURCES/sudo-1.8.6p3-sudoedit-selinux.patch deleted file mode 100644 index e816fdb..0000000 --- a/SOURCES/sudo-1.8.6p3-sudoedit-selinux.patch +++ /dev/null @@ -1,747 +0,0 @@ -diff -up sudo-1.8.6p3/src/sesh.c.sudoedit-selinux sudo-1.8.6p3/src/sesh.c ---- sudo-1.8.6p3/src/sesh.c.sudoedit-selinux 2012-09-18 15:56:30.000000000 +0200 -+++ sudo-1.8.6p3/src/sesh.c 2012-09-25 16:06:33.408584649 +0200 -@@ -34,6 +34,10 @@ - # include "compat/stdbool.h" - #endif /* HAVE_STDBOOL_H */ - -+#include -+#include -+#include -+ - #include "missing.h" - #include "alloc.h" - #include "error.h" -@@ -43,6 +47,16 @@ - #include "sudo_exec.h" - #include "sudo_plugin.h" - -+/* -+ * Return codes: -+ * EXIT_FAILURE ... unspecified error -+ * 0 ... everything ok -+ * 30 ... invalid -e arg value -+ * 31 ... odd number of paths -+ * 32 ... copy operation failed, no files copied -+ * 33 ... copy operation failed, some files copied -+ */ -+ - sudo_conv_t sudo_conv; /* NULL in non-plugin */ - - /* -@@ -77,19 +91,134 @@ main(int argc, char *argv[], char *envp[ - if ((cp = strrchr(argv[0], '-')) != NULL && cp != argv[0]) - noexec = strcmp(cp, "-noexec") == 0; - -- /* Shift argv and make a copy of the command to execute. */ -- argv++; -- argc--; -- cmnd = estrdup(argv[0]); -- -- /* If invoked as a login shell, modify argv[0] accordingly. */ -- if (argv[-1][0] == '-') { -- if ((cp = strrchr(argv[0], '/')) == NULL) -- cp = argv[0]; -- *cp = '-'; -+ /* check the first argument, if it's `-e' then we are in sudoedit mode */ -+ if (strncmp(argv[1], "-e", 3) == 0) { -+ int fd_src, fd_dst, post, n, ret = -1; -+ ssize_t nread, nwritten; -+ char *path_src, *path_dst, buf[BUFSIZ]; -+ -+ if (argc < 3) -+ return EXIT_FAILURE; -+ -+ /* -+ * We need to know whether we are performing the copy operation -+ * before or after the editing. Without this we would not know -+ * which files are temporary and which are the originals. -+ * post = 0 ... before -+ * post = 1 ... after -+ */ -+ if (strncmp(argv[2], "0", 2) == 0) -+ post = 0; -+ else if (strncmp(argv[2], "1", 2) == 0) -+ post = 1; -+ else /* invalid value */ -+ return 30; -+ -+ /* align argv & argc to the beggining of the file list */ -+ argv += 3; -+ argc -= 3; -+ -+ /* no files specified, nothing to do */ -+ if (argc == 0) -+ return 0; -+ /* odd number of paths specified */ -+ if (argc % 2 == 1) -+ return 31; -+ -+ for (n = 0; n < argc - 1; n += 2) { -+ path_src = argv[n]; -+ path_dst = argv[n+1]; -+ /* -+ * Try to open the source file for reading. If it -+ * doesn't exist, it's ok, we'll create an empty -+ * destination file. -+ */ -+ if ((fd_src = open(path_src, O_RDONLY, 0600)) < 0) { -+ if (errno == ENOENT) { -+ /* new file */ -+ } else { -+ warning(_("open(%s)"), path_src); -+ if (post) { -+ ret = 33; -+ goto nocleanup; -+ } else -+ goto cleanup_0; -+ } -+ } -+ -+ /* -+ * Use O_EXCL if we are not in the post editing stage -+ * so that it's ensured that the temporary files are -+ * created by us and that we are not opening any sym- -+ * links. -+ */ -+ if ((fd_dst = open(path_dst, (post ? 0 : O_EXCL) | -+ O_WRONLY|O_TRUNC|O_CREAT, post ? 0644 : 0600)) < 0) -+ { -+ /* error - cleanup */ -+ warning(_("open(%s%s)"), path_dst, post ? "" : ", O_EXCL"); -+ if (post) { -+ ret = 33; -+ goto nocleanup; -+ } else -+ goto cleanup_0; -+ } -+ -+ if (fd_src != -1) { -+ while ((nread = read(fd_src, buf, sizeof(buf))) > 0) { -+ if ((nwritten = write(fd_dst, buf, nread)) != nread) { -+ warning(_("write")); -+ if (post) { -+ ret = 33; -+ goto nocleanup; -+ } else -+ goto cleanup_0; -+ } -+ } -+ } -+ -+ if (fd_dst != -1) -+ close(fd_dst); -+ if (fd_src != -1) -+ close(fd_src); -+ fd_dst = fd_src = -1; -+ } -+ -+ ret = 0; -+ /* remove temporary files (post=1) */ -+ for (n = 0; n < argc - 1; n += 2) -+ unlink(argv[n]); -+nocleanup: -+ if (fd_dst != -1) -+ close(fd_dst); -+ if (fd_src != -1) -+ close(fd_src); -+ _exit(ret); -+cleanup_0: -+ /* remove temporary files (post=0) */ -+ for (n = 0; n < argc - 1; n += 2) -+ unlink(argv[n+1]); -+ if (fd_dst != -1) -+ close(fd_dst); -+ if (fd_src != -1) -+ close(fd_src); -+ _exit(32); -+ } else { -+ -+ /* Shift argv and make a copy of the command to execute. */ -+ argv++; -+ argc--; -+ cmnd = estrdup(argv[0]); -+ -+ /* If invoked as a login shell, modify argv[0] accordingly. */ -+ if (argv[-1][0] == '-') { -+ if ((cp = strrchr(argv[0], '/')) == NULL) -+ cp = argv[0]; -+ *cp = '-'; -+ } -+ sudo_execve(cmnd, argv, envp, noexec); -+ warning(_("unable to execute %s"), argv[0]); -+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, EXIT_FAILURE); - } -- sudo_execve(cmnd, argv, envp, noexec); -- warning(_("unable to execute %s"), argv[0]); -- sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, EXIT_FAILURE); - _exit(EXIT_FAILURE); - } -diff -up sudo-1.8.6p3/src/sudo.c.sudoedit-selinux sudo-1.8.6p3/src/sudo.c ---- sudo-1.8.6p3/src/sudo.c.sudoedit-selinux 2012-09-18 15:57:43.000000000 +0200 -+++ sudo-1.8.6p3/src/sudo.c 2012-09-25 16:04:36.687422997 +0200 -@@ -915,6 +915,10 @@ exec_setup(struct command_details *detai - if (selinux_setup(details->selinux_role, details->selinux_type, - ptyname ? ptyname : user_details.tty, ptyfd) == -1) - goto done; -+ if (details->flags & CD_SUDOEDIT_COPY) { -+ rval = true; -+ goto done; -+ } - } - #endif - -@@ -1116,6 +1120,8 @@ run_command(struct command_details *deta - break; - case CMD_WSTATUS: - /* Command ran, exited or was killed. */ -+ if (details->flags & CD_SUDOEDIT_COPY) -+ break; - sudo_debug_printf(SUDO_DEBUG_DEBUG, - "calling policy close with wait status %d", cstat.val); - policy_close(&policy_plugin, cstat.val, 0); -diff -up sudo-1.8.6p3/src/sudo_edit.c.sudoedit-selinux sudo-1.8.6p3/src/sudo_edit.c ---- sudo-1.8.6p3/src/sudo_edit.c.sudoedit-selinux 2012-09-18 15:56:30.000000000 +0200 -+++ sudo-1.8.6p3/src/sudo_edit.c 2012-09-25 16:06:19.108564255 +0200 -@@ -49,11 +49,284 @@ - #if TIME_WITH_SYS_TIME - # include - #endif -+#ifdef HAVE_SELINUX -+# include -+#endif - - #include "sudo.h" - - #if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID) - -+struct tempfile { -+ char *tfile; -+ char *ofile; -+ struct timeval omtim; -+ off_t osize; -+}; -+ -+static int -+selinux_edit_copy(struct command_details *command_details, struct tempfile *tf, char **files, int nfiles, const char *tmpdir, int tmplen, int tval_isset) -+{ -+ char **sesh_args; -+ int i, sesh_nargs, ret; -+ struct command_details sesh_details; -+ debug_decl(selinux_edit_copy, SUDO_DEBUG_EDIT); -+ -+ /* Prepare selinux stuff (setexeccon) */ -+ if (selinux_setup(command_details->selinux_role, -+ command_details->selinux_type, NULL, -1) != 0) -+ return -1; -+ -+ if (nfiles < 1) -+ return 1; -+ -+ /* Construct common args for sesh */ -+ memcpy(&sesh_details, command_details, sizeof(sesh_details)); -+ sesh_details.command = _PATH_SUDO_SESH; -+ sesh_details.flags |= CD_SUDOEDIT_COPY; -+ -+ sesh_nargs = (nfiles * 2) + 4 + 1; -+ sesh_args = (char **)emalloc2(sesh_nargs, sizeof(char *)); -+ sesh_args++; -+ sesh_args[0] = "sesh"; -+ sesh_args[1] = "-e"; -+ -+ if (files != NULL) { -+ sesh_args[2] = "0"; -+ -+ for (i = 2; i < nfiles+2; ++i) { -+ sesh_args[2*i-1] = files[i-2]; -+ tf[i-2].ofile = files[i-2]; -+ /* -+ * O_CREAT | O_EXCL is used in the sesh helper, so the -+ * usage of the tempnam function here is safe. -+ */ -+ sesh_args[2*i] = tempnam(tmpdir, "sudo."); -+ tf[i-2].tfile = sesh_args[2*i]; -+ //tf[i-2].omtim = 0; -+ tf[i-2].osize = 0; -+ } -+ -+ sesh_args[2*i-1] = NULL; -+ -+ /* Run sesh -e 0 ... */ -+ sesh_details.argv = sesh_args; -+ switch(run_command(&sesh_details)) { -+ case 0: -+ break; -+ case 31: -+ error(1, _("sesh: internal error: odd number of paths")); -+ case 32: -+ error(1, _("sesh: unable to create temporary files")); -+ } -+ -+ /* Chown to user's UID so he can edit the temporary files */ -+ for (i = 2; i < nfiles+2; ++i) { -+ if (chown(tf[i-2].tfile, user_details.uid, user_details.gid) != 0) { -+ warning("Unable to chown(%s) to %d:%d for editing", -+ tf[i-2].tfile, user_details.uid, user_details.gid); -+ } -+ } -+ } else { -+ sesh_args[2] = "1"; -+ -+ /* Construct args for sesh -e 1 */ -+ for (i = 2; i < nfiles+2; ++i) { -+ sesh_args[2*i-1] = tf[i-2].tfile; -+ sesh_args[2*i] = tf[i-2].ofile; -+ -+ if (chown(tf[i-2].tfile, sesh_details.uid, sesh_details.gid) != 0) { -+ warning("Unable to chown(%s) back to %d:%d", -+ tf[i-2].tfile, sesh_details.uid, sesh_details.gid); -+ } -+ } -+ -+ sesh_args[2*i-1] = NULL; -+ -+ /* Run sesh -e 1 ... */ -+ sesh_details.argv = sesh_args; -+ switch(run_command(&sesh_details)) { -+ case 0: -+ break; -+ case 32: -+ warning(_("Copying the temporary files back to its original place failed. The files were left in %s"), tmpdir); -+ break; -+ case 33: -+ warning(_("Copying of some of the temporary files back to its original place failed and they were left in %s"), -+ tmpdir); -+ break; -+ } -+ } -+ -+ return (nfiles); -+} -+ -+static void switch_user(uid_t euid, gid_t egid, int ngroups, GETGROUPS_T *groups); -+ -+static int sudo_edit_copy(struct command_details *command_details, struct tempfile *tf, char **files, int nfiles, const char *tmpdir, int tmplen, int tval_isset) -+{ -+ int i, j, tfd, ofd, rc; -+ char *cp, *suff, buf[BUFSIZ]; -+ ssize_t nwritten, nread; -+ struct stat sb; -+ struct timeval tv; -+ debug_decl(sudo_edit_copy, SUDO_DEBUG_EDIT); -+ -+ if (files != NULL) { -+ /* Create temporary copies */ -+ for (i = 0, j = 0; i < nfiles; i++) { -+ rc = -1; -+ switch_user(command_details->euid, command_details->egid, -+ command_details->ngroups, command_details->groups); -+ if ((ofd = open(files[i], O_RDONLY, 0644)) != -1 || errno == ENOENT) { -+ if (ofd == -1) { -+ zero_bytes(&sb, sizeof(sb)); /* new file */ -+ rc = 0; -+ } else { -+ rc = fstat(ofd, &sb); -+ } -+ } -+ switch_user(ROOT_UID, user_details.egid, -+ user_details.ngroups, user_details.groups); -+ if (rc || (ofd != -1 && !S_ISREG(sb.st_mode))) { -+ if (rc) -+ warning("%s", files[i]); -+ else -+ warningx(_("%s: not a regular file"), files[i]); -+ if (ofd != -1) -+ close(ofd); -+ continue; -+ } -+ tf[j].ofile = files[i]; -+ tf[j].osize = sb.st_size; -+ mtim_get(&sb, &tf[j].omtim); -+ if ((cp = strrchr(tf[j].ofile, '/')) != NULL) -+ cp++; -+ else -+ cp = tf[j].ofile; -+ suff = strrchr(cp, '.'); -+ if (suff != NULL) { -+ easprintf(&tf[j].tfile, "%.*s/%.*sXXXXXXXX%s", tmplen, tmpdir, -+ (int)(size_t)(suff - cp), cp, suff); -+ } else { -+ easprintf(&tf[j].tfile, "%.*s/%s.XXXXXXXX", tmplen, tmpdir, cp); -+ } -+ if (seteuid(user_details.uid) != 0) -+ error(1, "seteuid(%d)", (int)user_details.uid); -+ tfd = mkstemps(tf[j].tfile, suff ? strlen(suff) : 0); -+ if (seteuid(ROOT_UID) != 0) -+ error(1, "seteuid(ROOT_UID)"); -+ if (tfd == -1) { -+ warning("mkstemps"); -+ goto cleanup; -+ } -+ if (ofd != -1) { -+ while ((nread = read(ofd, buf, sizeof(buf))) != 0) { -+ if ((nwritten = write(tfd, buf, nread)) != nread) { -+ if (nwritten == -1) -+ warning("%s", tf[j].tfile); -+ else -+ warningx(_("%s: short write"), tf[j].tfile); -+ goto cleanup; -+ } -+ } -+ close(ofd); -+ } -+ /* -+ * We always update the stashed mtime because the time -+ * resolution of the filesystem the temporary file is on may -+ * not match that of the filesystem where the file to be edited -+ * resides. It is OK if touch() fails since we only use the info -+ * to determine whether or not a file has been modified. -+ */ -+ (void) touch(tfd, NULL, &tf[j].omtim); -+ rc = fstat(tfd, &sb); -+ if (!rc) -+ mtim_get(&sb, &tf[j].omtim); -+ close(tfd); -+ j++; -+ } -+ if ((nfiles = j) == 0) -+ goto cleanup; /* no files readable, you lose */ -+ } else { -+ /* Copy contents of temp files to real ones */ -+ for (i = 0; i < nfiles; i++) { -+ rc = -1; -+ if (seteuid(user_details.uid) != 0) -+ error(1, "seteuid(%d)", (int)user_details.uid); -+ if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) { -+ rc = fstat(tfd, &sb); -+ } -+ if (seteuid(ROOT_UID) != 0) -+ error(1, "seteuid(ROOT_UID)"); -+ if (rc || !S_ISREG(sb.st_mode)) { -+ if (rc) -+ warning("%s", tf[i].tfile); -+ else -+ warningx(_("%s: not a regular file"), tf[i].tfile); -+ warningx(_("%s left unmodified"), tf[i].ofile); -+ if (tfd != -1) -+ close(tfd); -+ continue; -+ } -+ mtim_get(&sb, &tv); -+ if (tf[i].osize == sb.st_size && timevalcmp(&tf[i].omtim, &tv, ==)) { -+ /* -+ * If mtime and size match but the user spent no measurable -+ * time in the editor we can't tell if the file was changed. -+ */ -+ if (tval_isset) { -+ warningx(_("%s unchanged"), tf[i].ofile); -+ unlink(tf[i].tfile); -+ close(tfd); -+ continue; -+ } -+ } -+ switch_user(command_details->euid, command_details->egid, -+ command_details->ngroups, command_details->groups); -+ ofd = open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644); -+ switch_user(ROOT_UID, user_details.egid, -+ user_details.ngroups, user_details.groups); -+ if (ofd == -1) { -+ warning(_("unable to write to %s"), tf[i].ofile); -+ warningx(_("contents of edit session left in %s"), tf[i].tfile); -+ close(tfd); -+ continue; -+ } -+ while ((nread = read(tfd, buf, sizeof(buf))) > 0) { -+ if ((nwritten = write(ofd, buf, nread)) != nread) { -+ if (nwritten == -1) -+ warning("%s", tf[i].ofile); -+ else -+ warningx(_("%s: short write"), tf[i].ofile); -+ break; -+ } -+ } -+ if (nread == 0) { -+ /* success, got EOF */ -+ unlink(tf[i].tfile); -+ } else if (nread < 0) { -+ warning(_("unable to read temporary file")); -+ warningx(_("contents of edit session left in %s"), tf[i].tfile); -+ } else { -+ warning(_("unable to write to %s"), tf[i].ofile); -+ warningx(_("contents of edit session left in %s"), tf[i].tfile); -+ } -+ close(ofd); -+ } -+ j = 0; -+ } -+ -+ debug_return_int(j); -+cleanup: -+ for (i = 0; i < nfiles; i++) { -+ if (tf[i].tfile != NULL) -+ unlink(tf[i].tfile); -+ } -+ -+ debug_return_int(-1); -+} -+ - static void - switch_user(uid_t euid, gid_t egid, int ngroups, GETGROUPS_T *groups) - { -@@ -87,20 +360,17 @@ int - sudo_edit(struct command_details *command_details) - { - struct command_details editor_details; -- ssize_t nread, nwritten; - const char *tmpdir; -- char *cp, *suff, **nargv, **ap, **files = NULL; -- char buf[BUFSIZ]; -- int rc, i, j, ac, ofd, tfd, nargc, rval, tmplen; -- int editor_argc = 0, nfiles = 0; -+ char **ap; -+ char **nargv, **files = NULL; -+ int editor_argc = 0; -+ int i, ac, nargc, rval, nfiles = 0, tmplen; - struct stat sb; -- struct timeval tv, tv1, tv2; -- struct tempfile { -- char *tfile; -- char *ofile; -- struct timeval omtim; -- off_t osize; -- } *tf = NULL; -+ struct timeval tv1, tv2; -+ struct tempfile *tf; -+#ifdef HAVE_SELINUX -+ int rbac_enabled; -+#endif - debug_decl(sudo_edit, SUDO_DEBUG_EDIT) - - /* -@@ -109,7 +379,7 @@ sudo_edit(struct command_details *comman - */ - if (setuid(ROOT_UID) != 0) { - warning(_("unable to change uid to root (%u)"), ROOT_UID); -- goto cleanup; -+ return 1; - } - - /* -@@ -127,6 +397,9 @@ sudo_edit(struct command_details *comman - while (tmplen > 0 && tmpdir[tmplen - 1] == '/') - tmplen--; - -+#ifdef HAVE_SELINUX -+ rbac_enabled = is_selinux_enabled() > 0 && command_details->selinux_role != NULL; -+#endif - /* - * The user's editor must be separated from the files to be - * edited by a "--" option. -@@ -141,7 +414,7 @@ sudo_edit(struct command_details *comman - } - if (nfiles == 0) { - warningx(_("plugin error: missing file list for sudoedit")); -- goto cleanup; -+ return 1; - } - - /* -@@ -150,81 +423,18 @@ sudo_edit(struct command_details *comman - */ - tf = emalloc2(nfiles, sizeof(*tf)); - zero_bytes(tf, nfiles * sizeof(*tf)); -- for (i = 0, j = 0; i < nfiles; i++) { -- rc = -1; -- switch_user(command_details->euid, command_details->egid, -- command_details->ngroups, command_details->groups); -- if ((ofd = open(files[i], O_RDONLY, 0644)) != -1 || errno == ENOENT) { -- if (ofd == -1) { -- zero_bytes(&sb, sizeof(sb)); /* new file */ -- rc = 0; -- } else { -- rc = fstat(ofd, &sb); -- } -- } -- switch_user(ROOT_UID, user_details.egid, -- user_details.ngroups, user_details.groups); -- if (rc || (ofd != -1 && !S_ISREG(sb.st_mode))) { -- if (rc) -- warning("%s", files[i]); -- else -- warningx(_("%s: not a regular file"), files[i]); -- if (ofd != -1) -- close(ofd); -- continue; -- } -- tf[j].ofile = files[i]; -- tf[j].osize = sb.st_size; -- mtim_get(&sb, &tf[j].omtim); -- if ((cp = strrchr(tf[j].ofile, '/')) != NULL) -- cp++; -- else -- cp = tf[j].ofile; -- suff = strrchr(cp, '.'); -- if (suff != NULL) { -- easprintf(&tf[j].tfile, "%.*s/%.*sXXXXXXXX%s", tmplen, tmpdir, -- (int)(size_t)(suff - cp), cp, suff); -- } else { -- easprintf(&tf[j].tfile, "%.*s/%s.XXXXXXXX", tmplen, tmpdir, cp); -- } -- if (seteuid(user_details.uid) != 0) -- error(1, "seteuid(%d)", (int)user_details.uid); -- tfd = mkstemps(tf[j].tfile, suff ? strlen(suff) : 0); -- if (seteuid(ROOT_UID) != 0) -- error(1, "seteuid(ROOT_UID)"); -- if (tfd == -1) { -- warning("mkstemps"); -- goto cleanup; -- } -- if (ofd != -1) { -- while ((nread = read(ofd, buf, sizeof(buf))) != 0) { -- if ((nwritten = write(tfd, buf, nread)) != nread) { -- if (nwritten == -1) -- warning("%s", tf[j].tfile); -- else -- warningx(_("%s: short write"), tf[j].tfile); -- goto cleanup; -- } -- } -- close(ofd); -- } -- /* -- * We always update the stashed mtime because the time -- * resolution of the filesystem the temporary file is on may -- * not match that of the filesystem where the file to be edited -- * resides. It is OK if touch() fails since we only use the info -- * to determine whether or not a file has been modified. -- */ -- (void) touch(tfd, NULL, &tf[j].omtim); -- rc = fstat(tfd, &sb); -- if (!rc) -- mtim_get(&sb, &tf[j].omtim); -- close(tfd); -- j++; -- } -- if ((nfiles = j) == 0) -- goto cleanup; /* no files readable, you lose */ -+ -+ /* Make temporary copies of the original files */ -+ if (!rbac_enabled) -+ nfiles = sudo_edit_copy(command_details, tf, files, nfiles, tmpdir, tmplen, 0); -+ else -+ nfiles = selinux_edit_copy(command_details, tf, files, nfiles, tmpdir, tmplen, 0); - -+ if (nfiles <= 0) -+ return 1; -+ -+ switch_user(ROOT_UID, user_details.egid, -+ user_details.ngroups, user_details.groups); - /* - * Allocate space for the new argument vector and fill it in. - * We concatenate the editor with its args and the file list -@@ -253,84 +463,18 @@ sudo_edit(struct command_details *comman - editor_details.argv = nargv; - rval = run_command(&editor_details); - gettimeofday(&tv2, NULL); -+ timevalsub(&tv1, &tv2); - -- /* Copy contents of temp files to real ones */ -- for (i = 0; i < nfiles; i++) { -- rc = -1; -- if (seteuid(user_details.uid) != 0) -- error(1, "seteuid(%d)", (int)user_details.uid); -- if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) { -- rc = fstat(tfd, &sb); -- } -- if (seteuid(ROOT_UID) != 0) -- error(1, "seteuid(ROOT_UID)"); -- if (rc || !S_ISREG(sb.st_mode)) { -- if (rc) -- warning("%s", tf[i].tfile); -- else -- warningx(_("%s: not a regular file"), tf[i].tfile); -- warningx(_("%s left unmodified"), tf[i].ofile); -- if (tfd != -1) -- close(tfd); -- continue; -- } -- mtim_get(&sb, &tv); -- if (tf[i].osize == sb.st_size && timevalcmp(&tf[i].omtim, &tv, ==)) { -- /* -- * If mtime and size match but the user spent no measurable -- * time in the editor we can't tell if the file was changed. -- */ -- timevalsub(&tv1, &tv2); -- if (timevalisset(&tv2)) { -- warningx(_("%s unchanged"), tf[i].ofile); -- unlink(tf[i].tfile); -- close(tfd); -- continue; -- } -- } -- switch_user(command_details->euid, command_details->egid, -- command_details->ngroups, command_details->groups); -- ofd = open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644); -- switch_user(ROOT_UID, user_details.egid, -- user_details.ngroups, user_details.groups); -- if (ofd == -1) { -- warning(_("unable to write to %s"), tf[i].ofile); -- warningx(_("contents of edit session left in %s"), tf[i].tfile); -- close(tfd); -- continue; -- } -- while ((nread = read(tfd, buf, sizeof(buf))) > 0) { -- if ((nwritten = write(ofd, buf, nread)) != nread) { -- if (nwritten == -1) -- warning("%s", tf[i].ofile); -- else -- warningx(_("%s: short write"), tf[i].ofile); -- break; -- } -- } -- if (nread == 0) { -- /* success, got EOF */ -- unlink(tf[i].tfile); -- } else if (nread < 0) { -- warning(_("unable to read temporary file")); -- warningx(_("contents of edit session left in %s"), tf[i].tfile); -- } else { -- warning(_("unable to write to %s"), tf[i].ofile); -- warningx(_("contents of edit session left in %s"), tf[i].tfile); -- } -- close(ofd); -- } -+ switch_user(ROOT_UID, user_details.egid, -+ user_details.ngroups, user_details.groups); -+ -+ /* Copy the temporary files back to originals */ -+ if (!rbac_enabled) -+ nfiles = sudo_edit_copy(command_details, tf, NULL, nfiles, NULL, 0, timevalisset(&tv2)); -+ else -+ nfiles = selinux_edit_copy(command_details, tf, NULL, nfiles, NULL, 0, timevalisset(&tv2)); -+ - debug_return_int(rval); -- --cleanup: -- /* Clean up temp files and return. */ -- if (tf != NULL) { -- for (i = 0; i < nfiles; i++) { -- if (tf[i].tfile != NULL) -- unlink(tf[i].tfile); -- } -- } -- debug_return_int(1); - } - - #else /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */ -diff -up sudo-1.8.6p3/src/sudo.h.sudoedit-selinux sudo-1.8.6p3/src/sudo.h ---- sudo-1.8.6p3/src/sudo.h.sudoedit-selinux 2012-09-18 15:56:30.000000000 +0200 -+++ sudo-1.8.6p3/src/sudo.h 2012-09-25 16:04:36.690423001 +0200 -@@ -130,6 +130,7 @@ struct user_details { - #define CD_RBAC_ENABLED 0x0800 - #define CD_USE_PTY 0x1000 - #define CD_SET_UTMP 0x2000 -+#define CD_SUDOEDIT_COPY 0x4000 - - struct command_details { - uid_t uid; diff --git a/SOURCES/sudo-1.8.6p3-visudo-quiet-flag.patch b/SOURCES/sudo-1.8.6p3-visudo-quiet-flag.patch deleted file mode 100644 index 30c4eef..0000000 --- a/SOURCES/sudo-1.8.6p3-visudo-quiet-flag.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up sudo-1.8.6p3/plugins/sudoers/visudo.c.fix sudo-1.8.6p3/plugins/sudoers/visudo.c ---- sudo-1.8.6p3/plugins/sudoers/visudo.c.fix 2015-07-22 11:29:03.899122767 +0200 -+++ sudo-1.8.6p3/plugins/sudoers/visudo.c 2015-07-22 11:29:33.001826535 +0200 -@@ -201,7 +201,7 @@ main(int argc, char *argv[]) - strict = true; /* strict mode */ - break; - case 'q': -- quiet = false; /* quiet mode */ -+ quiet = true; /* quiet mode */ - break; - default: - usage(1); diff --git a/SOURCES/sudo-1.8.6p7-CVE-2014-9680.patch b/SOURCES/sudo-1.8.6p7-CVE-2014-9680.patch deleted file mode 100644 index 64cfdb9..0000000 --- a/SOURCES/sudo-1.8.6p7-CVE-2014-9680.patch +++ /dev/null @@ -1,333 +0,0 @@ -diff -up sudo-1.8.6p7/aclocal.m4.CVE-2014-9680 sudo-1.8.6p7/aclocal.m4 ---- sudo-1.8.6p7/aclocal.m4.CVE-2014-9680 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/aclocal.m4 2015-07-05 13:44:11.610596042 +0200 -@@ -156,6 +156,25 @@ AC_DEFUN([SUDO_IO_LOGDIR], [ - AC_MSG_RESULT($iolog_dir) - ])dnl - -+dnl Detect time zone file directory, if any. -+dnl -+AC_DEFUN([SUDO_TZDIR], [AC_MSG_CHECKING(time zone data directory) -+tzdir="$with_tzdir" -+if test -z "$tzdir"; then -+ tzdir=no -+ for d in /usr/share /usr/share/lib /usr/lib /etc; do -+ if test -d "$d/zoneinfo"; then -+ tzdir="$d/zoneinfo" -+ break -+ fi -+ done -+fi -+AC_MSG_RESULT([$tzdir]) -+if test "${tzdir}" != "no"; then -+ SUDO_DEFINE_UNQUOTED(_PATH_ZONEINFO, "$tzdir") -+fi -+])dnl -+ - dnl - dnl check for working fnmatch(3) - dnl -diff -up sudo-1.8.6p7/configure.in.CVE-2014-9680 sudo-1.8.6p7/configure.in ---- sudo-1.8.6p7/configure.in.CVE-2014-9680 2015-07-05 13:44:11.598596222 +0200 -+++ sudo-1.8.6p7/configure.in 2015-07-05 13:44:11.610596042 +0200 -@@ -776,6 +776,12 @@ AC_ARG_WITH(iologdir, [AS_HELP_STRING([- - ;; - esac]) - -+AC_ARG_WITH(tzdir, [AS_HELP_STRING([--with-tzdir=DIR], [path to the time zone data directory])], -+[case $with_tzdir in -+ yes) AC_MSG_ERROR(["must give --with-tzdir an argument."]) -+ ;; -+esac]) -+ - AC_ARG_WITH(sendmail, [AS_HELP_STRING([--with-sendmail], [set path to sendmail]) - AS_HELP_STRING([--without-sendmail], [do not send mail at all])], - [case $with_sendmail in -@@ -3250,6 +3256,7 @@ fi - SUDO_LOGFILE - SUDO_TIMEDIR - SUDO_IO_LOGDIR -+SUDO_TZDIR - - dnl - dnl Turn warnings into errors. -diff -up sudo-1.8.6p7/doc/sudoers.cat.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.cat ---- sudo-1.8.6p7/doc/sudoers.cat.CVE-2014-9680 2015-07-05 13:44:11.586596402 +0200 -+++ sudo-1.8.6p7/doc/sudoers.cat 2015-07-05 13:44:11.610596042 +0200 -@@ -1421,20 +1421,36 @@ SSUUDDOOEERRSS OOPPTTIIOONN - - LLiissttss tthhaatt ccaann bbee uusseedd iinn aa bboooolleeaann ccoonntteexxtt: - -- env_check Environment variables to be removed from the user's -- environment if the variable's value contains `%' or `/' -+ env_check Environment variables to be removed from the user's -+ environment if unless they are considered ``safe''. -+ For all variables except TZ, ``safe'' means that the -+ variable's value does not contain any `%' or `/' - characters. This can be used to guard against printf- - style format vulnerabilities in poorly-written -- programs. The argument may be a double-quoted, space- -- separated list or a single value without double-quotes. -- The list can be replaced, added to, deleted from, or -- disabled by using the =, +=, -=, and ! operators -- respectively. Regardless of whether the env_reset -- option is enabled or disabled, variables specified by -- env_check will be preserved in the environment if they -- pass the aforementioned check. The default list of -- environment variables to check is displayed when ssuuddoo -- is run by root with the --VV option. -+ programs. The TZ variable is considerd unsafe if any -+ of the following are true: -+ -+ ++oo It consists of a fully-qualified path name, -+ optionally prefixed with a colon (`:'), that does -+ not match the location of the _z_o_n_e_i_n_f_o directory. -+ -+ ++oo It contains a _._. path element. -+ -+ ++oo It contains white space or non-printable -+ characters. -+ -+ ++oo It is longer than the value of PATH_MAX. -+ -+ The argument may be a double-quoted, space-separated -+ list or a single value without double-quotes. The list -+ can be replaced, added to, deleted from, or disabled by -+ using the =, +=, -=, and ! operators respectively. -+ Regardless of whether the env_reset option is enabled -+ or disabled, variables specified by env_check will be -+ preserved in the environment if they pass the -+ aforementioned check. The default list of environment -+ variables to check is displayed when ssuuddoo is run by -+ root with the --VV option. - - env_delete Environment variables to be removed from the user's - environment when the _e_n_v___r_e_s_e_t option is not in effect. -diff -up sudo-1.8.6p7/doc/sudoers.man.in.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.man.in ---- sudo-1.8.6p7/doc/sudoers.man.in.CVE-2014-9680 2015-07-05 13:44:11.586596402 +0200 -+++ sudo-1.8.6p7/doc/sudoers.man.in 2015-07-05 13:44:11.611596027 +0200 -@@ -3002,14 +3002,47 @@ The default value is - \fBLists that can be used in a boolean context\fR: - .TP 18n - env_check --Environment variables to be removed from the user's environment if --the variable's value contains --`%' -+ Environment variables to be removed from the user's environment if -+unless they are considered -+\(lqsafe\(rq. -+For all variables except -+\fRTZ\fR, -+\(lqsafe\(rq -+means that the variable's value does not contain any -+\(oq%\(cq - or --`/' -+\(oq/\(cq - characters. - This can be used to guard against printf-style format vulnerabilities - in poorly-written programs. -+The -+\fRTZ\fR -+variable is considerd unsafe if any of the following are true: -+.PP -+.RS 18n -+.PD 0 -+.TP 4n -+\fB\(bu\fR -+It consists of a fully-qualified path name, -+optionally prefixed with a colon -+(\(oq:\&\(cq), -+that does not match the location of the -+\fIzoneinfo\fR -+directory. -+.PD -+.TP 4n -+\fB\(bu\fR -+It contains a -+\fI..\fR -+path element. -+.TP 4n -+\fB\(bu\fR -+It contains white space or non-printable characters. -+.TP 4n -+\fB\(bu\fR -+It is longer than the value of -+\fRPATH_MAX\fR. -+.PP - The argument may be a double-quoted, space-separated list or a - single value without double-quotes. - The list can be replaced, added to, deleted from, or disabled by using -@@ -3031,6 +3064,7 @@ is run by root with - the - \fB\-V\fR - option. -+.RE - .TP 18n - env_delete - Environment variables to be removed from the user's environment when the -diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.mdoc.in ---- sudo-1.8.6p7/doc/sudoers.mdoc.in.CVE-2014-9680 2015-07-05 13:44:11.586596402 +0200 -+++ sudo-1.8.6p7/doc/sudoers.mdoc.in 2015-07-05 13:44:11.611596027 +0200 -@@ -2791,13 +2791,40 @@ The default value is - .Bl -tag -width 16n - .It env_check - Environment variables to be removed from the user's environment if --the variable's value contains -+unless they are considered -+.Dq safe . -+For all variables except -+.Li TZ , -+.Dq safe -+means that the variable's value does not contain any - .Ql % - or - .Ql / - characters. - This can be used to guard against printf-style format vulnerabilities - in poorly-written programs. -+The -+.Li TZ -+variable is considerd unsafe if any of the following are true: -+.Bl -bullet -+.It -+It consists of a fully-qualified path name, -+optionally prefixed with a colon -+.Pq Ql :\& , -+that does not match the location of the -+.Pa zoneinfo -+directory. -+.It -+It contains a -+.Pa .. -+path element. -+.It -+It contains white space or non-printable characters. -+.It -+It is longer than the value of -+.Li PATH_MAX . -+.El -+.Pp - The argument may be a double-quoted, space-separated list or a - single value without double-quotes. - The list can be replaced, added to, deleted from, or disabled by using -diff -up sudo-1.8.6p7/INSTALL.CVE-2014-9680 sudo-1.8.6p7/INSTALL ---- sudo-1.8.6p7/INSTALL.CVE-2014-9680 2013-02-25 20:42:43.000000000 +0100 -+++ sudo-1.8.6p7/INSTALL 2015-07-05 13:44:11.611596027 +0200 -@@ -461,6 +461,16 @@ The following options are also configura - Override the default location of the sudo timestamp directory and - use "path" instead. - -+ --with-tzdir=DIR -+ Set the directory to the system's time zone data files. This -+ is only used when sanitizing the TZ environment variable to -+ allow for fully-qualified paths in TZ. -+ By default, configure will look for an existing "zoneinfo" -+ directory in the following locations: -+ /usr/share /usr/share/lib /usr/lib /etc -+ If no zoneinfo directory is found, the TZ variable may not -+ contain a fully-qualified path. -+ - --with-sendmail=PATH - Override configure's guess as to the location of sendmail. - -diff -up sudo-1.8.6p7/pathnames.h.in.CVE-2014-9680 sudo-1.8.6p7/pathnames.h.in ---- sudo-1.8.6p7/pathnames.h.in.CVE-2014-9680 2012-09-18 15:56:28.000000000 +0200 -+++ sudo-1.8.6p7/pathnames.h.in 2015-07-05 13:44:11.612596011 +0200 -@@ -168,3 +168,7 @@ - #ifndef _PATH_NETSVC_CONF - #undef _PATH_NETSVC_CONF - #endif /* _PATH_NETSVC_CONF */ -+ -+#ifndef _PATH_ZONEINFO -+# undef _PATH_ZONEINFO -+#endif /* _PATH_ZONEINFO */ -diff -up sudo-1.8.6p7/plugins/sudoers/env.c.CVE-2014-9680 sudo-1.8.6p7/plugins/sudoers/env.c ---- sudo-1.8.6p7/plugins/sudoers/env.c.CVE-2014-9680 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/env.c 2015-07-05 13:44:11.612596011 +0200 -@@ -198,6 +198,7 @@ static const char *initial_checkenv_tabl - "LC_*", - "LINGUAS", - "TERM", -+ "TZ", - NULL - }; - -@@ -213,7 +214,6 @@ static const char *initial_keepenv_table - "PATH", - "PS1", - "PS2", -- "TZ", - "XAUTHORITY", - "XAUTHORIZATION", - NULL -@@ -584,6 +584,54 @@ matches_env_delete(const char *var) - } - - /* -+ * Sanity-check the TZ environment variable. -+ * On many systems it is possible to set this to a pathname. -+ */ -+static bool -+tz_is_sane(const char *tzval) -+{ -+ const char *cp; -+ char lastch; -+ debug_decl(tz_is_sane, SUDO_DEBUG_ENV) -+ -+ /* tzcode treats a value beginning with a ':' as a path. */ -+ if (tzval[0] == ':') -+ tzval++; -+ -+ /* Reject fully-qualified TZ that doesn't being with the zoneinfo dir. */ -+ if (tzval[0] == '/') { -+#ifdef _PATH_ZONEINFO -+ if (strncmp(tzval, _PATH_ZONEINFO, sizeof(_PATH_ZONEINFO) - 1) != 0 || -+ tzval[sizeof(_PATH_ZONEINFO) - 1] != '/') -+ debug_return_bool(false); -+#else -+ /* Assume the worst. */ -+ debug_return_bool(false); -+#endif -+ } -+ -+ /* -+ * Make sure TZ only contains printable non-space characters -+ * and does not contain a '..' path element. -+ */ -+ lastch = '/'; -+ for (cp = tzval; *cp != '\0'; cp++) { -+ if (isspace((unsigned char)*cp) || !isprint((unsigned char)*cp)) -+ debug_return_bool(false); -+ if (lastch == '/' && cp[0] == '.' && cp[1] == '.' && -+ (cp[2] == '/' || cp[2] == '\0')) -+ debug_return_bool(false); -+ lastch = *cp; -+ } -+ -+ /* Reject extra long TZ values (even if not a path). */ -+ if ((size_t)(cp - tzval) >= PATH_MAX) -+ debug_return_bool(false); -+ -+ debug_return_bool(true); -+} -+ -+/* - * Apply the env_check list. - * Returns true if the variable is allowed, false if denied - * or -1 if no match. -@@ -607,8 +655,13 @@ matches_env_check(const char *var) - iswild = false; - if (strncmp(cur->value, var, len) == 0 && - (iswild || var[len] == '=')) { -+ if (strncmp(var, "TZ=", 3) == 0 ) { -+ /* Sperial case for TZ */ -+ keepit = tz_is_sane(var + 3); -+ } else { - keepit = !strpbrk(var, "/%"); -- break; -+ } -+ break; - } - } - debug_return_bool(keepit); diff --git a/SOURCES/sudo-1.8.6p7-CVE-2017-1000368.patch b/SOURCES/sudo-1.8.6p7-CVE-2017-1000368.patch deleted file mode 100644 index 27ad7ba..0000000 --- a/SOURCES/sudo-1.8.6p7-CVE-2017-1000368.patch +++ /dev/null @@ -1,117 +0,0 @@ -diff --git a/src/ttyname.c b/src/ttyname.c -index 32f093c..d8858f7 100644 ---- a/src/ttyname.c -+++ b/src/ttyname.c -@@ -414,53 +414,80 @@ get_process_ttyname(void) - } - #elif defined(__linux__) - /* -- * Return a string from ttyname() containing the tty to which the process is -- * attached or NULL if there is no tty associated with the process (or its -- * parent). First tries field 7 in /proc/pid/stat, then /proc/ppid/stat. -- * Falls back on ttyname of std{in,out,err} if that fails. -+ * Store the name of the tty to which the process is attached in name. -+ * Returns name on success and NULL on failure, setting errno. - */ - char * - get_process_ttyname(void) - { -- char *line = NULL, *tty = NULL; -- size_t linesize = 0; -- ssize_t len; -- int i; -+ const char path[] = "/proc/self/stat"; -+ char *cp, buf[1024]; -+ char *ret = NULL; -+ int serrno = errno; -+ ssize_t nread; -+ int fd; - debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL) - -- /* Try to determine the tty from tty_nr in /proc/pid/stat. */ -- for (i = 0; tty == NULL && i < 2; i++) { -- FILE *fp; -- char path[PATH_MAX]; -- (void)snprintf(path, sizeof(path), "/proc/%u/stat", -- i ? (unsigned int)getppid() : (unsigned int)getpid()); -- if ((fp = fopen(path, "r")) == NULL) -- continue; -- len = getline(&line, &linesize, fp); -- fclose(fp); -- if (len != -1) { -+ /* -+ * Try to determine the tty from tty_nr in /proc/self/stat. -+ * Ignore /proc/self/stat if it contains embedded NUL bytes. -+ */ -+ if ((fd = open(path, O_RDONLY | O_NOFOLLOW)) != -1) { -+ cp = buf; -+ while ((nread = read(fd, cp, buf + sizeof(buf) - cp)) != 0) { -+ if (nread == -1) { -+ if (errno == EAGAIN || errno == EINTR) -+ continue; -+ break; -+ } -+ cp += nread; -+ if (cp >= buf + sizeof(buf)) -+ break; -+ } -+ if (nread == 0 && memchr(buf, '\0', cp - buf) == NULL) { - /* - * Field 7 is the tty dev (0 if no tty). -- * Since the process name at field 2 "(comm)" may include spaces, -- * start at the last ')' found. -+ * Since the process name at field 2 "(comm)" may include -+ * whitespace (including newlines), start at the last ')' found. - */ -- char *cp = strrchr(line, ')'); -- int field = 2; -- while (*cp != '\0') { -- if (*cp++ == ' ') { -- if (++field == 7) { -- dev_t tdev = (dev_t)atoi(cp); -- if (tdev > 0) -- tty = sudo_ttyname_dev(tdev); -- break; -+ *cp = '\0'; -+ cp = strrchr(buf, ')'); -+ if (cp != NULL) { -+ char *ep = cp; -+ int field = 1; -+ -+ while (*++ep != '\0') { -+ if (*ep == ' ') { -+ *ep = '\0'; -+ if (++field == 7) { -+ dev_t tdev = (dev_t)strtol(cp, NULL, 10); -+ if (tdev == 0 || errno == ERANGE || errno == EINVAL) { -+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, -+ "%s: tty device %s: %s", path, cp, strerror(errno)); -+ } -+ if (tdev > 0) { -+ errno = serrno; -+ ret = sudo_ttyname_dev(tdev); -+ goto done; -+ } -+ break; -+ } -+ cp = ep + 1; - } - } - } - } - } -- efree(line); -+ errno = ENOENT; - -- debug_return_str(tty); -+done: -+ if (fd != -1) -+ close(fd); -+ if (ret == NULL) -+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, -+ "unable to resolve tty via %s", path); -+ -+ debug_return_str(ret); - } - #else - /* diff --git a/SOURCES/sudo-1.8.6p7-authlogicfix.patch b/SOURCES/sudo-1.8.6p7-authlogicfix.patch deleted file mode 100644 index f721589..0000000 --- a/SOURCES/sudo-1.8.6p7-authlogicfix.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.authlogicfix sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.authlogicfix 2015-07-05 13:40:15.389145839 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2015-07-05 13:40:15.413145478 +0200 -@@ -2392,9 +2392,13 @@ sudo_ldap_lookup(struct sudo_nss *nss, i - for (i = 0; i < lres->nentries; i++) { - entry = lres->entries[i].entry; - if ((pwcheck == any && doauth != false) || -- (pwcheck == all && doauth == false)) { -- doauth = sudo_ldap_check_bool(ld, entry, "authenticate"); -+ (pwcheck == all && doauth != true)) { -+ doauth = !!sudo_ldap_check_bool(ld, entry, "authenticate"); - } -+ } -+ -+ for (i = 0; i < lres->nentries; i++) { -+ entry = lres->entries[i].entry; - /* Only check the command when listing another user. */ - if (user_uid == 0 || list_pw == NULL || - user_uid == list_pw->pw_uid || -diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.authlogicfix sudo-1.8.6p7/plugins/sudoers/sssd.c ---- sudo-1.8.6p7/plugins/sudoers/sssd.c.authlogicfix 2015-07-05 13:40:15.412145494 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2015-07-05 13:40:15.414145463 +0200 -@@ -970,9 +970,13 @@ sudo_sss_lookup(struct sudo_nss *nss, in - for (i = 0; i < sss_result->num_rules; i++) { - rule = sss_result->rules + i; - if ((pwcheck == any && doauth != false) || -- (pwcheck == all && doauth == false)) { -- doauth = sudo_sss_check_bool(handle, rule, "authenticate"); -+ (pwcheck == all && doauth != true)) { -+ doauth = !!sudo_sss_check_bool(handle, rule, "authenticate"); - } -+ } -+ -+ for (i = 0; i < sss_result->num_rules; i++) { -+ rule = sss_result->rules + i; - /* Only check the command when listing another user. */ - if (user_uid == 0 || list_pw == NULL || - user_uid == list_pw->pw_uid || diff --git a/SOURCES/sudo-1.8.6p7-clangfixes.patch b/SOURCES/sudo-1.8.6p7-clangfixes.patch deleted file mode 100644 index 70d9aff..0000000 --- a/SOURCES/sudo-1.8.6p7-clangfixes.patch +++ /dev/null @@ -1,46 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.clangfixes sudo-1.8.6p7/plugins/sudoers/sssd.c ---- sudo-1.8.6p7/plugins/sudoers/sssd.c.clangfixes 2014-09-30 10:31:43.920885432 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2014-09-30 10:32:39.413228871 +0200 -@@ -313,9 +313,9 @@ static int sudo_sss_close(struct sudo_ns - if (nss && nss->handle) { - handle = nss->handle; - dlclose(handle->ssslib); -+ efree(nss->handle); - } - -- efree(nss->handle); - debug_return_int(0); - } - -@@ -755,12 +755,15 @@ sudo_sss_result_get(struct sudo_nss *nss - *state |= _SUDO_SSS_STATE_HOSTMATCH; - } - } -+ sudo_debug_printf(SUDO_DEBUG_DEBUG, -+ "u_sss_result=(%p, %u) => f_sss_result=(%p, %u)", u_sss_result, -+ u_sss_result->num_rules, f_sss_result, f_sss_result->num_rules); -+ } else { -+ sudo_debug_printf(SUDO_DEBUG_DEBUG, -+ "u_sss_result=(%p, %u) => f_sss_result=NULL", u_sss_result, -+ u_sss_result->num_rules); - } - -- sudo_debug_printf(SUDO_DEBUG_DEBUG, -- "u_sss_result=(%p, %u) => f_sss_result=(%p, %u)", u_sss_result, -- u_sss_result->num_rules, f_sss_result, f_sss_result->num_rules); -- - handle->fn_free_result(u_sss_result); - - debug_return_ptr(f_sss_result); -diff -up sudo-1.8.6p7/plugins/sudoers/visudo.c.clangfixes sudo-1.8.6p7/plugins/sudoers/visudo.c ---- sudo-1.8.6p7/plugins/sudoers/visudo.c.clangfixes 2014-09-30 10:34:08.689174020 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/visudo.c 2014-09-30 11:00:15.215654285 +0200 -@@ -544,7 +544,7 @@ reparse_sudoers(char *editor, char *args - continue; - edit_sudoers(sp, editor, args, errorlineno); - } -- } while (parse_error); -+ } while (parse_error && sp != NULL); - - debug_return; - } diff --git a/SOURCES/sudo-1.8.6p7-closefrom-override-fix.patch b/SOURCES/sudo-1.8.6p7-closefrom-override-fix.patch deleted file mode 100644 index 73fc84c..0000000 --- a/SOURCES/sudo-1.8.6p7-closefrom-override-fix.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.c.closefrom-override-fix sudo-1.8.6p7/plugins/sudoers/sudoers.c ---- sudo-1.8.6p7/plugins/sudoers/sudoers.c.closefrom-override-fix 2016-02-15 10:31:11.694164366 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/sudoers.c 2016-02-15 10:33:47.711362062 +0100 -@@ -336,15 +336,6 @@ sudoers_policy_main(int argc, char * con - goto bad; - } - -- /* Check for -C overriding def_closefrom. */ -- if (user_closefrom >= 0 && user_closefrom != def_closefrom) { -- if (!def_closefrom_override) { -- warningx(_("you are not permitted to use the -C option")); -- goto bad; -- } -- def_closefrom = user_closefrom; -- } -- - set_perms(PERM_INITIAL); - - /* Environment variables specified on the command line. */ -@@ -374,8 +365,17 @@ sudoers_policy_main(int argc, char * con - if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS)) - def_preserve_groups = true; - -- /* Find command in path */ -+ /* Find command in path and apply per-command Defaults. */ - cmnd_status = set_cmnd(); -+ -+ /* Check for -C overriding def_closefrom. */ -+ if (user_closefrom >= 0 && user_closefrom != def_closefrom) { -+ if (!def_closefrom_override) { -+ warningx(_("you are not permitted to use the -C option")); -+ goto bad; -+ } -+ def_closefrom = user_closefrom; -+ } - - #ifdef HAVE_SETLOCALE - if (!setlocale(LC_ALL, def_sudoers_locale)) { diff --git a/SOURCES/sudo-1.8.6p7-constwarnfix.patch b/SOURCES/sudo-1.8.6p7-constwarnfix.patch deleted file mode 100644 index 5e3a6f6..0000000 --- a/SOURCES/sudo-1.8.6p7-constwarnfix.patch +++ /dev/null @@ -1,104 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/match.c.constwarnfix sudo-1.8.6p7/plugins/sudoers/match.c ---- sudo-1.8.6p7/plugins/sudoers/match.c.constwarnfix 2014-09-29 15:55:50.996485025 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/match.c 2014-09-29 15:55:51.002484954 +0200 -@@ -599,7 +599,7 @@ command_matches_dir(char *sudoers_dir, s - * Returns true if the hostname matches the pattern, else false - */ - bool --hostname_matches(char *shost, char *lhost, char *pattern) -+hostname_matches(const char *shost, const char *lhost, const char *pattern) - { - debug_decl(hostname_matches, SUDO_DEBUG_MATCH) - -@@ -621,7 +621,7 @@ hostname_matches(char *shost, char *lhos - * else returns false. - */ - bool --userpw_matches(char *sudoers_user, char *user, struct passwd *pw) -+userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw) - { - debug_decl(userpw_matches, SUDO_DEBUG_MATCH) - if (pw != NULL && *sudoers_user == '#') { -@@ -640,7 +640,7 @@ userpw_matches(char *sudoers_user, char - * else returns false. - */ - bool --group_matches(char *sudoers_group, struct group *gr) -+group_matches(const char *sudoers_group, const struct group *gr) - { - debug_decl(group_matches, SUDO_DEBUG_MATCH) - if (*sudoers_group == '#') { -@@ -659,7 +659,7 @@ group_matches(char *sudoers_group, struc - * else returns false. - */ - bool --usergr_matches(char *group, char *user, struct passwd *pw) -+usergr_matches(const char *group, const char *user, const struct passwd *pw) - { - int matched = false; - struct passwd *pw0 = NULL; -@@ -707,7 +707,7 @@ done: - * XXX - swap order of host & shost - */ - bool --netgr_matches(char *netgr, char *lhost, char *shost, char *user) -+netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user) - { - static char *domain; - #ifdef HAVE_GETDOMAINNAME -diff -up sudo-1.8.6p7/plugins/sudoers/parse.h.constwarnfix sudo-1.8.6p7/plugins/sudoers/parse.h ---- sudo-1.8.6p7/plugins/sudoers/parse.h.constwarnfix 2014-09-29 15:55:50.992485072 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/parse.h 2014-09-29 15:55:51.002484954 +0200 -@@ -188,11 +188,11 @@ bool addr_matches(char *n); - - /* match.c */ - bool command_matches(char *sudoers_cmnd, char *sudoers_args); --bool group_matches(char *sudoers_group, struct group *gr); --bool hostname_matches(char *shost, char *lhost, char *pattern); --bool netgr_matches(char *netgr, char *lhost, char *shost, char *user); --bool usergr_matches(char *group, char *user, struct passwd *pw); --bool userpw_matches(char *sudoers_user, char *user, struct passwd *pw); -+bool group_matches(const char *sudoers_group, const struct group *gr); -+bool hostname_matches(const char *shost, const char *lhost, const char *pattern); -+bool netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user); -+bool usergr_matches(const char *group, const char *user, const struct passwd *pw); -+bool userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw); - int cmnd_matches(struct member *m); - int cmndlist_matches(struct member_list *list); - int hostlist_matches(struct member_list *list); -diff -up sudo-1.8.6p7/plugins/sudoers/pwutil.c.constwarnfix sudo-1.8.6p7/plugins/sudoers/pwutil.c ---- sudo-1.8.6p7/plugins/sudoers/pwutil.c.constwarnfix 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/pwutil.c 2014-09-29 15:55:51.003484942 +0200 -@@ -841,7 +841,7 @@ sudo_endgrent(void) - } - - struct group_list * --sudo_get_grlist(struct passwd *pw) -+sudo_get_grlist(const struct passwd *pw) - { - struct cache_item key, *item; - struct rbnode *node; -@@ -905,7 +905,7 @@ done: - } - - bool --user_in_group(struct passwd *pw, const char *group) -+user_in_group(const struct passwd *pw, const char *group) - { - struct group_list *grlist; - struct group *grp = NULL; -diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.constwarnfix sudo-1.8.6p7/plugins/sudoers/sudoers.h ---- sudo-1.8.6p7/plugins/sudoers/sudoers.h.constwarnfix 2013-02-25 20:49:09.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/sudoers.h 2014-09-29 15:55:51.003484942 +0200 -@@ -288,9 +288,9 @@ __dso_public struct group *sudo_getgrgid - __dso_public struct group *sudo_getgrnam(const char *); - __dso_public void sudo_gr_addref(struct group *); - __dso_public void sudo_gr_delref(struct group *); --bool user_in_group(struct passwd *, const char *); -+bool user_in_group(const struct passwd *, const char *); - struct group *sudo_fakegrnam(const char *); --struct group_list *sudo_get_grlist(struct passwd *pw); -+struct group_list *sudo_get_grlist(const struct passwd *pw); - struct passwd *sudo_fakepwnam(const char *, gid_t); - struct passwd *sudo_fakepwnamid(const char *user, uid_t uid, gid_t gid); - struct passwd *sudo_getpwnam(const char *); diff --git a/SOURCES/sudo-1.8.6p7-digest-backport-checklinkfix.patch b/SOURCES/sudo-1.8.6p7-digest-backport-checklinkfix.patch deleted file mode 100644 index feeeb6c..0000000 --- a/SOURCES/sudo-1.8.6p7-digest-backport-checklinkfix.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/Makefile.in.digest-backport-checklinkfix sudo-1.8.6p7/plugins/sudoers/Makefile.in ---- sudo-1.8.6p7/plugins/sudoers/Makefile.in.digest-backport-checklinkfix 2015-08-25 14:31:24.889199953 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/Makefile.in 2015-08-25 14:32:34.817198098 +0200 -@@ -146,7 +146,7 @@ TEST_OBJS = interfaces.o testsudoers.o t - - CHECK_ADDR_OBJS = check_addr.o match_addr.o interfaces.o error.o - --CHECK_FILL_OBJS = check_fill.o toke_util.o error.o -+CHECK_FILL_OBJS = check_fill.o toke_util.o error.o hexchar.o - - CHECK_IOLOG_PATH_OBJS = check_iolog_path.o error.o iolog_path.o pwutil.o \ - redblack.o diff --git a/SOURCES/sudo-1.8.6p7-digest-backport-docs.patch b/SOURCES/sudo-1.8.6p7-digest-backport-docs.patch deleted file mode 100644 index 2b99b26..0000000 --- a/SOURCES/sudo-1.8.6p7-digest-backport-docs.patch +++ /dev/null @@ -1,260 +0,0 @@ -diff -up sudo-1.8.6p7/doc/sudoers.cat.digest-backport-docs sudo-1.8.6p7/doc/sudoers.cat ---- sudo-1.8.6p7/doc/sudoers.cat.digest-backport-docs 2015-07-07 13:06:11.078653045 +0200 -+++ sudo-1.8.6p7/doc/sudoers.cat 2015-07-07 13:12:05.170955417 +0200 -@@ -260,6 +260,14 @@ SSUUDDOOEERRSS FFIILLEE FFO - ``localhost'' will only match if that is the actual host name, which is - usually only the case for non-networked systems. - -+ digest ::= [A-Fa-f0-9]+ | -+ [[A-Za-z0-9+/=]+ -+ -+ Digest_Spec ::= "sha224" ':' digest | -+ "sha256" ':' digest | -+ "sha384" ':' digest | -+ "sha512" ':' digest -+ - Cmnd_List ::= Cmnd | - Cmnd ',' Cmnd_List - -@@ -267,7 +275,7 @@ SSUUDDOOEERRSS FFIILLEE FFO - file name args | - file name '""' - -- Cmnd ::= '!'* command name | -+ Cmnd ::= Digest_Spec? '!'* command name | - '!'* directory | - '!'* "sudoedit" | - '!'* Cmnd_Alias -@@ -291,6 +299,26 @@ SSUUDDOOEERRSS FFIILLEE FFO - to permit a user to run ssuuddoo with the --ee option (or as ssuuddooeeddiitt). It may - take command line arguments just as a normal command does. - -+ If a command name is prefixed with a Digest_Spec, the command will only -+ match successfully if it can be verified using the specified SHA-2 -+ digest. This may be useful in situations where the user invoking ssuuddoo -+ has write access to the command or its parent directory. The following -+ digest formats are supported: sha224, sha256, sha384 and sha512. The -+ string may be specified in either hex or base64 format (base64 is more -+ compact). There are several utilities capable of generating SHA-2 -+ digests in hex format such as openssl, shasum, sha224sum, sha256sum, -+ sha384sum, sha512sum. -+ -+ For example, using openssl: -+ -+ $ openssl dgst -sha224 /bin/ls -+ SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25 -+ -+ It is also possible to use openssl to generate base64 output: -+ -+ $ openssl dgst -binary -sha224 /bin/ls | openssl base64 -+ EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ== -+ - DDeeffaauullttss - Certain configuration options may be changed from their default values at - run-time via one or more Default_Entry lines. These may affect all users -@@ -1797,7 +1825,9 @@ EEXXAAMMPPLLEESS - - # Cmnd alias specification - Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\ -- /usr/sbin/restore, /usr/sbin/rrestore -+ /usr/sbin/restore, /usr/sbin/rrestore\ -+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \ -+ /home/operator/bin/start_backups - Cmnd_Alias KILL = /usr/bin/kill - Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm - Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown -@@ -1867,7 +1897,11 @@ EEXXAAMMPPLLEESS - The ooppeerraattoorr user may run commands limited to simple maintenance. Here, - those are commands related to backups, killing processes, the printing - system, shutting down the system, and any commands in the directory -- _/_u_s_r_/_o_p_e_r_/_b_i_n_/. -+ _/_u_s_r_/_o_p_e_r_/_b_i_n_/. Note that one command in the DUMPS Cmnd_Alias includes a -+ sha224 digest, _/_h_o_m_e_/_o_p_e_r_a_t_o_r_/_b_i_n_/_s_t_a_r_t___b_a_c_k_u_p_s. This is because the -+ directory containing the script is writable by the operator user. If the -+ script is modified (resulting in a digest mismatch) it will no longer be -+ possible to run it via ssuuddoo. - - joe ALL = /usr/bin/su operator - -diff -up sudo-1.8.6p7/doc/sudoers.man.in.digest-backport-docs sudo-1.8.6p7/doc/sudoers.man.in ---- sudo-1.8.6p7/doc/sudoers.man.in.digest-backport-docs 2015-07-07 13:06:28.363472547 +0200 -+++ sudo-1.8.6p7/doc/sudoers.man.in 2015-07-07 13:16:05.250448374 +0200 -@@ -602,6 +602,14 @@ only the case for non-networked systems. - .nf - .sp - .RS 0n -+digest ::= [A-Fa-f0-9]+ | -+ [[A-Za-z0-9\+/=]+ -+ -+Digest_Spec ::= "sha224" ':' digest | -+ "sha256" ':' digest | -+ "sha384" ':' digest | -+ "sha512" ':' digest -+ - Cmnd_List ::= Cmnd | - Cmnd ',' Cmnd_List - -@@ -609,7 +617,7 @@ command name ::= file name | - file name args | - file name '""' - --Cmnd ::= '!'* command name | -+Cmnd ::= Digest_Spec? '!'* command name | - '!'* directory | - '!'* "sudoedit" | - '!'* Cmnd_Alias -@@ -664,6 +672,39 @@ with the - option (or as - \fBsudoedit\fR). - It may take command line arguments just as a normal command does. -+.PP -+If a -+\fRcommand name\fR -+is prefixed with a -+\fRDigest_Spec\fR, -+the command will only match successfully if it can be verified -+using the specified SHA-2 digest. -+This may be useful in situations where the user invoking -+\fBsudo\fR -+has write access to the command or its parent directory. -+The following digest formats are supported: sha224, sha256, sha384 and sha512. -+The string may be specified in either hex or base64 format -+(base64 is more compact). -+There are several utilities capable of generating SHA-2 digests in hex -+format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum. -+.PP -+For example, using openssl: -+.nf -+.sp -+.RS 0n -+$ openssl dgst -sha224 /bin/ls -+SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25 -+.RE -+.fi -+.PP -+It is also possible to use openssl to generate base64 output: -+.nf -+.sp -+.RS 0n -+$ openssl dgst -binary -sha224 /bin/ls | openssl base64 -+EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ== -+.RE -+.fi - .SS "Defaults" - Certain configuration options may be changed from their default - values at run-time via one or more -@@ -3684,7 +3725,9 @@ Host_Alias CDROM = orion, perseus, hercu - - # Cmnd alias specification - Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e -- /usr/sbin/restore, /usr/sbin/rrestore -+ /usr/sbin/restore, /usr/sbin/rrestore\e -+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \e -+ /home/operator/bin/start_backups - Cmnd_Alias KILL = /usr/bin/kill - Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm - Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown -@@ -3836,6 +3879,15 @@ Here, those are commands related to back - printing system, shutting down the system, and any commands in the - directory - \fI/usr/oper/bin/\fR. -+Note that one command in the -+\fRDUMPS\fR -+Cmnd_Alias includes a sha224 digest, -+\fI/home/operator/bin/start_backups\fR. -+This is because the directory containing the script is writable by the -+operator user. -+If the script is modified (resulting in a digest mismatch) it will no longer -+be possible to run it via -+\fBsudo\fR. - .nf - .sp - .RS 0n -diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.digest-backport-docs sudo-1.8.6p7/doc/sudoers.mdoc.in ---- sudo-1.8.6p7/doc/sudoers.mdoc.in.digest-backport-docs 2015-07-07 13:06:18.919571166 +0200 -+++ sudo-1.8.6p7/doc/sudoers.mdoc.in 2015-07-07 13:23:45.072854748 +0200 -@@ -579,6 +579,14 @@ Also, the host name - will only match if that is the actual host name, which is usually - only the case for non-networked systems. - .Bd -literal -+digest ::= [A-Fa-f0-9]+ | -+ [[A-Za-z0-9\+/=]+ -+ -+Digest_Spec ::= "sha224" ':' digest | -+ "sha256" ':' digest | -+ "sha384" ':' digest | -+ "sha512" ':' digest -+ - Cmnd_List ::= Cmnd | - Cmnd ',' Cmnd_List - -@@ -586,7 +594,7 @@ command name ::= file name | - file name args | - file name '""' - --Cmnd ::= '!'* command name | -+Cmnd ::= Digest_Spec? '!'* command name | - '!'* directory | - '!'* "sudoedit" | - '!'* Cmnd_Alias -@@ -640,6 +648,33 @@ with the - option (or as - .Nm sudoedit ) . - It may take command line arguments just as a normal command does. -+.Pp -+If a -+.Li command name -+is prefixed with a -+.Li Digest_Spec , -+the command will only match successfully if it can be verified -+using the specified SHA-2 digest. -+This may be useful in situations where the user invoking -+.Nm sudo -+has write access to the command or its parent directory. -+The following digest formats are supported: sha224, sha256, sha384 and sha512. -+The string may be specified in either hex or base64 format -+(base64 is more compact). -+There are several utilities capable of generating SHA-2 digests in hex -+format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum. -+.Pp -+For example, using openssl: -+.Bd -literal -+$ openssl dgst -sha224 /bin/ls -+SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25 -+.Ed -+.Pp -+It is also possible to use openssl to generate base64 output: -+.Bd -literal -+$ openssl dgst -binary -sha224 /bin/ls | openssl base64 -+EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ== -+.Ed - .Ss Defaults - Certain configuration options may be changed from their default - values at run-time via one or more -@@ -3407,7 +3442,9 @@ Host_Alias CDROM = orion, perseus, hercu - - # Cmnd alias specification - Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e -- /usr/sbin/restore, /usr/sbin/rrestore -+ /usr/sbin/restore, /usr/sbin/rrestore\e -+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \e -+ /home/operator/bin/start_backups - Cmnd_Alias KILL = /usr/bin/kill - Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm - Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown -@@ -3540,6 +3577,15 @@ Here, those are commands related to back - printing system, shutting down the system, and any commands in the - directory - .Pa /usr/oper/bin/ . -+Note that one command in the -+.Li DUMPS -+Cmnd_Alias includes a sha224 digest, -+.Pa /home/operator/bin/start_backups . -+This is because the directory containing the script is writable by the -+operator user. -+If the script is modified (resulting in a digest mismatch) it will no longer -+be possible to run it via -+.Nm sudo . - .Bd -literal - joe ALL = /usr/bin/su operator - .Ed diff --git a/SOURCES/sudo-1.8.6p7-digest-backport.patch b/SOURCES/sudo-1.8.6p7-digest-backport.patch index f815af2..a814b2c 100644 --- a/SOURCES/sudo-1.8.6p7-digest-backport.patch +++ b/SOURCES/sudo-1.8.6p7-digest-backport.patch @@ -1,106 +1,61 @@ -diff -up sudo-1.8.6p7/config.h.in.digest-backport sudo-1.8.6p7/config.h.in ---- sudo-1.8.6p7/config.h.in.digest-backport 2013-02-25 20:46:09.000000000 +0100 -+++ sudo-1.8.6p7/config.h.in 2015-07-06 11:42:35.000000000 +0200 -@@ -164,6 +164,9 @@ - /* Define to 1 if you use the FWTK authsrv daemon. */ - #undef HAVE_FWTK - -+/* Define to 1 if you have the `gcry_md_open' function. */ -+#undef HAVE_GCRY_MD_OPEN -+ - /* Define to 1 if you have the `getaddrinfo' function. */ - #undef HAVE_GETADDRINFO - -@@ -331,6 +334,9 @@ - /* Define to 1 if you have the `ldap_unbind_ext_s' function. */ - #undef HAVE_LDAP_UNBIND_EXT_S - -+/* Define to 1 to enable libgcrypt support. */ -+#undef HAVE_LIBGCRYPT -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_LIBINTL_H - -@@ -676,6 +682,9 @@ - /* Define to 1 if you have the `unsetenv' function. */ - #undef HAVE_UNSETENV - -+/* Define to 1 if the system has the type `unsigned long long int'. */ -+#undef HAVE_UNSIGNED_LONG_LONG_INT -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_UTIL_H - -@@ -901,6 +910,11 @@ - /* Define to avoid using the passwd/shadow file for authentication. */ - #undef WITHOUT_PASSWD - -+/* Enable large inode numbers on Mac OS X 10.5. */ -+#ifndef _DARWIN_USE_64_BIT_INODE -+# define _DARWIN_USE_64_BIT_INODE 1 -+#endif -+ - /* Number of bits in a file offset, on hosts where this is settable. */ - #undef _FILE_OFFSET_BITS - -@@ -945,6 +959,15 @@ - /* Define to `int' if doesn't define. */ - #undef uid_t - -+/* Define to `unsigned int' if does not define. */ -+#undef uint32_t -+ -+/* Define to `unsigned long long' if does not define. */ -+#undef uint64_t -+ -+/* Define to `unsigned char' if does not define. */ -+#undef uint8_t -+ - /* Define to empty if the keyword `volatile' does not work. Warning: valid - code using `volatile' can become incorrect without. Disable with care. */ - #undef volatile -diff -up sudo-1.8.6p7/configure.in.digest-backport sudo-1.8.6p7/configure.in ---- sudo-1.8.6p7/configure.in.digest-backport 2015-07-06 11:42:33.124904862 +0200 -+++ sudo-1.8.6p7/configure.in 2015-07-06 11:42:33.129904786 +0200 -@@ -31,6 +31,7 @@ AC_SUBST([SUDO_OBJS]) +From c8a6eecf768d8102a9a77f5fdb5b516e571d462e Mon Sep 17 00:00:00 2001 +From: Radovan Sroka +Date: Tue, 23 Aug 2016 13:43:08 +0200 +Subject: [PATCH] Using libgcrypt + +Using libgcrypt and not sudo implementation of SHA... + +Rebased patch of digest backport. +Added option --with-gcrypt + +Rebased from: +Patch35: sudo-1.8.6p7-digest-backport.patch + +Resolves: +rhbz#1183818 +--- + configure.ac | 16 +++++++ + plugins/sudoers/Makefile.in | 9 +++- + plugins/sudoers/filedigest.c | 104 +++++++++++++++++++++++++++++++++++++++++++ + plugins/sudoers/filedigest.h | 17 +++++++ + plugins/sudoers/match.c | 94 ++++++++++++++++++++++++++++++-------- + 5 files changed, 219 insertions(+), 21 deletions(-) + create mode 100644 plugins/sudoers/filedigest.c + create mode 100644 plugins/sudoers/filedigest.h + +diff --git a/configure.ac b/configure.ac +index 13c3c1b..54929b2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -35,6 +35,7 @@ AC_SUBST([SUDO_OBJS]) AC_SUBST([LIBS]) AC_SUBST([SUDO_LIBS]) AC_SUBST([SUDOERS_LIBS]) +AC_SUBST([LIBPARSESUDOERS_LIBS]) + AC_SUBST([STATIC_SUDOERS]) AC_SUBST([NET_LIBS]) AC_SUBST([AFS_LIBS]) - AC_SUBST([REPLAY_LIBS]) -@@ -1404,6 +1405,19 @@ AC_ARG_WITH(selinux, [AS_HELP_STRING([-- +@@ -1517,6 +1518,19 @@ AC_ARG_WITH(selinux, [AS_HELP_STRING([--with-selinux], [enable SELinux support]) ;; - esac]) + esac], [with_selinux=no]) +AC_ARG_WITH(gcrypt, [AS_HELP_STRING([--with-gcrypt], [enable libgcrypt support])], +[case $with_gcrypt in + yes) -+ AC_DEFINE(HAVE_LIBGCRYPT) -+ LIBPARSESUDOERS_LIBS="${LIBPARSESUDOERS_LIBS} -lgcrypt" -+ AC_CHECK_LIB([gcrypt], [gcry_md_open], -+ [AC_DEFINE(HAVE_GCRY_MD_OPEN)]) -+ ;; -+ no) ;; -+ *) AC_MSG_ERROR(["--with-gcrypt does not take an argument."]) -+ ;; ++ AC_DEFINE(HAVE_LIBGCRYPT) ++ LIBPARSESUDOERS_LIBS="${LIBPARSESUDOERS_LIBS} -lgcrypt" ++ AC_CHECK_LIB([gcrypt], [gcry_md_open], ++ [AC_DEFINE(HAVE_GCRY_MD_OPEN)]) ++ ;; ++ no) ;; ++ *) AC_MSG_ERROR(["--with-gcrypt does not take an argument."]) ++ ;; +esac]) + dnl dnl gss_krb5_ccache_name() may not work on Heimdal so we don't use it by default dnl -@@ -2152,6 +2166,9 @@ AC_CHECK_TYPE(size_t, unsigned int) - AC_CHECK_TYPE(ssize_t, int) - AC_CHECK_TYPE(dev_t, int) - AC_CHECK_TYPE(ino_t, unsigned int) -+AC_CHECK_TYPE(uint8_t, unsigned char) -+AC_CHECK_TYPE(uint32_t, unsigned int) -+AC_CHECK_TYPE(uint64_t, unsigned long long) - AC_CHECK_TYPE(socklen_t, [], [AC_DEFINE(socklen_t, unsigned int)], [ - AC_INCLUDES_DEFAULT - #include ]) -@@ -3625,6 +3642,8 @@ AH_TEMPLATE(HAVE_PROJECT_H, [Define to 1 +@@ -4344,6 +4358,8 @@ AH_TEMPLATE(HAVE_PROJECT_H, [Define to 1 if you have the header file AH_TEMPLATE(HAVE_SECURID, [Define to 1 if you use SecurID for authentication.]) AH_TEMPLATE(HAVE_SELINUX, [Define to 1 to enable SELinux RBAC support.]) AH_TEMPLATE(HAVE_SETKEYCREATECON, [Define to 1 if you have the `setkeycreatecon' function.]) @@ -109,21 +64,53 @@ diff -up sudo-1.8.6p7/configure.in.digest-backport sudo-1.8.6p7/configure.in AH_TEMPLATE(HAVE_SHL_LOAD, [Define to 1 if you have the `shl_load' function.]) AH_TEMPLATE(HAVE_SKEY, [Define to 1 if you use S/Key.]) AH_TEMPLATE(HAVE_SKEYACCESS, [Define to 1 if your S/Key library has skeyaccess().]) -diff -up sudo-1.8.6p7/MANIFEST.digest-backport sudo-1.8.6p7/MANIFEST ---- sudo-1.8.6p7/MANIFEST.digest-backport 2015-07-06 11:42:33.103905177 +0200 -+++ sudo-1.8.6p7/MANIFEST 2015-07-06 11:42:33.129904786 +0200 -@@ -171,6 +171,7 @@ plugins/sudoers/gram.c - plugins/sudoers/gram.h - plugins/sudoers/gram.y - plugins/sudoers/group_plugin.c -+plugins/sudoers/hexchar.c - plugins/sudoers/ins_2001.h - plugins/sudoers/ins_classic.h - plugins/sudoers/ins_csops.h -diff -up sudo-1.8.6p7/plugins/sudoers/filedigest.c.digest-backport sudo-1.8.6p7/plugins/sudoers/filedigest.c ---- sudo-1.8.6p7/plugins/sudoers/filedigest.c.digest-backport 2015-07-06 11:42:33.129904786 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/filedigest.c 2015-07-06 11:42:33.129904786 +0200 -@@ -0,0 +1,105 @@ +diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in +index f36f9ef..32c0ed0 100644 +--- a/plugins/sudoers/Makefile.in ++++ b/plugins/sudoers/Makefile.in +@@ -55,6 +55,7 @@ LT_LIBS = $(top_builddir)/lib/util/libsudo_util.la + LIBS = $(LT_LIBS) + NET_LIBS = @NET_LIBS@ + SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(LIBS) $(NET_LIBS) @ZLIB@ @LIBMD@ ++LIBPARSESUDOERS_LIBS = @LIBPARSESUDOERS_LIBS@ + REPLAY_LIBS = @REPLAY_LIBS@ @ZLIB@ + VISUDO_LIBS = $(NET_LIBS) @LIBMD@ + TESTSUDOERS_LIBS = $(NET_LIBS) @LIBMD@ +@@ -153,7 +154,7 @@ AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@ + LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo hexchar.lo \ + gram.lo match.lo match_addr.lo pwutil.lo pwutil_impl.lo \ + rcstr.lo redblack.lo sudoers_debug.lo timestr.lo \ +- toke.lo toke_util.lo ++ toke.lo toke_util.lo filedigest.lo + + SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo find_path.lo \ + gc.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \ +@@ -217,7 +218,7 @@ Makefile: $(srcdir)/Makefile.in + (cd $(top_builddir) && ./config.status --file plugins/sudoers/Makefile) + + libparsesudoers.la: $(LIBPARSESUDOERS_OBJS) +- $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) -no-install ++ $(LIBTOOL) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) $(LIBPARSESUDOERS_LIBS) -no-install + + sudoers.la: $(SUDOERS_OBJS) $(LT_LIBS) libparsesudoers.la @LT_LDDEP@ + case "$(LT_LDFLAGS)" in \ +@@ -656,6 +657,10 @@ env.lo: $(srcdir)/env.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \ + $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \ + $(top_builddir)/pathnames.h + $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/env.c ++filedigest.lo: $(srcdir)/filedigest.c $(top_builddir)/config.h \ ++ $(incdir)/sudo_debug.h ++ $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/filedigest.c ++filedigest.o: filedigest.lo + find_path.lo: $(srcdir)/find_path.c $(devdir)/def_data.h \ + $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ +diff --git a/plugins/sudoers/filedigest.c b/plugins/sudoers/filedigest.c +new file mode 100644 +index 0000000..c173741 +--- /dev/null ++++ b/plugins/sudoers/filedigest.c +@@ -0,0 +1,104 @@ +#include +#include +#include @@ -132,9 +119,8 @@ diff -up sudo-1.8.6p7/plugins/sudoers/filedigest.c.digest-backport sudo-1.8.6p7/ +#include +#include +#include "filedigest.h" -+#include "missing.h" ++#include "sudo_compat.h" +#include "sudo_debug.h" -+#include "alloc.h" + +#if defined(HAVE_LIBGCRYPT) +#include @@ -195,7 +181,7 @@ diff -up sudo-1.8.6p7/plugins/sudoers/filedigest.c.digest-backport sudo-1.8.6p7/ + * gcry_md_close was called + */ + (*dvalue_size) = gcry_md_get_algo_dlen(gcry_algo); -+ (*dvalue) = emalloc(*dvalue_size); ++ (*dvalue) = malloc(*dvalue_size); + + if (*dvalue == NULL) { + debug_return_int(-1); @@ -229,17 +215,19 @@ diff -up sudo-1.8.6p7/plugins/sudoers/filedigest.c.digest-backport sudo-1.8.6p7/ +#endif + debug_return_int(rc); +} -diff -up sudo-1.8.6p7/plugins/sudoers/filedigest.h.digest-backport sudo-1.8.6p7/plugins/sudoers/filedigest.h ---- sudo-1.8.6p7/plugins/sudoers/filedigest.h.digest-backport 2015-07-06 11:42:33.129904786 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/filedigest.h 2015-07-06 12:03:03.006422923 +0200 +diff --git a/plugins/sudoers/filedigest.h b/plugins/sudoers/filedigest.h +new file mode 100644 +index 0000000..437f02f +--- /dev/null ++++ b/plugins/sudoers/filedigest.h @@ -0,0 +1,17 @@ +#include + -+#define SUDO_DIGEST_INVALID -1 +#define SUDO_DIGEST_SHA224 0 +#define SUDO_DIGEST_SHA256 1 +#define SUDO_DIGEST_SHA384 2 +#define SUDO_DIGEST_SHA512 3 ++#define SUDO_DIGEST_INVALID 4 + +#define SUDO_SHA224_DIGEST_LENGTH 28 +#define SUDO_SHA256_DIGEST_LENGTH 32 @@ -250,11140 +238,198 @@ diff -up sudo-1.8.6p7/plugins/sudoers/filedigest.h.digest-backport sudo-1.8.6p7/ + * Compute a digest of a given file. Returns 0 on success, -1 otherwise. + */ +int sudo_filedigest(const char *path, int algo, unsigned char **dvalue, size_t *dvalue_size); -diff -up sudo-1.8.6p7/plugins/sudoers/gram.c.digest-backport sudo-1.8.6p7/plugins/sudoers/gram.c ---- sudo-1.8.6p7/plugins/sudoers/gram.c.digest-backport 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/gram.c 2015-07-06 11:42:33.131904756 +0200 -@@ -1,16 +1,71 @@ - #include --#include --#include --#define YYBYACC 1 --#define YYMAJOR 1 --#define YYMINOR 9 --#define YYLEX yylex() --#define YYEMPTY -1 --#define yyclearin (yychar=(YYEMPTY)) --#define yyerrok (yyerrflag=0) --#define YYRECOVERING() (yyerrflag!=0) --#define YYPREFIX "yy" --#line 2 "gram.y" -+/* A Bison parser, made by GNU Bison 2.7. */ -+ -+/* Bison implementation for Yacc-like parsers in C -+ -+ Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. -+ -+ This program is free software: you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation, either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+/* As a special exception, you may create a larger work that contains -+ part or all of the Bison parser skeleton and distribute that work -+ under terms of your choice, so long as that work isn't itself a -+ parser generator using the skeleton or a modified version thereof -+ as a parser skeleton. Alternatively, if you modify or redistribute -+ the parser skeleton itself, you may (at your option) remove this -+ special exception, which will cause the skeleton and the resulting -+ Bison output files to be licensed under the GNU General Public -+ License without this special exception. -+ -+ This special exception was added by the Free Software Foundation in -+ version 2.2 of Bison. */ -+ -+/* C LALR(1) parser skeleton written by Richard Stallman, by -+ simplifying the original so-called "semantic" parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Bison version. */ -+#define YYBISON_VERSION "2.7" -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 0 -+ -+/* Push parsers. */ -+#define YYPUSH 0 -+ -+/* Pull parsers. */ -+#define YYPULL 1 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+/* Line 371 of yacc.c */ -+#line 1 "gram.y" -+ - /* - * Copyright (c) 1996, 1998-2005, 2007-2012 - * Todd C. Miller -@@ -103,6 +158,8 @@ static void add_defaults(int, struct me - static void add_userspec(struct member *, struct privilege *); - static struct defaults *new_default(char *, char *, int); - static struct member *new_member(char *, int); -+static struct sudo_digest *new_digest(int, const char *); -+ - void yyerror(const char *); - - void -@@ -129,1661 +186,2863 @@ yyerror(const char *s) - parse_error = true; - debug_return; - } --#line 122 "gram.y" --#ifndef YYSTYPE_DEFINED --#define YYSTYPE_DEFINED --typedef union { -+ -+/* Line 371 of yacc.c */ -+#line 191 "gram.c" -+ -+# ifndef YY_NULL -+# if defined __cplusplus && 201103L <= __cplusplus -+# define YY_NULL nullptr -+# else -+# define YY_NULL 0 -+# endif -+# endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+/* In a future release of Bison, this section will be replaced -+ by #include "y.tab.h". */ -+#ifndef YY_YY_Y_TAB_H_INCLUDED -+# define YY_YY_Y_TAB_H_INCLUDED -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+#if YYDEBUG -+extern int yydebug; -+#endif -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COMMAND = 258, -+ ALIAS = 259, -+ DEFVAR = 260, -+ NTWKADDR = 261, -+ NETGROUP = 262, -+ USERGROUP = 263, -+ WORD = 264, -+ DIGEST = 265, -+ DEFAULTS = 266, -+ DEFAULTS_HOST = 267, -+ DEFAULTS_USER = 268, -+ DEFAULTS_RUNAS = 269, -+ DEFAULTS_CMND = 270, -+ NOPASSWD = 271, -+ PASSWD = 272, -+ NOEXEC = 273, -+ EXEC = 274, -+ SETENV = 275, -+ NOSETENV = 276, -+ LOG_INPUT = 277, -+ NOLOG_INPUT = 278, -+ LOG_OUTPUT = 279, -+ NOLOG_OUTPUT = 280, -+ ALL = 281, -+ COMMENT = 282, -+ HOSTALIAS = 283, -+ CMNDALIAS = 284, -+ USERALIAS = 285, -+ RUNASALIAS = 286, -+ ERROR = 287, -+ TYPE = 288, -+ ROLE = 289, -+ PRIVS = 290, -+ LIMITPRIVS = 291, -+ MYSELF = 292, -+ SHA224 = 293, -+ SHA256 = 294, -+ SHA384 = 295, -+ SHA512 = 296 -+ }; -+#endif -+/* Tokens. */ -+#define COMMAND 258 -+#define ALIAS 259 -+#define DEFVAR 260 -+#define NTWKADDR 261 -+#define NETGROUP 262 -+#define USERGROUP 263 -+#define WORD 264 -+#define DIGEST 265 -+#define DEFAULTS 266 -+#define DEFAULTS_HOST 267 -+#define DEFAULTS_USER 268 -+#define DEFAULTS_RUNAS 269 -+#define DEFAULTS_CMND 270 -+#define NOPASSWD 271 -+#define PASSWD 272 -+#define NOEXEC 273 -+#define EXEC 274 -+#define SETENV 275 -+#define NOSETENV 276 -+#define LOG_INPUT 277 -+#define NOLOG_INPUT 278 -+#define LOG_OUTPUT 279 -+#define NOLOG_OUTPUT 280 -+#define ALL 281 -+#define COMMENT 282 -+#define HOSTALIAS 283 -+#define CMNDALIAS 284 -+#define USERALIAS 285 -+#define RUNASALIAS 286 -+#define ERROR 287 -+#define TYPE 288 -+#define ROLE 289 -+#define PRIVS 290 -+#define LIMITPRIVS 291 -+#define MYSELF 292 -+#define SHA224 293 -+#define SHA256 294 -+#define SHA384 295 -+#define SHA512 296 -+ -+ -+ -+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -+typedef union YYSTYPE -+{ -+/* Line 387 of yacc.c */ -+#line 124 "gram.y" -+ - struct cmndspec *cmndspec; - struct defaults *defaults; - struct member *member; - struct runascontainer *runas; - struct privilege *privilege; -+ struct sudo_digest *digest; - struct sudo_command command; - struct cmndtag tag; - struct selinux_info seinfo; - struct solaris_privs_info privinfo; - char *string; - int tok; -+ -+ -+/* Line 387 of yacc.c */ -+#line 332 "gram.c" - } YYSTYPE; --#endif /* YYSTYPE_DEFINED */ --#line 149 "gram.c" --#define COMMAND 257 --#define ALIAS 258 --#define DEFVAR 259 --#define NTWKADDR 260 --#define NETGROUP 261 --#define USERGROUP 262 --#define WORD 263 --#define DEFAULTS 264 --#define DEFAULTS_HOST 265 --#define DEFAULTS_USER 266 --#define DEFAULTS_RUNAS 267 --#define DEFAULTS_CMND 268 --#define NOPASSWD 269 --#define PASSWD 270 --#define NOEXEC 271 --#define EXEC 272 --#define SETENV 273 --#define NOSETENV 274 --#define LOG_INPUT 275 --#define NOLOG_INPUT 276 --#define LOG_OUTPUT 277 --#define NOLOG_OUTPUT 278 --#define ALL 279 --#define COMMENT 280 --#define HOSTALIAS 281 --#define CMNDALIAS 282 --#define USERALIAS 283 --#define RUNASALIAS 284 --#define ERROR 285 --#define TYPE 286 --#define ROLE 287 --#define PRIVS 288 --#define LIMITPRIVS 289 --#define MYSELF 290 --#define YYERRCODE 256 --#if defined(__cplusplus) || defined(__STDC__) --const short yylhs[] = --#else --short yylhs[] = --#endif -- { -1, -- 0, 0, 28, 28, 29, 29, 29, 29, 29, 29, -- 29, 29, 29, 29, 29, 29, 4, 4, 3, 3, -- 3, 3, 3, 20, 20, 19, 10, 10, 8, 8, -- 8, 8, 8, 2, 2, 1, 6, 6, 23, 24, -- 22, 22, 22, 22, 22, 26, 27, 25, 25, 25, -- 25, 25, 17, 17, 18, 18, 18, 18, 18, 21, -- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -- 5, 5, 5, 31, 31, 34, 9, 9, 32, 32, -- 35, 7, 7, 33, 33, 36, 30, 30, 37, 13, -- 13, 11, 11, 12, 12, 12, 12, 12, 16, 16, -- 14, 14, 15, 15, 15, --}; --#if defined(__cplusplus) || defined(__STDC__) --const short yylen[] = -+# define YYSTYPE_IS_TRIVIAL 1 -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+#endif -+ -+extern YYSTYPE yylval; -+ -+#ifdef YYPARSE_PARAM -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void *YYPARSE_PARAM); - #else --short yylen[] = -+int yyparse (); - #endif -- { 2, -- 0, 1, 1, 2, 1, 2, 2, 2, 2, 2, -- 2, 2, 3, 3, 3, 3, 1, 3, 1, 2, -- 3, 3, 3, 1, 3, 3, 1, 2, 1, 1, -- 1, 1, 1, 1, 3, 5, 1, 2, 3, 3, -- 0, 1, 1, 2, 2, 3, 3, 0, 1, 1, -- 2, 2, 0, 3, 0, 1, 3, 2, 1, 0, -- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 1, 1, 1, 1, 3, 3, 1, 3, 1, 3, -- 3, 1, 3, 1, 3, 3, 1, 3, 3, 1, -- 3, 1, 2, 1, 1, 1, 1, 1, 1, 3, -- 1, 2, 1, 1, 1, --}; --#if defined(__cplusplus) || defined(__STDC__) --const short yydefred[] = -+#else /* ! YYPARSE_PARAM */ -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void); - #else --short yydefred[] = -+int yyparse (); - #endif -- { 0, -- 0, 94, 96, 97, 98, 0, 0, 0, 0, 0, -- 95, 5, 0, 0, 0, 0, 0, 0, 90, 92, -- 0, 0, 3, 6, 0, 0, 17, 0, 29, 32, -- 31, 33, 30, 0, 27, 0, 77, 0, 0, 73, -- 72, 71, 0, 37, 82, 0, 0, 0, 74, 0, -- 0, 79, 0, 0, 87, 0, 0, 84, 93, 0, -- 0, 24, 0, 4, 0, 0, 0, 20, 0, 28, -- 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 91, 0, 0, 21, 22, -- 23, 18, 78, 83, 0, 75, 0, 80, 0, 88, -- 0, 85, 0, 34, 0, 0, 25, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 103, 105, 104, 0, -- 99, 101, 0, 0, 54, 35, 0, 0, 0, 0, -- 60, 0, 0, 44, 45, 102, 0, 0, 40, 39, -- 0, 0, 0, 51, 52, 100, 46, 47, 61, 62, -- 63, 64, 65, 66, 67, 68, 69, 70, 36, --}; --#if defined(__cplusplus) || defined(__STDC__) --const short yydgoto[] = -+#endif /* ! YYPARSE_PARAM */ -+ -+#endif /* !YY_YY_Y_TAB_H_INCLUDED */ -+ -+/* Copy the second part of user declarations. */ -+ -+/* Line 390 of yacc.c */ -+#line 360 "gram.c" -+ -+#ifdef short -+# undef short -+#endif -+ -+#ifdef YYTYPE_UINT8 -+typedef YYTYPE_UINT8 yytype_uint8; - #else --short yydgoto[] = -+typedef unsigned char yytype_uint8; - #endif -- { 18, -- 104, 105, 27, 28, 44, 45, 46, 35, 61, 37, -- 19, 20, 21, 121, 122, 123, 106, 110, 62, 63, -- 143, 114, 115, 116, 131, 132, 133, 22, 23, 54, -- 48, 51, 57, 49, 52, 58, 55, --}; --#if defined(__cplusplus) || defined(__STDC__) --const short yysindex[] = -+ -+#ifdef YYTYPE_INT8 -+typedef YYTYPE_INT8 yytype_int8; -+#elif (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+typedef signed char yytype_int8; - #else --short yysindex[] = -+typedef short int yytype_int8; - #endif -- { 541, -- -270, 0, 0, 0, 0, -21, -5, 553, 553, 20, -- 0, 0, -242, -229, -216, -214, -240, 0, 0, 0, -- -27, 541, 0, 0, -18, -227, 0, 2, 0, 0, -- 0, 0, 0, -223, 0, -33, 0, -31, -31, 0, -- 0, 0, -243, 0, 0, -24, -12, -6, 0, 3, -- 4, 0, 5, 7, 0, 6, 10, 0, 0, 553, -- -20, 0, 11, 0, -206, -193, -191, 0, -21, 0, -- -5, 2, 2, 2, 0, 20, 2, -5, -242, 20, -- -229, 553, -216, 553, -214, 0, 33, -5, 0, 0, -- 0, 0, 0, 0, 31, 0, 32, 0, 34, 0, -- 34, 0, 513, 0, 35, -226, 0, 86, -25, 36, -- 33, 19, 21, -234, -202, -201, 0, 0, 0, -232, -- 0, 0, 41, 86, 0, 0, -176, -173, 37, 38, -- 0, -198, -195, 0, 0, 0, 86, 41, 0, 0, -- -169, -168, 569, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0,}; --#if defined(__cplusplus) || defined(__STDC__) --const short yyrindex[] = --#else --short yyrindex[] = --#endif -- { 96, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 97, 0, 0, 1, 0, 0, 177, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 207, 0, 0, -- 237, 0, 0, 271, 0, 0, 300, 0, 0, 0, -- 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, -- 0, 358, 387, 417, 0, 0, 446, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, -- 0, 0, 0, 0, 30, 0, 59, 0, 89, 0, -- 118, 0, 60, 0, 148, -28, 0, 62, 63, 0, -- 463, 0, 0, 594, 489, 512, 0, 0, 0, 0, -- 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, -- 0, 623, 653, 0, 0, 0, 0, 65, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0,}; --#if defined(__cplusplus) || defined(__STDC__) --const short yygindex[] = --#else --short yygindex[] = --#endif -- { 0, -- -11, 0, 39, 12, 66, -72, 27, 76, -4, 40, -- 52, 98, -1, -23, -7, -8, 0, 0, 42, 0, -- 0, 0, 8, 13, 0, -13, -9, 0, 99, 0, -- 0, 0, 0, 46, 45, 44, 48, --}; --#define YYTABLESIZE 932 --#if defined(__cplusplus) || defined(__STDC__) --const short yytable[] = --#else --short yytable[] = --#endif -- { 26, -- 19, 26, 36, 94, 41, 34, 38, 39, 26, 24, -- 71, 26, 60, 40, 41, 47, 60, 2, 60, 76, -- 3, 4, 5, 71, 66, 117, 67, 34, 50, 76, -- 118, 68, 124, 19, 29, 42, 30, 31, 11, 32, -- 87, 53, 65, 56, 19, 69, 119, 72, 78, 73, -- 74, 79, 43, 129, 130, 33, 89, 77, 81, 112, -- 113, 81, 76, 80, 83, 82, 84, 85, 88, 90, -- 159, 91, 103, 95, 71, 76, 125, 60, 111, 127, -- 99, 128, 101, 112, 137, 113, 139, 76, 89, 140, -- 130, 81, 129, 147, 148, 1, 2, 141, 142, 126, -- 55, 109, 59, 56, 58, 57, 97, 92, 75, 70, -- 93, 86, 136, 146, 59, 138, 81, 86, 120, 145, -- 64, 89, 144, 135, 96, 98, 0, 134, 102, 107, -- 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 89, 26, 0, 0, -- 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 86, 12, 0, 0, 0, -- 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 26, 9, 0, 0, 12, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 25, 0, 25, 41, 41, -- 29, 0, 30, 31, 25, 32, 10, 25, 0, 9, -- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, -- 41, 33, 29, 0, 30, 31, 19, 32, 19, 41, -- 41, 19, 19, 19, 19, 19, 19, 19, 19, 10, -- 8, 0, 0, 33, 0, 0, 40, 41, 0, 19, -- 19, 19, 19, 19, 19, 76, 0, 76, 0, 0, -- 76, 76, 76, 76, 76, 76, 76, 76, 42, 11, -- 0, 0, 0, 8, 0, 0, 0, 0, 76, 76, -- 76, 76, 76, 76, 81, 0, 81, 0, 0, 81, -- 81, 81, 81, 81, 81, 81, 81, 0, 7, 0, -- 0, 0, 11, 0, 0, 0, 0, 81, 81, 81, -- 81, 81, 81, 117, 89, 0, 89, 0, 118, 89, -- 89, 89, 89, 89, 89, 89, 89, 15, 0, 0, -- 0, 7, 0, 0, 119, 0, 0, 89, 89, 89, -- 89, 89, 89, 86, 0, 86, 0, 0, 86, 86, -- 86, 86, 86, 86, 86, 86, 13, 0, 0, 0, -- 15, 0, 0, 0, 0, 0, 86, 86, 86, 86, -- 86, 86, 0, 26, 0, 26, 0, 0, 26, 26, -- 26, 26, 26, 26, 26, 26, 14, 0, 0, 13, -- 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, -- 26, 26, 12, 0, 12, 0, 0, 12, 12, 12, -- 12, 12, 12, 12, 12, 16, 0, 0, 0, 14, -- 0, 0, 0, 0, 0, 12, 12, 12, 12, 12, -- 12, 0, 9, 0, 9, 0, 0, 9, 9, 9, -- 9, 9, 9, 9, 9, 0, 0, 0, 16, 0, -- 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, -- 9, 0, 10, 0, 10, 53, 0, 10, 10, 10, -- 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, -- 10, 42, 0, 0, 0, 0, 8, 0, 8, 0, -- 0, 8, 8, 8, 8, 8, 8, 8, 8, 0, -- 0, 0, 0, 0, 43, 17, 0, 0, 0, 8, -- 8, 8, 8, 8, 8, 11, 0, 11, 0, 0, -- 11, 11, 11, 11, 11, 11, 11, 11, 0, 0, -- 108, 0, 0, 17, 0, 0, 0, 0, 11, 11, -- 11, 11, 11, 11, 7, 17, 7, 0, 0, 7, -- 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, -- 0, 43, 0, 0, 0, 0, 0, 7, 7, 7, -- 7, 7, 7, 15, 0, 15, 0, 0, 15, 15, -- 15, 15, 15, 15, 15, 15, 48, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, -- 15, 15, 13, 0, 13, 0, 0, 13, 13, 13, -- 13, 13, 13, 13, 13, 49, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, -- 13, 0, 14, 0, 14, 0, 0, 14, 14, 14, -- 14, 14, 14, 14, 14, 50, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, -- 14, 16, 0, 16, 0, 0, 16, 16, 16, 16, -- 16, 16, 16, 16, 0, 0, 0, 0, 0, 53, -- 53, 0, 0, 0, 16, 16, 16, 16, 16, 16, -- 0, 53, 53, 53, 53, 53, 53, 53, 53, 53, -- 53, 53, 0, 0, 0, 42, 42, 0, 53, 53, -- 53, 53, 0, 0, 0, 0, 0, 42, 42, 42, -- 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, -- 2, 0, 0, 3, 4, 5, 42, 42, 0, 0, -- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -- 43, 11, 0, 0, 0, 0, 1, 0, 2, 43, -- 43, 3, 4, 5, 6, 7, 8, 9, 10, 0, -- 2, 0, 0, 3, 4, 5, 0, 0, 0, 11, -- 12, 13, 14, 15, 16, 40, 41, 0, 0, 0, -- 0, 11, 0, 0, 0, 0, 0, 149, 150, 151, -- 152, 153, 154, 155, 156, 157, 158, 42, 0, 0, -- 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, -- 48, 48, 48, 0, 0, 0, 0, 0, 0, 49, -- 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, -- 49, 49, 0, 0, 0, 0, 0, 0, 0, 50, -- 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 50, 50, 50, 50, 50, 50, 50, 50, 50, -- 50, 50, --}; --#if defined(__cplusplus) || defined(__STDC__) --const short yycheck[] = -+ -+#ifdef YYTYPE_UINT16 -+typedef YYTYPE_UINT16 yytype_uint16; -+#else -+typedef unsigned short int yytype_uint16; -+#endif -+ -+#ifdef YYTYPE_INT16 -+typedef YYTYPE_INT16 yytype_int16; -+#else -+typedef short int yytype_int16; -+#endif -+ -+#ifndef YYSIZE_T -+# ifdef __SIZE_TYPE__ -+# define YYSIZE_T __SIZE_TYPE__ -+# elif defined size_t -+# define YYSIZE_T size_t -+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# else -+# define YYSIZE_T unsigned int -+# endif -+#endif -+ -+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) -+ -+#ifndef YY_ -+# if defined YYENABLE_NLS && YYENABLE_NLS -+# if ENABLE_NLS -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -+# endif -+# endif -+# ifndef YY_ -+# define YY_(Msgid) Msgid -+# endif -+#endif -+ -+/* Suppress unused-variable warnings by "using" E. */ -+#if ! defined lint || defined __GNUC__ -+# define YYUSE(E) ((void) (E)) -+#else -+# define YYUSE(E) /* empty */ -+#endif -+ -+/* Identity function, used to suppress warnings about constant conditions. */ -+#ifndef lint -+# define YYID(N) (N) -+#else -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static int -+YYID (int yyi) - #else --short yycheck[] = -+static int -+YYID (yyi) -+ int yyi; -+#endif -+{ -+ return yyi; -+} - #endif -- { 33, -- 0, 33, 7, 76, 33, 33, 8, 9, 33, 280, -- 44, 33, 44, 257, 258, 258, 44, 258, 44, 44, -- 261, 262, 263, 44, 43, 258, 45, 33, 258, 0, -- 263, 259, 58, 33, 258, 279, 260, 261, 279, 263, -- 61, 258, 61, 258, 44, 44, 279, 36, 61, 38, -- 39, 58, 33, 288, 289, 279, 263, 46, 0, 286, -- 287, 58, 33, 61, 58, 61, 61, 58, 58, 263, -- 143, 263, 40, 78, 44, 44, 41, 44, 44, 61, -- 82, 61, 84, 286, 44, 287, 263, 58, 0, 263, -- 289, 33, 288, 263, 263, 0, 0, 61, 61, 111, -- 41, 103, 41, 41, 41, 41, 80, 69, 43, 34, -- 71, 60, 120, 137, 17, 124, 58, 0, 33, 133, -- 22, 33, 132, 116, 79, 81, -1, 115, 85, 88, -- 83, -1, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, -1, 58, 0, -1, -1, -- 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, 58, 0, -1, -1, -1, -- 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, 58, 0, -1, -1, 33, -- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, 259, -1, 259, 257, 258, -- 258, -1, 260, 261, 259, 263, 0, 259, -1, 33, -- 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, -- 279, 279, 258, -1, 260, 261, 256, 263, 258, 288, -- 289, 261, 262, 263, 264, 265, 266, 267, 268, 33, -- 0, -1, -1, 279, -1, -1, 257, 258, -1, 279, -- 280, 281, 282, 283, 284, 256, -1, 258, -1, -1, -- 261, 262, 263, 264, 265, 266, 267, 268, 279, 0, -- -1, -1, -1, 33, -1, -1, -1, -1, 279, 280, -- 281, 282, 283, 284, 256, -1, 258, -1, -1, 261, -- 262, 263, 264, 265, 266, 267, 268, -1, 0, -1, -- -1, -1, 33, -1, -1, -1, -1, 279, 280, 281, -- 282, 283, 284, 258, 256, -1, 258, -1, 263, 261, -- 262, 263, 264, 265, 266, 267, 268, 0, -1, -1, -- -1, 33, -1, -1, 279, -1, -1, 279, 280, 281, -- 282, 283, 284, 256, -1, 258, -1, -1, 261, 262, -- 263, 264, 265, 266, 267, 268, 0, -1, -1, -1, -- 33, -1, -1, -1, -1, -1, 279, 280, 281, 282, -- 283, 284, -1, 256, -1, 258, -1, -1, 261, 262, -- 263, 264, 265, 266, 267, 268, 0, -1, -1, 33, -- -1, -1, -1, -1, -1, -1, 279, 280, 281, 282, -- 283, 284, 256, -1, 258, -1, -1, 261, 262, 263, -- 264, 265, 266, 267, 268, 0, -1, -1, -1, 33, -- -1, -1, -1, -1, -1, 279, 280, 281, 282, 283, -- 284, -1, 256, -1, 258, -1, -1, 261, 262, 263, -- 264, 265, 266, 267, 268, -1, -1, -1, 33, -1, -- -1, -1, -1, -1, -1, 279, 280, 281, 282, 283, -- 284, -1, 256, -1, 258, 33, -1, 261, 262, 263, -- 264, 265, 266, 267, 268, -1, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, 279, 280, 281, 282, 283, -- 284, 33, -1, -1, -1, -1, 256, -1, 258, -1, -- -1, 261, 262, 263, 264, 265, 266, 267, 268, -1, -- -1, -1, -1, -1, 33, 33, -1, -1, -1, 279, -- 280, 281, 282, 283, 284, 256, -1, 258, -1, -1, -- 261, 262, 263, 264, 265, 266, 267, 268, -1, -1, -- 58, -1, -1, 33, -1, -1, -1, -1, 279, 280, -- 281, 282, 283, 284, 256, 33, 258, -1, -1, 261, -- 262, 263, 264, 265, 266, 267, 268, -1, -1, -1, -- -1, 33, -1, -1, -1, -1, -1, 279, 280, 281, -- 282, 283, 284, 256, -1, 258, -1, -1, 261, 262, -- 263, 264, 265, 266, 267, 268, 33, -1, -1, -1, -- -1, -1, -1, -1, -1, -1, 279, 280, 281, 282, -- 283, 284, 256, -1, 258, -1, -1, 261, 262, 263, -- 264, 265, 266, 267, 268, 33, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, 279, 280, 281, 282, 283, -- 284, -1, 256, -1, 258, -1, -1, 261, 262, 263, -- 264, 265, 266, 267, 268, 33, -1, -1, -1, -1, -- -1, -1, -1, -1, -1, 279, 280, 281, 282, 283, -- 284, 256, -1, 258, -1, -1, 261, 262, 263, 264, -- 265, 266, 267, 268, -1, -1, -1, -1, -1, 257, -- 258, -1, -1, -1, 279, 280, 281, 282, 283, 284, -- -1, 269, 270, 271, 272, 273, 274, 275, 276, 277, -- 278, 279, -1, -1, -1, 257, 258, -1, 286, 287, -- 288, 289, -1, -1, -1, -1, -1, 269, 270, 271, -- 272, 273, 274, 275, 276, 277, 278, 279, 257, 258, -- 258, -1, -1, 261, 262, 263, 288, 289, -1, -1, -- 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, -- 279, 279, -1, -1, -1, -1, 256, -1, 258, 288, -- 289, 261, 262, 263, 264, 265, 266, 267, 268, -1, -- 258, -1, -1, 261, 262, 263, -1, -1, -1, 279, -- 280, 281, 282, 283, 284, 257, 258, -1, -1, -1, -- -1, 279, -1, -1, -1, -1, -1, 269, 270, 271, -- 272, 273, 274, 275, 276, 277, 278, 279, -1, -1, -- 257, 258, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, -1, 269, 270, 271, 272, 273, 274, 275, 276, -- 277, 278, 279, -1, -1, -1, -1, -1, -1, 257, -- 258, -1, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, 269, 270, 271, 272, 273, 274, 275, 276, 277, -- 278, 279, -1, -1, -1, -1, -1, -1, -1, 257, -- 258, -1, -1, -1, -1, -1, -1, -1, -1, -1, -- -1, 269, 270, 271, 272, 273, 274, 275, 276, 277, -- 278, 279, -+ -+#if ! defined yyoverflow || YYERROR_VERBOSE -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# elif defined __BUILTIN_VA_ARG_INCR -+# include /* INFRINGES ON USER NAME SPACE */ -+# elif defined _AIX -+# define YYSTACK_ALLOC __alloca -+# elif defined _MSC_VER -+# include /* INFRINGES ON USER NAME SPACE */ -+# define alloca _alloca -+# else -+# define YYSTACK_ALLOC alloca -+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+# include /* INFRINGES ON USER NAME SPACE */ -+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -+# ifndef EXIT_SUCCESS -+# define EXIT_SUCCESS 0 -+# endif -+# endif -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -+# ifndef YYSTACK_ALLOC_MAXIMUM -+ /* The OS might guarantee only one guard page at the bottom of the stack, -+ and a page size can be as small as 4096 bytes. So we cannot safely -+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number -+ to allow for a few compiler-allocated temporary stack slots. */ -+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -+# endif -+# else -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# ifndef YYSTACK_ALLOC_MAXIMUM -+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -+# endif -+# if (defined __cplusplus && ! defined EXIT_SUCCESS \ -+ && ! ((defined YYMALLOC || defined malloc) \ -+ && (defined YYFREE || defined free))) -+# include /* INFRINGES ON USER NAME SPACE */ -+# ifndef EXIT_SUCCESS -+# define EXIT_SUCCESS 0 -+# endif -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifndef YYFREE -+# define YYFREE free -+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+void free (void *); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# endif -+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ -+ -+ -+#if (! defined yyoverflow \ -+ && (! defined __cplusplus \ -+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ yytype_int16 yyss_alloc; -+ YYSTYPE yyvs_alloc; - }; --#define YYFINAL 18 --#ifndef YYDEBUG --#define YYDEBUG 0 -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ -+ + YYSTACK_GAP_MAXIMUM) -+ -+# define YYCOPY_NEEDED 1 -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ -+ Stack = &yyptr->Stack_alloc; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (YYID (0)) -+ - #endif --#define YYMAXTOKEN 290 -+ -+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -+/* Copy COUNT objects from SRC to DST. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined __GNUC__ && 1 < __GNUC__ -+# define YYCOPY(Dst, Src, Count) \ -+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -+# else -+# define YYCOPY(Dst, Src, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (Dst)[yyi] = (Src)[yyi]; \ -+ } \ -+ while (YYID (0)) -+# endif -+# endif -+#endif /* !YYCOPY_NEEDED */ -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 66 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 225 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 50 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 41 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 112 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 176 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 296 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const yytype_uint8 yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 35, 2, 2, 2, 2, 2, 2, -+ 38, 39, 2, 36, 34, 37, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 32, 2, -+ 2, 33, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, -+ 25, 26, 27, 28, 29, 30, 31, 40, 41, 42, -+ 43, 44, 45, 46, 47, 48, 49 -+}; -+ - #if YYDEBUG --#if defined(__cplusplus) || defined(__STDC__) --const char * const yyname[] = --#else --char *yyname[] = -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const yytype_uint16 yyprhs[] = -+{ -+ 0, 0, 3, 4, 6, 8, 11, 13, 16, 19, -+ 22, 25, 28, 31, 34, 38, 42, 46, 50, 52, -+ 56, 58, 61, 65, 69, 73, 75, 79, 83, 85, -+ 88, 90, 92, 94, 96, 98, 100, 104, 110, 114, -+ 118, 122, 126, 128, 131, 133, 136, 140, 144, 145, -+ 147, 149, 152, 155, 159, 163, 164, 166, 168, 171, -+ 174, 175, 179, 180, 182, 186, 189, 191, 192, 195, -+ 198, 201, 204, 207, 210, 213, 216, 219, 222, 224, -+ 226, 228, 230, 234, 238, 240, 244, 246, 250, 254, -+ 256, 260, 262, 266, 270, 272, 276, 280, 282, 286, -+ 288, 291, 293, 295, 297, 299, 301, 303, 307, 309, -+ 312, 314, 316 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yytype_int8 yyrhs[] = -+{ -+ 51, 0, -1, -1, 52, -1, 53, -1, 52, 53, -+ -1, 27, -1, 1, 27, -1, 85, 56, -1, 30, -+ 83, -1, 28, 75, -1, 29, 78, -1, 31, 81, -+ -1, 11, 54, -1, 13, 85, 54, -1, 14, 85, -+ 54, -1, 12, 77, 54, -1, 15, 80, 54, -1, -+ 55, -1, 54, 34, 55, -1, 5, -1, 35, 5, -+ -1, 5, 33, 9, -1, 5, 36, 9, -1, 5, -+ 37, 9, -1, 57, -1, 56, 32, 57, -1, 77, -+ 33, 60, -1, 59, -1, 35, 59, -1, 4, -1, -+ 26, -1, 7, -1, 6, -1, 9, -1, 61, -1, -+ 60, 34, 61, -1, 71, 67, 70, 73, 63, -1, -+ 46, 32, 10, -1, 47, 32, 10, -1, 48, 32, -+ 10, -1, 49, 32, 10, -1, 64, -1, 62, 64, -+ -1, 74, -1, 35, 74, -1, 42, 33, 9, -1, -+ 41, 33, 9, -1, -1, 65, -1, 66, -1, 65, -+ 66, -1, 66, 65, -1, 43, 33, 9, -1, 44, -+ 33, 9, -1, -1, 68, -1, 69, -1, 68, 69, -+ -1, 69, 68, -1, -1, 38, 72, 39, -1, -1, -+ 85, -1, 85, 32, 88, -1, 32, 88, -1, 32, -+ -1, -1, 73, 16, -1, 73, 17, -1, 73, 18, -+ -1, 73, 19, -1, 73, 20, -1, 73, 21, -1, -+ 73, 22, -1, 73, 23, -1, 73, 24, -1, 73, -+ 25, -1, 26, -1, 4, -1, 3, -1, 76, -1, -+ 75, 32, 76, -1, 4, 33, 77, -1, 58, -1, -+ 77, 34, 58, -1, 79, -1, 78, 32, 79, -1, -+ 4, 33, 80, -1, 63, -1, 80, 34, 63, -1, -+ 82, -1, 81, 32, 82, -1, 4, 33, 85, -1, -+ 84, -1, 83, 32, 84, -1, 4, 33, 85, -1, -+ 86, -1, 85, 34, 86, -1, 87, -1, 35, 87, -+ -1, 4, -1, 26, -1, 7, -1, 8, -1, 9, -+ -1, 89, -1, 88, 34, 89, -1, 90, -1, 35, -+ 90, -1, 4, -1, 26, -1, 9, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const yytype_uint16 yyrline[] = -+{ -+ 0, 214, 214, 215, 218, 219, 222, 225, 228, 231, -+ 234, 237, 240, 243, 246, 249, 252, 255, 260, 261, -+ 267, 270, 273, 276, 279, 284, 285, 291, 301, 305, -+ 311, 314, 317, 320, 323, 328, 329, 368, 398, 401, -+ 404, 407, 412, 415, 425, 429, 435, 440, 445, 449, -+ 453, 457, 461, 467, 471, 476, 480, 484, 488, 492, -+ 497, 500, 505, 510, 515, 520, 525, 532, 536, 539, -+ 542, 545, 548, 551, 554, 557, 560, 563, 568, 571, -+ 574, 582, 583, 586, 595, 596, 602, 603, 606, 615, -+ 616, 622, 623, 626, 635, 636, 639, 648, 649, 655, -+ 659, 665, 668, 671, 674, 677, 682, 683, 689, 693, -+ 699, 702, 705 -+}; - #endif -- { --"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, --"'!'",0,0,0,0,0,0,"'('","')'",0,"'+'","','","'-'",0,0,0,0,0,0,0,0,0,0,0,0,"':'", --0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, --0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, --0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, --0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, --0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, --"COMMAND","ALIAS","DEFVAR","NTWKADDR","NETGROUP","USERGROUP","WORD","DEFAULTS", --"DEFAULTS_HOST","DEFAULTS_USER","DEFAULTS_RUNAS","DEFAULTS_CMND","NOPASSWD", --"PASSWD","NOEXEC","EXEC","SETENV","NOSETENV","LOG_INPUT","NOLOG_INPUT", --"LOG_OUTPUT","NOLOG_OUTPUT","ALL","COMMENT","HOSTALIAS","CMNDALIAS","USERALIAS", --"RUNASALIAS","ERROR","TYPE","ROLE","PRIVS","LIMITPRIVS","MYSELF", -+ -+#if YYDEBUG || YYERROR_VERBOSE || 0 -+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "COMMAND", "ALIAS", "DEFVAR", "NTWKADDR", -+ "NETGROUP", "USERGROUP", "WORD", "DIGEST", "DEFAULTS", "DEFAULTS_HOST", -+ "DEFAULTS_USER", "DEFAULTS_RUNAS", "DEFAULTS_CMND", "NOPASSWD", "PASSWD", -+ "NOEXEC", "EXEC", "SETENV", "NOSETENV", "LOG_INPUT", "NOLOG_INPUT", -+ "LOG_OUTPUT", "NOLOG_OUTPUT", "ALL", "COMMENT", "HOSTALIAS", "CMNDALIAS", -+ "USERALIAS", "RUNASALIAS", "':'", "'='", "','", "'!'", "'+'", "'-'", -+ "'('", "')'", "ERROR", "TYPE", "ROLE", "PRIVS", "LIMITPRIVS", "MYSELF", -+ "SHA224", "SHA256", "SHA384", "SHA512", "$accept", "file", "line", -+ "entry", "defaults_list", "defaults_entry", "privileges", "privilege", -+ "ophost", "host", "cmndspeclist", "cmndspec", "digest", "digcmnd", -+ "opcmnd", "rolespec", "typespec", "selinux", "privsspec", -+ "limitprivsspec", "solarisprivs", "runasspec", "runaslist", "cmndtag", -+ "cmnd", "hostaliases", "hostalias", "hostlist", "cmndaliases", -+ "cmndalias", "cmndlist", "runasaliases", "runasalias", "useraliases", -+ "useralias", "userlist", "opuser", "user", "grouplist", "opgroup", -+ "group", YY_NULL - }; --#if defined(__cplusplus) || defined(__STDC__) --const char * const yyrule[] = --#else --char *yyrule[] = - #endif -- {"$accept : file", --"file :", --"file : line", --"line : entry", --"line : line entry", --"entry : COMMENT", --"entry : error COMMENT", --"entry : userlist privileges", --"entry : USERALIAS useraliases", --"entry : HOSTALIAS hostaliases", --"entry : CMNDALIAS cmndaliases", --"entry : RUNASALIAS runasaliases", --"entry : DEFAULTS defaults_list", --"entry : DEFAULTS_USER userlist defaults_list", --"entry : DEFAULTS_RUNAS userlist defaults_list", --"entry : DEFAULTS_HOST hostlist defaults_list", --"entry : DEFAULTS_CMND cmndlist defaults_list", --"defaults_list : defaults_entry", --"defaults_list : defaults_list ',' defaults_entry", --"defaults_entry : DEFVAR", --"defaults_entry : '!' DEFVAR", --"defaults_entry : DEFVAR '=' WORD", --"defaults_entry : DEFVAR '+' WORD", --"defaults_entry : DEFVAR '-' WORD", --"privileges : privilege", --"privileges : privileges ':' privilege", --"privilege : hostlist '=' cmndspeclist", --"ophost : host", --"ophost : '!' host", --"host : ALIAS", --"host : ALL", --"host : NETGROUP", --"host : NTWKADDR", --"host : WORD", --"cmndspeclist : cmndspec", --"cmndspeclist : cmndspeclist ',' cmndspec", --"cmndspec : runasspec selinux solarisprivs cmndtag opcmnd", --"opcmnd : cmnd", --"opcmnd : '!' cmnd", --"rolespec : ROLE '=' WORD", --"typespec : TYPE '=' WORD", --"selinux :", --"selinux : rolespec", --"selinux : typespec", --"selinux : rolespec typespec", --"selinux : typespec rolespec", --"privsspec : PRIVS '=' WORD", --"limitprivsspec : LIMITPRIVS '=' WORD", --"solarisprivs :", --"solarisprivs : privsspec", --"solarisprivs : limitprivsspec", --"solarisprivs : privsspec limitprivsspec", --"solarisprivs : limitprivsspec privsspec", --"runasspec :", --"runasspec : '(' runaslist ')'", --"runaslist :", --"runaslist : userlist", --"runaslist : userlist ':' grouplist", --"runaslist : ':' grouplist", --"runaslist : ':'", --"cmndtag :", --"cmndtag : cmndtag NOPASSWD", --"cmndtag : cmndtag PASSWD", --"cmndtag : cmndtag NOEXEC", --"cmndtag : cmndtag EXEC", --"cmndtag : cmndtag SETENV", --"cmndtag : cmndtag NOSETENV", --"cmndtag : cmndtag LOG_INPUT", --"cmndtag : cmndtag NOLOG_INPUT", --"cmndtag : cmndtag LOG_OUTPUT", --"cmndtag : cmndtag NOLOG_OUTPUT", --"cmnd : ALL", --"cmnd : ALIAS", --"cmnd : COMMAND", --"hostaliases : hostalias", --"hostaliases : hostaliases ':' hostalias", --"hostalias : ALIAS '=' hostlist", --"hostlist : ophost", --"hostlist : hostlist ',' ophost", --"cmndaliases : cmndalias", --"cmndaliases : cmndaliases ':' cmndalias", --"cmndalias : ALIAS '=' cmndlist", --"cmndlist : opcmnd", --"cmndlist : cmndlist ',' opcmnd", --"runasaliases : runasalias", --"runasaliases : runasaliases ':' runasalias", --"runasalias : ALIAS '=' userlist", --"useraliases : useralias", --"useraliases : useraliases ':' useralias", --"useralias : ALIAS '=' userlist", --"userlist : opuser", --"userlist : userlist ',' opuser", --"opuser : user", --"opuser : '!' user", --"user : ALIAS", --"user : ALL", --"user : NETGROUP", --"user : USERGROUP", --"user : WORD", --"grouplist : opgroup", --"grouplist : grouplist ',' opgroup", --"opgroup : group", --"opgroup : '!' group", --"group : ALIAS", --"group : ALL", --"group : WORD", -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const yytype_uint16 yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, -+ 285, 286, 58, 61, 44, 33, 43, 45, 40, 41, -+ 287, 288, 289, 290, 291, 292, 293, 294, 295, 296 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const yytype_uint8 yyr1[] = -+{ -+ 0, 50, 51, 51, 52, 52, 53, 53, 53, 53, -+ 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, -+ 55, 55, 55, 55, 55, 56, 56, 57, 58, 58, -+ 59, 59, 59, 59, 59, 60, 60, 61, 62, 62, -+ 62, 62, 63, 63, 64, 64, 65, 66, 67, 67, -+ 67, 67, 67, 68, 69, 70, 70, 70, 70, 70, -+ 71, 71, 72, 72, 72, 72, 72, 73, 73, 73, -+ 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, -+ 74, 75, 75, 76, 77, 77, 78, 78, 79, 80, -+ 80, 81, 81, 82, 83, 83, 84, 85, 85, 86, -+ 86, 87, 87, 87, 87, 87, 88, 88, 89, 89, -+ 90, 90, 90 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const yytype_uint8 yyr2[] = -+{ -+ 0, 2, 0, 1, 1, 2, 1, 2, 2, 2, -+ 2, 2, 2, 2, 3, 3, 3, 3, 1, 3, -+ 1, 2, 3, 3, 3, 1, 3, 3, 1, 2, -+ 1, 1, 1, 1, 1, 1, 3, 5, 3, 3, -+ 3, 3, 1, 2, 1, 2, 3, 3, 0, 1, -+ 1, 2, 2, 3, 3, 0, 1, 1, 2, 2, -+ 0, 3, 0, 1, 3, 2, 1, 0, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, -+ 1, 1, 3, 3, 1, 3, 1, 3, 3, 1, -+ 3, 1, 3, 3, 1, 3, 3, 1, 3, 1, -+ 2, 1, 1, 1, 1, 1, 1, 3, 1, 2, -+ 1, 1, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. -+ Performed when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const yytype_uint8 yydefact[] = -+{ -+ 0, 0, 101, 103, 104, 105, 0, 0, 0, 0, -+ 0, 102, 6, 0, 0, 0, 0, 0, 0, 0, -+ 4, 0, 97, 99, 7, 20, 0, 13, 18, 30, -+ 33, 32, 34, 31, 0, 84, 28, 0, 0, 0, -+ 80, 79, 78, 0, 0, 0, 0, 0, 0, 89, -+ 42, 44, 0, 0, 10, 81, 0, 11, 86, 0, -+ 9, 94, 0, 12, 91, 100, 1, 5, 0, 8, -+ 25, 0, 0, 0, 0, 21, 0, 29, 0, 16, -+ 14, 15, 45, 0, 0, 0, 0, 43, 0, 17, -+ 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, -+ 60, 22, 23, 24, 19, 85, 38, 39, 40, 41, -+ 90, 83, 82, 88, 87, 96, 95, 93, 92, 26, -+ 62, 27, 35, 48, 66, 0, 63, 60, 0, 0, -+ 49, 50, 55, 110, 112, 111, 0, 65, 106, 108, -+ 61, 0, 36, 0, 0, 51, 52, 0, 0, 56, -+ 57, 67, 109, 0, 64, 47, 46, 0, 0, 58, -+ 59, 0, 107, 53, 54, 68, 69, 70, 71, 72, -+ 73, 74, 75, 76, 77, 37 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const yytype_int16 yydefgoto[] = -+{ -+ -1, 18, 19, 20, 27, 28, 69, 70, 35, 36, -+ 121, 122, 48, 49, 50, 130, 131, 132, 149, 150, -+ 151, 123, 125, 161, 51, 54, 55, 71, 57, 58, -+ 52, 63, 64, 60, 61, 21, 22, 23, 137, 138, -+ 139 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -86 -+static const yytype_int16 yypact[] = -+{ -+ 66, 8, -86, -86, -86, -86, 29, 56, 134, 134, -+ 5, -86, -86, 26, 28, 33, 39, 144, 46, 102, -+ -86, 7, -86, -86, -86, 121, 54, 27, -86, -86, -+ -86, -86, -86, -86, 155, -86, -86, 10, 23, 23, -+ -86, -86, -86, 101, 55, 57, 58, 67, 3, -86, -+ -86, -86, 34, 65, 68, -86, 74, 76, -86, 86, -+ 88, -86, 91, 93, -86, -86, -86, -86, 134, 94, -+ -86, 22, 126, 127, 138, -86, 29, -86, 56, 27, -+ 27, 27, -86, 145, 153, 156, 158, -86, 5, 27, -+ 56, 26, 5, 28, 134, 33, 134, 39, -86, 56, -+ 106, -86, -86, -86, -86, -86, -86, -86, -86, -86, -+ -86, 137, -86, 142, -86, 143, -86, 143, -86, -86, -+ 114, 146, -86, 30, 130, 136, -22, 106, 149, 150, -+ 147, 148, 40, -86, -86, -86, 141, 151, -86, -86, -+ -86, 130, -86, 169, 170, -86, -86, 159, 160, 140, -+ 152, -86, -86, 130, 151, -86, -86, 177, 180, -86, -+ -86, 1, -86, -86, -86, -86, -86, -86, -86, -86, -+ -86, -86, -86, -86, -86, -86 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const yytype_int16 yypgoto[] = -+{ -+ -86, -86, -86, 172, 135, 118, -86, 97, 119, 164, -+ -86, 72, -86, -85, 154, 69, 71, -86, 53, 59, -+ -86, -86, -86, -86, 161, -86, 115, -5, -86, 112, -+ 117, -86, 110, -86, 116, -8, 157, 193, 73, 60, -+ 79 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -4 -+static const yytype_int16 yytable[] = -+{ -+ 38, 39, 37, 110, 40, 41, 40, 41, 40, 41, -+ 141, 29, 68, 30, 31, 25, 32, 165, 166, 167, -+ 168, 169, 170, 171, 172, 173, 174, 42, 25, 42, -+ 53, 42, 56, 33, 25, 24, 43, 59, 43, 25, -+ 43, 68, 34, 62, 78, 26, 66, 44, 45, 46, -+ 47, 44, 45, 46, 47, 100, 78, 68, 26, 75, -+ 29, 76, 30, 31, 26, 32, -2, 1, 88, 26, -+ 2, 128, 129, 3, 4, 5, 175, 6, 7, 8, -+ 9, 10, 33, 147, 148, 111, 115, 83, 117, 84, -+ 85, 34, 11, 12, 13, 14, 15, 16, 90, 86, -+ 91, 17, -3, 1, 40, 41, 2, 92, 93, 3, -+ 4, 5, 126, 6, 7, 8, 9, 10, 2, 94, -+ 95, 3, 4, 5, 96, 97, 99, 42, 11, 12, -+ 13, 14, 15, 16, 133, 101, 102, 17, 2, 134, -+ 11, 3, 4, 5, 120, 133, 124, 103, 2, 17, -+ 134, 3, 4, 5, 72, 106, 135, 73, 74, 29, -+ 11, 30, 31, 107, 32, 136, 108, 135, 109, 17, -+ 11, 78, 79, 80, 81, 140, 88, 68, 155, 156, -+ 127, 33, 143, 144, 148, 153, 163, 89, 128, 164, -+ 129, 67, 157, 158, 104, 147, 119, 105, 77, 142, -+ 146, 145, 87, 160, 82, 114, 112, 118, 159, 113, -+ 65, 116, 0, 162, 154, 152, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 98 - }; -+ -+#define yypact_value_is_default(Yystate) \ -+ (!!((Yystate) == (-86))) -+ -+#define yytable_value_is_error(Yytable_value) \ -+ YYID (0) -+ -+static const yytype_int16 yycheck[] = -+{ -+ 8, 9, 7, 88, 3, 4, 3, 4, 3, 4, -+ 32, 4, 34, 6, 7, 5, 9, 16, 17, 18, -+ 19, 20, 21, 22, 23, 24, 25, 26, 5, 26, -+ 4, 26, 4, 26, 5, 27, 35, 4, 35, 5, -+ 35, 34, 35, 4, 34, 35, 0, 46, 47, 48, -+ 49, 46, 47, 48, 49, 33, 34, 34, 35, 5, -+ 4, 34, 6, 7, 35, 9, 0, 1, 34, 35, -+ 4, 41, 42, 7, 8, 9, 161, 11, 12, 13, -+ 14, 15, 26, 43, 44, 90, 94, 32, 96, 32, -+ 32, 35, 26, 27, 28, 29, 30, 31, 33, 32, -+ 32, 35, 0, 1, 3, 4, 4, 33, 32, 7, -+ 8, 9, 120, 11, 12, 13, 14, 15, 4, 33, -+ 32, 7, 8, 9, 33, 32, 32, 26, 26, 27, -+ 28, 29, 30, 31, 4, 9, 9, 35, 4, 9, -+ 26, 7, 8, 9, 38, 4, 32, 9, 4, 35, -+ 9, 7, 8, 9, 33, 10, 26, 36, 37, 4, -+ 26, 6, 7, 10, 9, 35, 10, 26, 10, 35, -+ 26, 34, 37, 38, 39, 39, 34, 34, 9, 9, -+ 34, 26, 33, 33, 44, 34, 9, 52, 41, 9, -+ 42, 19, 33, 33, 76, 43, 99, 78, 34, 127, -+ 131, 130, 48, 150, 43, 93, 91, 97, 149, 92, -+ 17, 95, -1, 153, 141, 136, -1, -1, -1, -1, -+ -1, -1, -1, -1, -1, 68 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const yytype_uint8 yystos[] = -+{ -+ 0, 1, 4, 7, 8, 9, 11, 12, 13, 14, -+ 15, 26, 27, 28, 29, 30, 31, 35, 51, 52, -+ 53, 85, 86, 87, 27, 5, 35, 54, 55, 4, -+ 6, 7, 9, 26, 35, 58, 59, 77, 85, 85, -+ 3, 4, 26, 35, 46, 47, 48, 49, 62, 63, -+ 64, 74, 80, 4, 75, 76, 4, 78, 79, 4, -+ 83, 84, 4, 81, 82, 87, 0, 53, 34, 56, -+ 57, 77, 33, 36, 37, 5, 34, 59, 34, 54, -+ 54, 54, 74, 32, 32, 32, 32, 64, 34, 54, -+ 33, 32, 33, 32, 33, 32, 33, 32, 86, 32, -+ 33, 9, 9, 9, 55, 58, 10, 10, 10, 10, -+ 63, 77, 76, 80, 79, 85, 84, 85, 82, 57, -+ 38, 60, 61, 71, 32, 72, 85, 34, 41, 42, -+ 65, 66, 67, 4, 9, 26, 35, 88, 89, 90, -+ 39, 32, 61, 33, 33, 66, 65, 43, 44, 68, -+ 69, 70, 90, 34, 88, 9, 9, 33, 33, 69, -+ 68, 73, 89, 9, 9, 16, 17, 18, 19, 20, -+ 21, 22, 23, 24, 25, 63 -+}; -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. However, -+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated -+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is -+ discussed. */ -+ -+#define YYFAIL goto yyerrlab -+#if defined YYFAIL -+ /* This is here to suppress warnings from the GCC cpp's -+ -Wunused-macros. Normally we don't worry about that warning, but -+ some users do, and we want to make it easy for users to remove -+ YYFAIL uses, which will produce warnings from Bison 2.5. */ -+#endif -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ YYPOPSTACK (yylen); \ -+ yystate = *yyssp; \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror (YY_("syntax error: cannot back up")); \ -+ YYERROR; \ -+ } \ -+while (YYID (0)) -+ -+/* Error token number */ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+ -+/* This macro is provided for backward compatibility. */ -+#ifndef YY_LOCATION_PRINT -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) - #endif --#ifdef YYSTACKSIZE --#undef YYMAXDEPTH --#define YYMAXDEPTH YYSTACKSIZE --#else --#ifdef YYMAXDEPTH --#define YYSTACKSIZE YYMAXDEPTH -+ -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (YYLEX_PARAM) - #else --#define YYSTACKSIZE 10000 --#define YYMAXDEPTH 10000 -+# define YYLEX yylex () - #endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (YYID (0)) -+ -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yy_symbol_print (stderr, \ -+ Type, Value); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (YYID (0)) -+ -+ -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+/*ARGSUSED*/ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -+#else -+static void -+yy_symbol_value_print (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE const * const yyvaluep; - #endif --#define YYINITSTACKSIZE 200 --/* LINTUSED */ --int yydebug; --int yynerrs; --int yyerrflag; --int yychar; --short *yyssp; --YYSTYPE *yyvsp; --YYSTYPE yyval; --YYSTYPE yylval; --short *yyss; --short *yysslim; --YYSTYPE *yyvs; --int yystacksize; --#line 674 "gram.y" --static struct defaults * --new_default(char *var, char *val, int op) - { -- struct defaults *d; -- debug_decl(new_default, SUDO_DEBUG_PARSER) -+ FILE *yyo = yyoutput; -+ YYUSE (yyo); -+ if (!yyvaluep) -+ return; -+# ifdef YYPRINT -+ if (yytype < YYNTOKENS) -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# else -+ YYUSE (yyoutput); -+# endif -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+} +diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c +index 1916bde..2a9ea4b 100644 +--- a/plugins/sudoers/match.c ++++ b/plugins/sudoers/match.c +@@ -62,6 +62,7 @@ -- 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; */ - -- debug_return_ptr(d); --} -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ - --static struct member * --new_member(char *name, int type) -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -+#else -+static void -+yy_symbol_print (yyoutput, yytype, yyvaluep) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE const * const yyvaluep; -+#endif - { -- struct member *m; -- debug_decl(new_member, SUDO_DEBUG_PARSER) -- -- m = ecalloc(1, sizeof(struct member)); -- m->name = name; -- m->type = type; -- m->prev = m; -- /* m->next = NULL; */ -+ if (yytype < YYNTOKENS) -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + #include "sudoers.h" + #include "parse.h" ++#include "filedigest.h" + #include -- debug_return_ptr(m); -+ yy_symbol_value_print (yyoutput, yytype, yyvaluep); -+ YYFPRINTF (yyoutput, ")"); + #ifdef HAVE_FNMATCH +@@ -576,6 +577,7 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const } - --/* -- * Add a list of defaults structures to the defaults list. -- * The binding, if non-NULL, specifies a list of hosts, users, or -- * runas users the entries apply to (specified by the type). -- */ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) - static void --add_defaults(int type, struct member *bmem, struct defaults *defs) -+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -+#else -+static void -+yy_stack_print (yybottom, yytop) -+ yytype_int16 *yybottom; -+ yytype_int16 *yytop; -+#endif - { -- struct defaults *d; -- struct member_list binding; -- debug_decl(add_defaults, SUDO_DEBUG_PARSER) -+ YYFPRINTF (stderr, "Stack now"); -+ for (; yybottom <= yytop; yybottom++) -+ { -+ int yybot = *yybottom; -+ YYFPRINTF (stderr, " %d", yybot); + #else /* !SUDOERS_NAME_MATCH */ + ++#ifndef HAVE_LIBGCRYPT /* !!! */ + static struct digest_function { + const char *digest_name; + const unsigned int digest_len; +@@ -616,24 +618,43 @@ static struct digest_function { + NULL + } + }; ++#endif /* !HAVE_LIBGCRYPT */ ++ ++static const char *digesttype2str(int digest_type) ++{ ++ switch(digest_type) { ++ case SUDO_DIGEST_SHA224: ++ return "SHA224"; ++ case SUDO_DIGEST_SHA256: ++ return "SHA256"; ++ case SUDO_DIGEST_SHA384: ++ return "SHA384"; ++ case SUDO_DIGEST_SHA512: ++ return "SHA512"; + } -+ YYFPRINTF (stderr, "\n"); ++ return ""; +} -- /* -- * We can only call list2tq once on bmem as it will zero -- * out the prev pointer when it consumes bmem. -- */ -- list2tq(&binding, bmem); -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (YYID (0)) - -- /* -- * Set type and binding (who it applies to) for new entries. -- */ -- for (d = defs; d != NULL; d = d->next) { -- d->type = type; -- d->binding = binding; -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -+#else -+static void -+yy_reduce_print (yyvsp, yyrule) -+ YYSTYPE *yyvsp; -+ int yyrule; -+#endif -+{ -+ int yynrhs = yyr2[yyrule]; -+ int yyi; -+ unsigned long int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", -+ yyrule - 1, yylno); -+ /* The symbols being reduced. */ -+ for (yyi = 0; yyi < yynrhs; yyi++) -+ { -+ YYFPRINTF (stderr, " $%d = ", yyi + 1); -+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], -+ &(yyvsp[(yyi + 1) - (yynrhs)]) -+ ); -+ YYFPRINTF (stderr, "\n"); + static bool + digest_matches(const char *file, const struct sudo_digest *sd, int *fd) + { +- unsigned char file_digest[SHA512_DIGEST_LENGTH]; +- unsigned char sudoers_digest[SHA512_DIGEST_LENGTH]; ++ unsigned char * file_digest = NULL; ++ unsigned char * sudoers_digest = NULL; ++ size_t digest_size; + unsigned char buf[32 * 1024]; +- struct digest_function *func = NULL; + #ifdef HAVE_FEXECVE + bool first = true; + bool is_script = false; + #endif /* HAVE_FEXECVE */ + size_t nread; +- SHA2_CTX ctx; + FILE *fp; + unsigned int i; + debug_decl(digest_matches, SUDOERS_DEBUG_MATCH) + ++#ifndef HAVE_LIBGCRYPT /* !!! */ ++ ++ SHA2_CTX ctx; ++ struct digest_function *func = NULL; + for (i = 0; digest_functions[i].digest_name != NULL; i++) { + if (sd->digest_type == i) { + func = &digest_functions[i]; +@@ -644,9 +665,33 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd) + sudo_warnx(U_("unsupported digest type %d for %s"), sd->digest_type, file); + debug_return_bool(false); } -- tq_append(&defaults, defs); -+} - -- debug_return; -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (yyvsp, Rule); \ -+} while (YYID (0)) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined __GLIBC__ && defined _STRING_H -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static YYSIZE_T -+yystrlen (const char *yystr) -+#else -+static YYSIZE_T -+yystrlen (yystr) -+ const char *yystr; -+#endif -+{ -+ YYSIZE_T yylen; -+ for (yylen = 0; yystr[yylen]; yylen++) -+ continue; -+ return yylen; - } -+# endif -+# endif - --/* -- * Allocate a new struct userspec, populate it, and insert it at the -- * and of the userspecs list. -- */ --static void --add_userspec(struct member *members, struct privilege *privs) -+# ifndef yystpcpy -+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static char * -+yystpcpy (char *yydest, const char *yysrc) -+#else -+static char * -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+#endif - { -- struct userspec *u; -- debug_decl(add_userspec, SUDO_DEBUG_PARSER) -+ char *yyd = yydest; -+ const char *yys = yysrc; - -- u = ecalloc(1, sizeof(*u)); -- list2tq(&u->users, members); -- list2tq(&u->privileges, privs); -- u->prev = u; -- /* u->next = NULL; */ -- tq_append(&userspecs, u); -+ while ((*yyd++ = *yys++) != '\0') -+ continue; - -- debug_return; -+ return yyd - 1; - } -+# endif -+# endif - --/* -- * Free up space used by data structures from a previous parser run and sets -- * the current sudoers file to path. -- */ --void --init_parser(const char *path, bool quiet) -+# ifndef yytnamerr -+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary -+ quotes and backslashes, so that it's suitable for yyerror. The -+ heuristic is that double-quoting is unnecessary unless the string -+ contains an apostrophe, a comma, or backslash (other than -+ backslash-backslash). YYSTR is taken from yytname. If YYRES is -+ null, do not copy; instead, return the length of what the result -+ would have been. */ -+static YYSIZE_T -+yytnamerr (char *yyres, const char *yystr) - { -- 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) -+ if (*yystr == '"') -+ { -+ YYSIZE_T yyn = 0; -+ char const *yyp = yystr; - -- while ((us = tq_pop(&userspecs)) != NULL) { -- while ((m = tq_pop(&us->users)) != NULL) { -- efree(m->name); -- efree(m); -- } -- while ((priv = tq_pop(&us->privileges)) != NULL) { -- struct member *runasuser = NULL, *runasgroup = NULL; --#ifdef HAVE_SELINUX -- char *role = NULL, *type = NULL; --#endif /* HAVE_SELINUX */ --#ifdef HAVE_PRIV_SET -- char *privs = NULL, *limitprivs = NULL; --#endif /* HAVE_PRIV_SET */ -+ for (;;) -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; +- if (strlen(sd->digest_str) == func->digest_len * 2) { + -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; ++ digest_size = func->digest_len; + -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } -+ do_not_strip_quotes: ; ++ file_digest = malloc(digest_size); ++ if (file_digest == NULL) { ++ debug_return_bool(false); + } - -- while ((m = tq_pop(&priv->hostlist)) != NULL) { -- efree(m->name); -- efree(m); -- } -- while ((cs = tq_pop(&priv->cmndlist)) != NULL) { --#ifdef HAVE_SELINUX -- /* Only free the first instance of a role/type. */ -- if (cs->role != role) { -- role = cs->role; -- efree(cs->role); -- } -- if (cs->type != type) { -- type = cs->type; -- efree(cs->type); -- } --#endif /* HAVE_SELINUX */ --#ifdef HAVE_PRIV_SET -- /* Only free the first instance of privs/limitprivs. */ -- if (cs->privs != privs) { -- privs = cs->privs; -- efree(cs->privs); -- } -- if (cs->limitprivs != limitprivs) { -- limitprivs = cs->limitprivs; -- 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) { -- efree(m->name); -- efree(m); -- } -- } -- if (tq_last(&cs->runasgrouplist) != runasgroup) { -- runasgroup = tq_last(&cs->runasgrouplist); -- while ((m = tq_pop(&cs->runasgrouplist)) != NULL) { -- efree(m->name); -- efree(m); -- } -- } -- if (cs->cmnd->type == COMMAND) { -- c = (struct sudo_command *) cs->cmnd->name; -- efree(c->cmnd); -- efree(c->args); -- } -- efree(cs->cmnd->name); -- efree(cs->cmnd); -- efree(cs); -- } -- efree(priv); -- } -- efree(us); -+ if (! yyres) -+ return yystrlen (yystr); + -+ return yystpcpy (yyres, yystr) - yyres; -+} -+# endif ++#elif HAVE_LIBGCRYPT + -+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message -+ about the unexpected token YYTOKEN for the state stack whose top is -+ YYSSP. ++ if (sudo_filedigest(file, sd->digest_type, ++ &file_digest, &digest_size) != 0) { ++ sudo_warnx(U_("Cannot compute digest type %d for %s"), sd->digest_type, file); ++ goto clean_up; ++ } + -+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is -+ not large enough to hold the message. In that case, also set -+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the -+ required number of bytes is too large to store. */ -+static int -+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, -+ yytype_int16 *yyssp, int yytoken) -+{ -+ YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); -+ YYSIZE_T yysize = yysize0; -+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; -+ /* Internationalized format string. */ -+ const char *yyformat = YY_NULL; -+ /* Arguments of yyformat. */ -+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; -+ /* Number of reported tokens (one for the "unexpected", one per -+ "expected"). */ -+ int yycount = 0; ++#endif /* !HAVE_LIBGCRYPT */ + -+ /* There are many possibilities here to consider: -+ - Assume YYFAIL is not used. It's too flawed to consider. See -+ -+ for details. YYERROR is fine as it does not invoke this -+ function. -+ - If this state is a consistent state with a default action, then -+ the only way this function was invoked is if the default action -+ is an error action. In that case, don't check for expected -+ tokens because there are none. -+ - The only way there can be no lookahead present (in yychar) is if -+ this state is a consistent state with a default action. Thus, -+ detecting the absence of a lookahead is sufficient to determine -+ that there is no unexpected or expected token to report. In that -+ case, just report a simple "syntax error". -+ - Don't assume there isn't a lookahead just because this state is a -+ consistent state with a default action. There might have been a -+ previous inconsistent state, consistent state with a non-default -+ action, or user semantic action that manipulated yychar. -+ - Of course, the expected token list depends on states to have -+ correct lookahead information, and it depends on the parser not -+ to perform extra reductions after fetching a lookahead from the -+ scanner and before detecting a syntax error. Thus, state merging -+ (from LALR or IELR) and default reductions corrupt the expected -+ token list. However, the list is correct for canonical LR with -+ one exception: it will still contain any token that will not be -+ accepted due to an error action in a later state. -+ */ -+ if (yytoken != YYEMPTY) -+ { -+ int yyn = yypact[*yyssp]; -+ yyarg[yycount++] = yytname[yytoken]; -+ if (!yypact_value_is_default (yyn)) -+ { -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. In other words, skip the first -YYN actions for -+ this state because they are default actions. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn + 1; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yyx; ++ sudoers_digest = malloc(digest_size); ++ if (sudoers_digest == NULL) { ++ free(file_digest); ++ debug_return_bool(false); ++ } + -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR -+ && !yytable_value_is_error (yytable[yyx + yyn])) -+ { -+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) -+ { -+ yycount = 1; -+ yysize = yysize0; -+ break; -+ } -+ yyarg[yycount++] = yytname[yyx]; -+ { -+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); -+ if (! (yysize <= yysize1 -+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; -+ } -+ } -+ } ++ if (strlen(sd->digest_str) == digest_size * 2) { + /* Convert the command digest from ascii hex to binary. */ +- for (i = 0; i < func->digest_len; i++) { ++ for (i = 0; i < digest_size ; i++) { + const int h = hexchar(&sd->digest_str[i + i]); + if (h == -1) + goto bad_format; +@@ -654,11 +699,11 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd) + } + } else { + size_t len = base64_decode(sd->digest_str, sudoers_digest, +- sizeof(sudoers_digest)); +- if (len != func->digest_len) { ++ digest_size); ++ if (len != digest_size) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, +- "incorrect length for digest, expected %u, got %zu", +- func->digest_len, len); ++ "incorrect length for digest, expected %zu, got %zu", ++ digest_size, len); + goto bad_format; + } } -- tq_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) { -- if (m->type == COMMAND) { -- c = (struct sudo_command *) m->name; -- efree(c->cmnd); -- efree(c->args); -- } -- efree(m->name); -- efree(m); -- } -- } -- efree(d->var); -- efree(d->val); -- efree(d); -+ switch (yycount) -+ { -+# define YYCASE_(N, S) \ -+ case N: \ -+ yyformat = S; \ -+ break -+ YYCASE_(0, YY_("syntax error")); -+ YYCASE_(1, YY_("syntax error, unexpected %s")); -+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); -+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); -+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); -+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -+# undef YYCASE_ +@@ -666,10 +711,11 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd) + if ((fp = fopen(file, "r")) == NULL) { + sudo_debug_printf(SUDO_DEBUG_INFO, "unable to open %s: %s", + file, strerror(errno)); +- debug_return_bool(false); ++ goto clean_up; } -- tq_init(&defaults); - -- init_aliases(); -+ { -+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat); -+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) -+ return 2; -+ yysize = yysize1; -+ } - -- init_lexer(); -+ if (*yymsg_alloc < yysize) -+ { -+ *yymsg_alloc = 2 * yysize; -+ if (! (yysize <= *yymsg_alloc -+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) -+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; -+ return 1; -+ } - -- efree(sudoers); -- sudoers = path ? estrdup(path) : NULL; -+ /* Avoid sprintf, as that infringes on the user's name space. -+ Don't have undefined behavior even if the translation -+ produced a string with the wrong number of "%s"s. */ -+ { -+ char *yyp = *yymsg; -+ int yyi = 0; -+ while ((*yyp = *yyformat) != '\0') -+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) -+ { -+ yyp += yytnamerr (yyp, yyarg[yyi++]); -+ yyformat += 2; -+ } -+ else -+ { -+ yyp++; -+ yyformat++; -+ } -+ } -+ return 0; -+} -+#endif /* YYERROR_VERBOSE */ - -- parse_error = false; -- errorlineno = -1; -- errorfile = sudoers; -- sudoers_warnings = !quiet; -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+/*ARGSUSED*/ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -+#else -+static void -+yydestruct (yymsg, yytype, yyvaluep) -+ const char *yymsg; -+ int yytype; -+ YYSTYPE *yyvaluep; -+#endif -+{ -+ YYUSE (yyvaluep); - -- debug_return; --} --#line 827 "gram.c" --/* allocate initial stack or double stack size, up to YYMAXDEPTH */ --#if defined(__cplusplus) || defined(__STDC__) --static int yygrowstack(void) --#else --static int yygrowstack() --#endif --{ -- int newsize, i; -- short *newss; -- YYSTYPE *newvs; - -- newsize = yystacksize ? yystacksize : YYINITSTACKSIZE; -- if (newsize >= YYMAXDEPTH) -- return -1; -- else if ((newsize *= 2) > YYMAXDEPTH) -- newsize = YYMAXDEPTH; --#ifdef SIZE_MAX --#define YY_SIZE_MAX SIZE_MAX --#else --#define YY_SIZE_MAX 0x7fffffff --#endif -- if (YY_SIZE_MAX / newsize < sizeof *newss) -- goto bail; -- i = yyssp - yyss; -- newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) : -- (short *)malloc(newsize * sizeof *newss); /* overflow check above */ -- if (newss == NULL) -- goto bail; -- yyss = newss; -- yyssp = newss + i; -- newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) : -- (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */ -- if (newvs == NULL) -- goto bail; -- yyvs = newvs; -- yyvsp = newvs + i; -- yystacksize = newsize; -- yysslim = yyss + newsize - 1; -- return 0; --bail: -- if (yyss) -- free(yyss); -- if (yyvs) -- free(yyvs); -- yyss = yyssp = NULL; -- yyvs = yyvsp = NULL; -- yystacksize = 0; -- return -1; -+ if (!yymsg) -+ yymsg = "Deleting"; -+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } - } - --#define YYABORT goto yyabort --#define YYREJECT goto yyabort --#define YYACCEPT goto yyaccept --#define YYERROR goto yyerrlab -+ -+ -+ -+/* The lookahead symbol. */ -+int yychar; -+ -+ -+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+# define YY_IGNORE_MAYBE_UNINITIALIZED_END -+#endif -+#ifndef YY_INITIAL_VALUE -+# define YY_INITIAL_VALUE(Value) /* Nothing. */ -+#endif -+ -+/* The semantic value of the lookahead symbol. */ -+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+int -+yyparse (void *YYPARSE_PARAM) -+#else - int --#if defined(__cplusplus) || defined(__STDC__) --yyparse(void) -+yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+#endif -+#else /* ! YYPARSE_PARAM */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+int -+yyparse (void) - #else --yyparse() -+int -+yyparse () -+ -+#endif - #endif - { -- int yym, yyn, yystate; --#if YYDEBUG --#if defined(__cplusplus) || defined(__STDC__) -- const char *yys; --#else /* !(defined(__cplusplus) || defined(__STDC__)) */ -- char *yys; --#endif /* !(defined(__cplusplus) || defined(__STDC__)) */ -- -- if ((yys = getenv("YYDEBUG"))) -- { -- yyn = *yys; -- if (yyn >= '0' && yyn <= '9') -- yydebug = yyn - '0'; -- } --#endif /* YYDEBUG */ -- -- yynerrs = 0; -- yyerrflag = 0; -- yychar = (-1); -- -- if (yyss == NULL && yygrowstack()) goto yyoverflow; -- yyssp = yyss; -- yyvsp = yyvs; -- *yyssp = yystate = 0; -- --yyloop: -- if ((yyn = yydefred[yystate]) != 0) goto yyreduce; -- if (yychar < 0) -- { -- if ((yychar = yylex()) < 0) yychar = 0; --#if YYDEBUG -- if (yydebug) -- { -- yys = 0; -- if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; -- if (!yys) yys = "illegal-symbol"; -- printf("%sdebug: state %d, reading %d (%s)\n", -- YYPREFIX, yystate, yychar, yys); -- } -+ int yystate; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ -+ /* The stacks and their tools: -+ `yyss': related to states. -+ `yyvs': related to semantic values. -+ -+ Refer to the stacks through separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ yytype_int16 yyssa[YYINITDEPTH]; -+ yytype_int16 *yyss; -+ yytype_int16 *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs; -+ YYSTYPE *yyvsp; -+ -+ YYSIZE_T yystacksize; -+ -+ int yyn; -+ int yyresult; -+ /* Lookahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ -+#if YYERROR_VERBOSE -+ /* Buffer for error messages, and its allocated size. */ -+ char yymsgbuf[128]; -+ char *yymsg = yymsgbuf; -+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf; - #endif -+ -+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) -+ -+ /* The number of symbols on the RHS of the reduced rule. -+ Keep to zero when no symbol should be popped. */ -+ int yylen = 0; -+ -+ yyssp = yyss = yyssa; -+ yyvsp = yyvs = yyvsa; -+ yystacksize = YYINITDEPTH; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. So pushing a state here evens the stacks. */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ yytype_int16 *yyss1 = yyss; -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ &yystacksize); -+ -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyexhaustedlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyexhaustedlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ yytype_int16 *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss_alloc, yyss); -+ YYSTACK_RELOCATE (yyvs_alloc, yyvs); -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; - } -- if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && -- yyn <= YYTABLESIZE && yycheck[yyn] == yychar) -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ if (yystate == YYFINAL) -+ YYACCEPT; -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+ /* Do appropriate processing given the current state. Read a -+ lookahead token if we need one and don't already have one. */ -+ -+ /* First try to decide what to do without reference to lookahead token. */ -+ yyn = yypact[yystate]; -+ if (yypact_value_is_default (yyn)) -+ goto yydefault; -+ -+ /* Not known => get a lookahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ -+ if (yychar == YYEMPTY) - { --#if YYDEBUG -- if (yydebug) -- printf("%sdebug: state %d, shifting to state %d\n", -- YYPREFIX, yystate, yytable[yyn]); --#endif -- if (yyssp >= yysslim && yygrowstack()) -- { -- goto yyoverflow; -- } -- *++yyssp = yystate = yytable[yyn]; -- *++yyvsp = yylval; -- yychar = (-1); -- if (yyerrflag > 0) --yyerrflag; -- goto yyloop; -- } -- if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && -- yyn <= YYTABLESIZE && yycheck[yyn] == yychar) -- { -- yyn = yytable[yyn]; -- goto yyreduce; -- } -- if (yyerrflag) goto yyinrecovery; --#if defined(lint) || defined(__GNUC__) -- goto yynewerror; --#endif --yynewerror: -- yyerror("syntax error"); --#if defined(lint) || defined(__GNUC__) -- goto yyerrlab; --#endif --yyerrlab: -- ++yynerrs; --yyinrecovery: -- if (yyerrflag < 3) -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) - { -- yyerrflag = 3; -- for (;;) -- { -- if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && -- yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) -- { --#if YYDEBUG -- if (yydebug) -- printf("%sdebug: state %d, error recovery shifting\ -- to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); --#endif -- if (yyssp >= yysslim && yygrowstack()) -- { -- goto yyoverflow; -- } -- *++yyssp = yystate = yytable[yyn]; -- *++yyvsp = yylval; -- goto yyloop; -- } -- else -- { --#if YYDEBUG -- if (yydebug) -- printf("%sdebug: error recovery discarding state %d\n", -- YYPREFIX, *yyssp); --#endif -- if (yyssp <= yyss) goto yyabort; -- --yyssp; -- --yyvsp; -- } -- } -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); - } -- else -+ else - { -- if (yychar == 0) goto yyabort; --#if YYDEBUG -- if (yydebug) -- { -- yys = 0; -- if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; -- if (!yys) yys = "illegal-symbol"; -- printf("%sdebug: state %d, error recovery discards token %d (%s)\n", -- YYPREFIX, yystate, yychar, yys); -- } --#endif -- yychar = (-1); -- goto yyloop; -+ yytoken = YYTRANSLATE (yychar); -+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yytable_value_is_error (yyn)) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; - } -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ /* Shift the lookahead token. */ -+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); -+ -+ /* Discard the shifted token. */ -+ yychar = YYEMPTY; -+ -+ yystate = yyn; -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+ *++yyvsp = yylval; -+ YY_IGNORE_MAYBE_UNINITIALIZED_END -+ -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ - yyreduce: --#if YYDEBUG -- if (yydebug) -- printf("%sdebug: state %d, reducing by rule %d (%s)\n", -- YYPREFIX, yystate, yyn, yyrule[yyn]); --#endif -- yym = yylen[yyn]; -- if (yym) -- yyval = yyvsp[1-yym]; -- else -- memset(&yyval, 0, sizeof yyval); -- switch (yyn) -- { --case 1: --#line 204 "gram.y" --{ ; } --break; --case 5: --#line 212 "gram.y" --{ -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+/* Line 1792 of yacc.c */ -+#line 214 "gram.y" -+ { ; } -+ break; -+ -+ case 6: -+/* Line 1792 of yacc.c */ -+#line 222 "gram.y" -+ { - ; - } --break; --case 6: --#line 215 "gram.y" --{ -+ break; -+ -+ case 7: -+/* Line 1792 of yacc.c */ -+#line 225 "gram.y" -+ { - yyerrok; - } --break; --case 7: --#line 218 "gram.y" --{ -- add_userspec(yyvsp[-1].member, yyvsp[0].privilege); -- } --break; --case 8: --#line 221 "gram.y" --{ -- ; -+ break; -+ -+ case 8: -+/* Line 1792 of yacc.c */ -+#line 228 "gram.y" -+ { -+ add_userspec((yyvsp[(1) - (2)].member), (yyvsp[(2) - (2)].privilege)); - } --break; --case 9: --#line 224 "gram.y" --{ -+ break; -+ -+ case 9: -+/* Line 1792 of yacc.c */ -+#line 231 "gram.y" -+ { - ; - } --break; --case 10: --#line 227 "gram.y" --{ -+ break; -+ -+ case 10: -+/* Line 1792 of yacc.c */ -+#line 234 "gram.y" -+ { - ; - } --break; --case 11: --#line 230 "gram.y" --{ -+ break; -+ -+ case 11: -+/* Line 1792 of yacc.c */ -+#line 237 "gram.y" -+ { - ; - } --break; --case 12: --#line 233 "gram.y" --{ -- add_defaults(DEFAULTS, NULL, yyvsp[0].defaults); -+ break; -+ -+ case 12: -+/* Line 1792 of yacc.c */ -+#line 240 "gram.y" -+ { -+ ; - } --break; --case 13: --#line 236 "gram.y" --{ -- add_defaults(DEFAULTS_USER, yyvsp[-1].member, yyvsp[0].defaults); -+ break; -+ -+ case 13: -+/* Line 1792 of yacc.c */ -+#line 243 "gram.y" -+ { -+ add_defaults(DEFAULTS, NULL, (yyvsp[(2) - (2)].defaults)); - } --break; --case 14: --#line 239 "gram.y" --{ -- add_defaults(DEFAULTS_RUNAS, yyvsp[-1].member, yyvsp[0].defaults); -+ break; -+ -+ case 14: -+/* Line 1792 of yacc.c */ -+#line 246 "gram.y" -+ { -+ add_defaults(DEFAULTS_USER, (yyvsp[(2) - (3)].member), (yyvsp[(3) - (3)].defaults)); - } --break; --case 15: --#line 242 "gram.y" --{ -- add_defaults(DEFAULTS_HOST, yyvsp[-1].member, yyvsp[0].defaults); -+ break; -+ -+ case 15: -+/* Line 1792 of yacc.c */ -+#line 249 "gram.y" -+ { -+ add_defaults(DEFAULTS_RUNAS, (yyvsp[(2) - (3)].member), (yyvsp[(3) - (3)].defaults)); - } --break; --case 16: --#line 245 "gram.y" --{ -- add_defaults(DEFAULTS_CMND, yyvsp[-1].member, yyvsp[0].defaults); -+ break; -+ -+ case 16: -+/* Line 1792 of yacc.c */ -+#line 252 "gram.y" -+ { -+ add_defaults(DEFAULTS_HOST, (yyvsp[(2) - (3)].member), (yyvsp[(3) - (3)].defaults)); - } --break; --case 18: --#line 251 "gram.y" --{ -- list_append(yyvsp[-2].defaults, yyvsp[0].defaults); -- yyval.defaults = yyvsp[-2].defaults; -+ break; -+ -+ case 17: -+/* Line 1792 of yacc.c */ -+#line 255 "gram.y" -+ { -+ add_defaults(DEFAULTS_CMND, (yyvsp[(2) - (3)].member), (yyvsp[(3) - (3)].defaults)); - } --break; --case 19: --#line 257 "gram.y" --{ -- yyval.defaults = new_default(yyvsp[0].string, NULL, true); -+ break; -+ -+ case 19: -+/* Line 1792 of yacc.c */ -+#line 261 "gram.y" -+ { -+ list_append((yyvsp[(1) - (3)].defaults), (yyvsp[(3) - (3)].defaults)); -+ (yyval.defaults) = (yyvsp[(1) - (3)].defaults); - } --break; --case 20: --#line 260 "gram.y" --{ -- yyval.defaults = new_default(yyvsp[0].string, NULL, false); -+ break; -+ -+ case 20: -+/* Line 1792 of yacc.c */ -+#line 267 "gram.y" -+ { -+ (yyval.defaults) = new_default((yyvsp[(1) - (1)].string), NULL, true); - } --break; --case 21: --#line 263 "gram.y" --{ -- yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, true); -+ break; -+ -+ case 21: -+/* Line 1792 of yacc.c */ -+#line 270 "gram.y" -+ { -+ (yyval.defaults) = new_default((yyvsp[(2) - (2)].string), NULL, false); - } --break; --case 22: --#line 266 "gram.y" --{ -- yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '+'); -+ break; -+ -+ case 22: -+/* Line 1792 of yacc.c */ -+#line 273 "gram.y" -+ { -+ (yyval.defaults) = new_default((yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].string), true); - } --break; --case 23: --#line 269 "gram.y" --{ -- yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '-'); -+ break; -+ -+ case 23: -+/* Line 1792 of yacc.c */ -+#line 276 "gram.y" -+ { -+ (yyval.defaults) = new_default((yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].string), '+'); - } --break; --case 25: --#line 275 "gram.y" --{ -- list_append(yyvsp[-2].privilege, yyvsp[0].privilege); -- yyval.privilege = yyvsp[-2].privilege; -+ break; -+ -+ case 24: -+/* Line 1792 of yacc.c */ -+#line 279 "gram.y" -+ { -+ (yyval.defaults) = new_default((yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].string), '-'); - } --break; --case 26: --#line 281 "gram.y" --{ -+ break; -+ -+ case 26: -+/* Line 1792 of yacc.c */ -+#line 285 "gram.y" -+ { -+ list_append((yyvsp[(1) - (3)].privilege), (yyvsp[(3) - (3)].privilege)); -+ (yyval.privilege) = (yyvsp[(1) - (3)].privilege); -+ } -+ break; -+ -+ case 27: -+/* Line 1792 of yacc.c */ -+#line 291 "gram.y" -+ { - struct privilege *p = ecalloc(1, sizeof(*p)); -- list2tq(&p->hostlist, yyvsp[-2].member); -- list2tq(&p->cmndlist, yyvsp[0].cmndspec); -+ list2tq(&p->hostlist, (yyvsp[(1) - (3)].member)); -+ list2tq(&p->cmndlist, (yyvsp[(3) - (3)].cmndspec)); - p->prev = p; - /* p->next = NULL; */ -- yyval.privilege = p; -+ (yyval.privilege) = p; - } --break; --case 27: --#line 291 "gram.y" --{ -- yyval.member = yyvsp[0].member; -- yyval.member->negated = false; -+ break; -+ -+ case 28: -+/* Line 1792 of yacc.c */ -+#line 301 "gram.y" -+ { -+ (yyval.member) = (yyvsp[(1) - (1)].member); -+ (yyval.member)->negated = false; - } --break; --case 28: --#line 295 "gram.y" --{ -- yyval.member = yyvsp[0].member; -- yyval.member->negated = true; -+ break; -+ -+ case 29: -+/* Line 1792 of yacc.c */ -+#line 305 "gram.y" -+ { -+ (yyval.member) = (yyvsp[(2) - (2)].member); -+ (yyval.member)->negated = true; - } --break; --case 29: --#line 301 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, ALIAS); -+ break; -+ -+ case 30: -+/* Line 1792 of yacc.c */ -+#line 311 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), ALIAS); - } --break; --case 30: --#line 304 "gram.y" --{ -- yyval.member = new_member(NULL, ALL); -+ break; -+ -+ case 31: -+/* Line 1792 of yacc.c */ -+#line 314 "gram.y" -+ { -+ (yyval.member) = new_member(NULL, ALL); - } --break; --case 31: --#line 307 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, NETGROUP); -+ break; -+ -+ case 32: -+/* Line 1792 of yacc.c */ -+#line 317 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), NETGROUP); - } --break; --case 32: --#line 310 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, NTWKADDR); -+ break; -+ -+ case 33: -+/* Line 1792 of yacc.c */ -+#line 320 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), NTWKADDR); - } --break; --case 33: --#line 313 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, WORD); -+ break; -+ -+ case 34: -+/* Line 1792 of yacc.c */ -+#line 323 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), WORD); - } --break; --case 35: --#line 319 "gram.y" --{ -- list_append(yyvsp[-2].cmndspec, yyvsp[0].cmndspec); -+ break; -+ -+ case 36: -+/* Line 1792 of yacc.c */ -+#line 329 "gram.y" -+ { -+ list_append((yyvsp[(1) - (3)].cmndspec), (yyvsp[(3) - (3)].cmndspec)); - #ifdef HAVE_SELINUX - /* propagate role and type */ -- if (yyvsp[0].cmndspec->role == NULL) -- yyvsp[0].cmndspec->role = yyvsp[0].cmndspec->prev->role; -- if (yyvsp[0].cmndspec->type == NULL) -- yyvsp[0].cmndspec->type = yyvsp[0].cmndspec->prev->type; -+ if ((yyvsp[(3) - (3)].cmndspec)->role == NULL) -+ (yyvsp[(3) - (3)].cmndspec)->role = (yyvsp[(3) - (3)].cmndspec)->prev->role; -+ if ((yyvsp[(3) - (3)].cmndspec)->type == NULL) -+ (yyvsp[(3) - (3)].cmndspec)->type = (yyvsp[(3) - (3)].cmndspec)->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; -- if (yyvsp[0].cmndspec->limitprivs == NULL) -- yyvsp[0].cmndspec->limitprivs = yyvsp[0].cmndspec->prev->limitprivs; -+ if ((yyvsp[(3) - (3)].cmndspec)->privs == NULL) -+ (yyvsp[(3) - (3)].cmndspec)->privs = (yyvsp[(3) - (3)].cmndspec)->prev->privs; -+ if ((yyvsp[(3) - (3)].cmndspec)->limitprivs == NULL) -+ (yyvsp[(3) - (3)].cmndspec)->limitprivs = (yyvsp[(3) - (3)].cmndspec)->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; -- if (yyvsp[0].cmndspec->tags.noexec == UNSPEC) -- yyvsp[0].cmndspec->tags.noexec = yyvsp[0].cmndspec->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; -- if (yyvsp[0].cmndspec->tags.log_input == UNSPEC) -- yyvsp[0].cmndspec->tags.log_input = yyvsp[0].cmndspec->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; -+ if ((yyvsp[(3) - (3)].cmndspec)->tags.nopasswd == UNSPEC) -+ (yyvsp[(3) - (3)].cmndspec)->tags.nopasswd = (yyvsp[(3) - (3)].cmndspec)->prev->tags.nopasswd; -+ if ((yyvsp[(3) - (3)].cmndspec)->tags.noexec == UNSPEC) -+ (yyvsp[(3) - (3)].cmndspec)->tags.noexec = (yyvsp[(3) - (3)].cmndspec)->prev->tags.noexec; -+ if ((yyvsp[(3) - (3)].cmndspec)->tags.setenv == UNSPEC && -+ (yyvsp[(3) - (3)].cmndspec)->prev->tags.setenv != IMPLIED) -+ (yyvsp[(3) - (3)].cmndspec)->tags.setenv = (yyvsp[(3) - (3)].cmndspec)->prev->tags.setenv; -+ if ((yyvsp[(3) - (3)].cmndspec)->tags.log_input == UNSPEC) -+ (yyvsp[(3) - (3)].cmndspec)->tags.log_input = (yyvsp[(3) - (3)].cmndspec)->prev->tags.log_input; -+ if ((yyvsp[(3) - (3)].cmndspec)->tags.log_output == UNSPEC) -+ (yyvsp[(3) - (3)].cmndspec)->tags.log_output = (yyvsp[(3) - (3)].cmndspec)->prev->tags.log_output; -+ if ((tq_empty(&(yyvsp[(3) - (3)].cmndspec)->runasuserlist) && -+ tq_empty(&(yyvsp[(3) - (3)].cmndspec)->runasgrouplist)) && -+ (!tq_empty(&(yyvsp[(3) - (3)].cmndspec)->prev->runasuserlist) || -+ !tq_empty(&(yyvsp[(3) - (3)].cmndspec)->prev->runasgrouplist))) { -+ (yyvsp[(3) - (3)].cmndspec)->runasuserlist = (yyvsp[(3) - (3)].cmndspec)->prev->runasuserlist; -+ (yyvsp[(3) - (3)].cmndspec)->runasgrouplist = (yyvsp[(3) - (3)].cmndspec)->prev->runasgrouplist; - } -- yyval.cmndspec = yyvsp[-2].cmndspec; -+ (yyval.cmndspec) = (yyvsp[(1) - (3)].cmndspec); - } --break; --case 36: --#line 358 "gram.y" --{ -+ break; -+ -+ case 37: -+/* Line 1792 of yacc.c */ -+#line 368 "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); -- efree(yyvsp[-4].runas); -+ if ((yyvsp[(1) - (5)].runas) != NULL) { -+ list2tq(&cs->runasuserlist, (yyvsp[(1) - (5)].runas)->runasusers); -+ list2tq(&cs->runasgrouplist, (yyvsp[(1) - (5)].runas)->runasgroups); -+ efree((yyvsp[(1) - (5)].runas)); - } else { - tq_init(&cs->runasuserlist); - tq_init(&cs->runasgrouplist); - } - #ifdef HAVE_SELINUX -- cs->role = yyvsp[-3].seinfo.role; -- cs->type = yyvsp[-3].seinfo.type; -+ cs->role = (yyvsp[(2) - (5)].seinfo).role; -+ cs->type = (yyvsp[(2) - (5)].seinfo).type; - #endif - #ifdef HAVE_PRIV_SET -- cs->privs = yyvsp[-2].privinfo.privs; -- cs->limitprivs = yyvsp[-2].privinfo.limitprivs; -+ cs->privs = (yyvsp[(3) - (5)].privinfo).privs; -+ cs->limitprivs = (yyvsp[(3) - (5)].privinfo).limitprivs; - #endif -- cs->tags = yyvsp[-1].tag; -- cs->cmnd = yyvsp[0].member; -+ cs->tags = (yyvsp[(4) - (5)].tag); -+ cs->cmnd = (yyvsp[(5) - (5)].member); - cs->prev = cs; - cs->next = NULL; - /* sudo "ALL" implies the SETENV tag */ - if (cs->cmnd->type == ALL && !cs->cmnd->negated && - cs->tags.setenv == UNSPEC) - cs->tags.setenv = IMPLIED; -- yyval.cmndspec = cs; -- } --break; --case 37: --#line 388 "gram.y" --{ -- yyval.member = yyvsp[0].member; -- yyval.member->negated = false; -+ (yyval.cmndspec) = cs; - } --break; --case 38: --#line 392 "gram.y" --{ -- yyval.member = yyvsp[0].member; -- yyval.member->negated = true; -- } --break; --case 39: -+ break; -+ -+ case 38: -+/* Line 1792 of yacc.c */ - #line 398 "gram.y" --{ -- yyval.string = yyvsp[0].string; -+ { -+ (yyval.digest) = new_digest(SUDO_DIGEST_SHA224, (yyvsp[(3) - (3)].string)); - } --break; --case 40: --#line 403 "gram.y" --{ -- yyval.string = yyvsp[0].string; -+ break; -+ -+ case 39: -+/* Line 1792 of yacc.c */ -+#line 401 "gram.y" -+ { -+ (yyval.digest) = new_digest(SUDO_DIGEST_SHA256, (yyvsp[(3) - (3)].string)); - } --break; --case 41: --#line 408 "gram.y" --{ -- yyval.seinfo.role = NULL; -- yyval.seinfo.type = NULL; -+ break; -+ -+ case 40: -+/* Line 1792 of yacc.c */ -+#line 404 "gram.y" -+ { -+ (yyval.digest) = new_digest(SUDO_DIGEST_SHA384, (yyvsp[(3) - (3)].string)); - } --break; --case 42: -+ break; -+ -+ case 41: -+/* Line 1792 of yacc.c */ -+#line 407 "gram.y" -+ { -+ (yyval.digest) = new_digest(SUDO_DIGEST_SHA512, (yyvsp[(3) - (3)].string)); -+ } -+ break; -+ -+ case 42: -+/* Line 1792 of yacc.c */ - #line 412 "gram.y" --{ -- yyval.seinfo.role = yyvsp[0].string; -- yyval.seinfo.type = NULL; -+ { -+ (yyval.member) = (yyvsp[(1) - (1)].member); - } --break; --case 43: --#line 416 "gram.y" --{ -- yyval.seinfo.type = yyvsp[0].string; -- yyval.seinfo.role = NULL; -+ break; -+ -+ case 43: -+/* Line 1792 of yacc.c */ -+#line 415 "gram.y" -+ { -+ if ((yyvsp[(2) - (2)].member)->type != COMMAND) { -+ YYERROR; -+ } -+ /* XXX - yuck */ -+ ((struct sudo_command *) (yyvsp[(2) - (2)].member)->name)->digest = (yyvsp[(1) - (2)].digest); -+ (yyval.member) = (yyvsp[(2) - (2)].member); -+ } -+ break; -+ -+ case 44: -+/* Line 1792 of yacc.c */ -+#line 425 "gram.y" -+ { -+ (yyval.member) = (yyvsp[(1) - (1)].member); -+ (yyval.member)->negated = false; - } --break; --case 44: --#line 420 "gram.y" --{ -- yyval.seinfo.role = yyvsp[-1].string; -- yyval.seinfo.type = yyvsp[0].string; -+ break; -+ -+ case 45: -+/* Line 1792 of yacc.c */ -+#line 429 "gram.y" -+ { -+ (yyval.member) = (yyvsp[(2) - (2)].member); -+ (yyval.member)->negated = true; - } --break; --case 45: --#line 424 "gram.y" --{ -- yyval.seinfo.type = yyvsp[-1].string; -- yyval.seinfo.role = yyvsp[0].string; -+ break; -+ -+ case 46: -+/* Line 1792 of yacc.c */ -+#line 435 "gram.y" -+ { -+ (yyval.string) = (yyvsp[(3) - (3)].string); - } --break; --case 46: --#line 430 "gram.y" --{ -- yyval.string = yyvsp[0].string; -+ break; -+ -+ case 47: -+/* Line 1792 of yacc.c */ -+#line 440 "gram.y" -+ { -+ (yyval.string) = (yyvsp[(3) - (3)].string); - } --break; --case 47: --#line 434 "gram.y" --{ -- yyval.string = yyvsp[0].string; -+ break; -+ -+ case 48: -+/* Line 1792 of yacc.c */ -+#line 445 "gram.y" -+ { -+ (yyval.seinfo).role = NULL; -+ (yyval.seinfo).type = NULL; - } --break; --case 48: --#line 439 "gram.y" --{ -- yyval.privinfo.privs = NULL; -- yyval.privinfo.limitprivs = NULL; -+ break; -+ -+ case 49: -+/* Line 1792 of yacc.c */ -+#line 449 "gram.y" -+ { -+ (yyval.seinfo).role = (yyvsp[(1) - (1)].string); -+ (yyval.seinfo).type = NULL; - } --break; --case 49: --#line 443 "gram.y" --{ -- yyval.privinfo.privs = yyvsp[0].string; -- yyval.privinfo.limitprivs = NULL; -+ break; -+ -+ case 50: -+/* Line 1792 of yacc.c */ -+#line 453 "gram.y" -+ { -+ (yyval.seinfo).type = (yyvsp[(1) - (1)].string); -+ (yyval.seinfo).role = NULL; - } --break; --case 50: --#line 447 "gram.y" --{ -- yyval.privinfo.privs = NULL; -- yyval.privinfo.limitprivs = yyvsp[0].string; -+ break; -+ -+ case 51: -+/* Line 1792 of yacc.c */ -+#line 457 "gram.y" -+ { -+ (yyval.seinfo).role = (yyvsp[(1) - (2)].string); -+ (yyval.seinfo).type = (yyvsp[(2) - (2)].string); - } --break; --case 51: --#line 451 "gram.y" --{ -- yyval.privinfo.privs = yyvsp[-1].string; -- yyval.privinfo.limitprivs = yyvsp[0].string; -+ break; -+ -+ case 52: -+/* Line 1792 of yacc.c */ -+#line 461 "gram.y" -+ { -+ (yyval.seinfo).type = (yyvsp[(1) - (2)].string); -+ (yyval.seinfo).role = (yyvsp[(2) - (2)].string); - } --break; --case 52: --#line 455 "gram.y" --{ -- yyval.privinfo.limitprivs = yyvsp[-1].string; -- yyval.privinfo.privs = yyvsp[0].string; -+ break; -+ -+ case 53: -+/* Line 1792 of yacc.c */ -+#line 467 "gram.y" -+ { -+ (yyval.string) = (yyvsp[(3) - (3)].string); - } --break; --case 53: --#line 460 "gram.y" --{ -- yyval.runas = NULL; -+ break; -+ -+ case 54: -+/* Line 1792 of yacc.c */ -+#line 471 "gram.y" -+ { -+ (yyval.string) = (yyvsp[(3) - (3)].string); - } --break; --case 54: --#line 463 "gram.y" --{ -- yyval.runas = yyvsp[-1].runas; -+ break; -+ -+ case 55: -+/* Line 1792 of yacc.c */ -+#line 476 "gram.y" -+ { -+ (yyval.privinfo).privs = NULL; -+ (yyval.privinfo).limitprivs = NULL; - } --break; --case 55: --#line 468 "gram.y" --{ -- yyval.runas = ecalloc(1, sizeof(struct runascontainer)); -- yyval.runas->runasusers = new_member(NULL, MYSELF); -+ break; -+ -+ case 56: -+/* Line 1792 of yacc.c */ -+#line 480 "gram.y" -+ { -+ (yyval.privinfo).privs = (yyvsp[(1) - (1)].string); -+ (yyval.privinfo).limitprivs = NULL; -+ } -+ break; -+ -+ case 57: -+/* Line 1792 of yacc.c */ -+#line 484 "gram.y" -+ { -+ (yyval.privinfo).privs = NULL; -+ (yyval.privinfo).limitprivs = (yyvsp[(1) - (1)].string); -+ } -+ break; -+ -+ case 58: -+/* Line 1792 of yacc.c */ -+#line 488 "gram.y" -+ { -+ (yyval.privinfo).privs = (yyvsp[(1) - (2)].string); -+ (yyval.privinfo).limitprivs = (yyvsp[(2) - (2)].string); -+ } -+ break; -+ -+ case 59: -+/* Line 1792 of yacc.c */ -+#line 492 "gram.y" -+ { -+ (yyval.privinfo).limitprivs = (yyvsp[(1) - (2)].string); -+ (yyval.privinfo).privs = (yyvsp[(2) - (2)].string); -+ } -+ break; -+ -+ case 60: -+/* Line 1792 of yacc.c */ -+#line 497 "gram.y" -+ { -+ (yyval.runas) = NULL; -+ } -+ break; -+ -+ case 61: -+/* Line 1792 of yacc.c */ -+#line 500 "gram.y" -+ { -+ (yyval.runas) = (yyvsp[(2) - (3)].runas); -+ } -+ break; -+ -+ case 62: -+/* Line 1792 of yacc.c */ -+#line 505 "gram.y" -+ { -+ (yyval.runas) = ecalloc(1, sizeof(struct runascontainer)); -+ (yyval.runas)->runasusers = new_member(NULL, MYSELF); - /* $$->runasgroups = NULL; */ - } --break; --case 56: --#line 473 "gram.y" --{ -- yyval.runas = ecalloc(1, sizeof(struct runascontainer)); -- yyval.runas->runasusers = yyvsp[0].member; -+ break; -+ -+ case 63: -+/* Line 1792 of yacc.c */ -+#line 510 "gram.y" -+ { -+ (yyval.runas) = ecalloc(1, sizeof(struct runascontainer)); -+ (yyval.runas)->runasusers = (yyvsp[(1) - (1)].member); - /* $$->runasgroups = NULL; */ - } --break; --case 57: --#line 478 "gram.y" --{ -- yyval.runas = ecalloc(1, sizeof(struct runascontainer)); -- yyval.runas->runasusers = yyvsp[-2].member; -- yyval.runas->runasgroups = yyvsp[0].member; -- } --break; --case 58: --#line 483 "gram.y" --{ -- yyval.runas = ecalloc(1, sizeof(struct runascontainer)); -+ break; -+ -+ case 64: -+/* Line 1792 of yacc.c */ -+#line 515 "gram.y" -+ { -+ (yyval.runas) = ecalloc(1, sizeof(struct runascontainer)); -+ (yyval.runas)->runasusers = (yyvsp[(1) - (3)].member); -+ (yyval.runas)->runasgroups = (yyvsp[(3) - (3)].member); -+ } -+ break; -+ -+ case 65: -+/* Line 1792 of yacc.c */ -+#line 520 "gram.y" -+ { -+ (yyval.runas) = ecalloc(1, sizeof(struct runascontainer)); - /* $$->runasusers = NULL; */ -- yyval.runas->runasgroups = yyvsp[0].member; -+ (yyval.runas)->runasgroups = (yyvsp[(2) - (2)].member); - } --break; --case 59: --#line 488 "gram.y" --{ -- yyval.runas = ecalloc(1, sizeof(struct runascontainer)); -- yyval.runas->runasusers = new_member(NULL, MYSELF); -+ break; -+ -+ case 66: -+/* Line 1792 of yacc.c */ -+#line 525 "gram.y" -+ { -+ (yyval.runas) = ecalloc(1, sizeof(struct runascontainer)); -+ (yyval.runas)->runasusers = new_member(NULL, MYSELF); - /* $$->runasgroups = NULL; */ - } --break; --case 60: --#line 495 "gram.y" --{ -- yyval.tag.nopasswd = yyval.tag.noexec = yyval.tag.setenv = -- yyval.tag.log_input = yyval.tag.log_output = UNSPEC; -+ break; -+ -+ case 67: -+/* Line 1792 of yacc.c */ -+#line 532 "gram.y" -+ { -+ (yyval.tag).nopasswd = (yyval.tag).noexec = (yyval.tag).setenv = -+ (yyval.tag).log_input = (yyval.tag).log_output = UNSPEC; - } --break; --case 61: --#line 499 "gram.y" --{ -- yyval.tag.nopasswd = true; -+ break; -+ -+ case 68: -+/* Line 1792 of yacc.c */ -+#line 536 "gram.y" -+ { -+ (yyval.tag).nopasswd = true; - } --break; --case 62: --#line 502 "gram.y" --{ -- yyval.tag.nopasswd = false; -+ break; -+ -+ case 69: -+/* Line 1792 of yacc.c */ -+#line 539 "gram.y" -+ { -+ (yyval.tag).nopasswd = false; - } --break; --case 63: --#line 505 "gram.y" --{ -- yyval.tag.noexec = true; -+ break; -+ -+ case 70: -+/* Line 1792 of yacc.c */ -+#line 542 "gram.y" -+ { -+ (yyval.tag).noexec = true; - } --break; --case 64: --#line 508 "gram.y" --{ -- yyval.tag.noexec = false; -+ break; -+ -+ case 71: -+/* Line 1792 of yacc.c */ -+#line 545 "gram.y" -+ { -+ (yyval.tag).noexec = false; - } --break; --case 65: --#line 511 "gram.y" --{ -- yyval.tag.setenv = true; -+ break; -+ -+ case 72: -+/* Line 1792 of yacc.c */ -+#line 548 "gram.y" -+ { -+ (yyval.tag).setenv = true; - } --break; --case 66: --#line 514 "gram.y" --{ -- yyval.tag.setenv = false; -+ break; -+ -+ case 73: -+/* Line 1792 of yacc.c */ -+#line 551 "gram.y" -+ { -+ (yyval.tag).setenv = false; - } --break; --case 67: --#line 517 "gram.y" --{ -- yyval.tag.log_input = true; -+ break; -+ -+ case 74: -+/* Line 1792 of yacc.c */ -+#line 554 "gram.y" -+ { -+ (yyval.tag).log_input = true; - } --break; --case 68: --#line 520 "gram.y" --{ -- yyval.tag.log_input = false; -+ break; -+ -+ case 75: -+/* Line 1792 of yacc.c */ -+#line 557 "gram.y" -+ { -+ (yyval.tag).log_input = false; - } --break; --case 69: --#line 523 "gram.y" --{ -- yyval.tag.log_output = true; -+ break; -+ -+ case 76: -+/* Line 1792 of yacc.c */ -+#line 560 "gram.y" -+ { -+ (yyval.tag).log_output = true; - } --break; --case 70: --#line 526 "gram.y" --{ -- yyval.tag.log_output = false; -+ break; -+ -+ case 77: -+/* Line 1792 of yacc.c */ -+#line 563 "gram.y" -+ { -+ (yyval.tag).log_output = false; - } --break; --case 71: --#line 531 "gram.y" --{ -- yyval.member = new_member(NULL, ALL); -+ break; -+ -+ case 78: -+/* Line 1792 of yacc.c */ -+#line 568 "gram.y" -+ { -+ (yyval.member) = new_member(NULL, ALL); - } --break; --case 72: --#line 534 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, ALIAS); -+ break; -+ -+ case 79: -+/* Line 1792 of yacc.c */ -+#line 571 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), ALIAS); - } --break; --case 73: --#line 537 "gram.y" --{ -+ break; -+ -+ case 80: -+/* Line 1792 of yacc.c */ -+#line 574 "gram.y" -+ { - struct sudo_command *c = ecalloc(1, sizeof(*c)); -- c->cmnd = yyvsp[0].command.cmnd; -- c->args = yyvsp[0].command.args; -- yyval.member = new_member((char *)c, COMMAND); -- } --break; --case 76: --#line 549 "gram.y" --{ -+ c->cmnd = (yyvsp[(1) - (1)].command).cmnd; -+ c->args = (yyvsp[(1) - (1)].command).args; -+ (yyval.member) = new_member((char *)c, COMMAND); -+ } -+ break; -+ -+ case 83: -+/* Line 1792 of yacc.c */ -+#line 586 "gram.y" -+ { - char *s; -- if ((s = alias_add(yyvsp[-2].string, HOSTALIAS, yyvsp[0].member)) != NULL) { -+ if ((s = alias_add((yyvsp[(1) - (3)].string), HOSTALIAS, (yyvsp[(3) - (3)].member))) != NULL) { - yyerror(s); - YYERROR; - } - } --break; --case 78: --#line 559 "gram.y" --{ -- list_append(yyvsp[-2].member, yyvsp[0].member); -- yyval.member = yyvsp[-2].member; -- } --break; --case 81: --#line 569 "gram.y" --{ -+ break; -+ -+ case 85: -+/* Line 1792 of yacc.c */ -+#line 596 "gram.y" -+ { -+ list_append((yyvsp[(1) - (3)].member), (yyvsp[(3) - (3)].member)); -+ (yyval.member) = (yyvsp[(1) - (3)].member); -+ } -+ break; -+ -+ case 88: -+/* Line 1792 of yacc.c */ -+#line 606 "gram.y" -+ { - char *s; -- if ((s = alias_add(yyvsp[-2].string, CMNDALIAS, yyvsp[0].member)) != NULL) { -+ if ((s = alias_add((yyvsp[(1) - (3)].string), CMNDALIAS, (yyvsp[(3) - (3)].member))) != NULL) { - yyerror(s); - YYERROR; - } - } --break; --case 83: --#line 579 "gram.y" --{ -- list_append(yyvsp[-2].member, yyvsp[0].member); -- yyval.member = yyvsp[-2].member; -- } --break; --case 86: --#line 589 "gram.y" --{ -+ break; -+ -+ case 90: -+/* Line 1792 of yacc.c */ -+#line 616 "gram.y" -+ { -+ list_append((yyvsp[(1) - (3)].member), (yyvsp[(3) - (3)].member)); -+ (yyval.member) = (yyvsp[(1) - (3)].member); -+ } -+ break; -+ -+ case 93: -+/* Line 1792 of yacc.c */ -+#line 626 "gram.y" -+ { - char *s; -- if ((s = alias_add(yyvsp[-2].string, RUNASALIAS, yyvsp[0].member)) != NULL) { -+ if ((s = alias_add((yyvsp[(1) - (3)].string), RUNASALIAS, (yyvsp[(3) - (3)].member))) != NULL) { - yyerror(s); - YYERROR; - } - } --break; --case 89: --#line 602 "gram.y" --{ -+ break; -+ -+ case 96: -+/* Line 1792 of yacc.c */ -+#line 639 "gram.y" -+ { - char *s; -- if ((s = alias_add(yyvsp[-2].string, USERALIAS, yyvsp[0].member)) != NULL) { -+ if ((s = alias_add((yyvsp[(1) - (3)].string), USERALIAS, (yyvsp[(3) - (3)].member))) != NULL) { - yyerror(s); - YYERROR; - } - } --break; --case 91: --#line 612 "gram.y" --{ -- list_append(yyvsp[-2].member, yyvsp[0].member); -- yyval.member = yyvsp[-2].member; -+ break; -+ -+ case 98: -+/* Line 1792 of yacc.c */ -+#line 649 "gram.y" -+ { -+ list_append((yyvsp[(1) - (3)].member), (yyvsp[(3) - (3)].member)); -+ (yyval.member) = (yyvsp[(1) - (3)].member); - } --break; --case 92: --#line 618 "gram.y" --{ -- yyval.member = yyvsp[0].member; -- yyval.member->negated = false; -+ break; -+ -+ case 99: -+/* Line 1792 of yacc.c */ -+#line 655 "gram.y" -+ { -+ (yyval.member) = (yyvsp[(1) - (1)].member); -+ (yyval.member)->negated = false; - } --break; --case 93: --#line 622 "gram.y" --{ -- yyval.member = yyvsp[0].member; -- yyval.member->negated = true; -+ break; -+ -+ case 100: -+/* Line 1792 of yacc.c */ -+#line 659 "gram.y" -+ { -+ (yyval.member) = (yyvsp[(2) - (2)].member); -+ (yyval.member)->negated = true; - } --break; --case 94: --#line 628 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, ALIAS); -+ break; -+ -+ case 101: -+/* Line 1792 of yacc.c */ -+#line 665 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), ALIAS); - } --break; --case 95: --#line 631 "gram.y" --{ -- yyval.member = new_member(NULL, ALL); -+ break; -+ -+ case 102: -+/* Line 1792 of yacc.c */ -+#line 668 "gram.y" -+ { -+ (yyval.member) = new_member(NULL, ALL); - } --break; --case 96: --#line 634 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, NETGROUP); -+ break; -+ -+ case 103: -+/* Line 1792 of yacc.c */ -+#line 671 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), NETGROUP); - } --break; --case 97: --#line 637 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, USERGROUP); -+ break; -+ -+ case 104: -+/* Line 1792 of yacc.c */ -+#line 674 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), USERGROUP); - } --break; --case 98: --#line 640 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, WORD); -+ break; -+ -+ case 105: -+/* Line 1792 of yacc.c */ -+#line 677 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), WORD); - } --break; --case 100: --#line 646 "gram.y" --{ -- list_append(yyvsp[-2].member, yyvsp[0].member); -- yyval.member = yyvsp[-2].member; -+ break; -+ -+ case 107: -+/* Line 1792 of yacc.c */ -+#line 683 "gram.y" -+ { -+ list_append((yyvsp[(1) - (3)].member), (yyvsp[(3) - (3)].member)); -+ (yyval.member) = (yyvsp[(1) - (3)].member); - } --break; --case 101: --#line 652 "gram.y" --{ -- yyval.member = yyvsp[0].member; -- yyval.member->negated = false; -+ break; -+ -+ case 108: -+/* Line 1792 of yacc.c */ -+#line 689 "gram.y" -+ { -+ (yyval.member) = (yyvsp[(1) - (1)].member); -+ (yyval.member)->negated = false; - } --break; --case 102: --#line 656 "gram.y" --{ -- yyval.member = yyvsp[0].member; -- yyval.member->negated = true; -+ break; -+ -+ case 109: -+/* Line 1792 of yacc.c */ -+#line 693 "gram.y" -+ { -+ (yyval.member) = (yyvsp[(2) - (2)].member); -+ (yyval.member)->negated = true; - } --break; --case 103: --#line 662 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, ALIAS); -+ break; -+ -+ case 110: -+/* Line 1792 of yacc.c */ -+#line 699 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), ALIAS); - } --break; --case 104: --#line 665 "gram.y" --{ -- yyval.member = new_member(NULL, ALL); -+ break; -+ -+ case 111: -+/* Line 1792 of yacc.c */ -+#line 702 "gram.y" -+ { -+ (yyval.member) = new_member(NULL, ALL); - } --break; --case 105: --#line 668 "gram.y" --{ -- yyval.member = new_member(yyvsp[0].string, WORD); -+ break; -+ -+ case 112: -+/* Line 1792 of yacc.c */ -+#line 705 "gram.y" -+ { -+ (yyval.member) = new_member((yyvsp[(1) - (1)].string), WORD); - } --break; --#line 1667 "gram.c" -+ break; -+ -+ -+/* Line 1792 of yacc.c */ -+#line 2600 "gram.c" -+ default: break; - } -- yyssp -= yym; -- yystate = *yyssp; -- yyvsp -= yym; -- yym = yylhs[yyn]; -- if (yystate == 0 && yym == 0) -+ /* User semantic actions sometimes alter yychar, and that requires -+ that yytoken be updated with the new translation. We take the -+ approach of translating immediately before every use of yytoken. -+ One alternative is translating here after every semantic action, -+ but that translation would be missed if the semantic action invokes -+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or -+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an -+ incorrect destructor might then be invoked immediately. In the -+ case of YYERROR or YYBACKUP, subsequent parser actions might lead -+ to an incorrect destructor call or verbose syntax error message -+ before the lookahead is translated. */ -+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); -+ -+ YYPOPSTACK (yylen); -+ yylen = 0; -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* Make sure we have latest lookahead translation. See comments at -+ user semantic actions for why this is necessary. */ -+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); -+ -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) - { --#if YYDEBUG -- if (yydebug) -- printf("%sdebug: after reduction, shifting from state 0 to\ -- state %d\n", YYPREFIX, YYFINAL); --#endif -- yystate = YYFINAL; -- *++yyssp = YYFINAL; -- *++yyvsp = yyval; -- if (yychar < 0) -- { -- if ((yychar = yylex()) < 0) yychar = 0; --#if YYDEBUG -- if (yydebug) -- { -- yys = 0; -- if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; -- if (!yys) yys = "illegal-symbol"; -- printf("%sdebug: state %d, reading %d (%s)\n", -- YYPREFIX, YYFINAL, yychar, yys); -- } -+ ++yynerrs; -+#if ! YYERROR_VERBOSE -+ yyerror (YY_("syntax error")); -+#else -+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ -+ yyssp, yytoken) -+ { -+ char const *yymsgp = YY_("syntax error"); -+ int yysyntax_error_status; -+ yysyntax_error_status = YYSYNTAX_ERROR; -+ if (yysyntax_error_status == 0) -+ yymsgp = yymsg; -+ else if (yysyntax_error_status == 1) -+ { -+ if (yymsg != yymsgbuf) -+ YYSTACK_FREE (yymsg); -+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); -+ if (!yymsg) -+ { -+ yymsg = yymsgbuf; -+ yymsg_alloc = sizeof yymsgbuf; -+ yysyntax_error_status = 2; -+ } -+ else -+ { -+ yysyntax_error_status = YYSYNTAX_ERROR; -+ yymsgp = yymsg; -+ } -+ } -+ yyerror (yymsgp); -+ if (yysyntax_error_status == 2) -+ goto yyexhaustedlab; -+ } -+# undef YYSYNTAX_ERROR - #endif -- } -- if (yychar == 0) goto yyaccept; -- goto yyloop; - } -- if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && -- yyn <= YYTABLESIZE && yycheck[yyn] == yystate) -- yystate = yytable[yyn]; -- else -- yystate = yydgoto[yym]; --#if YYDEBUG -- if (yydebug) -- printf("%sdebug: after reduction, shifting from state %d \ --to state %d\n", YYPREFIX, *yyssp, yystate); --#endif -- if (yyssp >= yysslim && yygrowstack()) -- { -- goto yyoverflow; -- } -- *++yyssp = yystate; -- *++yyvsp = yyval; -- goto yyloop; --yyoverflow: -- yyerror("yacc stack overflow"); --yyabort: -- if (yyss) -- free(yyss); -- if (yyvs) -- free(yyvs); -- yyss = yyssp = NULL; -- yyvs = yyvsp = NULL; -- yystacksize = 0; -- return (1); --yyaccept: -- if (yyss) -- free(yyss); -- if (yyvs) -- free(yyvs); -- yyss = yyssp = NULL; -- yyvs = yyvsp = NULL; -- yystacksize = 0; -- return (0); -+ -+ -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse lookahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } -+ else -+ { -+ yydestruct ("Error: discarding", -+ yytoken, &yylval); -+ yychar = YYEMPTY; -+ } -+ } -+ -+ /* Else will try to reuse lookahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+ /* Pacify compilers like GCC when the user code never invokes -+ YYERROR and the label yyerrorlab therefore never appears in user -+ code. */ -+ if (/*CONSTCOND*/ 0) -+ goto yyerrorlab; -+ -+ /* Do not reclaim the symbols of the rule which action triggered -+ this YYERROR. */ -+ YYPOPSTACK (yylen); -+ yylen = 0; -+ YY_STACK_PRINT (yyss, yyssp); -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (!yypact_value_is_default (yyn)) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ -+ yydestruct ("Error: popping", -+ yystos[yystate], yyvsp); -+ YYPOPSTACK (1); -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -+ *++yyvsp = yylval; -+ YY_IGNORE_MAYBE_UNINITIALIZED_END -+ -+ -+ /* Shift the error token. */ -+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#if !defined yyoverflow || YYERROR_VERBOSE -+/*-------------------------------------------------. -+| yyexhaustedlab -- memory exhaustion comes here. | -+`-------------------------------------------------*/ -+yyexhaustedlab: -+ yyerror (YY_("memory exhausted")); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+ if (yychar != YYEMPTY) -+ { -+ /* Make sure we have latest lookahead translation. See comments at -+ user semantic actions for why this is necessary. */ -+ yytoken = YYTRANSLATE (yychar); -+ yydestruct ("Cleanup: discarding lookahead", -+ yytoken, &yylval); -+ } -+ /* Do not reclaim the symbols of the rule which action triggered -+ this YYABORT or YYACCEPT. */ -+ YYPOPSTACK (yylen); -+ YY_STACK_PRINT (yyss, yyssp); -+ while (yyssp != yyss) -+ { -+ yydestruct ("Cleanup: popping", -+ yystos[*yyssp], yyvsp); -+ YYPOPSTACK (1); -+ } -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+#if YYERROR_VERBOSE -+ if (yymsg != yymsgbuf) -+ YYSTACK_FREE (yymsg); -+#endif -+ /* Make sure YYID is used. */ -+ return YYID (yyresult); -+} -+ -+ -+/* Line 2055 of yacc.c */ -+#line 710 "gram.y" -+ -+static struct defaults * -+new_default(char *var, char *val, int op) -+{ -+ struct defaults *d; -+ debug_decl(new_default, SUDO_DEBUG_PARSER) -+ -+ 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; */ -+ -+ debug_return_ptr(d); -+} -+ -+static struct member * -+new_member(char *name, int type) -+{ -+ struct member *m; -+ debug_decl(new_member, SUDO_DEBUG_PARSER) -+ -+ m = ecalloc(1, sizeof(struct member)); -+ m->name = name; -+ m->type = type; -+ m->prev = m; -+ /* m->next = NULL; */ -+ -+ debug_return_ptr(m); -+} -+ -+struct sudo_digest * -+new_digest(int digest_type, const char *digest_str) -+{ -+ struct sudo_digest *dig; -+ debug_decl(new_digest, SUDO_DEBUG_PARSER) -+ -+ dig = emalloc(sizeof(*dig)); -+ dig->digest_type = digest_type; -+ dig->digest_str = estrdup(digest_str); -+ -+ debug_return_ptr(dig); -+} -+ -+/* -+ * Add a list of defaults structures to the defaults list. -+ * The binding, if non-NULL, specifies a list of hosts, users, or -+ * runas users the entries apply to (specified by the type). -+ */ -+static void -+add_defaults(int type, struct member *bmem, struct defaults *defs) -+{ -+ struct defaults *d; -+ 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. -+ */ -+ list2tq(&binding, bmem); -+ -+ /* -+ * Set type and binding (who it applies to) for new entries. -+ */ -+ for (d = defs; d != NULL; d = d->next) { -+ d->type = type; -+ d->binding = binding; -+ } -+ tq_append(&defaults, defs); -+ -+ debug_return; -+} -+ -+/* -+ * Allocate a new struct userspec, populate it, and insert it at the -+ * and of the userspecs list. -+ */ -+static void -+add_userspec(struct member *members, struct privilege *privs) -+{ -+ struct userspec *u; -+ 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); -+ -+ debug_return; -+} -+ -+/* -+ * Free up space used by data structures from a previous parser run and sets -+ * the current sudoers file to path. -+ */ -+void -+init_parser(const char *path, bool quiet) -+{ -+ 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) { -+ efree(m->name); -+ efree(m); -+ } -+ while ((priv = tq_pop(&us->privileges)) != NULL) { -+ struct member *runasuser = NULL, *runasgroup = NULL; -+#ifdef HAVE_SELINUX -+ char *role = NULL, *type = NULL; -+#endif /* HAVE_SELINUX */ -+#ifdef HAVE_PRIV_SET -+ char *privs = NULL, *limitprivs = NULL; -+#endif /* HAVE_PRIV_SET */ -+ -+ while ((m = tq_pop(&priv->hostlist)) != NULL) { -+ efree(m->name); -+ efree(m); -+ } -+ while ((cs = tq_pop(&priv->cmndlist)) != NULL) { -+#ifdef HAVE_SELINUX -+ /* Only free the first instance of a role/type. */ -+ if (cs->role != role) { -+ role = cs->role; -+ efree(cs->role); -+ } -+ if (cs->type != type) { -+ type = cs->type; -+ efree(cs->type); -+ } -+#endif /* HAVE_SELINUX */ -+#ifdef HAVE_PRIV_SET -+ /* Only free the first instance of privs/limitprivs. */ -+ if (cs->privs != privs) { -+ privs = cs->privs; -+ efree(cs->privs); -+ } -+ if (cs->limitprivs != limitprivs) { -+ limitprivs = cs->limitprivs; -+ 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) { -+ efree(m->name); -+ efree(m); -+ } -+ } -+ if (tq_last(&cs->runasgrouplist) != runasgroup) { -+ runasgroup = tq_last(&cs->runasgrouplist); -+ while ((m = tq_pop(&cs->runasgrouplist)) != NULL) { -+ efree(m->name); -+ efree(m); -+ } -+ } -+ if (cs->cmnd->type == COMMAND) { -+ c = (struct sudo_command *) cs->cmnd->name; -+ efree(c->cmnd); -+ efree(c->args); -+ } -+ efree(cs->cmnd->name); -+ efree(cs->cmnd); -+ efree(cs); -+ } -+ efree(priv); -+ } -+ efree(us); -+ } -+ tq_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) { -+ if (m->type == COMMAND) { -+ c = (struct sudo_command *) m->name; -+ efree(c->cmnd); -+ efree(c->args); -+ } -+ efree(m->name); -+ efree(m); -+ } -+ } -+ efree(d->var); -+ efree(d->val); -+ efree(d); -+ } -+ tq_init(&defaults); -+ -+ init_aliases(); -+ -+ init_lexer(); -+ -+ efree(sudoers); -+ sudoers = path ? estrdup(path) : NULL; -+ -+ parse_error = false; -+ errorlineno = -1; -+ errorfile = sudoers; -+ sudoers_warnings = !quiet; -+ -+ debug_return; - } -diff -up sudo-1.8.6p7/plugins/sudoers/gram.h.digest-backport sudo-1.8.6p7/plugins/sudoers/gram.h ---- sudo-1.8.6p7/plugins/sudoers/gram.h.digest-backport 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/gram.h 2015-07-06 11:42:33.131904756 +0200 -@@ -1,51 +1,177 @@ --#define COMMAND 257 --#define ALIAS 258 --#define DEFVAR 259 --#define NTWKADDR 260 --#define NETGROUP 261 --#define USERGROUP 262 --#define WORD 263 --#define DEFAULTS 264 --#define DEFAULTS_HOST 265 --#define DEFAULTS_USER 266 --#define DEFAULTS_RUNAS 267 --#define DEFAULTS_CMND 268 --#define NOPASSWD 269 --#define PASSWD 270 --#define NOEXEC 271 --#define EXEC 272 --#define SETENV 273 --#define NOSETENV 274 --#define LOG_INPUT 275 --#define NOLOG_INPUT 276 --#define LOG_OUTPUT 277 --#define NOLOG_OUTPUT 278 --#define ALL 279 --#define COMMENT 280 --#define HOSTALIAS 281 --#define CMNDALIAS 282 --#define USERALIAS 283 --#define RUNASALIAS 284 --#define ERROR 285 --#define TYPE 286 --#define ROLE 287 --#define PRIVS 288 --#define LIMITPRIVS 289 --#define MYSELF 290 --#ifndef YYSTYPE_DEFINED --#define YYSTYPE_DEFINED --typedef union { -+/* A Bison parser, made by GNU Bison 2.7. */ -+ -+/* Bison interface for Yacc-like parsers in C -+ -+ Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. -+ -+ This program is free software: you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation, either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+/* As a special exception, you may create a larger work that contains -+ part or all of the Bison parser skeleton and distribute that work -+ under terms of your choice, so long as that work isn't itself a -+ parser generator using the skeleton or a modified version thereof -+ as a parser skeleton. Alternatively, if you modify or redistribute -+ the parser skeleton itself, you may (at your option) remove this -+ special exception, which will cause the skeleton and the resulting -+ Bison output files to be licensed under the GNU General Public -+ License without this special exception. -+ -+ This special exception was added by the Free Software Foundation in -+ version 2.2 of Bison. */ -+ -+#ifndef YY_YY_Y_TAB_H_INCLUDED -+# define YY_YY_Y_TAB_H_INCLUDED -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 1 -+#endif -+#if YYDEBUG -+extern int yydebug; -+#endif -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ COMMAND = 258, -+ ALIAS = 259, -+ DEFVAR = 260, -+ NTWKADDR = 261, -+ NETGROUP = 262, -+ USERGROUP = 263, -+ WORD = 264, -+ DIGEST = 265, -+ DEFAULTS = 266, -+ DEFAULTS_HOST = 267, -+ DEFAULTS_USER = 268, -+ DEFAULTS_RUNAS = 269, -+ DEFAULTS_CMND = 270, -+ NOPASSWD = 271, -+ PASSWD = 272, -+ NOEXEC = 273, -+ EXEC = 274, -+ SETENV = 275, -+ NOSETENV = 276, -+ LOG_INPUT = 277, -+ NOLOG_INPUT = 278, -+ LOG_OUTPUT = 279, -+ NOLOG_OUTPUT = 280, -+ ALL = 281, -+ COMMENT = 282, -+ HOSTALIAS = 283, -+ CMNDALIAS = 284, -+ USERALIAS = 285, -+ RUNASALIAS = 286, -+ ERROR = 287, -+ TYPE = 288, -+ ROLE = 289, -+ PRIVS = 290, -+ LIMITPRIVS = 291, -+ MYSELF = 292, -+ SHA224 = 293, -+ SHA256 = 294, -+ SHA384 = 295, -+ SHA512 = 296 -+ }; -+#endif -+/* Tokens. */ -+#define COMMAND 258 -+#define ALIAS 259 -+#define DEFVAR 260 -+#define NTWKADDR 261 -+#define NETGROUP 262 -+#define USERGROUP 263 -+#define WORD 264 -+#define DIGEST 265 -+#define DEFAULTS 266 -+#define DEFAULTS_HOST 267 -+#define DEFAULTS_USER 268 -+#define DEFAULTS_RUNAS 269 -+#define DEFAULTS_CMND 270 -+#define NOPASSWD 271 -+#define PASSWD 272 -+#define NOEXEC 273 -+#define EXEC 274 -+#define SETENV 275 -+#define NOSETENV 276 -+#define LOG_INPUT 277 -+#define NOLOG_INPUT 278 -+#define LOG_OUTPUT 279 -+#define NOLOG_OUTPUT 280 -+#define ALL 281 -+#define COMMENT 282 -+#define HOSTALIAS 283 -+#define CMNDALIAS 284 -+#define USERALIAS 285 -+#define RUNASALIAS 286 -+#define ERROR 287 -+#define TYPE 288 -+#define ROLE 289 -+#define PRIVS 290 -+#define LIMITPRIVS 291 -+#define MYSELF 292 -+#define SHA224 293 -+#define SHA256 294 -+#define SHA384 295 -+#define SHA512 296 -+ -+ -+ -+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -+typedef union YYSTYPE -+{ -+/* Line 2058 of yacc.c */ -+#line 124 "gram.y" -+ - struct cmndspec *cmndspec; - struct defaults *defaults; - struct member *member; - struct runascontainer *runas; - struct privilege *privilege; -+ struct sudo_digest *digest; - struct sudo_command command; - struct cmndtag tag; - struct selinux_info seinfo; - struct solaris_privs_info privinfo; - char *string; - int tok; -+ -+ -+/* Line 2058 of yacc.c */ -+#line 155 "y.tab.h" - } YYSTYPE; --#endif /* YYSTYPE_DEFINED */ -+# define YYSTYPE_IS_TRIVIAL 1 -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+#endif -+ - extern YYSTYPE yylval; -+ -+#ifdef YYPARSE_PARAM -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void *YYPARSE_PARAM); -+#else -+int yyparse (); -+#endif -+#else /* ! YYPARSE_PARAM */ -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+#endif /* !YY_YY_Y_TAB_H_INCLUDED */ -diff -up sudo-1.8.6p7/plugins/sudoers/gram.y.digest-backport sudo-1.8.6p7/plugins/sudoers/gram.y ---- sudo-1.8.6p7/plugins/sudoers/gram.y.digest-backport 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/gram.y 2015-07-06 11:42:33.131904756 +0200 -@@ -91,6 +91,8 @@ static void add_defaults(int, struct me - static void add_userspec(struct member *, struct privilege *); - static struct defaults *new_default(char *, char *, int); - static struct member *new_member(char *, int); -+static struct sudo_digest *new_digest(int, const char *); -+ - void yyerror(const char *); - - void -@@ -125,6 +127,7 @@ yyerror(const char *s) - struct member *member; - struct runascontainer *runas; - struct privilege *privilege; -+ struct sudo_digest *digest; - struct sudo_command command; - struct cmndtag tag; - struct selinux_info seinfo; -@@ -141,6 +144,7 @@ yyerror(const char *s) - %token NETGROUP /* a netgroup (+NAME) */ - %token USERGROUP /* a usergroup (%NAME) */ - %token WORD /* a word */ -+%token DIGEST /* a SHA-2 digest */ - %token DEFAULTS /* Defaults entry */ - %token DEFAULTS_HOST /* Host-specific defaults entry */ - %token DEFAULTS_USER /* User-specific defaults entry */ -@@ -168,8 +172,12 @@ yyerror(const char *s) - %token TYPE /* SELinux type */ - %token ROLE /* SELinux role */ - %token PRIVS /* Solaris privileges */ --%token LIMITPRIVS /* Solaris limit privileges */ -+%token LIMITPRIVS /* Solaris limit privileges */ - %token MYSELF /* run as myself, not another user */ -+%token SHA224 /* sha224 digest */ -+%token SHA256 /* sha256 digest */ -+%token SHA384 /* sha384 digest */ -+%token SHA512 /* sha512 digest */ - - %type cmndspec - %type cmndspeclist -@@ -177,6 +185,7 @@ yyerror(const char *s) - %type defaults_list - %type cmnd - %type opcmnd -+%type digcmnd - %type cmndlist - %type host - %type hostlist -@@ -198,6 +207,7 @@ yyerror(const char *s) - %type solarisprivs - %type privsspec - %type limitprivsspec -+%type digest - - %% - -@@ -355,7 +365,7 @@ cmndspeclist : cmndspec - } - ; - --cmndspec : runasspec selinux solarisprivs cmndtag opcmnd { -+cmndspec : runasspec selinux solarisprivs cmndtag digcmnd { - struct cmndspec *cs = ecalloc(1, sizeof(*cs)); - if ($1 != NULL) { - list2tq(&cs->runasuserlist, $1->runasusers); -@@ -385,6 +395,33 @@ cmndspec : runasspec selinux solarispriv - } - ; - -+digest : SHA224 ':' DIGEST { -+ $$ = new_digest(SUDO_DIGEST_SHA224, $3); -+ } -+ | SHA256 ':' DIGEST { -+ $$ = new_digest(SUDO_DIGEST_SHA256, $3); -+ } -+ | SHA384 ':' DIGEST { -+ $$ = new_digest(SUDO_DIGEST_SHA384, $3); -+ } -+ | SHA512 ':' DIGEST { -+ $$ = new_digest(SUDO_DIGEST_SHA512, $3); -+ } -+ ; -+ -+digcmnd : opcmnd { -+ $$ = $1; -+ } -+ | digest opcmnd { -+ if ($2->type != COMMAND) { -+ YYERROR; -+ } -+ /* XXX - yuck */ -+ ((struct sudo_command *) $2->name)->digest = $1; -+ $$ = $2; -+ } -+ ; -+ - opcmnd : cmnd { - $$ = $1; - $$->negated = false; -@@ -575,8 +612,8 @@ cmndalias : ALIAS '=' cmndlist { - } - ; - --cmndlist : opcmnd -- | cmndlist ',' opcmnd { -+cmndlist : digcmnd -+ | cmndlist ',' digcmnd { - list_append($1, $3); - $$ = $1; - } -@@ -704,6 +741,19 @@ new_member(char *name, int type) - debug_return_ptr(m); - } - -+struct sudo_digest * -+new_digest(int digest_type, const char *digest_str) -+{ -+ struct sudo_digest *dig; -+ debug_decl(new_digest, SUDO_DEBUG_PARSER) -+ -+ dig = emalloc(sizeof(*dig)); -+ dig->digest_type = digest_type; -+ dig->digest_str = estrdup(digest_str); -+ -+ debug_return_ptr(dig); -+} -+ - /* - * Add a list of defaults structures to the defaults list. - * The binding, if non-NULL, specifies a list of hosts, users, or -diff -up sudo-1.8.6p7/plugins/sudoers/hexchar.c.digest-backport sudo-1.8.6p7/plugins/sudoers/hexchar.c ---- sudo-1.8.6p7/plugins/sudoers/hexchar.c.digest-backport 2015-07-06 11:42:33.131904756 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/hexchar.c 2015-07-06 11:42:33.131904756 +0200 -@@ -0,0 +1,95 @@ -+/* -+ * Copyright (c) 2013 Todd C. Miller -+ * -+ * 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 -+ -+#include -+#include -+ -+#include "missing.h" -+#include "sudo_debug.h" -+#include "error.h" -+ -+int -+hexchar(const char *s) -+{ -+ unsigned char result[2]; -+ int i; -+ debug_decl(hexchar, SUDO_DEBUG_UTIL) -+ -+ for (i = 0; i < 2; i++) { -+ switch (s[i]) { -+ case '0': -+ result[i] = 0; -+ break; -+ case '1': -+ result[i] = 1; -+ break; -+ case '2': -+ result[i] = 2; -+ break; -+ case '3': -+ result[i] = 3; -+ break; -+ case '4': -+ result[i] = 4; -+ break; -+ case '5': -+ result[i] = 5; -+ break; -+ case '6': -+ result[i] = 6; -+ break; -+ case '7': -+ result[i] = 7; -+ break; -+ case '8': -+ result[i] = 8; -+ break; -+ case '9': -+ result[i] = 9; -+ break; -+ case 'A': -+ case 'a': -+ result[i] = 10; -+ break; -+ case 'B': -+ case 'b': -+ result[i] = 11; -+ break; -+ case 'C': -+ case 'c': -+ result[i] = 12; -+ break; -+ case 'D': -+ case 'd': -+ result[i] = 13; -+ break; -+ case 'E': -+ case 'e': -+ result[i] = 14; -+ break; -+ case 'F': -+ case 'f': -+ result[i] = 15; -+ break; -+ default: -+ /* Should not happen. */ -+ errorx(1, "internal error, \\x%s not in proper hex format", s); -+ } -+ } -+ debug_return_int((result[0] << 4) | result[1]); -+} -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.digest-backport sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.digest-backport 2015-07-06 11:42:33.123904876 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2015-07-06 12:05:06.636565082 +0200 -@@ -805,6 +805,68 @@ sudo_ldap_check_runas(LDAP *ld, LDAPMess - debug_return_bool(ret); - } - -+static struct sudo_digest * -+sudo_ldap_extract_digest(char **cmnd, struct sudo_digest *digest) -+{ -+ char *ep, *cp = *cmnd; -+ int digest_type = SUDO_DIGEST_INVALID; -+ debug_decl(sudo_ldap_extract_digest, SUDO_DEBUG_LDAP) -+ -+ /* -+ * Check for and extract a digest prefix, e.g. -+ * sha224:d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1 /bin/ls -+ */ -+ if (cp[0] == 's' && cp[1] == 'h' && cp[2] == 'a') { -+ switch (cp[3]) { -+ case '2': -+ if (cp[4] == '2' && cp[5] == '4') -+ digest_type = SUDO_DIGEST_SHA224; -+ else if (cp[4] == '5' && cp[5] == '6') -+ digest_type = SUDO_DIGEST_SHA256; -+ break; -+ case '3': -+ if (cp[4] == '8' && cp[5] == '4') -+ digest_type = SUDO_DIGEST_SHA384; -+ break; -+ case '5': -+ if (cp[4] == '1' && cp[5] == '2') -+ digest_type = SUDO_DIGEST_SHA512; -+ break; -+ } -+ if (digest_type != SUDO_DIGEST_INVALID) { -+ cp += 6; -+ while (isblank((unsigned char)*cp)) -+ cp++; -+ if (*cp == ':') { -+ cp++; -+ while (isblank((unsigned char)*cp)) -+ cp++; -+ ep = cp; -+ while (*ep != '\0' && !isblank((unsigned char)*ep)) -+ ep++; -+ if (*ep != '\0') { -+ digest->digest_type = digest_type; -+ digest->digest_str = strndup(cp, (size_t)(ep - cp)); -+ if (digest->digest_str == NULL) { -+ debug_return_ptr(NULL); -+ } -+ cp = ep + 1; -+ while (isblank((unsigned char)*cp)) -+ cp++; -+ *cmnd = cp; -+ DPRINTF(("%s digest %s for %s", -+ digest_type == SUDO_DIGEST_SHA224 ? "sha224" : -+ digest_type == SUDO_DIGEST_SHA256 ? "sha256" : -+ digest_type == SUDO_DIGEST_SHA384 ? "sha384" : -+ "sha512", digest->digest_str, cp), 2); -+ debug_return_ptr(digest); -+ } -+ } -+ } -+ } -+ debug_return_ptr(NULL); -+} -+ - /* - * Walk through search results and return true if we have a command match, - * false if disallowed and UNSPEC if not matched. -@@ -812,6 +874,7 @@ sudo_ldap_check_runas(LDAP *ld, LDAPMess - static int - sudo_ldap_check_command(LDAP *ld, LDAPMessage *entry, int *setenv_implied) - { -+ struct sudo_digest digest, *allowed_digest = NULL; - struct berval **bv, **p; - char *allowed_cmnd, *allowed_args, *val; - bool foundbang; -@@ -836,6 +899,9 @@ sudo_ldap_check_command(LDAP *ld, LDAPMe - continue; - } - -+ /* check for sha-2 digest */ -+ allowed_digest = sudo_ldap_extract_digest(&val, &digest); -+ - /* check for !command */ - if (*val == '!') { - foundbang = true; -@@ -851,7 +917,7 @@ sudo_ldap_check_command(LDAP *ld, LDAPMe - *allowed_args++ = '\0'; - - /* check the command like normal */ -- if (command_matches(allowed_cmnd, allowed_args)) { -+ if (command_matches(allowed_cmnd, allowed_args, allowed_digest)) { - /* - * If allowed (no bang) set ret but keep on checking. - * If disallowed (bang), exit loop. -@@ -861,6 +927,9 @@ sudo_ldap_check_command(LDAP *ld, LDAPMe - DPRINTF(("ldap sudoCommand '%s' ... %s", val, - ret == true ? "MATCH!" : "not"), 2); - -+ if (allowed_digest != NULL) -+ free(allowed_digest->digest_str); -+ - efree(allowed_cmnd); /* cleanup */ - } - -diff -up sudo-1.8.6p7/plugins/sudoers/Makefile.in.digest-backport sudo-1.8.6p7/plugins/sudoers/Makefile.in ---- sudo-1.8.6p7/plugins/sudoers/Makefile.in.digest-backport 2015-07-06 11:42:33.112905042 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/Makefile.in 2015-07-06 11:42:33.132904741 +0200 -@@ -50,6 +50,7 @@ LT_LIBS = $(top_builddir)/common/libcomm - LIBS = $(LT_LIBS) @LIBINTL@ - NET_LIBS = @NET_LIBS@ - SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(LIBS) $(NET_LIBS) @ZLIB@ -+LIBPARSESUDOERS_LIBS = @LIBPARSESUDOERS_LIBS@ - REPLAY_LIBS = @REPLAY_LIBS@ @ZLIB@ - - # C preprocessor flags -@@ -129,7 +130,7 @@ AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@ - - LIBPARSESUDOERS_OBJS = alias.lo audit.lo defaults.lo gram.lo match.lo \ - match_addr.lo pwutil.lo timestr.lo toke.lo \ -- toke_util.lo redblack.lo -+ toke_util.lo redblack.lo hexchar.lo filedigest.lo - - SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo env.lo goodpath.lo \ - group_plugin.lo find_path.lo interfaces.lo logging.lo \ -@@ -184,7 +185,7 @@ Makefile: $(srcdir)/Makefile.in - (cd $(top_builddir) && ./config.status --file plugins/sudoers/Makefile) - - libparsesudoers.la: $(LIBPARSESUDOERS_OBJS) -- $(LIBTOOL) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) -no-install -+ $(LIBTOOL) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) $(LIBPARSESUDOERS_LIBS) -no-install - - sudoers.la: $(SUDOERS_OBJS) $(LT_LIBS) libparsesudoers.la @LT_LDDEP@ - $(LIBTOOL) @LT_STATIC@ --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) -o $@ $(SUDOERS_OBJS) libparsesudoers.la $(SUDOERS_LIBS) -module -avoid-version -rpath $(plugindir) -@@ -512,6 +513,10 @@ env.lo: $(srcdir)/env.c $(top_builddir)/ - error.o: $(top_srcdir)/src/error.c $(top_builddir)/config.h \ - $(incdir)/missing.h $(incdir)/error.h $(incdir)/gettext.h - $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(top_srcdir)/src/error.c -+filedigest.lo: $(srcdir)/filedigest.c $(top_builddir)/config.h $(incdir)/missing.h \ -+ $(incdir)/sudo_debug.h $(incdir)/error.h -+ $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/filedigest.c -+filedigest.o: filedigest.lo - find_path.lo: $(srcdir)/find_path.c $(top_builddir)/config.h \ - $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \ - $(top_builddir)/pathnames.h $(incdir)/missing.h \ -@@ -565,6 +570,10 @@ group_plugin.lo: $(srcdir)/group_plugin. - $(incdir)/gettext.h - $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/group_plugin.c - group_plugin.o: group_plugin.lo -+hexchar.lo: $(srcdir)/hexchar.c $(top_builddir)/config.h $(incdir)/missing.h \ -+ $(incdir)/sudo_debug.h $(incdir)/error.h -+ $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/hexchar.c -+hexchar.o: hexchar.lo - interfaces.lo: $(srcdir)/interfaces.c $(top_builddir)/config.h \ - $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \ - $(top_builddir)/pathnames.h $(incdir)/missing.h \ -diff -up sudo-1.8.6p7/plugins/sudoers/match.c.digest-backport sudo-1.8.6p7/plugins/sudoers/match.c ---- sudo-1.8.6p7/plugins/sudoers/match.c.digest-backport 2015-07-06 11:42:33.120904922 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/match.c 2015-07-06 11:42:33.132904741 +0200 -@@ -53,9 +53,6 @@ - #ifdef HAVE_NETGROUP_H - # include - #endif /* HAVE_NETGROUP_H */ --#include --#include --#include - #include - #ifdef HAVE_DIRENT_H - # include -@@ -73,9 +70,14 @@ - # include - # endif - #endif -+#include -+#include -+#include -+#include - - #include "sudoers.h" - #include "parse.h" -+#include "filedigest.h" - #include - - #ifndef HAVE_FNMATCH -@@ -90,7 +92,7 @@ static struct member_list empty; - static bool command_matches_dir(char *, size_t); - static bool command_matches_glob(char *, char *); - static bool command_matches_fnmatch(char *, char *); --static bool command_matches_normal(char *, char *); -+static bool command_matches_normal(char *, char *, struct sudo_digest *); - - /* - * Returns true if string 's' contains meta characters. -@@ -339,7 +341,7 @@ cmnd_matches(struct member *m) - break; - case COMMAND: - c = (struct sudo_command *)m->name; -- if (command_matches(c->cmnd, c->args)) -+ if (command_matches(c->cmnd, c->args, c->digest)) - matched = !m->negated; - break; - } -@@ -347,9 +349,7 @@ cmnd_matches(struct member *m) - } - - static bool --command_args_match(sudoers_cmnd, sudoers_args) -- char *sudoers_cmnd; -- char *sudoers_args; -+command_args_match(char *sudoers_cmnd, char *sudoers_args) - { - int flags = 0; - debug_decl(command_args_match, SUDO_DEBUG_MATCH) -@@ -380,7 +380,7 @@ command_args_match(sudoers_cmnd, sudoers - * otherwise, return true if user_cmnd names one of the inodes in path. - */ - bool --command_matches(char *sudoers_cmnd, char *sudoers_args) -+command_matches(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest) - { - debug_decl(command_matches, SUDO_DEBUG_MATCH) - -@@ -412,7 +412,7 @@ command_matches(char *sudoers_cmnd, char - debug_return_bool(command_matches_fnmatch(sudoers_cmnd, sudoers_args)); - debug_return_bool(command_matches_glob(sudoers_cmnd, sudoers_args)); - } -- debug_return_bool(command_matches_normal(sudoers_cmnd, sudoers_args)); -+ debug_return_bool(command_matches_normal(sudoers_cmnd, sudoers_args, digest)); - } - - static bool -@@ -509,8 +509,119 @@ command_matches_glob(char *sudoers_cmnd, - debug_return_bool(false); - } - -+/* -+ * Decode a NUL-terminated string in base64 format and store the -+ * result in dst. -+ */ -+size_t -+base64_decode(const char *str, unsigned char *dst, size_t dsize) -+{ -+ static const char b64[] = -+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -+ const unsigned char *dst0 = dst; -+ const unsigned char *dend = dst + dsize; -+ unsigned char ch[4]; -+ char *pos; -+ int i; -+ debug_decl(base64_decode, SUDO_DEBUG_MATCH) -+ -+ /* -+ * Convert from base64 to binary. Each base64 char holds 6 bits of data -+ * so 4 base64 chars equals 3 chars of data. -+ * Padding (with the '=' char) may or may not be present. -+ */ -+ while (*str != '\0') { -+ for (i = 0; i < 4; i++) { -+ switch (*str) { -+ case '=': -+ str++; -+ /* FALLTHROUGH */ -+ case '\0': -+ ch[i] = '='; -+ break; -+ default: -+ if ((pos = strchr(b64, *str++)) == NULL) -+ debug_return_size_t((size_t)-1); -+ ch[i] = (unsigned char)(pos - b64); -+ break; -+ } -+ } -+ if (ch[0] == '=' || ch[1] == '=' || dst == dend) -+ break; -+ *dst++ = (ch[0] << 2) | ((ch[1] & 0x30) >> 4); -+ if (ch[2] == '=' || dst == dend) -+ break; -+ *dst++ = ((ch[1] & 0x0f) << 4) | ((ch[2] & 0x3c) >> 2); -+ if (ch[3] == '=' || dst == dend) -+ break; -+ *dst++ = ((ch[2] & 0x03) << 6) | ch[3]; -+ } -+ debug_return_size_t((size_t)(dst - dst0)); -+} -+ -+static bool -+digest_matches(char *file, struct sudo_digest *sd) -+{ -+ unsigned char *sudoers_digest = NULL; -+ size_t sudoers_digest_size; -+ unsigned char *file_digest = NULL; -+ size_t file_digest_size; -+ int i; -+ debug_decl(digest_matches, SUDO_DEBUG_MATCH); -+ -+ if (sudo_filedigest(file, sd->digest_type, -+ &file_digest, &file_digest_size) != 0) { -+ warningx(_("Cannot compute digest type %d for %s"), sd->digest_type, file); -+ debug_return_bool(false); -+ } -+ -+ /* First convert the digest from sudoers from ascii to binary. */ -+ sudoers_digest = emalloc(file_digest_size); -+ sudoers_digest_size = file_digest_size; -+ -+ if (sudoers_digest == NULL) { -+ efree(file_digest); -+ debug_return_bool(false); -+ } -+ -+ /* Check whether the digest is specifed as a hexchar string */ -+ if (strlen(sd->digest_str) == file_digest_size * 2) { -+ for (i = 0; i < sudoers_digest_size; i++) { -+ if (!isxdigit((unsigned char)sd->digest_str[i + i]) || -+ !isxdigit((unsigned char)sd->digest_str[i + i + 1])) { -+ warningx(_("digest for %s (%s) is not in %s form"), file, -+ sd->digest_str, sd->digest_str); -+ goto bad_format; -+ } -+ sudoers_digest[i] = hexchar(&sd->digest_str[i + i]); -+ } -+ } -+ /* Try base64 */ -+ else { -+ if (base64_decode(sd->digest_str, sudoers_digest, -+ sudoers_digest_size) != file_digest_size) { -+ goto bad_format; -+ } -+ } -+ -+ bool match = memcmp(file_digest, sudoers_digest, file_digest_size) == 0; -+ -+ efree(sudoers_digest); -+ efree(file_digest); -+ -+ debug_return_bool(match); -+ bad_format: -+ warningx(_("digest for %s (%s) is not in %s form"), file, -+ sd->digest_str, sd->digest_str); -+ if (sudoers_digest) -+ efree(sudoers_digest); -+ if (file_digest) -+ efree(file_digest); -+ debug_return_bool(false); -+} -+ - static bool --command_matches_normal(char *sudoers_cmnd, char *sudoers_args) -+command_matches_normal(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *digest) - { - struct stat sudoers_stat; - char *base; -@@ -541,12 +652,15 @@ command_matches_normal(char *sudoers_cmn - (user_stat->st_dev != sudoers_stat.st_dev || - user_stat->st_ino != sudoers_stat.st_ino)) - debug_return_bool(false); -- if (command_args_match(sudoers_cmnd, sudoers_args)) { -- efree(safe_cmnd); -- safe_cmnd = estrdup(sudoers_cmnd); -- debug_return_bool(true); -+ if (!command_args_match(sudoers_cmnd, sudoers_args)) -+ debug_return_bool(false); -+ if (digest != NULL && !digest_matches(sudoers_cmnd, digest)) { -+ /* XXX - log functions not available but we should log very loudly */ -+ debug_return_bool(false); - } -- debug_return_bool(false); -+ efree(safe_cmnd); -+ safe_cmnd = estrdup(sudoers_cmnd); -+ debug_return_bool(true); - } - - /* -diff -up sudo-1.8.6p7/plugins/sudoers/parse.h.digest-backport sudo-1.8.6p7/plugins/sudoers/parse.h ---- sudo-1.8.6p7/plugins/sudoers/parse.h.digest-backport 2015-07-06 11:42:33.120904922 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/parse.h 2015-07-06 11:42:33.132904741 +0200 -@@ -27,12 +27,21 @@ - #undef IMPLIED - #define IMPLIED 2 - -+#include "filedigest.h" -+ -+struct sudo_digest { -+ int digest_type; -+ char *digest_str; -+}; -+ - /* -- * A command with args. XXX - merge into struct member. -+ * A command with args and digest. -+ * XXX - merge into struct member. - */ - struct sudo_command { - char *cmnd; - char *args; -+ struct sudo_digest *digest; - }; - - /* -@@ -117,6 +126,7 @@ struct cmndspec { - 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 */ - #ifdef HAVE_SELINUX - char *role, *type; /* SELinux role and type */ -@@ -183,11 +193,14 @@ void init_aliases(void); - /* gram.c */ - void init_parser(const char *, bool); - -+/* hexchar.c */ -+int hexchar(const char *s); -+ - /* match_addr.c */ - bool addr_matches(char *n); - - /* match.c */ --bool command_matches(char *sudoers_cmnd, char *sudoers_args); -+bool command_matches(char *sudoers_cmnd, char *sudoers_args, struct sudo_digest *); - bool group_matches(const char *sudoers_group, const struct group *gr); - bool hostname_matches(const char *shost, const char *lhost, const char *pattern); - bool netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user); -diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.digest-backport sudo-1.8.6p7/plugins/sudoers/sssd.c ---- sudo-1.8.6p7/plugins/sudoers/sssd.c.digest-backport 2015-07-06 11:42:33.123904876 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2015-07-06 12:03:21.220149218 +0200 -@@ -812,6 +812,74 @@ sudo_sss_check_bool(struct sudo_sss_hand - } - - /* -+ * If a digest prefix is present, fills in struct sudo_digest -+ * and returns a pointer to it, updating cmnd to point to the -+ * command after the digest. -+ */ -+static struct sudo_digest * -+sudo_sss_extract_digest(char **cmnd, struct sudo_digest *digest) -+{ -+ char *ep, *cp = *cmnd; -+ int digest_type = SUDO_DIGEST_INVALID; -+ debug_decl(sudo_sss_check_command, SUDO_DEBUG_SSSD) -+ -+ /* -+ * Check for and extract a digest prefix, e.g. -+ * sha224:d06a2617c98d377c250edd470fd5e576327748d82915d6e33b5f8db1 /bin/ls -+ */ -+ if (cp[0] == 's' && cp[1] == 'h' && cp[2] == 'a') { -+ switch (cp[3]) { -+ case '2': -+ if (cp[4] == '2' && cp[5] == '4') -+ digest_type = SUDO_DIGEST_SHA224; -+ else if (cp[4] == '5' && cp[5] == '6') -+ digest_type = SUDO_DIGEST_SHA256; -+ break; -+ case '3': -+ if (cp[4] == '8' && cp[5] == '4') -+ digest_type = SUDO_DIGEST_SHA384; -+ break; -+ case '5': -+ if (cp[4] == '1' && cp[5] == '2') -+ digest_type = SUDO_DIGEST_SHA512; -+ break; -+ } -+ if (digest_type != SUDO_DIGEST_INVALID) { -+ cp += 6; -+ while (isblank((unsigned char)*cp)) -+ cp++; -+ if (*cp == ':') { -+ cp++; -+ while (isblank((unsigned char)*cp)) -+ cp++; -+ ep = cp; -+ while (*ep != '\0' && !isblank((unsigned char)*ep)) -+ ep++; -+ if (*ep != '\0') { -+ digest->digest_type = digest_type; -+ digest->digest_str = strndup(cp, (size_t)(ep - cp)); -+ if (digest->digest_str == NULL) { -+ debug_return_ptr(NULL); -+ } -+ cp = ep + 1; -+ while (isblank((unsigned char)*cp)) -+ cp++; -+ *cmnd = cp; -+ sudo_debug_printf(SUDO_DEBUG_INFO, -+ "%s digest %s for %s", -+ digest_type == SUDO_DIGEST_SHA224 ? "sha224" : -+ digest_type == SUDO_DIGEST_SHA256 ? "sha256" : -+ digest_type == SUDO_DIGEST_SHA384 ? "sha384" : -+ "sha512", digest->digest_str, cp); -+ debug_return_ptr(digest); -+ } -+ } -+ } -+ } -+ debug_return_ptr(NULL); -+} -+ -+/* - * Walk through search results and return true if we have a command match, - * false if disallowed and UNSPEC if not matched. - */ -@@ -822,6 +890,7 @@ sudo_sss_check_command(struct sudo_sss_h - char **val_array = NULL, *val; - char *allowed_cmnd, *allowed_args; - int i, foundbang, ret = UNSPEC; -+ struct sudo_digest digest, *allowed_digest = NULL; - debug_decl(sudo_sss_check_command, SUDO_DEBUG_SSSD); - - if (rule == NULL) -@@ -853,6 +922,9 @@ sudo_sss_check_command(struct sudo_sss_h - continue; - } - -+ /* check for sha-2 digest */ -+ allowed_digest = sudo_sss_extract_digest(&val, &digest); -+ - /* check for !command */ - if (*val == '!') { - foundbang = true; -@@ -868,7 +940,7 @@ sudo_sss_check_command(struct sudo_sss_h - *allowed_args++ = '\0'; - - /* check the command like normal */ -- if (command_matches(allowed_cmnd, allowed_args)) { -+ if (command_matches(allowed_cmnd, allowed_args, allowed_digest)) { - /* - * If allowed (no bang) set ret but keep on checking. - * If disallowed (bang), exit loop. -@@ -878,6 +950,8 @@ sudo_sss_check_command(struct sudo_sss_h - - sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/ldap sudoCommand '%s' ... %s", - val, ret == true ? "MATCH!" : "not"); -+ if (allowed_digest != NULL) -+ free(allowed_digest->digest_str); - efree(allowed_cmnd); /* cleanup */ - } - -diff -up sudo-1.8.6p7/plugins/sudoers/toke.c.digest-backport sudo-1.8.6p7/plugins/sudoers/toke.c ---- sudo-1.8.6p7/plugins/sudoers/toke.c.digest-backport 2015-07-06 11:42:33.114905012 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/toke.c 2015-07-06 11:42:33.135904696 +0200 -@@ -1,71 +1,114 @@ - #include --/* $OpenBSD: flex.skl,v 1.11 2010/08/04 18:24:50 millert Exp $ */ - --/* A lexical scanner generated by flex */ -+#line 3 "lex.yy.c" - --/* Scanner skeleton version: -- * $Header: /home/cvs/openbsd/src/usr.bin/lex/flex.skl,v 1.11 2010/08/04 18:24:50 millert Exp $ -- */ -+#define YY_INT_ALIGNED short int -+ -+/* A lexical scanner generated by flex */ - - #define FLEX_SCANNER - #define YY_FLEX_MAJOR_VERSION 2 - #define YY_FLEX_MINOR_VERSION 5 -+#define YY_FLEX_SUBMINOR_VERSION 37 -+#if YY_FLEX_SUBMINOR_VERSION > 0 -+#define FLEX_BETA -+#endif -+ -+/* First, we deal with platform-specific or compiler-specific issues. */ - -+/* begin standard C headers. */ - #include -+#include - #include -+#include - -+/* end standard C headers. */ - --/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ --#ifdef c_plusplus --#ifndef __cplusplus --#define __cplusplus --#endif -+/* flex integer type definitions */ -+ -+#ifndef FLEXINT_H -+#define FLEXINT_H -+ -+/* C99 systems have . Non-C99 systems may or may not. */ -+ -+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -+ -+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, -+ * if you want the limit (max/min) macros for int types. -+ */ -+#ifndef __STDC_LIMIT_MACROS -+#define __STDC_LIMIT_MACROS 1 - #endif - -+#include -+typedef int8_t flex_int8_t; -+typedef uint8_t flex_uint8_t; -+typedef int16_t flex_int16_t; -+typedef uint16_t flex_uint16_t; -+typedef int32_t flex_int32_t; -+typedef uint32_t flex_uint32_t; -+#else -+typedef signed char flex_int8_t; -+typedef short int flex_int16_t; -+typedef int flex_int32_t; -+typedef unsigned char flex_uint8_t; -+typedef unsigned short int flex_uint16_t; -+typedef unsigned int flex_uint32_t; - --#ifdef __cplusplus -+/* Limits of integral types. */ -+#ifndef INT8_MIN -+#define INT8_MIN (-128) -+#endif -+#ifndef INT16_MIN -+#define INT16_MIN (-32767-1) -+#endif -+#ifndef INT32_MIN -+#define INT32_MIN (-2147483647-1) -+#endif -+#ifndef INT8_MAX -+#define INT8_MAX (127) -+#endif -+#ifndef INT16_MAX -+#define INT16_MAX (32767) -+#endif -+#ifndef INT32_MAX -+#define INT32_MAX (2147483647) -+#endif -+#ifndef UINT8_MAX -+#define UINT8_MAX (255U) -+#endif -+#ifndef UINT16_MAX -+#define UINT16_MAX (65535U) -+#endif -+#ifndef UINT32_MAX -+#define UINT32_MAX (4294967295U) -+#endif - --#include --#include -+#endif /* ! C99 */ - --/* Use prototypes in function declarations. */ --#define YY_USE_PROTOS -+#endif /* ! FLEXINT_H */ -+ -+#ifdef __cplusplus - - /* The "const" storage-class-modifier is valid. */ - #define YY_USE_CONST - - #else /* ! __cplusplus */ - --#ifdef __STDC__ -+/* C99 requires __STDC__ to be defined as 1. */ -+#if defined (__STDC__) - --#define YY_USE_PROTOS - #define YY_USE_CONST - --#endif /* __STDC__ */ -+#endif /* defined (__STDC__) */ - #endif /* ! __cplusplus */ - --#ifdef __TURBOC__ -- #pragma warn -rch -- #pragma warn -use --#include --#include --#define YY_USE_CONST --#define YY_USE_PROTOS --#endif -- - #ifdef YY_USE_CONST - #define yyconst const - #else - #define yyconst - #endif - -- --#ifdef YY_USE_PROTOS --#define YY_PROTO(proto) proto --#else --#define YY_PROTO(proto) () --#endif -- - /* Returned upon end-of-file. */ - #define YY_NULL 0 - -@@ -80,71 +123,70 @@ - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ --#define BEGIN yy_start = 1 + 2 * -+#define BEGIN (yy_start) = 1 + 2 * - - /* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ --#define YY_START ((yy_start - 1) / 2) -+#define YY_START (((yy_start) - 1) / 2) - #define YYSTATE YY_START - - /* Action number for EOF rule of a given start state. */ - #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - - /* Special action meaning "start processing a new file". */ --#define YY_NEW_FILE yyrestart( yyin ) -+#define YY_NEW_FILE yyrestart(yyin ) - - #define YY_END_OF_BUFFER_CHAR 0 - - /* Size of default input buffer. */ -+#ifndef YY_BUF_SIZE - #define YY_BUF_SIZE 16384 -+#endif -+ -+/* The state buf must be large enough to hold one state per character in the main buffer. -+ */ -+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -+#ifndef YY_TYPEDEF_YY_BUFFER_STATE -+#define YY_TYPEDEF_YY_BUFFER_STATE - typedef struct yy_buffer_state *YY_BUFFER_STATE; -+#endif -+ -+#ifndef YY_TYPEDEF_YY_SIZE_T -+#define YY_TYPEDEF_YY_SIZE_T -+typedef size_t yy_size_t; -+#endif -+ -+extern yy_size_t yyleng; - --extern int yyleng; - extern FILE *yyin, *yyout; - - #define EOB_ACT_CONTINUE_SCAN 0 - #define EOB_ACT_END_OF_FILE 1 - #define EOB_ACT_LAST_MATCH 2 - --/* The funky do-while in the following #define is used to turn the definition -- * int a single C statement (which needs a semi-colon terminator). This -- * avoids problems with code like: -- * -- * if ( condition_holds ) -- * yyless( 5 ); -- * else -- * do_something_else(); -- * -- * Prior to using the do-while the compiler would get upset at the -- * "else" because it interpreted the "if" statement as being all -- * done when it reached the ';' after the yyless() call. -- */ -- --/* Return all but the first 'n' matched characters back to the input stream. */ -- -+ #define YY_LESS_LINENO(n) -+ -+/* Return all but the first "n" matched characters back to the input stream. */ - #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ -- *yy_cp = yy_hold_char; \ -+ int yyless_macro_arg = (n); \ -+ YY_LESS_LINENO(yyless_macro_arg);\ -+ *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ -- yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ -+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - --#define unput(c) yyunput( c, yytext_ptr ) -- --/* The following is because we cannot portably get our hands on size_t -- * (without autoconf's help, which isn't available because we want -- * flex-generated scanners to compile on their own). -- */ --typedef unsigned int yy_size_t; -- -+#define unput(c) yyunput( c, (yytext_ptr) ) - -+#ifndef YY_STRUCT_YY_BUFFER_STATE -+#define YY_STRUCT_YY_BUFFER_STATE - struct yy_buffer_state - { - FILE *yy_input_file; -@@ -160,7 +202,7 @@ struct yy_buffer_state - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ -- int yy_n_chars; -+ yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to -@@ -181,12 +223,16 @@ struct yy_buffer_state - */ - int yy_at_bol; - -+ int yy_bs_lineno; /**< The line count. */ -+ int yy_bs_column; /**< The column count. */ -+ - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -+ - #define YY_BUFFER_NEW 0 - #define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process -@@ -200,28 +246,38 @@ struct yy_buffer_state - * just pointing yyin at a new input file. - */ - #define YY_BUFFER_EOF_PENDING 2 -+ - }; -+#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - --static YY_BUFFER_STATE yy_current_buffer = 0; -+/* Stack of input buffers. */ -+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - - /* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". -+ * -+ * Returns the top of the stack, or NULL. - */ --#define YY_CURRENT_BUFFER yy_current_buffer -+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ -+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ -+ : NULL) - -+/* Same as previous macro, but useful when we know that the buffer stack is not -+ * NULL or when we need an lvalue. For internal use only. -+ */ -+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - - /* yy_hold_char holds the character lost when yytext is formed. */ - static char yy_hold_char; -- --static int yy_n_chars; /* number of characters read into yy_ch_buf */ -- -- --int yyleng; -+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ -+yy_size_t yyleng; - - /* Points to current character in buffer. */ - static char *yy_c_buf_p = (char *) 0; --static int yy_init = 1; /* whether we need to initialize */ -+static int yy_init = 0; /* whether we need to initialize */ - static int yy_start = 0; /* start state number */ - - /* Flag which is used to allow yywrap()'s to do buffer switches -@@ -229,157 +285,204 @@ static int yy_start = 0; /* start state - */ - static int yy_did_buffer_switch_on_eof; - --void yyrestart YY_PROTO(( FILE *input_file )); -- --void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); --void yy_load_buffer_state YY_PROTO(( void )); --YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); --void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); --void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); --void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); --#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) -- --YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); --YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); --YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); -- --static void *yy_flex_alloc YY_PROTO(( yy_size_t )); --static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); --static void yy_flex_free YY_PROTO(( void * )); -+void yyrestart (FILE *input_file ); -+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -+void yy_delete_buffer (YY_BUFFER_STATE b ); -+void yy_flush_buffer (YY_BUFFER_STATE b ); -+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -+void yypop_buffer_state (void ); -+ -+static void yyensure_buffer_stack (void ); -+static void yy_load_buffer_state (void ); -+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); -+ -+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) -+ -+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); -+ -+void *yyalloc (yy_size_t ); -+void *yyrealloc (void *,yy_size_t ); -+void yyfree (void * ); - - #define yy_new_buffer yy_create_buffer - - #define yy_set_interactive(is_interactive) \ - { \ -- if ( ! yy_current_buffer ) \ -- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ -- yy_current_buffer->yy_is_interactive = is_interactive; \ -+ if ( ! YY_CURRENT_BUFFER ){ \ -+ yyensure_buffer_stack (); \ -+ YY_CURRENT_BUFFER_LVALUE = \ -+ yy_create_buffer(yyin,YY_BUF_SIZE ); \ -+ } \ -+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - - #define yy_set_bol(at_bol) \ - { \ -- if ( ! yy_current_buffer ) \ -- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ -- yy_current_buffer->yy_at_bol = at_bol; \ -+ if ( ! YY_CURRENT_BUFFER ){\ -+ yyensure_buffer_stack (); \ -+ YY_CURRENT_BUFFER_LVALUE = \ -+ yy_create_buffer(yyin,YY_BUF_SIZE ); \ -+ } \ -+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - --#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) -+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -+/* Begin user sect3 */ - - #define yywrap() 1 - #define YY_SKIP_YYWRAP -+ - typedef unsigned char YY_CHAR; -+ - FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -+ - typedef int yy_state_type; -+ -+extern int yylineno; -+ -+int yylineno = 1; -+ - extern char *yytext; - #define yytext_ptr yytext - --static yy_state_type yy_get_previous_state YY_PROTO(( void )); --static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); --static int yy_get_next_buffer YY_PROTO(( void )); --static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); -+static yy_state_type yy_get_previous_state (void ); -+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -+static int yy_get_next_buffer (void ); -+static void yy_fatal_error (yyconst char msg[] ); - - /* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ - #define YY_DO_BEFORE_ACTION \ -- yytext_ptr = yy_bp; \ -- yyleng = (int) (yy_cp - yy_bp); \ -- yy_hold_char = *yy_cp; \ -+ (yytext_ptr) = yy_bp; \ -+ yyleng = (size_t) (yy_cp - yy_bp); \ -+ (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ -- yy_c_buf_p = yy_cp; -+ (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 61 --#define YY_END_OF_BUFFER 62 --static yyconst short int yy_accept[622] = -+#define YY_NUM_RULES 67 -+#define YY_END_OF_BUFFER 68 -+/* This struct is not used in this scanner, -+ but its presence is necessary. */ -+struct yy_trans_info -+ { -+ flex_int32_t yy_verify; -+ flex_int32_t yy_nxt; -+ }; -+static yyconst flex_int16_t yy_accept[814] = - { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 62, 49, 57, 56, 55, 48, 60, 32, -- 50, 51, 32, 52, 49, 49, 49, 49, 54, 53, -- 60, 44, 44, 44, 44, 44, 44, 44, 44, 44, -- 44, 60, 49, 49, 57, 60, 44, 44, 44, 44, -- 44, 2, 60, 1, 49, 44, 44, 49, 17, 16, -- 17, 16, 16, 60, 60, 60, 3, 9, 8, 9, -- 4, 9, 5, 60, 13, 13, 13, 11, 12, 49, -- 0, 57, 55, 0, 59, 0, 49, 34, 0, 32, -- 0, 33, 0, 47, 47, 0, 49, 49, 0, 49, -- -- 49, 49, 49, 0, 37, 44, 44, 44, 44, 44, -- 44, 44, 44, 44, 44, 44, 44, 49, 58, 49, -- 57, 0, 0, 0, 0, 0, 0, 49, 49, 49, -- 49, 49, 2, 1, 0, 1, 45, 45, 0, 49, -- 17, 17, 15, 14, 15, 0, 0, 3, 9, 0, -- 6, 7, 9, 9, 13, 0, 13, 13, 0, 10, -- 0, 0, 0, 34, 34, 0, 0, 49, 49, 49, -- 49, 49, 0, 0, 37, 37, 44, 39, 44, 44, -- 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, -- 49, 0, 0, 0, 0, 0, 0, 49, 49, 49, -- -- 49, 49, 0, 49, 10, 0, 49, 49, 49, 49, -- 49, 49, 0, 38, 38, 38, 0, 0, 37, 37, -- 37, 37, 37, 37, 37, 44, 44, 44, 44, 44, -- 44, 44, 44, 44, 44, 40, 44, 41, 49, 0, -- 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, -- 49, 49, 0, 0, 38, 38, 38, 0, 37, 37, -- 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, -- 37, 37, 0, 25, 44, 44, 44, 44, 44, 44, -- 44, 44, 42, 44, 49, 0, 0, 0, 0, 49, -- 49, 49, 49, 49, 49, 49, 49, 0, 38, 0, -- -- 37, 37, 37, 0, 0, 0, 37, 37, 37, 37, -- 37, 37, 37, 37, 37, 37, 37, 37, 37, 44, -- 44, 44, 44, 44, 44, 44, 44, 44, 49, 0, -- 0, 0, 49, 49, 49, 35, 35, 35, 0, 0, -- 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, -- 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, -- 37, 37, 37, 37, 37, 37, 44, 44, 44, 0, -- 24, 44, 44, 44, 44, 0, 23, 0, 26, 49, -- 0, 0, 0, 49, 49, 49, 49, 35, 35, 35, -- 35, 0, 37, 0, 37, 37, 37, 37, 37, 37, -- -- 37, 37, 37, 37, 37, 0, 0, 0, 37, 37, -- 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -- 37, 44, 44, 44, 44, 44, 44, 44, 46, 0, -- 0, 0, 49, 20, 45, 36, 36, 36, 36, 37, -- 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, -- 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, -- 0, 37, 37, 37, 37, 37, 37, 37, 37, 44, -- 44, 44, 44, 44, 0, 22, 0, 27, 0, 20, -- 0, 0, 49, 0, 49, 49, 49, 36, 36, 36, -- 36, 0, 0, 0, 0, 0, 37, 37, 37, 37, -+ 0, 0, 0, 0, 68, 55, 63, 62, 61, 54, -+ 66, 34, 56, 57, 34, 58, 55, 55, 55, 55, -+ 60, 59, 66, 46, 46, 46, 46, 46, 46, 46, -+ 46, 46, 46, 66, 55, 55, 63, 66, 46, 46, -+ 46, 46, 46, 2, 66, 1, 55, 46, 46, 55, -+ 17, 16, 17, 16, 16, 66, 66, 66, 3, 9, -+ 8, 9, 4, 9, 5, 66, 13, 13, 13, 11, -+ 12, 66, 19, 19, 18, 18, 18, 19, 18, 18, -+ 18, 19, 19, 19, 19, 19, 18, 19, 19, 55, -+ -+ 0, 63, 61, 0, 65, 0, 55, 36, 0, 34, -+ 0, 35, 0, 53, 53, 0, 55, 55, 0, 55, -+ 55, 55, 55, 0, 39, 46, 46, 46, 46, 46, -+ 46, 46, 46, 46, 46, 46, 46, 55, 64, 55, -+ 55, 63, 0, 0, 0, 0, 0, 0, 55, 55, -+ 55, 55, 55, 2, 1, 0, 1, 47, 47, 0, -+ 55, 17, 17, 15, 14, 15, 0, 0, 3, 9, -+ 0, 6, 7, 9, 9, 13, 0, 13, 13, 0, -+ 10, 36, 0, 0, 35, 19, 19, 0, 19, 0, -+ 0, 18, 18, 18, 18, 18, 18, 19, 19, 46, -+ -+ 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, -+ 36, 55, 55, 55, 55, 55, 0, 0, 39, 39, -+ 46, 41, 46, 46, 46, 46, 46, 46, 46, 46, -+ 46, 46, 46, 46, 55, 55, 0, 0, 0, 0, -+ 0, 0, 55, 55, 55, 55, 55, 0, 55, 10, -+ 0, 0, 0, 18, 18, 18, 19, 19, 19, 19, -+ 19, 19, 19, 19, 19, 19, 19, 0, 55, 55, -+ 55, 55, 55, 55, 0, 40, 40, 40, 0, 0, -+ 39, 39, 39, 39, 39, 39, 39, 46, 46, 46, -+ 46, 46, 46, 46, 46, 46, 46, 42, 46, 43, -+ -+ 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, -+ 55, 55, 55, 55, 0, 0, 0, 0, 0, 18, -+ 18, 19, 46, 19, 19, 19, 19, 19, 19, 19, -+ 19, 19, 19, 55, 55, 55, 0, 0, 40, 40, -+ 40, 0, 39, 39, 0, 39, 39, 39, 39, 39, -+ 39, 39, 39, 39, 39, 39, 0, 27, 46, 46, -+ 46, 46, 46, 46, 46, 46, 44, 46, 55, 55, -+ 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, -+ 0, 0, 0, 18, 18, 46, 46, 19, 19, 19, -+ 19, 19, 19, 19, 19, 19, 19, 19, 55, 55, -+ -+ 55, 55, 55, 0, 40, 0, 39, 39, 39, 0, -+ 0, 0, 39, 39, 39, 39, 39, 39, 39, 39, -+ 39, 39, 39, 39, 39, 46, 46, 46, 46, 46, -+ 46, 46, 46, 46, 48, 49, 50, 51, 55, 0, -+ 0, 0, 55, 55, 55, 0, 0, 0, 0, 0, -+ 46, 46, 19, 46, 19, 19, 19, 19, 19, 19, -+ 19, 19, 19, 37, 37, 37, 0, 0, 39, 39, -+ 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, -+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -+ 39, 39, 39, 39, 46, 46, 46, 0, 26, 46, -+ -+ 46, 46, 46, 0, 25, 0, 28, 55, 0, 0, -+ 0, 55, 55, 55, 37, 37, 37, 46, 46, 46, -+ 46, 19, 19, 19, 55, 37, 37, 37, 37, 0, -+ 39, 0, 39, 39, 39, 39, 39, 39, 39, 39, -+ 39, 39, 39, 0, 0, 0, 39, 39, 39, 39, -+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 46, -+ 46, 46, 46, 46, 46, 46, 52, 0, 0, 0, -+ 55, 22, 47, 0, 37, 37, 37, 37, 46, 46, -+ 46, 46, 19, 19, 19, 38, 38, 38, 38, 39, -+ 0, 0, 0, 39, 39, 39, 39, 39, 39, 39, -+ -+ 39, 39, 39, 39, 39, 39, 0, 0, 0, 0, -+ 0, 39, 39, 39, 39, 39, 39, 39, 39, 46, -+ 46, 46, 46, 46, 0, 24, 0, 29, 0, 22, -+ 0, 0, 55, 0, 55, 38, 38, 38, 38, 46, -+ 46, 46, 46, 55, 55, 38, 38, 38, 38, 0, -+ 0, 0, 0, 0, 39, 39, 39, 39, 39, 39, -+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -+ 39, 39, 39, 39, 45, 0, 32, 46, 46, 46, -+ 0, 0, 0, 20, 0, 23, 22, 0, 0, 0, -+ 0, 0, 22, 0, 0, 0, 38, 38, 38, 38, -+ -+ 46, 46, 46, 55, 55, 55, 0, 0, 0, 39, -+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, -+ 39, 39, 39, 39, 39, 39, 39, 0, 30, 46, -+ 46, 23, 0, 0, 22, 0, 0, 0, 46, 46, -+ 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, -+ 39, 39, 39, 39, 39, 39, 39, 39, 0, 33, -+ 46, 0, 0, 0, 0, 0, 0, 46, 55, 55, -+ 55, 39, 39, 39, 39, 39, 39, 0, 31, 0, -+ 0, 21, 0, 0, 0, 55, 55, 55, 55, 55, -+ 39, 39, 39, 39, 39, 0, 0, 0, 0, 0, - - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -- 37, 37, 37, 37, 37, 37, 43, 0, 30, 44, -- 44, 44, 0, 0, 0, 18, 0, 21, 20, 0, -- 0, 0, 0, 0, 20, 0, 49, 49, 49, 0, -- 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, -- 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, -- 0, 28, 44, 44, 21, 0, 0, 20, 49, 49, -- 49, 49, 49, 0, 0, 0, 0, 0, 37, 37, -- 37, 37, 37, 37, 37, 37, 0, 31, 44, 0, -- 49, 49, 49, 37, 37, 37, 37, 37, 37, 0, -- -- 29, 0, 0, 19, 49, 49, 49, 49, 49, 37, -- 37, 37, 37, 37, 35, 35, 35, 35, 35, 35, -- 0 -+ 37, 37, 0 - } ; - --static yyconst int yy_ec[256] = -+static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 6, 1, 7, 1, 1, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -- 19, 20, 21, 22, 22, 22, 23, 24, 1, 1, -- 25, 26, 10, 27, 28, 29, 30, 31, 32, 29, -- 33, 34, 35, 36, 36, 37, 38, 39, 40, 41, -- 36, 42, 43, 44, 45, 46, 47, 48, 49, 36, -- 10, 50, 10, 1, 51, 1, 52, 53, 54, 55, -- -- 56, 57, 58, 58, 59, 58, 58, 60, 61, 62, -- 63, 58, 58, 64, 65, 66, 67, 58, 58, 58, -- 58, 58, 1, 1, 1, 1, 1, 1, 1, 1, -+ 19, 20, 21, 22, 23, 24, 25, 26, 1, 1, -+ 27, 28, 10, 29, 30, 31, 32, 33, 34, 31, -+ 35, 36, 37, 38, 38, 39, 40, 41, 42, 43, -+ 38, 44, 45, 46, 47, 48, 49, 50, 51, 38, -+ 10, 52, 10, 1, 53, 1, 54, 55, 56, 57, -+ -+ 58, 59, 60, 61, 62, 60, 60, 63, 64, 65, -+ 66, 60, 60, 67, 68, 69, 70, 60, 60, 60, -+ 60, 60, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -396,583 +499,858 @@ static yyconst int yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst int yy_meta[68] = -+static yyconst flex_int32_t yy_meta[71] = - { 0, - 1, 2, 3, 4, 5, 6, 1, 7, 7, 1, -- 1, 8, 1, 9, 10, 11, 11, 11, 11, 11, -- 11, 11, 11, 12, 13, 7, 1, 11, 11, 11, -- 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, -- 15, 16, 16, 16, 16, 16, 16, 15, 15, 15, -- 15, 15, 15, 15, 15, 15, 15 -+ 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, -+ 13, 13, 13, 13, 13, 14, 15, 7, 1, 16, -+ 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, -+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, -+ 17, 18, 19, 20, 20, 20, 20, 20, 20, 21, -+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21 - } ; - --static yyconst short int yy_base[686] = -+static yyconst flex_int16_t yy_base[931] = - { 0, -- 0, 66, 68, 76, 119, 124, 173, 239, 148, 197, -- 82, 90, 2937, 2886, 2933, 3595, 2929, 3595, 165, 65, -- 3595, 3595, 2882, 3595, 130, 293, 173, 146, 2907, 3595, -- 3595, 350, 2893, 42, 402, 41, 2889, 74, 2888, 2895, -- 2876, 458, 197, 57, 219, 482, 38, 207, 2854, 37, -- 2851, 117, 249, 2880, 326, 2841, 2852, 105, 0, 3595, -- 2875, 3595, 0, 469, 424, 143, 0, 2828, 3595, 48, -- 3595, 223, 3595, 155, 2827, 202, 97, 3595, 252, 2817, -- 504, 2855, 2852, 2852, 3595, 258, 504, 312, 526, 201, -- 548, 2796, 557, 528, 2795, 582, 579, 614, 2820, 2829, -- -- 593, 601, 266, 2818, 182, 656, 0, 2796, 2791, 2766, -- 2761, 296, 2727, 2725, 2713, 2696, 2691, 426, 3595, 87, -- 659, 2659, 2663, 2655, 2650, 2651, 257, 196, 318, 276, -- 258, 288, 436, 2694, 631, 2693, 655, 2644, 690, 303, -- 0, 2681, 168, 3595, 3595, 701, 352, 0, 2634, 723, -- 3595, 3595, 2633, 447, 2632, 2676, 467, 461, 433, 2670, -- 2659, 2600, 720, 733, 206, 755, 759, 771, 781, 791, -- 828, 2581, 2570, 870, 453, 913, 955, 0, 2563, 2557, -- 2540, 2523, 2530, 2541, 2536, 2516, 2502, 2496, 2475, 2473, -- 277, 2442, 2436, 2402, 2404, 2407, 477, 436, 2405, 424, -- -- 401, 292, 813, 488, 2454, 2450, 845, 438, 855, 890, -- 756, 465, 2428, 2418, 930, 554, 2409, 2408, 463, 898, -- 999, 939, 972, 1042, 980, 2403, 490, 2378, 500, 2380, -- 2338, 2327, 2325, 2321, 2310, 0, 2305, 0, 508, 2274, -- 2238, 2212, 2211, 2176, 515, 517, 615, 527, 529, 1018, -- 1061, 1086, 2212, 2210, 1026, 2209, 2203, 2171, 2166, 565, -- 1069, 754, 1096, 802, 1123, 0, 1106, 1134, 1151, 1159, -- 1177, 1196, 601, 3595, 2136, 2137, 2127, 2131, 2090, 2090, -- 2084, 2078, 0, 2062, 607, 2056, 2024, 2025, 573, 576, -- 578, 676, 1204, 591, 1221, 1239, 1231, 2064, 2031, 2006, -- -- 2004, 1274, 676, 1256, 1293, 1318, 682, 808, 815, 1301, -- 819, 1328, 0, 1339, 1350, 1367, 1247, 1393, 1377, 1955, -- 1915, 1888, 742, 692, 1884, 1891, 794, 980, 777, 1889, -- 1856, 652, 945, 680, 820, 1411, 1420, 1436, 1842, 1824, -- 1800, 1446, 1473, 1455, 1266, 1515, 1492, 1500, 1809, 1534, -- 1559, 1544, 1009, 1052, 1569, 1571, 1580, 1590, 1601, 0, -- 1612, 1623, 1590, 1463, 1666, 1642, 1762, 1737, 1740, 1108, -- 3595, 1696, 1672, 1662, 1628, 1157, 3595, 1158, 3595, 774, -- 1514, 1500, 730, 1152, 697, 913, 1650, 805, 1686, 1709, -- 1695, 1516, 1500, 1721, 1222, 1730, 1474, 1744, 0, 830, -- -- 1755, 1772, 1571, 1797, 1782, 1816, 1841, 1851, 1284, 1377, -- 1832, 1861, 1861, 1872, 1883, 0, 1894, 1905, 1872, 1824, -- 1924, 1414, 1400, 1375, 1336, 1331, 1159, 1483, 1312, 1274, -- 1260, 1539, 606, 1730, 1238, 1949, 1959, 1969, 1984, 1256, -- 1994, 2004, 2019, 1245, 1535, 1915, 1932, 1950, 2029, 0, -- 874, 2040, 2057, 2065, 2082, 2101, 2109, 1214, 2126, 2136, -- 2146, 1633, 1675, 2154, 924, 966, 2165, 0, 1003, 1092, -- 1731, 1087, 1056, 1052, 2042, 3595, 2063, 3595, 1017, 2147, -- 1126, 624, 1311, 2187, 2192, 2183, 1756, 2193, 2203, 2230, -- 1979, 2238, 992, 2248, 2265, 2275, 830, 811, 1970, 2194, -- -- 2281, 2214, 2291, 0, 1111, 2302, 2319, 2256, 2344, 2329, -- 2362, 2371, 2387, 1807, 813, 1170, 0, 2065, 3595, 2228, -- 738, 713, 680, 731, 1201, 3595, 900, 653, 2409, 2414, -- 2419, 2424, 2418, 2436, 2445, 2446, 2459, 2469, 2480, 2494, -- 2504, 2515, 569, 531, 2215, 2217, 2523, 2221, 2533, 0, -- 1278, 2544, 2561, 2569, 2588, 519, 2597, 2606, 2615, 492, -- 2304, 3595, 2393, 452, 3595, 1416, 2621, 2629, 2637, 1981, -- 2647, 2657, 2672, 2682, 345, 2692, 2707, 2717, 305, 264, -- 2303, 245, 191, 2725, 0, 1477, 2441, 3595, 2444, 1632, -- 2735, 2745, 2755, 2770, 2780, 2790, 90, 0, 92, 2482, -- -- 3595, 100, 1647, 3595, 2798, 1982, 2808, 2818, 2833, 3595, -- 2843, 2853, 2763, 3595, 2868, 2876, 2884, 19, 2892, 2903, -- 3595, 2953, 2969, 2985, 3001, 3017, 3033, 3049, 3065, 3081, -- 3087, 3103, 3119, 1676, 3135, 3151, 3167, 3183, 3199, 3215, -- 3231, 3237, 3244, 3260, 3276, 3282, 3289, 3295, 3301, 3307, -- 3314, 3320, 3326, 3332, 3339, 3347, 3353, 3359, 3365, 3372, -- 3380, 3386, 3392, 3399, 3407, 3413, 3421, 3428, 3436, 3442, -- 3450, 3457, 3465, 3481, 3497, 3513, 3519, 3527, 3534, 3540, -- 3548, 3554, 3562, 3578, 2159 -+ 0, 69, 71, 79, 94, 124, 175, 244, 153, 197, -+ 85, 130, 314, 0, 4514, 4461, 4510, 5604, 4507, 5604, -+ 382, 86, 5604, 5604, 4458, 5604, 140, 394, 195, 153, -+ 4483, 5604, 5604, 453, 4383, 43, 508, 37, 4379, 65, -+ 4378, 4385, 4367, 566, 581, 91, 151, 604, 39, 41, -+ 4351, 34, 4348, 117, 4402, 4412, 428, 4371, 4382, 136, -+ 0, 5604, 4407, 5604, 0, 606, 664, 105, 0, 4358, -+ 5604, 115, 5604, 133, 5604, 138, 4357, 152, 171, 5604, -+ 188, 383, 641, 694, 737, 235, 245, 794, 843, 4369, -+ 157, 898, 4365, 4364, 4375, 4370, 944, 0, 206, 4351, -+ -+ 266, 4400, 4397, 4397, 5604, 263, 532, 585, 4386, 608, -+ 707, 4346, 829, 648, 4345, 968, 981, 1018, 4359, 4370, -+ 563, 708, 422, 4357, 371, 1062, 1106, 4343, 4347, 4340, -+ 4344, 596, 4333, 4340, 4337, 4329, 4331, 644, 5604, 237, -+ 137, 946, 4309, 4314, 4305, 4300, 4301, 121, 225, 530, -+ 377, 369, 335, 445, 4366, 720, 4365, 931, 4314, 1018, -+ 169, 0, 4361, 160, 5604, 5604, 991, 388, 0, 4312, -+ 638, 5604, 5604, 4311, 661, 4310, 4356, 392, 221, 420, -+ 4358, 653, 665, 1139, 4296, 1145, 0, 1173, 1201, 1210, -+ 1037, 1239, 4333, 1081, 1170, 826, 1288, 1343, 4307, 0, -+ -+ 4311, 4309, 899, 4298, 4296, 4287, 4283, 4336, 4335, 1222, -+ 1258, 1389, 1362, 968, 1428, 4323, 4310, 1472, 520, 1517, -+ 1561, 1605, 4303, 4297, 4280, 4282, 4289, 4300, 4295, 4283, -+ 4279, 4292, 4291, 4290, 654, 493, 4258, 4252, 4242, 4244, -+ 4250, 534, 579, 4253, 491, 407, 506, 1413, 626, 4304, -+ 4251, 4239, 1651, 1661, 4227, 1705, 0, 4197, 4164, 4155, -+ 4151, 4151, 4135, 4112, 4111, 811, 4067, 4122, 1749, 378, -+ 0, 0, 1041, 243, 4098, 4097, 1786, 805, 4096, 4095, -+ 623, 1410, 1799, 1447, 1091, 1844, 1890, 4094, 429, 4073, -+ 632, 4084, 4082, 4056, 4054, 4050, 4053, 0, 4046, 0, -+ -+ 929, 638, 544, 561, 4022, 4024, 4008, 4022, 4008, 746, -+ 524, 1063, 413, 662, 1491, 4060, 4059, 4058, 1270, 1900, -+ 1944, 763, 904, 4037, 4020, 4009, 4007, 3992, 3988, 818, -+ 3993, 3988, 3912, 1990, 2002, 2014, 3930, 3929, 2024, 3929, -+ 3912, 3911, 3910, 919, 1536, 1003, 1580, 1142, 2037, 0, -+ 1626, 2083, 1680, 1372, 2128, 2174, 764, 5604, 3892, 3877, -+ 3870, 3884, 3862, 3869, 3879, 3879, 0, 3863, 698, 593, -+ 820, 973, 1093, 3857, 3824, 3825, 922, 897, 969, 1097, -+ 3866, 3858, 2186, 2196, 3829, 3807, 3800, 3814, 3778, 3784, -+ 3794, 3793, 3747, 3726, 3716, 3711, 3696, 3656, 2240, 1017, -+ -+ 2279, 2291, 1637, 3686, 3662, 3648, 3646, 2301, 1127, 3642, -+ 3641, 2347, 1154, 1205, 1209, 1724, 1761, 2359, 0, 1763, -+ 2405, 1774, 1457, 2450, 2496, 2521, 1024, 1127, 1181, 1190, -+ 1169, 1207, 1224, 1392, 3602, 3584, 3577, 3560, 1240, 3581, -+ 3547, 1313, 1391, 874, 1774, 1821, 3584, 3576, 3569, 1503, -+ 3523, 3519, 869, 1379, 3515, 3511, 949, 1045, 0, 0, -+ 0, 0, 3478, 2577, 1863, 1546, 3510, 3509, 3506, 1919, -+ 2616, 1963, 1590, 2660, 2706, 2056, 3517, 3509, 3487, 1692, -+ 1879, 1979, 2096, 2104, 2147, 2106, 2718, 0, 2217, 2764, -+ 2250, 1734, 2809, 2855, 2880, 2086, 1133, 1088, 5604, 421, -+ -+ 2087, 1184, 2088, 1369, 5604, 1370, 5604, 1197, 3418, 3389, -+ 1282, 2127, 1249, 1368, 3442, 3427, 2936, 3386, 3320, 3309, -+ 3295, 2951, 1219, 3272, 3006, 1181, 3044, 0, 1709, 3290, -+ 3263, 2260, 58, 2320, 1774, 3083, 0, 2380, 3129, 2424, -+ 1831, 3173, 3219, 3270, 3265, 3231, 2336, 2462, 2464, 2471, -+ 3256, 2477, 3243, 0, 2589, 3289, 2600, 1929, 3335, 3360, -+ 1376, 1087, 1847, 1409, 1542, 1586, 3218, 3184, 3166, 1832, -+ 1427, 2060, 3174, 2635, 3210, 3186, 3185, 2435, 3129, 3111, -+ 3114, 3066, 3429, 1454, 0, 3486, 2679, 2737, 1483, 3085, -+ 2989, 2839, 3525, 2819, 2003, 2280, 2783, 2381, 3537, 0, -+ -+ 2830, 3583, 3016, 2157, 3627, 3673, 3026, 2821, 2801, 2750, -+ 2228, 2472, 2474, 2695, 1189, 1531, 3685, 0, 2647, 1848, -+ 1925, 1602, 1522, 1849, 1587, 5604, 1664, 5604, 2692, 1967, -+ 1630, 2177, 2014, 2406, 2761, 2674, 2630, 3731, 2272, 1926, -+ 2155, 2500, 1927, 3741, 2076, 3780, 0, 1967, 2277, 3054, -+ 2598, 2535, 2509, 2841, 2470, 2431, 2485, 2600, 3064, 2617, -+ 3819, 0, 3104, 3865, 3148, 3036, 3909, 3955, 2390, 2373, -+ 3966, 3118, 2338, 1742, 2298, 2129, 5604, 2743, 1825, 1738, -+ 2219, 2153, 1825, 5604, 2062, 2083, 3130, 3172, 3276, 3281, -+ 1984, 2880, 1920, 3360, 3192, 1912, 1877, 1858, 3274, 1744, -+ -+ 2326, 2643, 2745, 3978, 3990, 4002, 1700, 1693, 4014, 1662, -+ 1623, 2856, 2951, 3496, 3084, 4026, 0, 3508, 4072, 3556, -+ 3074, 0, 1599, 1510, 1503, 3319, 1423, 2328, 5604, 3154, -+ 2037, 5604, 2124, 3602, 3646, 1409, 1403, 4118, 2407, 2791, -+ 4130, 2334, 4142, 4154, 3659, 3704, 1390, 1286, 1251, 3418, -+ 1158, 1087, 3105, 1077, 1056, 4166, 0, 3568, 2499, 5604, -+ 3270, 2220, 3751, 1014, 1005, 957, 3614, 2522, 4178, 4190, -+ 4202, 3761, 3790, 3800, 684, 0, 683, 2685, 5604, 658, -+ 2222, 5604, 522, 382, 4214, 4226, 2335, 4238, 4250, 3840, -+ 5604, 3846, 3884, 3202, 5604, 3928, 374, 208, 117, 3716, -+ -+ 4260, 4297, 4334, 4045, 4091, 4270, 59, 4371, 3941, 5604, -+ 4280, 3771, 5604, 4423, 4444, 4465, 4486, 4507, 4528, 4549, -+ 4570, 4591, 4600, 2074, 4620, 4641, 2383, 4662, 4683, 4704, -+ 4725, 4746, 4767, 4788, 4809, 2337, 4830, 4839, 4847, 4856, -+ 4876, 4897, 4918, 2474, 4939, 4960, 4981, 5002, 5011, 5030, -+ 5039, 5048, 2421, 2516, 5056, 5064, 5072, 5081, 5089, 5096, -+ 5104, 5112, 5121, 5131, 2600, 2694, 5139, 5147, 5155, 2695, -+ 2757, 5164, 5174, 5194, 2798, 5203, 5211, 2799, 5220, 5230, -+ 5250, 2228, 2615, 5259, 5271, 5280, 5290, 2803, 2825, 5299, -+ 5309, 5318, 5338, 2700, 5347, 5359, 2841, 2872, 5368, 5378, -+ -+ 2873, 5387, 5397, 5417, 5438, 5459, 3115, 3116, 5479, 3168, -+ 5486, 5496, 2951, 2967, 5505, 2520, 5525, 3304, 3313, 5534, -+ 5544, 3517, 3314, 3318, 5552, 5562, 5582, 3814, 3319, 3430 - } ; - --static yyconst short int yy_def[686] = -+static yyconst flex_int16_t yy_def[931] = - { 0, -- 621, 1, 1, 1, 622, 622, 623, 623, 624, 624, -- 625, 625, 621, 626, 621, 621, 621, 621, 627, 628, -- 621, 621, 629, 621, 630, 626, 26, 26, 631, 621, -- 621, 621, 32, 32, 32, 35, 35, 35, 35, 35, -- 35, 626, 26, 626, 621, 627, 32, 32, 35, 35, -- 35, 621, 621, 621, 632, 35, 35, 626, 633, 621, -- 633, 621, 633, 621, 627, 621, 634, 635, 621, 635, -- 621, 635, 621, 636, 637, 637, 637, 621, 621, 626, -- 626, 621, 621, 638, 621, 639, 621, 628, 621, 640, -- 628, 629, 629, 630, 641, 626, 626, 26, 631, 98, -- -- 98, 98, 98, 642, 643, 35, 35, 35, 35, 35, -- 35, 35, 35, 35, 35, 35, 35, 626, 621, 626, -- 621, 621, 621, 621, 621, 621, 638, 626, 98, 626, -- 626, 626, 621, 621, 621, 621, 632, 644, 626, 626, -- 633, 633, 621, 621, 621, 639, 621, 634, 635, 635, -- 621, 621, 635, 635, 637, 621, 637, 637, 621, 621, -- 638, 645, 621, 621, 640, 640, 621, 626, 626, 626, -- 98, 171, 646, 621, 647, 621, 106, 35, 35, 35, -- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -- 626, 621, 621, 621, 621, 621, 638, 626, 171, 626, -- -- 626, 626, 621, 626, 621, 645, 626, 626, 626, 626, -- 626, 626, 648, 649, 649, 215, 650, 649, 651, 176, -- 621, 221, 221, 621, 221, 35, 35, 35, 35, 35, -- 35, 35, 35, 35, 35, 35, 35, 35, 626, 621, -- 621, 621, 621, 621, 638, 626, 626, 626, 626, 626, -- 626, 626, 621, 652, 652, 255, 652, 653, 654, 655, -- 621, 656, 224, 656, 656, 265, 656, 621, 268, 268, -- 621, 268, 621, 621, 35, 35, 35, 35, 35, 35, -- 35, 35, 35, 35, 626, 621, 621, 621, 638, 626, -- 626, 626, 626, 626, 626, 626, 626, 657, 657, 658, -- -- 659, 621, 621, 621, 621, 621, 660, 660, 661, 271, -- 661, 661, 312, 661, 621, 315, 315, 621, 315, 35, -- 35, 35, 35, 35, 35, 35, 35, 35, 626, 621, -- 621, 638, 626, 626, 626, 626, 626, 626, 621, 662, -- 663, 302, 621, 343, 343, 621, 343, 621, 621, 621, -- 621, 621, 621, 664, 664, 665, 318, 665, 665, 359, -- 665, 621, 362, 362, 621, 362, 35, 35, 35, 621, -- 621, 35, 35, 35, 35, 621, 621, 621, 621, 626, -- 621, 621, 638, 626, 626, 626, 626, 626, 626, 626, -- 626, 621, 666, 621, 667, 346, 667, 667, 398, 398, -- -- 621, 401, 401, 621, 401, 621, 621, 621, 621, 668, -- 668, 669, 365, 669, 669, 415, 669, 621, 418, 418, -- 418, 35, 35, 35, 35, 35, 35, 35, 626, 621, -- 621, 638, 626, 626, 626, 626, 626, 626, 626, 621, -- 621, 621, 621, 670, 670, 671, 404, 671, 671, 449, -- 449, 621, 452, 452, 621, 452, 621, 621, 621, 621, -- 621, 621, 672, 672, 673, 673, 673, 467, 467, 35, -- 35, 35, 35, 35, 621, 621, 621, 621, 621, 621, -- 674, 638, 626, 675, 676, 626, 626, 626, 626, 626, -- 626, 621, 621, 621, 621, 621, 621, 677, 677, 678, -- -- 455, 678, 678, 503, 503, 621, 506, 506, 621, 506, -- 621, 621, 621, 621, 679, 679, 35, 621, 621, 35, -- 35, 35, 621, 674, 674, 621, 638, 626, 675, 675, -- 675, 675, 621, 675, 676, 676, 626, 626, 626, 621, -- 621, 621, 621, 680, 680, 681, 509, 681, 681, 549, -- 549, 621, 552, 552, 552, 621, 621, 621, 621, 621, -- 621, 621, 35, 35, 621, 638, 621, 621, 626, 626, -- 626, 626, 626, 621, 621, 621, 621, 621, 621, 682, -- 682, 683, 683, 683, 584, 584, 621, 621, 35, 684, -- 626, 626, 626, 621, 621, 621, 621, 685, 685, 621, -- -- 621, 684, 684, 621, 626, 626, 626, 626, 626, 621, -- 621, 621, 621, 621, 626, 626, 626, 626, 626, 626, -- 0, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621 -+ 813, 1, 1, 1, 814, 814, 815, 815, 816, 816, -+ 817, 817, 813, 13, 813, 818, 813, 813, 813, 813, -+ 819, 820, 813, 813, 821, 813, 822, 818, 28, 28, -+ 823, 813, 813, 813, 34, 34, 34, 37, 37, 37, -+ 37, 37, 37, 818, 28, 818, 813, 819, 34, 34, -+ 37, 37, 37, 813, 824, 813, 825, 37, 37, 818, -+ 826, 813, 826, 813, 826, 813, 819, 813, 827, 828, -+ 813, 828, 813, 828, 813, 829, 830, 830, 830, 813, -+ 813, 831, 832, 833, 813, 85, 85, 85, 813, 89, -+ 89, 89, 92, 92, 92, 92, 85, 88, 88, 818, -+ -+ 818, 813, 813, 834, 813, 835, 813, 820, 836, 831, -+ 820, 821, 821, 822, 837, 818, 818, 28, 838, 118, -+ 118, 118, 118, 839, 840, 37, 126, 127, 127, 127, -+ 127, 127, 127, 127, 127, 127, 127, 818, 813, 818, -+ 818, 813, 813, 813, 813, 813, 813, 834, 818, 118, -+ 818, 818, 818, 813, 813, 813, 813, 841, 842, 818, -+ 818, 843, 843, 813, 813, 813, 835, 813, 844, 845, -+ 845, 813, 813, 845, 845, 830, 813, 830, 830, 813, -+ 813, 831, 831, 831, 846, 847, 88, 846, 848, 813, -+ 813, 85, 192, 192, 192, 192, 813, 197, 198, 849, -+ -+ 198, 198, 198, 198, 198, 88, 88, 834, 850, 813, -+ 813, 818, 212, 212, 118, 215, 851, 813, 852, 813, -+ 127, 221, 222, 222, 222, 222, 222, 222, 222, 222, -+ 222, 222, 222, 222, 818, 818, 813, 813, 813, 813, -+ 813, 834, 818, 215, 818, 818, 818, 813, 818, 813, -+ 853, 854, 813, 88, 254, 197, 198, 198, 198, 198, -+ 198, 198, 198, 198, 198, 88, 88, 850, 818, 818, -+ 212, 212, 212, 818, 855, 856, 856, 277, 857, 856, -+ 858, 220, 813, 283, 283, 813, 283, 222, 222, 222, -+ 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, -+ -+ 818, 818, 818, 818, 813, 813, 813, 813, 813, 834, -+ 818, 818, 818, 818, 813, 813, 853, 853, 813, 254, -+ 197, 198, 859, 198, 198, 198, 198, 198, 198, 88, -+ 88, 88, 88, 212, 212, 212, 813, 860, 860, 339, -+ 860, 861, 862, 863, 813, 864, 286, 864, 813, 349, -+ 864, 813, 352, 352, 813, 352, 813, 813, 222, 222, -+ 222, 222, 222, 222, 222, 222, 222, 222, 818, 818, -+ 818, 818, 818, 813, 813, 813, 834, 818, 818, 818, -+ 865, 866, 813, 88, 321, 859, 859, 198, 198, 198, -+ 198, 198, 198, 88, 88, 88, 88, 88, 818, 818, -+ -+ 212, 212, 818, 867, 867, 868, 869, 813, 813, 870, -+ 871, 813, 872, 872, 873, 355, 873, 813, 418, 873, -+ 813, 421, 421, 813, 421, 813, 426, 426, 426, 426, -+ 426, 426, 426, 426, 818, 818, 818, 818, 818, 813, -+ 813, 874, 818, 818, 818, 813, 813, 875, 875, 813, -+ 859, 859, 198, 859, 198, 198, 198, 198, 88, 88, -+ 88, 88, 88, 818, 464, 464, 813, 876, 877, 408, -+ 813, 471, 471, 813, 471, 813, 813, 878, 878, 813, -+ 813, 879, 879, 880, 424, 880, 813, 487, 880, 813, -+ 490, 490, 813, 490, 813, 495, 495, 813, 813, 495, -+ -+ 495, 495, 495, 813, 813, 813, 813, 818, 813, 813, -+ 881, 818, 818, 818, 882, 883, 813, 884, 884, 884, -+ 884, 813, 522, 885, 818, 818, 818, 527, 527, 813, -+ 886, 813, 887, 474, 887, 813, 536, 887, 813, 539, -+ 539, 813, 539, 888, 889, 813, 813, 890, 890, 891, -+ 892, 891, 813, 553, 891, 813, 556, 556, 556, 813, -+ 560, 560, 560, 560, 560, 560, 818, 813, 813, 893, -+ 818, 818, 818, 813, 813, 894, 894, 813, 895, 895, -+ 895, 895, 813, 583, 896, 818, 586, 586, 586, 813, -+ 897, 898, 813, 899, 899, 900, 542, 900, 813, 599, -+ -+ 900, 813, 602, 602, 813, 602, 813, 813, 901, 901, -+ 813, 813, 902, 902, 903, 903, 813, 617, 903, 560, -+ 560, 560, 560, 560, 813, 813, 813, 813, 813, 813, -+ 904, 893, 818, 905, 906, 907, 908, 813, 907, 909, -+ 909, 909, 909, 818, 818, 818, 646, 646, 818, 813, -+ 813, 910, 910, 813, 813, 911, 911, 912, 605, 912, -+ 813, 661, 912, 813, 664, 664, 813, 664, 913, 914, -+ 813, 813, 915, 915, 560, 813, 813, 560, 560, 560, -+ 813, 904, 904, 813, 893, 818, 905, 905, 905, 905, -+ 916, 905, 917, 917, 813, 813, 907, 907, 813, 813, -+ -+ 909, 909, 909, 646, 646, 646, 918, 919, 813, 813, -+ 920, 920, 921, 667, 921, 813, 716, 921, 813, 719, -+ 719, 922, 813, 913, 913, 813, 813, 813, 813, 560, -+ 560, 813, 893, 813, 813, 923, 924, 813, 909, 909, -+ 646, 818, 646, 646, 818, 813, 813, 918, 918, 813, -+ 813, 925, 925, 926, 926, 926, 756, 926, 813, 813, -+ 560, 927, 813, 813, 923, 923, 813, 909, 646, 646, -+ 646, 813, 813, 813, 813, 928, 928, 813, 813, 927, -+ 927, 813, 929, 930, 813, 646, 818, 646, 646, 818, -+ 813, 813, 813, 813, 813, 813, 813, 929, 929, 813, -+ -+ 818, 818, 818, 813, 813, 813, 818, 818, 818, 813, -+ 813, 813, 0, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813 - } ; - --static yyconst short int yy_nxt[3663] = -+static yyconst flex_int16_t yy_nxt[5675] = - { 0, -- 14, 15, 16, 17, 18, 19, 20, 21, 22, 14, -- 23, 24, 14, 14, 25, 26, 27, 28, 26, 26, -- 26, 26, 26, 29, 30, 31, 14, 32, 33, 33, -- 33, 34, 35, 35, 35, 35, 36, 35, 37, 35, -- 38, 39, 40, 41, 35, 35, 35, 35, 35, 42, -- 14, 43, 43, 43, 43, 43, 43, 14, 14, 14, -- 14, 14, 14, 14, 44, 14, 14, 45, 81, 52, -- 89, 46, 151, 53, 107, 110, 115, 52, 107, 54, -- 111, 53, 55, 76, 16, 77, 78, 54, 90, 109, -- 55, 76, 16, 77, 78, 47, 48, 150, 128, 49, -- -- 158, 113, 604, 131, 56, 394, 81, 50, 57, 35, -- 51, 35, 56, 547, 91, 114, 57, 35, 133, 35, -- 15, 60, 61, 120, 62, 15, 60, 61, 134, 62, -- 62, 79, 58, 95, 95, 62, 81, 95, 95, 79, -- 58, 191, 62, 63, 147, 119, 156, 62, 63, 15, -- 16, 17, 69, 65, 81, 95, 154, 119, 70, 71, -- 72, 102, 102, 102, 102, 102, 103, 85, 64, 147, -- 119, 140, 73, 64, 15, 16, 17, 86, 65, 96, -- 87, 87, 87, 87, 87, 87, 87, 87, 101, 101, -- 101, 101, 101, 101, 101, 101, 174, 74, 15, 16, -- -- 17, 69, 65, 157, 621, 176, 89, 70, 71, 72, -- 80, 621, 100, 100, 100, 100, 100, 100, 100, 100, -- 121, 73, 66, 67, 67, 67, 67, 67, 67, 67, -- 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, -- 15, 16, 17, 107, 65, 81, 74, 152, 122, 123, -- 166, 156, 124, 159, 160, 166, 155, 198, 394, 85, -- 125, 135, 129, 126, 87, 87, 87, 87, 87, 87, -- 87, 87, 150, 87, 87, 87, 87, 87, 87, 87, -- 87, 172, 172, 172, 172, 172, 172, 547, 66, 67, -- 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, -- -- 67, 67, 67, 67, 67, 67, 97, 81, 98, 98, -- 98, 98, 98, 98, 98, 98, 99, 621, 197, 201, -- 100, 100, 100, 100, 100, 81, 81, 182, 501, 138, -- 138, 80, 183, 138, 138, 621, 184, 81, 185, 239, -- 200, 81, 81, 202, 100, 100, 100, 100, 100, 100, -- 80, 138, 81, 147, 119, 246, 80, 204, 574, 80, -- 80, 91, 80, 80, 80, 106, 106, 106, 106, 106, -- 106, 106, 106, 99, 199, 139, 80, 106, 106, 106, -- 106, 106, 107, 107, 107, 107, 108, 107, 107, 107, -- 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, -- -- 107, 100, 100, 100, 100, 100, 100, 80, 80, 80, -- 80, 80, 80, 80, 80, 80, 80, 107, 107, 107, -- 107, 107, 107, 107, 107, 621, 85, 147, 119, 107, -- 107, 107, 107, 107, 159, 160, 146, 133, 107, 621, -- 621, 621, 621, 621, 621, 621, 621, 134, 147, 119, -- 81, 207, 248, 80, 80, 80, 80, 80, 80, 118, -- 119, 80, 80, 80, 158, 80, 80, 174, 157, 80, -- 143, 119, 144, 81, 145, 81, 220, 174, 144, 85, -- 145, 80, 80, 80, 85, 81, 220, 81, 99, 246, -- 246, 273, 145, 145, 86, 589, 150, 87, 87, 87, -- -- 87, 87, 87, 87, 87, 80, 174, 80, 80, 80, -- 156, 80, 80, 274, 81, 80, 156, 85, 145, 87, -- 87, 87, 87, 87, 87, 87, 87, 80, 80, 80, -- 245, 95, 95, 174, 276, 95, 95, 81, 163, 277, -- 127, 164, 164, 164, 164, 164, 164, 164, 164, 88, -- 249, 88, 88, 95, 501, 88, 88, 81, 92, 88, -- 92, 92, 92, 285, 92, 92, 81, 290, 92, 257, -- 257, 257, 88, 88, 289, 85, 81, 96, 81, 174, -- 92, 92, 92, 94, 292, 80, 80, 94, 220, 80, -- 80, 246, 447, 94, 168, 169, 170, 168, 168, 168, -- -- 168, 168, 273, 333, 293, 94, 94, 80, 172, 172, -- 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, -- 172, 172, 172, 172, 274, 81, 85, 81, 81, 171, -- 171, 171, 171, 171, 171, 171, 171, 334, 99, 332, -- 81, 171, 171, 171, 171, 171, 87, 87, 87, 87, -- 87, 87, 87, 87, 85, 81, 81, 483, 138, 138, -- 121, 329, 138, 138, 81, 171, 171, 171, 171, 171, -- 171, 177, 177, 177, 177, 177, 177, 177, 177, 99, -- 138, 291, 527, 177, 177, 177, 177, 177, 122, 123, -- 174, 137, 124, 80, 80, 137, 174, 80, 80, 220, -- -- 125, 137, 81, 126, 139, 263, 383, 171, 171, 171, -- 171, 171, 171, 137, 137, 80, 621, 621, 621, 621, -- 621, 621, 621, 621, 149, 81, 372, 149, 149, 81, -- 335, 373, 85, 526, 149, 164, 164, 164, 164, 164, -- 164, 164, 164, 370, 565, 385, 81, 149, 164, 164, -- 164, 164, 164, 164, 164, 164, 165, 564, 165, 165, -- 95, 434, 165, 165, 95, 371, 165, 261, 174, 207, -- 95, 208, 208, 208, 208, 208, 208, 263, 165, 165, -- 165, 563, 95, 95, 207, 432, 208, 208, 208, 208, -- 208, 208, 208, 208, 207, 376, 209, 209, 209, 209, -- -- 209, 209, 209, 209, 207, 81, 210, 210, 210, 210, -- 210, 211, 208, 208, 138, 621, 174, 377, 138, 387, -- 81, 261, 174, 81, 138, 263, 81, 174, 261, 174, -- 81, 263, 621, 174, 447, 380, 138, 138, 310, 429, -- 81, 80, 310, 212, 212, 212, 212, 212, 212, 212, -- 212, 444, 444, 396, 81, 212, 212, 212, 212, 212, -- 250, 251, 252, 250, 250, 250, 250, 250, 207, 81, -- 208, 208, 208, 208, 208, 208, 208, 208, 386, 212, -- 212, 212, 212, 212, 212, 214, 215, 216, 216, 216, -- 216, 216, 216, 217, 81, 498, 498, 218, 218, 218, -- -- 218, 218, 85, 207, 81, 208, 208, 208, 208, 208, -- 208, 208, 208, 225, 225, 225, 225, 225, 225, 225, -- 225, 218, 218, 218, 218, 218, 218, 174, 221, 222, -- 223, 221, 221, 221, 221, 221, 224, 261, 174, 81, -- 225, 225, 225, 225, 225, 255, 255, 256, 257, 257, -- 257, 257, 257, 217, 265, 265, 265, 265, 265, 265, -- 265, 265, 81, 566, 225, 225, 225, 225, 225, 225, -- 226, 226, 226, 226, 226, 226, 226, 226, 435, 621, -- 174, 378, 226, 226, 226, 226, 226, 266, 266, 266, -- 266, 266, 267, 621, 81, 264, 264, 264, 264, 264, -- -- 264, 264, 264, 379, 384, 492, 212, 212, 212, 212, -- 212, 212, 261, 174, 262, 262, 262, 262, 262, 262, -- 262, 262, 263, 174, 515, 515, 264, 264, 264, 264, -- 264, 293, 263, 294, 294, 294, 294, 294, 294, 294, -- 294, 299, 299, 299, 299, 299, 299, 299, 299, 217, -- 264, 264, 264, 264, 264, 264, 174, 268, 269, 270, -- 268, 268, 268, 268, 268, 271, 174, 81, 523, 272, -- 272, 272, 272, 272, 293, 310, 295, 295, 295, 295, -- 295, 295, 295, 295, 304, 305, 306, 304, 304, 304, -- 304, 304, 522, 272, 272, 272, 272, 272, 272, 293, -- -- 521, 296, 296, 296, 296, 296, 297, 294, 294, 370, -- 81, 272, 272, 272, 272, 272, 272, 272, 272, 261, -- 174, 308, 308, 308, 308, 308, 308, 525, 526, 263, -- 520, 371, 544, 544, 517, 81, 261, 174, 308, 308, -- 308, 308, 308, 308, 308, 308, 263, 261, 174, 309, -- 309, 309, 309, 309, 309, 309, 309, 310, 376, 378, -- 475, 311, 311, 311, 311, 311, 312, 312, 312, 312, -- 312, 312, 312, 312, 313, 313, 313, 313, 313, 314, -- 377, 379, 476, 261, 174, 311, 311, 311, 311, 311, -- 311, 174, 315, 316, 317, 315, 315, 315, 315, 315, -- -- 318, 81, 525, 526, 319, 319, 319, 319, 319, 621, -- 433, 311, 311, 311, 311, 311, 311, 311, 311, 336, -- 337, 338, 336, 336, 336, 336, 336, 457, 319, 319, -- 319, 319, 319, 319, 293, 394, 294, 294, 294, 294, -- 294, 294, 294, 294, 293, 396, 294, 294, 294, 294, -- 294, 294, 293, 81, 294, 294, 294, 294, 294, 294, -- 294, 294, 360, 360, 360, 360, 360, 361, 396, 348, -- 81, 349, 349, 349, 349, 349, 349, 349, 349, 342, -- 81, 399, 399, 399, 399, 399, 400, 81, 81, 343, -- 344, 345, 343, 343, 343, 343, 343, 346, 174, 580, -- -- 580, 347, 347, 347, 347, 347, 348, 310, 350, 350, -- 350, 350, 350, 350, 350, 350, 319, 319, 319, 319, -- 319, 319, 319, 319, 480, 347, 347, 347, 347, 347, -- 347, 348, 479, 351, 351, 351, 351, 351, 352, 349, -- 349, 261, 174, 355, 355, 355, 355, 355, 355, 355, -- 355, 310, 261, 174, 355, 355, 355, 355, 355, 355, -- 81, 81, 310, 261, 174, 356, 356, 356, 356, 356, -- 356, 356, 356, 357, 474, 528, 473, 358, 358, 358, -- 358, 358, 359, 359, 359, 359, 359, 359, 359, 359, -- 621, 174, 358, 358, 358, 358, 358, 358, 358, 358, -- -- 357, 358, 358, 358, 358, 358, 358, 174, 362, 363, -- 364, 362, 362, 362, 362, 362, 365, 590, 85, 472, -- 366, 366, 366, 366, 366, 387, 388, 388, 388, 388, -- 388, 388, 388, 388, 387, 389, 389, 389, 389, 389, -- 389, 389, 389, 471, 366, 366, 366, 366, 366, 366, -- 387, 390, 390, 390, 390, 390, 391, 388, 388, 470, -- 81, 347, 347, 347, 347, 347, 347, 347, 347, 81, -- 398, 398, 398, 398, 398, 398, 398, 398, 416, 416, -- 416, 416, 416, 417, 477, 81, 394, 621, 395, 395, -- 395, 395, 395, 395, 395, 395, 396, 396, 598, 598, -- -- 397, 397, 397, 397, 397, 621, 478, 397, 397, 397, -- 397, 397, 397, 397, 397, 406, 407, 408, 406, 406, -- 406, 406, 406, 342, 397, 397, 397, 397, 397, 397, -- 401, 402, 403, 401, 401, 401, 401, 401, 404, 259, -- 481, 85, 405, 405, 405, 405, 405, 348, 394, 349, -- 349, 349, 349, 349, 349, 349, 349, 348, 396, 349, -- 349, 349, 349, 349, 349, 431, 405, 405, 405, 405, -- 405, 405, 348, 430, 349, 349, 349, 349, 349, 349, -- 349, 349, 261, 174, 261, 174, 450, 450, 450, 450, -- 450, 451, 310, 482, 357, 366, 366, 366, 366, 366, -- -- 366, 366, 366, 621, 174, 415, 415, 415, 415, 415, -- 415, 415, 415, 357, 261, 174, 411, 411, 411, 411, -- 411, 411, 411, 411, 357, 261, 174, 411, 411, 411, -- 411, 411, 411, 603, 604, 357, 261, 174, 412, 412, -- 412, 412, 412, 412, 412, 412, 413, 174, 603, 604, -- 414, 414, 414, 414, 414, 621, 357, 414, 414, 414, -- 414, 414, 414, 414, 414, 436, 437, 438, 439, 436, -- 436, 436, 436, 428, 414, 414, 414, 414, 414, 414, -- 174, 418, 419, 420, 418, 418, 418, 418, 418, 174, -- 148, 148, 427, 421, 421, 421, 421, 421, 413, 81, -- -- 387, 388, 388, 388, 388, 388, 388, 388, 388, 387, -- 388, 388, 388, 388, 388, 388, 426, 421, 421, 421, -- 421, 421, 421, 387, 388, 388, 388, 388, 388, 388, -- 388, 388, 518, 484, 425, 81, 441, 442, 443, 441, -- 441, 441, 441, 441, 81, 405, 405, 405, 405, 405, -- 405, 405, 405, 484, 519, 484, 485, 394, 81, 445, -- 445, 445, 445, 445, 445, 445, 445, 396, 394, 486, -- 446, 446, 446, 446, 446, 446, 446, 446, 447, 81, -- 424, 423, 448, 448, 448, 448, 448, 449, 449, 449, -- 449, 449, 449, 449, 449, 621, 422, 448, 448, 448, -- -- 448, 448, 448, 448, 448, 81, 448, 448, 448, 448, -- 448, 448, 452, 453, 454, 452, 452, 452, 452, 452, -- 455, 174, 348, 342, 456, 456, 456, 456, 456, 457, -- 413, 458, 458, 458, 458, 458, 458, 458, 458, 468, -- 468, 468, 468, 468, 469, 261, 174, 259, 456, 456, -- 456, 456, 456, 456, 457, 357, 459, 459, 459, 459, -- 459, 459, 459, 459, 457, 217, 460, 460, 460, 460, -- 460, 461, 458, 458, 261, 174, 421, 421, 421, 421, -- 421, 421, 421, 421, 413, 621, 174, 467, 467, 467, -- 467, 467, 467, 467, 467, 413, 261, 174, 464, 464, -- -- 464, 464, 464, 464, 464, 464, 413, 261, 174, 464, -- 464, 464, 464, 464, 464, 382, 381, 413, 261, 174, -- 465, 465, 465, 465, 465, 465, 465, 465, 394, 375, -- 374, 369, 466, 466, 466, 466, 466, 621, 447, 466, -- 466, 466, 466, 466, 466, 466, 466, 456, 456, 456, -- 456, 456, 456, 456, 456, 368, 466, 466, 466, 466, -- 466, 466, 486, 621, 487, 487, 487, 487, 487, 487, -- 487, 487, 486, 447, 488, 488, 488, 488, 488, 488, -- 488, 488, 486, 394, 489, 489, 489, 489, 489, 490, -- 491, 491, 486, 447, 569, 605, 367, 486, 81, 491, -- -- 491, 491, 487, 487, 487, 487, 487, 492, 81, 493, -- 493, 493, 493, 493, 493, 493, 493, 492, 81, 494, -- 494, 494, 494, 494, 494, 494, 494, 342, 81, 259, -- 81, 81, 492, 81, 495, 495, 495, 495, 495, 496, -- 493, 493, 394, 475, 499, 499, 499, 499, 499, 499, -- 499, 499, 447, 394, 217, 500, 500, 500, 500, 500, -- 500, 500, 500, 501, 477, 476, 518, 502, 502, 502, -- 502, 502, 503, 503, 503, 503, 503, 503, 503, 503, -- 504, 504, 504, 504, 504, 505, 478, 217, 519, 286, -- 331, 502, 502, 502, 502, 502, 502, 506, 507, 508, -- -- 506, 506, 506, 506, 506, 509, 330, 328, 327, 510, -- 510, 510, 510, 510, 621, 326, 502, 502, 502, 502, -- 502, 502, 502, 502, 511, 512, 513, 511, 511, 511, -- 511, 511, 325, 510, 510, 510, 510, 510, 510, 457, -- 324, 458, 458, 458, 458, 458, 458, 458, 458, 457, -- 484, 458, 458, 458, 458, 458, 458, 458, 458, 457, -- 323, 458, 458, 458, 458, 458, 458, 261, 174, 614, -- 484, 322, 484, 484, 614, 321, 320, 413, 261, 174, -- 516, 516, 516, 516, 516, 516, 516, 516, 530, 302, -- 531, 532, 533, 530, 259, 531, 532, 533, 537, 538, -- -- 539, 537, 537, 537, 537, 537, 486, 394, 487, 487, -- 487, 487, 487, 487, 487, 487, 486, 501, 487, 487, -- 487, 487, 487, 487, 487, 487, 217, 621, 394, 561, -- 394, 298, 81, 217, 621, 105, 534, 501, 501, 286, -- 547, 536, 81, 486, 547, 487, 487, 487, 487, 487, -- 487, 562, 81, 540, 541, 542, 540, 540, 540, 540, -- 540, 492, 288, 493, 493, 493, 493, 493, 493, 493, -- 493, 550, 550, 550, 550, 550, 551, 286, 492, 81, -- 493, 493, 493, 493, 493, 493, 493, 493, 492, 287, -- 493, 493, 493, 493, 493, 493, 510, 510, 510, 510, -- -- 510, 510, 510, 510, 394, 561, 545, 545, 545, 545, -- 545, 545, 545, 545, 501, 394, 394, 546, 546, 546, -- 546, 546, 546, 546, 546, 547, 547, 562, 286, 548, -- 548, 548, 548, 548, 549, 549, 549, 549, 549, 549, -- 549, 549, 621, 284, 548, 548, 548, 548, 548, 548, -- 548, 548, 283, 548, 548, 548, 548, 548, 548, 552, -- 553, 554, 552, 552, 552, 552, 552, 282, 281, 280, -- 279, 555, 555, 555, 555, 555, 174, 556, 556, 556, -- 556, 556, 556, 556, 556, 174, 557, 557, 557, 557, -- 557, 557, 557, 557, 587, 555, 555, 555, 555, 555, -- -- 555, 174, 558, 558, 558, 558, 558, 559, 556, 556, -- 621, 278, 621, 621, 621, 530, 588, 531, 532, 533, -- 621, 275, 531, 532, 533, 621, 99, 621, 621, 533, -- 567, 217, 259, 568, 568, 568, 568, 568, 568, 568, -- 568, 217, 587, 529, 529, 600, 621, 529, 621, 621, -- 621, 105, 85, 535, 535, 205, 247, 535, 534, 529, -- 529, 529, 244, 534, 588, 243, 242, 601, 534, 535, -- 535, 535, 569, 534, 570, 570, 570, 570, 570, 570, -- 570, 570, 569, 600, 571, 571, 571, 571, 571, 571, -- 571, 571, 241, 569, 536, 572, 572, 572, 572, 572, -- -- 573, 570, 570, 240, 238, 601, 237, 574, 81, 575, -- 575, 575, 575, 575, 575, 575, 575, 574, 81, 576, -- 576, 576, 576, 576, 576, 576, 576, 236, 574, 81, -- 577, 577, 577, 577, 577, 578, 575, 575, 555, 555, -- 555, 555, 555, 555, 555, 555, 394, 235, 581, 581, -- 581, 581, 581, 581, 581, 581, 547, 394, 234, 582, -- 582, 582, 582, 582, 582, 582, 582, 233, 232, 231, -- 230, 583, 583, 583, 583, 583, 584, 584, 584, 584, -- 584, 584, 584, 584, 585, 585, 585, 585, 585, 586, -- 229, 228, 227, 105, 97, 583, 583, 583, 583, 583, -- -- 583, 621, 85, 583, 583, 583, 583, 583, 583, 583, -- 583, 174, 556, 556, 556, 556, 556, 556, 556, 556, -- 174, 556, 556, 556, 556, 556, 556, 556, 556, 174, -- 556, 556, 556, 556, 556, 556, 568, 568, 568, 568, -- 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, -- 568, 568, 591, 592, 593, 591, 591, 591, 591, 591, -- 569, 85, 570, 570, 570, 570, 570, 570, 570, 570, -- 569, 205, 570, 570, 570, 570, 570, 570, 570, 570, -- 155, 156, 150, 150, 142, 569, 81, 570, 570, 570, -- 570, 570, 570, 203, 136, 136, 81, 594, 595, 596, -- -- 594, 594, 594, 594, 594, 574, 81, 575, 575, 575, -- 575, 575, 575, 575, 575, 196, 195, 194, 193, 192, -- 574, 81, 575, 575, 575, 575, 575, 575, 575, 575, -- 574, 190, 575, 575, 575, 575, 575, 575, 394, 189, -- 599, 599, 599, 599, 599, 599, 599, 599, 605, 188, -- 606, 606, 606, 606, 606, 606, 606, 606, 605, 187, -- 607, 607, 607, 607, 607, 607, 607, 607, 605, 186, -- 608, 608, 608, 608, 608, 609, 606, 606, 610, 610, -- 610, 610, 610, 610, 81, 610, 610, 610, 610, 610, -- 610, 610, 610, 181, 81, 611, 611, 611, 611, 611, -- -- 611, 611, 611, 180, 81, 612, 612, 612, 612, 612, -- 613, 610, 610, 615, 616, 617, 615, 615, 615, 615, -- 615, 605, 179, 606, 606, 606, 606, 606, 606, 606, -- 606, 605, 178, 606, 606, 606, 606, 606, 606, 606, -- 606, 105, 80, 105, 167, 93, 605, 81, 606, 606, -- 606, 606, 606, 606, 85, 83, 82, 81, 610, 610, -- 610, 610, 610, 610, 610, 610, 81, 81, 610, 610, -- 610, 610, 610, 610, 610, 610, 156, 150, 142, 113, -- 111, 136, 81, 618, 618, 618, 618, 618, 618, 618, -- 618, 615, 615, 615, 615, 615, 615, 615, 615, 619, -- -- 619, 619, 619, 619, 620, 618, 618, 618, 618, 618, -- 618, 618, 618, 618, 618, 132, 130, 81, 618, 618, -- 618, 618, 618, 618, 117, 81, 116, 115, 112, 107, -- 105, 93, 83, 81, 82, 81, 621, 621, 621, 621, -- 621, 81, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 81, 59, 59, 59, 59, 59, 59, 59, -- 59, 59, 59, 59, 59, 59, 59, 59, 59, 31, -- 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, -- 31, 31, 31, 31, 31, 68, 68, 68, 68, 68, -- 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, -- -- 68, 75, 75, 75, 75, 75, 75, 75, 75, 75, -- 75, 75, 75, 75, 75, 75, 75, 80, 621, 621, -- 621, 621, 621, 621, 621, 80, 80, 80, 621, 621, -- 80, 80, 80, 84, 84, 84, 84, 84, 84, 84, -- 84, 84, 84, 84, 84, 84, 84, 84, 84, 88, -- 621, 621, 621, 621, 88, 621, 621, 88, 88, 88, -- 88, 621, 88, 88, 88, 92, 621, 621, 621, 621, -- 621, 621, 621, 92, 92, 92, 621, 621, 92, 92, -- 92, 94, 621, 621, 94, 94, 621, 94, 621, 94, -- 94, 94, 621, 621, 94, 94, 94, 104, 104, 621, -- -- 621, 621, 104, 137, 621, 621, 137, 137, 621, 137, -- 621, 137, 137, 137, 621, 621, 137, 137, 137, 141, -- 621, 621, 141, 141, 621, 141, 621, 141, 141, 141, -- 621, 141, 621, 141, 141, 149, 621, 621, 149, 621, -- 621, 149, 621, 149, 149, 149, 149, 621, 149, 149, -- 149, 153, 153, 153, 153, 153, 153, 153, 153, 153, -- 153, 153, 153, 153, 153, 153, 153, 155, 155, 621, -- 155, 621, 155, 155, 155, 155, 155, 155, 155, 155, -- 155, 155, 155, 161, 161, 161, 161, 161, 161, 161, -- 161, 161, 161, 161, 161, 161, 161, 161, 161, 162, -- -- 162, 621, 162, 162, 162, 162, 162, 162, 162, 162, -- 162, 162, 162, 162, 162, 165, 621, 621, 621, 621, -- 165, 621, 621, 165, 165, 165, 621, 621, 165, 165, -- 165, 95, 621, 621, 95, 95, 621, 95, 621, 95, -- 95, 95, 621, 621, 95, 95, 95, 173, 173, 621, -- 621, 621, 173, 175, 175, 175, 621, 621, 621, 175, -- 138, 621, 621, 138, 138, 621, 138, 621, 138, 138, -- 138, 621, 621, 138, 138, 138, 206, 206, 206, 206, -- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, -- 206, 206, 213, 213, 621, 621, 621, 213, 219, 219, -- -- 219, 621, 621, 621, 219, 253, 253, 621, 621, 621, -- 253, 254, 254, 621, 621, 621, 254, 258, 258, 621, -- 621, 621, 258, 260, 260, 260, 621, 621, 621, 260, -- 298, 298, 621, 621, 621, 298, 300, 300, 621, 621, -- 621, 300, 301, 301, 621, 621, 621, 301, 303, 303, -- 303, 621, 621, 621, 303, 307, 307, 307, 307, 621, -- 621, 621, 307, 339, 339, 621, 621, 621, 339, 340, -- 340, 621, 621, 621, 340, 341, 341, 621, 621, 621, -- 341, 353, 353, 353, 621, 621, 621, 353, 354, 354, -- 354, 354, 621, 621, 621, 354, 392, 392, 621, 621, -- -- 621, 392, 393, 393, 621, 621, 621, 393, 409, 409, -- 409, 621, 621, 621, 409, 410, 410, 410, 410, 621, -- 621, 621, 410, 440, 440, 621, 621, 621, 440, 444, -- 621, 444, 444, 621, 621, 621, 444, 462, 462, 462, -- 621, 621, 621, 462, 463, 463, 463, 463, 621, 621, -- 621, 463, 497, 497, 621, 621, 621, 497, 498, 621, -- 498, 498, 621, 621, 621, 498, 514, 514, 514, 621, -- 621, 621, 514, 515, 515, 515, 621, 621, 621, 621, -- 515, 524, 524, 524, 524, 524, 524, 524, 524, 524, -- 524, 524, 524, 524, 524, 524, 524, 529, 529, 621, -- -- 529, 529, 529, 621, 621, 529, 529, 529, 621, 621, -- 529, 529, 529, 535, 535, 621, 535, 535, 535, 621, -- 621, 535, 535, 535, 621, 621, 535, 535, 535, 543, -- 543, 621, 621, 621, 543, 544, 621, 544, 544, 621, -- 621, 621, 544, 560, 560, 621, 621, 621, 621, 560, -- 579, 579, 621, 621, 621, 579, 580, 621, 580, 580, -- 621, 621, 621, 580, 597, 597, 621, 621, 621, 597, -- 598, 621, 598, 621, 621, 621, 621, 598, 602, 602, -- 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, -- 602, 602, 602, 602, 13, 621, 621, 621, 621, 621, -- -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621 -+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 16, -+ 25, 26, 16, 16, 27, 28, 29, 30, 28, 28, -+ 28, 28, 28, 28, 28, 31, 32, 33, 16, 34, -+ 35, 35, 35, 36, 37, 37, 37, 37, 38, 37, -+ 39, 37, 40, 41, 42, 43, 37, 37, 37, 37, -+ 37, 44, 16, 45, 45, 45, 45, 45, 45, 16, -+ 16, 16, 16, 16, 16, 16, 16, 46, 16, 16, -+ 47, 532, 54, 130, 48, 135, 55, 127, 131, 127, -+ 54, 127, 56, 534, 55, 57, 78, 18, 79, 80, -+ 56, 109, 129, 57, 133, 17, 62, 63, 150, 64, -+ -+ 49, 50, 149, 152, 51, 64, 168, 139, 134, 58, -+ 101, 110, 52, 59, 37, 53, 37, 58, 154, 64, -+ 65, 59, 37, 105, 37, 17, 62, 63, 155, 64, -+ 796, 78, 18, 79, 80, 64, 81, 111, 60, 175, -+ 139, 172, 101, 115, 115, 66, 60, 115, 115, 64, -+ 65, 140, 142, 178, 17, 18, 19, 71, 67, 173, -+ 141, 168, 139, 72, 73, 74, 171, 115, 122, 122, -+ 122, 122, 122, 123, 179, 66, 17, 18, 19, 75, -+ 67, 81, 143, 144, 171, 242, 145, 101, 101, 180, -+ 181, 116, 176, 236, 146, 198, 140, 147, 17, 18, -+ -+ 19, 71, 67, 177, 76, 161, 201, 72, 73, 74, -+ 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, -+ 101, 796, 177, 75, 179, 249, 68, 69, 69, 69, -+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, -+ 69, 69, 69, 69, 69, 17, 18, 19, 76, 67, -+ 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, -+ 195, 195, 195, 195, 195, 196, 206, 100, 119, 100, -+ 100, 100, 177, 100, 100, 207, 101, 100, 107, 107, -+ 107, 107, 107, 107, 107, 107, 107, 107, 101, 243, -+ 235, 100, 100, 100, 101, 68, 69, 69, 69, 69, -+ -+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, -+ 69, 69, 69, 69, 33, 17, 18, 19, 33, 33, -+ 82, 23, 24, 33, 83, 26, 33, 33, 84, 85, -+ 86, 87, 85, 85, 85, 85, 85, 85, 85, 31, -+ 88, 33, 33, 89, 90, 90, 90, 91, 92, 92, -+ 92, 92, 93, 92, 94, 92, 95, 92, 96, 92, -+ 92, 92, 92, 92, 92, 68, 33, 97, 97, 97, -+ 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, -+ 98, 99, 98, 98, 105, 218, 101, 796, 109, 168, -+ 139, 269, 247, 178, 106, 796, 220, 107, 107, 107, -+ -+ 107, 107, 107, 107, 107, 107, 107, 117, 183, 118, -+ 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, -+ 101, 180, 181, 120, 120, 120, 120, 120, 101, 101, -+ 357, 159, 159, 246, 184, 159, 159, 216, 216, 216, -+ 216, 216, 216, 177, 245, 101, 154, 120, 120, 120, -+ 120, 120, 120, 100, 358, 159, 155, 127, 101, 100, -+ 313, 563, 100, 100, 101, 100, 100, 100, 126, 126, -+ 126, 126, 126, 126, 126, 126, 126, 126, 119, 160, -+ 311, 100, 126, 126, 126, 126, 126, 127, 127, 127, -+ 127, 128, 127, 127, 127, 127, 127, 127, 127, 127, -+ -+ 127, 127, 127, 127, 101, 127, 120, 120, 120, 120, -+ 120, 120, 100, 100, 100, 100, 100, 100, 100, 100, -+ 100, 100, 100, 127, 127, 127, 127, 127, 127, 127, -+ 127, 127, 127, 813, 218, 796, 105, 127, 127, 127, -+ 127, 127, 101, 100, 101, 282, 127, 107, 107, 107, -+ 107, 107, 107, 107, 107, 107, 107, 101, 304, 311, -+ 372, 100, 100, 100, 100, 100, 100, 138, 139, 100, -+ 100, 100, 311, 100, 100, 101, 378, 100, 216, 216, -+ 216, 216, 216, 216, 216, 216, 216, 216, 244, 310, -+ 813, 100, 100, 100, 100, 101, 120, 120, 120, 120, -+ -+ 120, 120, 120, 120, 120, 120, 105, 164, 139, 165, -+ 813, 166, 101, 109, 436, 165, 106, 166, 373, 107, -+ 107, 107, 107, 107, 107, 107, 107, 107, 107, 226, -+ 101, 166, 166, 813, 227, 311, 111, 218, 228, 170, -+ 229, 185, 170, 170, 101, 168, 139, 185, 282, 170, -+ 185, 115, 115, 185, 185, 115, 115, 166, 813, 184, -+ 782, 371, 168, 139, 170, 148, 105, 187, 360, 185, -+ 109, 301, 302, 361, 303, 115, 167, 101, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 101, -+ 813, 314, 188, 185, 115, 101, 532, 115, 115, 116, -+ -+ 115, 115, 115, 115, 184, 101, 115, 115, 108, 714, -+ 108, 108, 171, 101, 108, 108, 184, 435, 108, 380, -+ 187, 115, 115, 216, 216, 216, 216, 216, 216, 216, -+ 216, 216, 216, 108, 108, 107, 107, 107, 107, 107, -+ 107, 107, 107, 107, 107, 190, 115, 187, 105, 101, -+ 191, 187, 192, 192, 192, 192, 192, 192, 192, 192, -+ 192, 192, 119, 187, 357, 357, 193, 193, 193, 193, -+ 193, 187, 187, 187, 187, 187, 187, 187, 187, 187, -+ 187, 187, 187, 187, 187, 187, 187, 187, 358, 358, -+ 193, 193, 193, 193, 193, 193, 187, 187, 187, 187, -+ -+ 187, 187, 187, 187, 187, 187, 187, 813, 377, 187, -+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 813, -+ 341, 341, 341, 187, 187, 187, 187, 187, 330, 331, -+ 112, 332, 112, 112, 112, 394, 112, 112, 395, 437, -+ 112, 255, 255, 255, 255, 255, 255, 187, 187, 187, -+ 187, 187, 187, 187, 112, 112, 112, 187, 197, 197, -+ 197, 197, 197, 197, 197, 197, 197, 197, 119, 187, -+ 498, 101, 197, 197, 197, 197, 197, 198, 198, 198, -+ 198, 199, 198, 198, 198, 198, 198, 198, 198, 198, -+ 198, 198, 198, 198, 499, 200, 193, 193, 193, 193, -+ -+ 193, 193, 187, 187, 187, 187, 187, 187, 187, 187, -+ 187, 187, 187, 198, 198, 198, 198, 198, 198, 198, -+ 198, 198, 198, 813, 105, 101, 443, 198, 198, 198, -+ 198, 198, 260, 218, 159, 159, 198, 261, 159, 159, -+ 386, 262, 513, 263, 282, 387, 369, 142, 101, 370, -+ 504, 187, 187, 187, 187, 187, 187, 813, 159, 193, -+ 193, 193, 193, 193, 193, 193, 193, 193, 193, 114, -+ 763, 100, 100, 114, 505, 100, 100, 143, 144, 114, -+ 101, 145, 160, 272, 272, 272, 272, 272, 273, 146, -+ 438, 442, 147, 114, 114, 100, 212, 213, 214, 212, -+ -+ 212, 212, 212, 212, 212, 212, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 345, 218, 763, 158, -+ 101, 100, 100, 158, 101, 100, 100, 763, 347, 158, -+ 399, 444, 101, 215, 215, 215, 215, 215, 215, 215, -+ 215, 215, 215, 158, 158, 100, 506, 215, 215, 215, -+ 215, 215, 251, 252, 253, 251, 251, 251, 251, 251, -+ 251, 251, 100, 100, 100, 100, 496, 127, 101, 813, -+ 507, 215, 215, 215, 215, 215, 215, 221, 221, 221, -+ 221, 221, 221, 221, 221, 221, 221, 119, 119, 498, -+ 532, 221, 221, 221, 221, 221, 255, 255, 255, 255, -+ -+ 255, 255, 255, 255, 255, 255, 350, 350, 350, 350, -+ 350, 351, 714, 499, 101, 215, 215, 215, 215, 215, -+ 215, 127, 127, 127, 127, 127, 127, 127, 127, 127, -+ 127, 813, 379, 622, 127, 127, 127, 127, 127, 127, -+ 182, 218, 182, 182, 101, 185, 182, 182, 101, 439, -+ 182, 185, 282, 445, 185, 813, 218, 185, 185, 100, -+ 100, 100, 100, 100, 100, 182, 182, 347, 218, 127, -+ 127, 187, 497, 185, 185, 562, 185, 185, 185, 347, -+ 185, 185, 498, 659, 185, 255, 255, 255, 255, 255, -+ 255, 255, 255, 255, 255, 525, 188, 185, 185, 185, -+ -+ 185, 115, 345, 218, 115, 115, 499, 115, 115, 115, -+ 115, 115, 127, 115, 115, 115, 565, 502, 345, 218, -+ 127, 115, 345, 218, 127, 504, 500, 187, 115, 115, -+ 347, 501, 101, 127, 416, 115, 115, 211, 211, 211, -+ 211, 211, 211, 211, 211, 211, 211, 503, 101, 505, -+ 127, 198, 190, 115, 254, 254, 254, 254, 254, 254, -+ 254, 254, 254, 254, 746, 567, 584, 127, 254, 254, -+ 254, 254, 254, 211, 211, 211, 211, 211, 211, 211, -+ 211, 211, 211, 315, 105, 316, 316, 316, 316, 316, -+ 316, 101, 254, 254, 254, 254, 254, 254, 187, 746, -+ -+ 101, 508, 187, 256, 256, 256, 256, 256, 256, 256, -+ 256, 256, 256, 119, 187, 105, 572, 256, 256, 256, -+ 256, 256, 198, 198, 198, 198, 198, 198, 198, 198, -+ 198, 198, 198, 198, 198, 198, 198, 198, 198, 570, -+ 200, 254, 254, 254, 254, 254, 254, 187, 187, 187, -+ 187, 187, 187, 187, 187, 187, 187, 187, 198, 198, -+ 198, 198, 198, 198, 198, 198, 198, 198, 813, 511, -+ 504, 506, 198, 198, 198, 198, 198, 271, 271, 271, -+ 271, 271, 271, 271, 271, 271, 271, 419, 419, 419, -+ 419, 419, 420, 506, 505, 507, 187, 187, 187, 187, -+ -+ 187, 187, 269, 746, 270, 270, 270, 270, 270, 270, -+ 270, 270, 270, 270, 159, 520, 763, 507, 159, 101, -+ 521, 621, 763, 127, 159, 287, 287, 287, 287, 287, -+ 287, 287, 287, 287, 287, 127, 573, 218, 159, 159, -+ 101, 100, 101, 274, 274, 274, 274, 274, 274, 274, -+ 274, 274, 274, 512, 624, 627, 127, 274, 274, 274, -+ 274, 274, 349, 349, 349, 349, 349, 349, 349, 349, -+ 349, 349, 488, 488, 488, 488, 488, 489, 101, 628, -+ 633, 274, 274, 274, 274, 274, 274, 276, 277, 278, -+ 278, 278, 278, 278, 278, 278, 278, 279, 649, 649, -+ -+ 649, 280, 280, 280, 280, 280, 381, 382, 383, 381, -+ 381, 381, 381, 381, 381, 381, 446, 218, 447, 447, -+ 447, 447, 447, 447, 218, 280, 280, 280, 280, 280, -+ 280, 218, 283, 284, 285, 283, 283, 283, 283, 283, -+ 283, 283, 286, 625, 813, 218, 287, 287, 287, 287, -+ 287, 410, 411, 412, 410, 410, 410, 410, 410, 410, -+ 410, 528, 528, 528, 528, 528, 529, 626, 679, 127, -+ 287, 287, 287, 287, 287, 287, 288, 288, 288, 288, -+ 288, 288, 288, 288, 288, 288, 119, 627, 625, 127, -+ 288, 288, 288, 288, 288, 356, 356, 356, 356, 356, -+ -+ 356, 356, 356, 356, 356, 537, 537, 537, 537, 537, -+ 538, 628, 626, 218, 274, 274, 274, 274, 274, 274, -+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -+ 813, 683, 684, 127, 127, 127, 127, 127, 127, 345, -+ 218, 414, 414, 414, 414, 414, 414, 678, 659, 127, -+ 399, 347, 400, 400, 400, 400, 400, 400, 100, 100, -+ 100, 100, 100, 100, 315, 627, 318, 318, 318, 318, -+ 318, 319, 316, 316, 316, 316, 320, 320, 320, 320, -+ 320, 320, 320, 320, 320, 320, 119, 597, 101, 628, -+ 320, 320, 320, 320, 320, 418, 418, 418, 418, 418, -+ -+ 418, 418, 418, 418, 418, 476, 746, 477, 477, 477, -+ 477, 477, 477, 746, 320, 320, 320, 320, 320, 320, -+ 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, -+ 100, 100, 100, 100, 321, 321, 321, 321, 321, 425, -+ 425, 425, 425, 425, 425, 425, 425, 425, 425, 554, -+ 554, 554, 554, 554, 555, 345, 218, 695, 320, 320, -+ 320, 320, 320, 320, 334, 335, 336, 334, 334, 334, -+ 334, 334, 334, 334, 813, 218, 345, 218, 483, 483, -+ 483, 483, 483, 483, 731, 127, 416, 813, 416, 487, -+ 487, 487, 487, 487, 487, 487, 487, 487, 487, 534, -+ -+ 101, 339, 339, 340, 341, 341, 341, 341, 341, 341, -+ 341, 279, 345, 218, 346, 346, 346, 346, 346, 346, -+ 346, 346, 346, 346, 347, 101, 683, 684, 348, 348, -+ 348, 348, 348, 631, 105, 514, 515, 516, 517, 515, -+ 515, 515, 515, 515, 515, 515, 600, 600, 600, 600, -+ 600, 601, 348, 348, 348, 348, 348, 348, 218, 352, -+ 353, 354, 352, 352, 352, 352, 352, 352, 352, 355, -+ 730, 695, 127, 356, 356, 356, 356, 356, 527, 527, -+ 527, 527, 527, 527, 527, 527, 527, 527, 632, 623, -+ 695, 680, 675, 218, 127, 127, 127, 356, 356, 356, -+ -+ 356, 356, 356, 813, 347, 348, 348, 348, 348, 348, -+ 348, 348, 348, 348, 348, 384, 384, 384, 384, 384, -+ 384, 384, 384, 384, 384, 695, 676, 676, 813, 384, -+ 384, 384, 384, 384, 475, 475, 475, 475, 475, 475, -+ 475, 475, 475, 475, 618, 618, 618, 618, 618, 619, -+ 677, 677, 813, 384, 384, 384, 384, 384, 384, 385, -+ 385, 385, 385, 385, 385, 385, 385, 385, 385, 703, -+ 634, 694, 127, 385, 385, 385, 385, 385, 536, 536, -+ 536, 536, 536, 536, 536, 536, 536, 536, 100, 100, -+ 100, 100, 634, 218, 634, 634, 734, 384, 384, 384, -+ -+ 384, 384, 384, 399, 416, 400, 400, 400, 400, 400, -+ 400, 400, 400, 400, 400, 399, 532, 401, 401, 401, -+ 401, 401, 401, 401, 401, 401, 401, 399, 534, 402, -+ 402, 402, 402, 402, 403, 400, 400, 400, 400, 405, -+ 405, 405, 405, 405, 405, 405, 405, 405, 405, 279, -+ 345, 218, 414, 414, 414, 414, 414, 414, 414, 414, -+ 414, 414, 347, 634, 105, 101, 413, 413, 413, 413, -+ 413, 544, 545, 546, 544, 544, 544, 544, 544, 544, -+ 544, 686, 761, 107, 127, 634, 107, 634, 635, 644, -+ 413, 413, 413, 413, 413, 413, 345, 218, 415, 415, -+ -+ 415, 415, 415, 415, 415, 415, 415, 415, 416, 345, -+ 218, 101, 417, 417, 417, 417, 417, 345, 218, 813, -+ 218, 416, 127, 127, 127, 762, 105, 101, 733, 485, -+ 676, 485, 561, 564, 101, 566, 417, 417, 417, 417, -+ 417, 417, 218, 421, 422, 423, 421, 421, 421, 421, -+ 421, 421, 421, 424, 677, 684, 813, 425, 425, 425, -+ 425, 425, 494, 494, 494, 494, 494, 494, 494, 494, -+ 494, 494, 662, 662, 662, 662, 662, 663, 101, 105, -+ 813, 425, 425, 425, 425, 425, 425, 813, 571, 417, -+ 417, 417, 417, 417, 417, 417, 417, 417, 417, 446, -+ -+ 701, 449, 449, 449, 449, 449, 450, 447, 447, 447, -+ 447, 384, 384, 384, 384, 384, 384, 384, 384, 384, -+ 384, 781, 782, 781, 782, 384, 384, 384, 384, 384, -+ 345, 218, 549, 549, 549, 549, 549, 549, 685, 575, -+ 575, 607, 485, 608, 608, 608, 608, 608, 608, 384, -+ 384, 384, 384, 384, 384, 464, 465, 466, 464, 464, -+ 464, 464, 464, 464, 464, 553, 553, 553, 553, 553, -+ 553, 553, 553, 553, 553, 591, 592, 593, 591, 591, -+ 591, 591, 591, 591, 591, 695, 732, 700, 700, 700, -+ 644, 101, 399, 532, 400, 400, 400, 400, 400, 400, -+ -+ 400, 400, 400, 400, 399, 597, 400, 400, 400, 400, -+ 400, 400, 400, 400, 400, 400, 471, 472, 473, 471, -+ 471, 471, 471, 471, 471, 471, 474, 728, 101, 728, -+ 475, 475, 475, 475, 475, 543, 543, 543, 543, 543, -+ 543, 543, 543, 543, 543, 127, 211, 741, 786, 211, -+ 218, 729, 218, 729, 475, 475, 475, 475, 475, 475, -+ 476, 416, 479, 479, 479, 479, 479, 480, 477, 477, -+ 477, 477, 345, 218, 483, 483, 483, 483, 483, 483, -+ 483, 483, 483, 483, 416, 101, 101, 218, 482, 482, -+ 482, 482, 482, 532, 813, 595, 595, 595, 595, 595, -+ -+ 595, 169, 169, 169, 218, 534, 597, 688, 759, 689, -+ 690, 691, 482, 482, 482, 482, 482, 482, 345, 218, -+ 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, -+ 485, 316, 760, 316, 486, 486, 486, 486, 486, 599, -+ 599, 599, 599, 599, 599, 599, 599, 599, 599, 574, -+ 575, 575, 575, 575, 575, 575, 597, 692, 486, 486, -+ 486, 486, 486, 486, 218, 490, 491, 492, 490, 490, -+ 490, 490, 490, 490, 490, 493, 218, 345, 218, 494, -+ 494, 494, 494, 494, 345, 218, 218, 485, 218, 485, -+ 813, 218, 169, 169, 169, 534, 551, 485, 532, 551, -+ -+ 759, 813, 551, 494, 494, 494, 494, 494, 494, 813, -+ 597, 486, 486, 486, 486, 486, 486, 486, 486, 486, -+ 486, 100, 650, 778, 760, 813, 317, 100, 317, 735, -+ 100, 100, 735, 100, 100, 100, 127, 127, 127, 127, -+ 127, 127, 127, 127, 127, 127, 702, 779, 650, 100, -+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -+ 127, 127, 127, 127, 495, 127, 127, 127, 127, 127, -+ 127, 127, 101, 127, 100, 100, 100, 100, 100, 100, -+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, -+ 100, 525, 526, 526, 526, 526, 526, 526, 526, 526, -+ -+ 526, 526, 345, 218, 614, 614, 614, 614, 614, 614, -+ 447, 650, 447, 532, 551, 617, 617, 617, 617, 617, -+ 617, 617, 617, 617, 617, 659, 576, 576, 101, 532, -+ 813, 533, 533, 533, 533, 533, 533, 533, 533, 533, -+ 533, 534, 659, 695, 813, 535, 535, 535, 535, 535, -+ 636, 637, 638, 639, 636, 636, 636, 636, 636, 636, -+ 345, 218, 674, 674, 674, 674, 674, 674, 813, 535, -+ 535, 535, 535, 535, 535, 539, 540, 541, 539, 539, -+ 539, 539, 539, 539, 539, 542, 778, 695, 739, 543, -+ 543, 543, 543, 543, 646, 646, 646, 646, 646, 646, -+ -+ 646, 646, 646, 646, 448, 477, 448, 477, 345, 218, -+ 779, 575, 575, 543, 543, 543, 543, 543, 543, 813, -+ 551, 535, 535, 535, 535, 535, 535, 535, 535, 535, -+ 535, 345, 218, 549, 549, 549, 549, 549, 549, 549, -+ 549, 549, 549, 485, 728, 681, 813, 548, 548, 548, -+ 548, 548, 647, 647, 647, 647, 647, 648, 649, 649, -+ 649, 649, 688, 607, 689, 690, 691, 478, 729, 478, -+ 813, 548, 548, 548, 548, 548, 548, 345, 218, 550, -+ 550, 550, 550, 550, 550, 550, 550, 550, 550, 551, -+ 127, 740, 813, 552, 552, 552, 552, 552, 606, 606, -+ -+ 606, 606, 606, 606, 606, 606, 606, 606, 447, 477, -+ 447, 477, 694, 608, 607, 608, 813, 552, 552, 552, -+ 552, 552, 552, 218, 556, 557, 558, 556, 556, 556, -+ 556, 556, 556, 556, 607, 609, 768, 609, 559, 559, -+ 559, 559, 559, 532, 534, 657, 657, 657, 657, 657, -+ 657, 651, 650, 651, 650, 597, 651, 651, 651, 651, -+ 651, 651, 559, 559, 559, 559, 559, 559, 813, 532, -+ 552, 552, 552, 552, 552, 552, 552, 552, 552, 552, -+ 100, 659, 652, 608, 652, 608, 100, 687, 687, 100, -+ 100, 687, 100, 100, 100, 127, 127, 127, 127, 127, -+ -+ 127, 127, 127, 127, 127, 687, 687, 687, 100, 127, -+ 127, 127, 127, 127, 127, 127, 560, 127, 127, 127, -+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -+ 127, 101, 127, 100, 100, 100, 100, 100, 100, 100, -+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, -+ 574, 577, 577, 577, 577, 577, 578, 575, 575, 575, -+ 575, 187, 723, 723, 532, 187, 198, 198, 198, 198, -+ 198, 198, 198, 198, 198, 198, 714, 187, 724, 724, -+ 198, 198, 198, 583, 198, 198, 198, 198, 198, 198, -+ 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, -+ -+ 198, 198, 650, 200, 187, 187, 187, 187, 187, 187, -+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, -+ 187, 586, 587, 588, 589, 586, 586, 586, 586, 586, -+ 586, 661, 661, 661, 661, 661, 661, 661, 661, 661, -+ 661, 669, 670, 671, 669, 669, 669, 669, 669, 669, -+ 669, 717, 717, 717, 717, 717, 718, 101, 525, 526, -+ 526, 526, 526, 526, 526, 526, 526, 526, 526, 707, -+ 708, 709, 707, 707, 707, 707, 707, 707, 707, 668, -+ 668, 668, 668, 668, 668, 668, 668, 668, 668, 757, -+ 757, 757, 757, 757, 758, 101, 532, 813, 595, 595, -+ -+ 595, 595, 595, 595, 595, 595, 595, 595, 534, 714, -+ 470, 643, 594, 594, 594, 594, 594, 532, 532, 712, -+ 712, 712, 712, 712, 712, 696, 697, 696, 697, 659, -+ 714, 813, 218, 813, 813, 813, 594, 594, 594, 594, -+ 594, 594, 532, 551, 596, 596, 596, 596, 596, 596, -+ 596, 596, 596, 596, 597, 759, 642, 641, 598, 598, -+ 598, 598, 598, 716, 716, 716, 716, 716, 716, 716, -+ 716, 716, 716, 688, 640, 689, 690, 691, 651, 760, -+ 651, 692, 598, 598, 598, 598, 598, 598, 602, 603, -+ 604, 602, 602, 602, 602, 602, 602, 602, 605, 574, -+ -+ 574, 127, 606, 606, 606, 606, 606, 736, 737, 738, -+ 736, 736, 736, 736, 736, 736, 736, 791, 791, 791, -+ 791, 791, 791, 692, 574, 101, 606, 606, 606, 606, -+ 606, 606, 813, 630, 598, 598, 598, 598, 598, 598, -+ 598, 598, 598, 598, 607, 629, 610, 610, 610, 610, -+ 610, 611, 608, 608, 608, 608, 345, 218, 614, 614, -+ 614, 614, 614, 614, 614, 614, 614, 614, 551, 101, -+ 218, 778, 613, 613, 613, 613, 613, 813, 607, 689, -+ 690, 691, 813, 607, 813, 813, 691, 695, 470, 696, -+ 696, 696, 696, 696, 696, 779, 613, 613, 613, 613, -+ -+ 613, 613, 345, 218, 615, 615, 615, 615, 615, 615, -+ 615, 615, 615, 615, 747, 343, 747, 127, 616, 616, -+ 616, 616, 616, 748, 764, 748, 764, 692, 765, 797, -+ 765, 797, 692, 218, 723, 723, 723, 723, 723, 723, -+ 585, 582, 616, 616, 616, 616, 616, 616, 813, 581, -+ 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, -+ 100, 693, 580, 693, 693, 693, 100, 693, 693, 100, -+ 100, 693, 100, 100, 100, 127, 127, 127, 127, 127, -+ 127, 127, 127, 127, 127, 693, 693, 693, 100, 127, -+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, -+ -+ 127, 127, 127, 127, 127, 127, 127, 620, 127, 127, -+ 127, 101, 127, 100, 100, 100, 100, 100, 100, 100, -+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, -+ 625, 746, 579, 747, 747, 747, 747, 747, 747, 187, -+ 798, 574, 798, 187, 198, 198, 198, 198, 198, 198, -+ 198, 198, 198, 198, 626, 187, 574, 569, 198, 198, -+ 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, -+ 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, -+ 568, 200, 187, 187, 187, 187, 187, 187, 187, 187, -+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 644, -+ -+ 476, 645, 645, 645, 645, 645, 645, 645, 645, 645, -+ 645, 722, 722, 722, 722, 722, 722, 722, 722, 722, -+ 722, 532, 476, 753, 753, 753, 753, 753, 753, 755, -+ 476, 470, 755, 714, 343, 279, 755, 101, 650, 524, -+ 653, 653, 653, 653, 653, 654, 651, 651, 651, 651, -+ 532, 523, 657, 657, 657, 657, 657, 657, 657, 657, -+ 657, 657, 597, 522, 519, 518, 656, 656, 656, 656, -+ 656, 756, 756, 756, 756, 756, 756, 756, 756, 756, -+ 756, 532, 446, 777, 777, 777, 777, 777, 777, 446, -+ 656, 656, 656, 656, 656, 656, 532, 446, 658, 658, -+ -+ 658, 658, 658, 658, 658, 658, 658, 658, 659, 510, -+ 509, 101, 660, 660, 660, 660, 660, 735, 735, 735, -+ 735, 735, 735, 735, 735, 735, 735, 763, 101, 764, -+ 764, 764, 764, 764, 764, 101, 660, 660, 660, 660, -+ 660, 660, 664, 665, 666, 664, 664, 664, 664, 664, -+ 664, 664, 667, 101, 476, 476, 668, 668, 668, 668, -+ 668, 735, 735, 735, 735, 735, 735, 735, 735, 735, -+ 735, 470, 741, 343, 742, 742, 742, 742, 742, 742, -+ 668, 668, 668, 668, 668, 668, 813, 279, 660, 660, -+ 660, 660, 660, 660, 660, 660, 660, 660, 345, 218, -+ -+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, -+ 101, 279, 463, 462, 673, 673, 673, 673, 673, 772, -+ 773, 774, 772, 772, 772, 772, 772, 772, 772, 796, -+ 461, 797, 797, 797, 797, 797, 797, 460, 673, 673, -+ 673, 673, 673, 673, 695, 459, 698, 698, 698, 698, -+ 698, 699, 700, 700, 700, 700, 704, 705, 706, 704, -+ 704, 704, 704, 704, 704, 704, 783, 784, 785, 783, -+ 783, 783, 783, 783, 783, 783, 791, 791, 791, 791, -+ 791, 791, 791, 791, 791, 791, 810, 810, 810, 810, -+ 810, 810, 101, 644, 458, 645, 645, 645, 645, 645, -+ -+ 645, 645, 645, 645, 645, 792, 792, 792, 792, 792, -+ 792, 792, 792, 792, 792, 793, 793, 793, 793, 793, -+ 794, 791, 791, 791, 791, 457, 795, 456, 455, 795, -+ 454, 101, 532, 795, 712, 712, 712, 712, 712, 712, -+ 712, 712, 712, 712, 659, 453, 452, 451, 711, 711, -+ 711, 711, 711, 786, 813, 787, 787, 787, 787, 787, -+ 787, 791, 791, 791, 791, 791, 791, 791, 791, 791, -+ 791, 446, 711, 711, 711, 711, 711, 711, 532, 446, -+ 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, -+ 714, 101, 374, 441, 715, 715, 715, 715, 715, 791, -+ -+ 791, 791, 791, 791, 791, 791, 791, 791, 791, 440, -+ 434, 433, 432, 431, 430, 429, 428, 427, 715, 715, -+ 715, 715, 715, 715, 719, 720, 721, 719, 719, 719, -+ 719, 719, 719, 719, 426, 408, 343, 279, 722, 722, -+ 722, 722, 722, 804, 805, 806, 804, 804, 804, 804, -+ 804, 804, 804, 404, 279, 125, 807, 807, 807, 807, -+ 807, 807, 722, 722, 722, 722, 722, 722, 813, 398, -+ 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, -+ 218, 725, 725, 725, 725, 725, 726, 723, 723, 723, -+ 723, 741, 101, 742, 742, 742, 742, 742, 742, 742, -+ -+ 742, 742, 742, 741, 397, 743, 743, 743, 743, 743, -+ 743, 743, 743, 743, 743, 741, 396, 744, 744, 744, -+ 744, 744, 745, 742, 742, 742, 742, 746, 393, 749, -+ 749, 749, 749, 749, 750, 747, 747, 747, 747, 532, -+ 392, 753, 753, 753, 753, 753, 753, 753, 753, 753, -+ 753, 714, 391, 390, 389, 752, 752, 752, 752, 752, -+ 810, 810, 810, 810, 810, 810, 810, 810, 810, 810, -+ 388, 315, 315, 315, 374, 376, 374, 375, 374, 752, -+ 752, 752, 752, 752, 752, 532, 368, 754, 754, 754, -+ 754, 754, 754, 754, 754, 754, 754, 367, 366, 365, -+ -+ 364, 755, 755, 755, 755, 755, 804, 804, 804, 804, -+ 804, 804, 804, 804, 804, 804, 363, 362, 359, 119, -+ 279, 343, 279, 125, 105, 755, 755, 755, 755, 755, -+ 755, 763, 333, 766, 766, 766, 766, 766, 767, 764, -+ 764, 764, 764, 100, 329, 769, 770, 771, 769, 769, -+ 769, 769, 769, 769, 769, 741, 328, 742, 742, 742, -+ 742, 742, 742, 742, 742, 742, 742, 741, 327, 742, -+ 742, 742, 742, 742, 742, 742, 742, 742, 742, 532, -+ 326, 777, 777, 777, 777, 777, 777, 777, 777, 777, -+ 777, 786, 325, 787, 787, 787, 787, 787, 787, 787, -+ -+ 787, 787, 787, 786, 324, 788, 788, 788, 788, 788, -+ 788, 788, 788, 788, 788, 786, 323, 789, 789, 789, -+ 789, 789, 790, 787, 787, 787, 787, 796, 322, 799, -+ 799, 799, 799, 799, 800, 797, 797, 797, 797, 100, -+ 191, 801, 802, 803, 801, 801, 801, 801, 801, 801, -+ 801, 786, 315, 787, 787, 787, 787, 787, 787, 787, -+ 787, 787, 787, 786, 315, 787, 787, 787, 787, 787, -+ 787, 787, 787, 787, 787, 807, 807, 807, 807, 807, -+ 807, 807, 807, 807, 807, 811, 811, 811, 811, 811, -+ 812, 810, 810, 810, 810, 810, 810, 810, 810, 810, -+ -+ 810, 810, 810, 810, 810, 250, 312, 309, 308, 307, -+ 306, 101, 801, 801, 801, 801, 801, 801, 801, 801, -+ 801, 801, 305, 300, 299, 298, 297, 296, 295, 294, -+ 293, 292, 291, 290, 289, 125, 117, 105, 105, 267, -+ 266, 265, 264, 259, 258, 257, 813, 188, 101, 808, -+ 808, 808, 808, 808, 809, 807, 807, 807, 807, 250, -+ 176, 177, 171, 171, 163, 248, 157, 157, 241, 240, -+ 239, 238, 237, 234, 233, 232, 231, 230, 225, 224, -+ 223, 222, 125, 100, 125, 101, 807, 807, 807, 807, -+ 807, 807, 807, 807, 807, 807, 190, 113, 210, 105, -+ -+ 103, 102, 101, 205, 204, 203, 202, 198, 177, 171, -+ 163, 133, 131, 157, 156, 153, 151, 137, 136, 135, -+ 132, 127, 101, 61, 61, 61, 61, 61, 61, 61, -+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, -+ 61, 61, 61, 61, 33, 33, 33, 33, 33, 33, -+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, -+ 33, 33, 33, 33, 33, 70, 70, 70, 70, 70, -+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, -+ 70, 70, 70, 70, 70, 70, 77, 77, 77, 77, -+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, -+ -+ 77, 77, 77, 77, 77, 77, 77, 100, 125, 113, -+ 103, 102, 101, 813, 100, 813, 100, 100, 100, 100, -+ 813, 813, 100, 100, 100, 100, 100, 100, 104, 104, -+ 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, -+ 104, 104, 104, 104, 104, 104, 104, 104, 104, 108, -+ 813, 813, 813, 813, 108, 813, 108, 813, 108, 108, -+ 108, 108, 108, 813, 108, 108, 108, 108, 108, 108, -+ 112, 813, 813, 813, 813, 813, 813, 112, 813, 112, -+ 112, 112, 112, 813, 813, 112, 112, 112, 112, 112, -+ 112, 114, 813, 813, 114, 114, 813, 114, 114, 813, -+ -+ 114, 114, 114, 114, 813, 813, 114, 114, 114, 114, -+ 114, 114, 124, 124, 813, 124, 813, 813, 813, 124, -+ 158, 813, 813, 158, 158, 813, 158, 158, 813, 158, -+ 158, 158, 158, 813, 813, 158, 158, 158, 158, 158, -+ 158, 162, 813, 813, 162, 162, 813, 162, 162, 813, -+ 162, 162, 162, 162, 813, 162, 162, 162, 813, 162, -+ 162, 162, 170, 813, 813, 170, 813, 813, 170, 170, -+ 813, 170, 170, 170, 170, 170, 813, 170, 170, 170, -+ 170, 170, 170, 174, 174, 174, 174, 174, 174, 174, -+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, -+ -+ 174, 174, 174, 174, 176, 176, 813, 176, 813, 176, -+ 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, -+ 176, 176, 176, 176, 176, 182, 813, 813, 813, 813, -+ 182, 813, 182, 813, 182, 182, 182, 182, 182, 813, -+ 182, 182, 182, 182, 182, 182, 186, 813, 813, 813, -+ 813, 813, 813, 186, 813, 186, 186, 186, 186, 813, -+ 186, 186, 186, 186, 186, 186, 186, 189, 813, 813, -+ 189, 189, 813, 189, 189, 813, 189, 189, 189, 189, -+ 813, 189, 189, 189, 189, 189, 189, 189, 208, 208, -+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, -+ -+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, -+ 209, 813, 209, 209, 209, 209, 209, 209, 209, 209, -+ 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, -+ 115, 813, 813, 115, 115, 813, 115, 115, 813, 115, -+ 115, 115, 115, 813, 813, 115, 115, 115, 115, 115, -+ 115, 124, 124, 813, 124, 813, 813, 813, 124, 217, -+ 217, 813, 217, 813, 813, 813, 217, 219, 219, 219, -+ 813, 219, 813, 813, 813, 219, 158, 813, 813, 158, -+ 158, 813, 158, 158, 813, 158, 158, 158, 158, 813, -+ 813, 158, 158, 158, 158, 158, 158, 159, 813, 813, -+ -+ 159, 159, 813, 159, 159, 813, 159, 159, 159, 159, -+ 813, 813, 159, 159, 159, 159, 159, 159, 162, 813, -+ 813, 162, 162, 813, 162, 162, 813, 162, 162, 162, -+ 162, 813, 162, 162, 162, 813, 162, 162, 162, 170, -+ 813, 813, 170, 813, 813, 170, 170, 813, 170, 170, -+ 170, 170, 170, 813, 170, 170, 170, 170, 170, 170, -+ 185, 813, 813, 813, 813, 813, 813, 185, 813, 185, -+ 185, 185, 185, 813, 813, 185, 185, 185, 185, 185, -+ 185, 186, 813, 813, 813, 813, 813, 813, 186, 813, -+ 186, 186, 186, 186, 813, 186, 186, 186, 186, 186, -+ -+ 186, 186, 189, 813, 813, 189, 189, 813, 189, 189, -+ 813, 189, 189, 189, 189, 813, 189, 189, 189, 189, -+ 189, 189, 189, 200, 813, 813, 200, 200, 813, 200, -+ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, -+ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, -+ 268, 275, 275, 813, 275, 813, 813, 813, 275, 281, -+ 281, 281, 813, 281, 813, 813, 813, 281, 337, 337, -+ 813, 337, 813, 813, 813, 337, 338, 338, 813, 338, -+ 813, 813, 813, 338, 342, 342, 813, 342, 813, 813, -+ 813, 342, 344, 344, 344, 813, 344, 813, 813, 813, -+ -+ 344, 200, 813, 813, 200, 200, 813, 200, 404, 404, -+ 813, 404, 813, 813, 813, 404, 406, 406, 813, 406, -+ 813, 813, 813, 406, 407, 407, 813, 407, 813, 813, -+ 813, 407, 409, 409, 409, 813, 409, 813, 813, 813, -+ 409, 413, 413, 413, 413, 813, 413, 813, 813, 813, -+ 413, 467, 467, 813, 467, 813, 813, 813, 467, 468, -+ 468, 813, 468, 813, 813, 813, 468, 469, 469, 813, -+ 469, 813, 813, 813, 469, 481, 481, 481, 813, 481, -+ 813, 813, 813, 481, 482, 482, 482, 482, 813, 482, -+ 813, 813, 813, 482, 208, 208, 208, 208, 208, 208, -+ -+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, -+ 208, 208, 208, 208, 208, 530, 530, 813, 530, 813, -+ 813, 813, 530, 531, 531, 813, 531, 813, 813, 813, -+ 531, 547, 547, 547, 813, 547, 813, 813, 813, 547, -+ 548, 548, 548, 548, 813, 548, 813, 813, 813, 548, -+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, -+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, -+ 208, 200, 813, 813, 200, 200, 813, 200, 187, 813, -+ 813, 813, 187, 187, 813, 187, 187, 187, 813, 813, -+ 187, 187, 590, 590, 813, 590, 813, 813, 813, 590, -+ -+ 594, 813, 594, 594, 813, 594, 813, 813, 813, 594, -+ 612, 612, 612, 813, 612, 813, 813, 813, 612, 613, -+ 613, 613, 613, 813, 613, 813, 813, 813, 613, 559, -+ 559, 813, 813, 559, 813, 813, 813, 559, 208, 208, -+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, -+ 208, 208, 208, 208, 208, 208, 208, 208, 208, 200, -+ 813, 813, 200, 200, 813, 200, 187, 813, 813, 813, -+ 187, 187, 813, 187, 187, 187, 813, 813, 187, 187, -+ 655, 655, 813, 655, 813, 813, 813, 655, 656, 813, -+ 656, 656, 813, 656, 813, 813, 813, 656, 672, 672, -+ -+ 672, 813, 672, 813, 813, 813, 672, 673, 673, 673, -+ 813, 813, 673, 813, 813, 813, 673, 682, 682, 682, -+ 682, 682, 682, 682, 682, 682, 682, 682, 682, 682, -+ 682, 682, 682, 682, 682, 682, 682, 682, 687, 687, -+ 813, 687, 687, 687, 813, 687, 813, 687, 687, 687, -+ 687, 813, 813, 687, 687, 687, 687, 687, 687, 693, -+ 693, 813, 693, 693, 693, 813, 693, 813, 693, 693, -+ 693, 693, 813, 813, 693, 693, 693, 693, 693, 693, -+ 200, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 200, 200, 813, 200, 200, 813, 200, 710, 710, -+ -+ 813, 710, 813, 813, 813, 710, 711, 813, 711, 711, -+ 813, 711, 813, 813, 813, 711, 727, 727, 813, 813, -+ 727, 813, 813, 813, 727, 693, 813, 813, 813, 813, -+ 813, 813, 693, 813, 693, 693, 693, 693, 813, 813, -+ 693, 693, 693, 693, 693, 693, 751, 751, 813, 751, -+ 813, 813, 813, 751, 752, 813, 752, 752, 813, 752, -+ 813, 813, 813, 752, 775, 775, 813, 775, 813, 813, -+ 813, 775, 776, 813, 776, 813, 813, 776, 813, 813, -+ 813, 776, 780, 780, 780, 780, 780, 780, 780, 780, -+ 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, -+ -+ 780, 780, 780, 15, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813 - } ; - --static yyconst short int yy_chk[3663] = -+static yyconst flex_int16_t yy_chk[5675] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -980,408 +1358,632 @@ static yyconst short int yy_chk[3663] = - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 2, 618, 3, -- 20, 2, 70, 3, 47, 36, 50, 4, 34, 3, -- 36, 4, 3, 11, 11, 11, 11, 4, 20, 34, -- 4, 12, 12, 12, 12, 2, 2, 70, 47, 2, -- -- 77, 38, 602, 50, 3, 599, 44, 2, 3, 3, -- 2, 3, 4, 597, 20, 38, 4, 4, 52, 4, -- 5, 5, 5, 44, 5, 6, 6, 6, 52, 6, -- 5, 11, 3, 25, 25, 6, 120, 25, 25, 12, -- 4, 120, 5, 5, 66, 66, 77, 6, 6, 9, -- 9, 9, 9, 9, 58, 25, 74, 74, 9, 9, -- 9, 28, 28, 28, 28, 28, 28, 19, 5, 143, -- 143, 58, 9, 6, 7, 7, 7, 19, 7, 25, -- 19, 19, 19, 19, 19, 19, 19, 19, 27, 27, -- 27, 27, 27, 27, 27, 27, 105, 9, 10, 10, -- -- 10, 10, 10, 76, 583, 105, 90, 10, 10, 10, -- 43, 165, 43, 43, 43, 43, 43, 43, 43, 43, -- 45, 10, 7, 7, 7, 7, 7, 7, 7, 7, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 2, 533, 3, 38, 2, 52, 3, 49, 38, 50, -+ 4, 36, 3, 533, 4, 3, 11, 11, 11, 11, -+ 4, 22, 36, 4, 40, 5, 5, 5, 50, 5, -+ -+ 2, 2, 49, 52, 2, 5, 68, 68, 40, 3, -+ 807, 22, 2, 3, 3, 2, 3, 4, 54, 5, -+ 5, 4, 4, 148, 4, 6, 6, 6, 54, 6, -+ 799, 12, 12, 12, 12, 6, 11, 22, 3, 76, -+ 76, 72, 46, 27, 27, 5, 4, 27, 27, 6, -+ 6, 46, 47, 78, 9, 9, 9, 9, 9, 74, -+ 46, 164, 164, 9, 9, 9, 72, 27, 30, 30, -+ 30, 30, 30, 30, 79, 6, 7, 7, 7, 9, -+ 7, 12, 47, 47, 74, 148, 47, 60, 141, 81, -+ 81, 27, 81, 141, 47, 91, 60, 47, 10, 10, -+ -+ 10, 10, 10, 78, 9, 60, 91, 10, 10, 10, -+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+ 161, 798, 79, 10, 179, 161, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -- 8, 8, 8, 48, 8, 128, 10, 72, 45, 45, -- 90, 76, 45, 79, 79, 165, 79, 128, 582, 127, -- 45, 53, 48, 45, 53, 53, 53, 53, 53, 53, -- 53, 53, 72, 86, 86, 86, 86, 86, 86, 86, -- 86, 103, 103, 103, 103, 103, 103, 580, 8, 8, -- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -+ 7, 7, 7, 7, 7, 8, 8, 8, 10, 8, -+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, -+ 87, 87, 87, 87, 87, 87, 99, 101, 274, 101, -+ 101, 101, 179, 101, 101, 99, 149, 101, 106, 106, -+ 106, 106, 106, 106, 106, 106, 106, 106, 140, 149, -+ 140, 101, 101, 101, 274, 8, 8, 8, 8, 8, - -- 8, 8, 8, 8, 8, 8, 26, 131, 26, 26, -- 26, 26, 26, 26, 26, 26, 26, 88, 127, 131, -- 26, 26, 26, 26, 26, 130, 191, 112, 579, 55, -- 55, 129, 112, 55, 55, 88, 112, 132, 112, 191, -- 130, 202, 26, 132, 26, 26, 26, 26, 26, 26, -- 32, 55, 140, 147, 147, 202, 32, 140, 575, 32, -- 32, 88, 32, 32, 32, 32, 32, 32, 32, 32, -- 32, 32, 32, 32, 129, 55, 32, 32, 32, 32, -- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -- -- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -- 32, 32, 32, 32, 32, 32, 32, 35, 35, 35, -- 35, 35, 35, 35, 35, 35, 65, 118, 118, 35, -- 35, 35, 35, 35, 159, 159, 65, 133, 35, 65, -- 65, 65, 65, 65, 65, 65, 65, 133, 154, 154, -- 201, 208, 201, 35, 35, 35, 35, 35, 35, 42, -- 42, 42, 42, 42, 158, 42, 42, 175, 157, 42, -- 64, 64, 64, 200, 64, 118, 175, 219, 64, 197, -- 64, 42, 42, 42, 46, 198, 219, 208, 212, 200, -- 198, 227, 64, 64, 46, 564, 154, 46, 46, 46, -- -- 46, 46, 46, 46, 46, 81, 560, 81, 81, 81, -- 158, 81, 81, 227, 212, 81, 157, 245, 64, 87, -- 87, 87, 87, 87, 87, 87, 87, 81, 81, 81, -- 197, 94, 94, 556, 229, 94, 94, 204, 89, 229, -- 46, 89, 89, 89, 89, 89, 89, 89, 89, 91, -- 204, 91, 91, 94, 544, 91, 91, 239, 93, 91, -- 93, 93, 93, 239, 93, 93, 246, 246, 93, 216, -- 216, 216, 91, 91, 245, 289, 248, 94, 249, 260, -- 93, 93, 93, 96, 249, 96, 96, 96, 260, 96, -- 96, 248, 543, 96, 97, 97, 97, 97, 97, 97, -- -- 97, 97, 273, 290, 294, 96, 96, 96, 101, 101, -- 101, 101, 101, 101, 101, 101, 102, 102, 102, 102, -- 102, 102, 102, 102, 273, 290, 482, 291, 97, 98, -- 98, 98, 98, 98, 98, 98, 98, 291, 247, 289, -- 294, 98, 98, 98, 98, 98, 135, 135, 135, 135, -- 135, 135, 135, 135, 332, 433, 285, 433, 137, 137, -- 121, 285, 137, 137, 247, 98, 98, 98, 98, 98, -- 98, 106, 106, 106, 106, 106, 106, 106, 106, 106, -- 137, 247, 482, 106, 106, 106, 106, 106, 121, 121, -- 303, 139, 121, 139, 139, 139, 307, 139, 139, 303, -- -- 121, 139, 528, 121, 137, 307, 332, 106, 106, 106, -- 106, 106, 106, 139, 139, 139, 146, 146, 146, 146, -- 146, 146, 146, 146, 150, 292, 324, 150, 150, 334, -- 292, 324, 383, 524, 150, 163, 163, 163, 163, 163, -- 163, 163, 163, 323, 523, 334, 385, 150, 164, 164, -- 164, 164, 164, 164, 164, 164, 166, 522, 166, 166, -- 167, 385, 166, 166, 167, 323, 166, 262, 262, 211, -- 167, 211, 211, 211, 211, 211, 211, 262, 166, 166, -- 166, 521, 167, 167, 168, 383, 168, 168, 168, 168, -- 168, 168, 168, 168, 169, 327, 169, 169, 169, 169, -- -- 169, 169, 169, 169, 170, 211, 170, 170, 170, 170, -- 170, 170, 170, 170, 203, 264, 264, 327, 203, 388, -- 168, 308, 308, 380, 203, 264, 329, 515, 309, 309, -- 169, 308, 311, 311, 498, 329, 203, 203, 309, 380, -- 170, 171, 311, 171, 171, 171, 171, 171, 171, 171, -- 171, 400, 400, 497, 388, 171, 171, 171, 171, 171, -- 207, 207, 207, 207, 207, 207, 207, 207, 209, 335, -- 209, 209, 209, 209, 209, 209, 209, 209, 335, 171, -- 171, 171, 171, 171, 171, 174, 174, 174, 174, 174, -- 174, 174, 174, 174, 207, 451, 451, 174, 174, 174, -- -- 174, 174, 527, 210, 209, 210, 210, 210, 210, 210, -- 210, 210, 210, 220, 220, 220, 220, 220, 220, 220, -- 220, 174, 174, 174, 174, 174, 174, 176, 176, 176, -- 176, 176, 176, 176, 176, 176, 176, 465, 465, 210, -- 176, 176, 176, 176, 176, 215, 215, 215, 215, 215, -- 215, 215, 215, 215, 222, 222, 222, 222, 222, 222, -- 222, 222, 386, 527, 176, 176, 176, 176, 176, 176, -- 177, 177, 177, 177, 177, 177, 177, 177, 386, 466, -- 466, 328, 177, 177, 177, 177, 177, 223, 223, 223, -- 223, 223, 223, 225, 333, 225, 225, 225, 225, 225, -- -- 225, 225, 225, 328, 333, 493, 177, 177, 177, 177, -- 177, 177, 221, 221, 221, 221, 221, 221, 221, 221, -- 221, 221, 221, 353, 469, 469, 221, 221, 221, 221, -- 221, 250, 353, 250, 250, 250, 250, 250, 250, 250, -- 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, -- 221, 221, 221, 221, 221, 221, 224, 224, 224, 224, -- 224, 224, 224, 224, 224, 224, 354, 250, 479, 224, -- 224, 224, 224, 224, 251, 354, 251, 251, 251, 251, -- 251, 251, 251, 251, 261, 261, 261, 261, 261, 261, -- 261, 261, 474, 224, 224, 224, 224, 224, 224, 252, -- -- 473, 252, 252, 252, 252, 252, 252, 252, 252, 370, -- 251, 263, 263, 263, 263, 263, 263, 263, 263, 267, -- 267, 267, 267, 267, 267, 267, 267, 481, 481, 267, -- 472, 370, 505, 505, 470, 252, 265, 265, 265, 265, -- 265, 265, 265, 265, 265, 265, 265, 268, 268, 268, -- 268, 268, 268, 268, 268, 268, 268, 268, 376, 378, -- 427, 268, 268, 268, 268, 268, 269, 269, 269, 269, -- 269, 269, 269, 269, 270, 270, 270, 270, 270, 270, -- 376, 378, 427, 516, 516, 268, 268, 268, 268, 268, -- 268, 271, 271, 271, 271, 271, 271, 271, 271, 271, -- -- 271, 384, 525, 525, 271, 271, 271, 271, 271, 272, -- 384, 272, 272, 272, 272, 272, 272, 272, 272, 293, -- 293, 293, 293, 293, 293, 293, 293, 458, 271, 271, -- 271, 271, 271, 271, 295, 395, 295, 295, 295, 295, -- 295, 295, 295, 295, 297, 395, 297, 297, 297, 297, -- 297, 297, 296, 293, 296, 296, 296, 296, 296, 296, -- 296, 296, 317, 317, 317, 317, 317, 317, 444, 304, -- 295, 304, 304, 304, 304, 304, 304, 304, 304, 440, -- 297, 345, 345, 345, 345, 345, 345, 435, 296, 302, -- 302, 302, 302, 302, 302, 302, 302, 302, 409, 551, -- -- 551, 302, 302, 302, 302, 302, 305, 409, 305, 305, -- 305, 305, 305, 305, 305, 305, 310, 310, 310, 310, -- 310, 310, 310, 310, 431, 302, 302, 302, 302, 302, -- 302, 306, 430, 306, 306, 306, 306, 306, 306, 306, -- 306, 312, 312, 312, 312, 312, 312, 312, 312, 312, -- 312, 312, 314, 314, 314, 314, 314, 314, 314, 314, -- 483, 429, 314, 315, 315, 315, 315, 315, 315, 315, -- 315, 315, 315, 315, 426, 483, 425, 315, 315, 315, -- 315, 315, 316, 316, 316, 316, 316, 316, 316, 316, -- 319, 410, 319, 319, 319, 319, 319, 319, 319, 319, -- -- 410, 315, 315, 315, 315, 315, 315, 318, 318, 318, -- 318, 318, 318, 318, 318, 318, 318, 566, 566, 424, -- 318, 318, 318, 318, 318, 336, 336, 336, 336, 336, -- 336, 336, 336, 336, 337, 337, 337, 337, 337, 337, -- 337, 337, 337, 423, 318, 318, 318, 318, 318, 318, -- 338, 338, 338, 338, 338, 338, 338, 338, 338, 422, -- 336, 342, 342, 342, 342, 342, 342, 342, 342, 337, -- 344, 344, 344, 344, 344, 344, 344, 344, 364, 364, -- 364, 364, 364, 364, 428, 338, 343, 397, 343, 343, -- 343, 343, 343, 343, 343, 343, 343, 397, 586, 586, -- -- 343, 343, 343, 343, 343, 347, 428, 347, 347, 347, -- 347, 347, 347, 347, 347, 348, 348, 348, 348, 348, -- 348, 348, 348, 393, 343, 343, 343, 343, 343, 343, -- 346, 346, 346, 346, 346, 346, 346, 346, 346, 392, -- 432, 432, 346, 346, 346, 346, 346, 350, 445, 350, -- 350, 350, 350, 350, 350, 350, 350, 352, 445, 352, -- 352, 352, 352, 352, 352, 382, 346, 346, 346, 346, -- 346, 346, 351, 381, 351, 351, 351, 351, 351, 351, -- 351, 351, 355, 355, 356, 356, 403, 403, 403, 403, -- 403, 403, 355, 432, 356, 357, 357, 357, 357, 357, -- -- 357, 357, 357, 358, 358, 363, 363, 363, 363, 363, -- 363, 363, 363, 358, 359, 359, 359, 359, 359, 359, -- 359, 359, 359, 359, 359, 361, 361, 361, 361, 361, -- 361, 361, 361, 590, 590, 361, 362, 362, 362, 362, -- 362, 362, 362, 362, 362, 362, 362, 462, 603, 603, -- 362, 362, 362, 362, 362, 366, 462, 366, 366, 366, -- 366, 366, 366, 366, 366, 387, 387, 387, 387, 387, -- 387, 387, 387, 375, 362, 362, 362, 362, 362, 362, -- 365, 365, 365, 365, 365, 365, 365, 365, 365, 463, -- 634, 634, 374, 365, 365, 365, 365, 365, 463, 387, -- -- 389, 389, 389, 389, 389, 389, 389, 389, 389, 391, -- 391, 391, 391, 391, 391, 391, 373, 365, 365, 365, -- 365, 365, 365, 390, 390, 390, 390, 390, 390, 390, -- 390, 390, 471, 434, 372, 389, 394, 394, 394, 394, -- 394, 394, 394, 394, 391, 396, 396, 396, 396, 396, -- 396, 396, 396, 434, 471, 434, 434, 398, 390, 398, -- 398, 398, 398, 398, 398, 398, 398, 398, 401, 487, -- 401, 401, 401, 401, 401, 401, 401, 401, 401, 434, -- 369, 368, 401, 401, 401, 401, 401, 402, 402, 402, -- 402, 402, 402, 402, 402, 405, 367, 405, 405, 405, -- -- 405, 405, 405, 405, 405, 487, 401, 401, 401, 401, -- 401, 401, 404, 404, 404, 404, 404, 404, 404, 404, -- 404, 514, 349, 341, 404, 404, 404, 404, 404, 406, -- 514, 406, 406, 406, 406, 406, 406, 406, 406, 420, -- 420, 420, 420, 420, 420, 411, 411, 340, 404, 404, -- 404, 404, 404, 404, 407, 411, 407, 407, 407, 407, -- 407, 407, 407, 407, 408, 339, 408, 408, 408, 408, -- 408, 408, 408, 408, 412, 412, 413, 413, 413, 413, -- 413, 413, 413, 413, 412, 414, 414, 419, 419, 419, -- 419, 419, 419, 419, 419, 414, 415, 415, 415, 415, -- -- 415, 415, 415, 415, 415, 415, 415, 417, 417, 417, -- 417, 417, 417, 417, 417, 331, 330, 417, 418, 418, -- 418, 418, 418, 418, 418, 418, 418, 418, 446, 326, -- 325, 322, 418, 418, 418, 418, 418, 421, 446, 421, -- 421, 421, 421, 421, 421, 421, 421, 447, 447, 447, -- 447, 447, 447, 447, 447, 321, 418, 418, 418, 418, -- 418, 418, 436, 448, 436, 436, 436, 436, 436, 436, -- 436, 436, 437, 448, 437, 437, 437, 437, 437, 437, -- 437, 437, 438, 499, 438, 438, 438, 438, 438, 438, -- 438, 438, 491, 499, 570, 606, 320, 439, 436, 439, -- -- 439, 439, 439, 439, 439, 439, 439, 441, 437, 441, -- 441, 441, 441, 441, 441, 441, 441, 442, 438, 442, -- 442, 442, 442, 442, 442, 442, 442, 301, 491, 300, -- 570, 606, 443, 439, 443, 443, 443, 443, 443, 443, -- 443, 443, 449, 475, 449, 449, 449, 449, 449, 449, -- 449, 449, 449, 452, 299, 452, 452, 452, 452, 452, -- 452, 452, 452, 452, 477, 475, 518, 452, 452, 452, -- 452, 452, 453, 453, 453, 453, 453, 453, 453, 453, -- 454, 454, 454, 454, 454, 454, 477, 298, 518, 288, -- 287, 452, 452, 452, 452, 452, 452, 455, 455, 455, -- -- 455, 455, 455, 455, 455, 455, 286, 284, 282, 455, -- 455, 455, 455, 455, 456, 281, 456, 456, 456, 456, -- 456, 456, 456, 456, 457, 457, 457, 457, 457, 457, -- 457, 457, 280, 455, 455, 455, 455, 455, 455, 459, -- 279, 459, 459, 459, 459, 459, 459, 459, 459, 460, -- 480, 460, 460, 460, 460, 460, 460, 460, 460, 461, -- 278, 461, 461, 461, 461, 461, 461, 464, 464, 685, -- 480, 277, 480, 480, 685, 276, 275, 464, 467, 467, -- 467, 467, 467, 467, 467, 467, 467, 467, 484, 259, -- 484, 484, 484, 485, 258, 485, 485, 485, 486, 486, -- -- 486, 486, 486, 486, 486, 486, 488, 500, 488, 488, -- 488, 488, 488, 488, 488, 488, 489, 500, 489, 489, -- 489, 489, 489, 489, 489, 489, 257, 502, 545, 520, -- 546, 256, 486, 254, 548, 253, 484, 502, 545, 244, -- 546, 485, 488, 490, 548, 490, 490, 490, 490, 490, -- 490, 520, 489, 492, 492, 492, 492, 492, 492, 492, -- 492, 494, 243, 494, 494, 494, 494, 494, 494, 494, -- 494, 508, 508, 508, 508, 508, 508, 242, 495, 490, -- 495, 495, 495, 495, 495, 495, 495, 495, 496, 241, -- 496, 496, 496, 496, 496, 496, 501, 501, 501, 501, -- -- 501, 501, 501, 501, 503, 561, 503, 503, 503, 503, -- 503, 503, 503, 503, 503, 506, 581, 506, 506, 506, -- 506, 506, 506, 506, 506, 506, 581, 561, 240, 506, -- 506, 506, 506, 506, 507, 507, 507, 507, 507, 507, -- 507, 507, 510, 237, 510, 510, 510, 510, 510, 510, -- 510, 510, 235, 506, 506, 506, 506, 506, 506, 509, -- 509, 509, 509, 509, 509, 509, 509, 234, 233, 232, -- 231, 509, 509, 509, 509, 509, 511, 511, 511, 511, -- 511, 511, 511, 511, 511, 512, 512, 512, 512, 512, -- 512, 512, 512, 512, 563, 509, 509, 509, 509, 509, -- -- 509, 513, 513, 513, 513, 513, 513, 513, 513, 513, -- 529, 230, 529, 529, 529, 530, 563, 530, 530, 530, -- 531, 228, 531, 531, 531, 532, 226, 532, 532, 532, -- 533, 218, 217, 533, 533, 533, 533, 533, 533, 533, -- 533, 214, 587, 534, 534, 589, 535, 534, 535, 535, -- 535, 213, 206, 536, 536, 205, 199, 536, 529, 534, -- 534, 534, 196, 530, 587, 195, 194, 589, 531, 536, -- 536, 536, 537, 532, 537, 537, 537, 537, 537, 537, -- 537, 537, 538, 600, 538, 538, 538, 538, 538, 538, -- 538, 538, 193, 539, 535, 539, 539, 539, 539, 539, -- -- 539, 539, 539, 192, 190, 600, 189, 540, 537, 540, -- 540, 540, 540, 540, 540, 540, 540, 541, 538, 541, -- 541, 541, 541, 541, 541, 541, 541, 188, 542, 539, -- 542, 542, 542, 542, 542, 542, 542, 542, 547, 547, -- 547, 547, 547, 547, 547, 547, 549, 187, 549, 549, -- 549, 549, 549, 549, 549, 549, 549, 552, 186, 552, -- 552, 552, 552, 552, 552, 552, 552, 185, 184, 183, -- 182, 552, 552, 552, 552, 552, 553, 553, 553, 553, -- 553, 553, 553, 553, 554, 554, 554, 554, 554, 554, -- 181, 180, 179, 173, 172, 552, 552, 552, 552, 552, -- -- 552, 555, 162, 555, 555, 555, 555, 555, 555, 555, -- 555, 557, 557, 557, 557, 557, 557, 557, 557, 557, -- 558, 558, 558, 558, 558, 558, 558, 558, 558, 559, -- 559, 559, 559, 559, 559, 559, 567, 567, 567, 567, -- 567, 567, 567, 567, 568, 568, 568, 568, 568, 568, -- 568, 568, 569, 569, 569, 569, 569, 569, 569, 569, -- 571, 161, 571, 571, 571, 571, 571, 571, 571, 571, -- 572, 160, 572, 572, 572, 572, 572, 572, 572, 572, -- 156, 155, 153, 149, 142, 573, 569, 573, 573, 573, -- 573, 573, 573, 138, 136, 134, 571, 574, 574, 574, -- -- 574, 574, 574, 574, 574, 576, 572, 576, 576, 576, -- 576, 576, 576, 576, 576, 126, 125, 124, 123, 122, -- 577, 573, 577, 577, 577, 577, 577, 577, 577, 577, -- 578, 117, 578, 578, 578, 578, 578, 578, 584, 116, -- 584, 584, 584, 584, 584, 584, 584, 584, 591, 115, -- 591, 591, 591, 591, 591, 591, 591, 591, 592, 114, -- 592, 592, 592, 592, 592, 592, 592, 592, 593, 113, -- 593, 593, 593, 593, 593, 593, 593, 593, 613, 613, -- 613, 613, 613, 613, 591, 594, 594, 594, 594, 594, -- 594, 594, 594, 111, 592, 595, 595, 595, 595, 595, -- -- 595, 595, 595, 110, 593, 596, 596, 596, 596, 596, -- 596, 596, 596, 605, 605, 605, 605, 605, 605, 605, -- 605, 607, 109, 607, 607, 607, 607, 607, 607, 607, -- 607, 608, 108, 608, 608, 608, 608, 608, 608, 608, -- 608, 104, 100, 99, 95, 92, 609, 605, 609, 609, -- 609, 609, 609, 609, 84, 83, 82, 607, 611, 611, -- 611, 611, 611, 611, 611, 611, 80, 608, 612, 612, -- 612, 612, 612, 612, 612, 612, 75, 68, 61, 57, -- 56, 54, 609, 615, 615, 615, 615, 615, 615, 615, -- 615, 616, 616, 616, 616, 616, 616, 616, 616, 617, -- -- 617, 617, 617, 617, 617, 617, 617, 619, 619, 619, -- 619, 619, 619, 619, 619, 51, 49, 615, 620, 620, -- 620, 620, 620, 620, 41, 616, 40, 39, 37, 33, -- 29, 23, 17, 617, 15, 14, 13, 0, 0, 0, -- 0, 619, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 620, 622, 622, 622, 622, 622, 622, 622, -- 622, 622, 622, 622, 622, 622, 622, 622, 622, 623, -- 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, -- 623, 623, 623, 623, 623, 624, 624, 624, 624, 624, -- 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, -- -- 624, 625, 625, 625, 625, 625, 625, 625, 625, 625, -- 625, 625, 625, 625, 625, 625, 625, 626, 0, 0, -- 0, 0, 0, 0, 0, 626, 626, 626, 0, 0, -- 626, 626, 626, 627, 627, 627, 627, 627, 627, 627, -- 627, 627, 627, 627, 627, 627, 627, 627, 627, 628, -- 0, 0, 0, 0, 628, 0, 0, 628, 628, 628, -- 628, 0, 628, 628, 628, 629, 0, 0, 0, 0, -- 0, 0, 0, 629, 629, 629, 0, 0, 629, 629, -- 629, 630, 0, 0, 630, 630, 0, 630, 0, 630, -- 630, 630, 0, 0, 630, 630, 630, 631, 631, 0, -- -- 0, 0, 631, 632, 0, 0, 632, 632, 0, 632, -- 0, 632, 632, 632, 0, 0, 632, 632, 632, 633, -- 0, 0, 633, 633, 0, 633, 0, 633, 633, 633, -- 0, 633, 0, 633, 633, 635, 0, 0, 635, 0, -- 0, 635, 0, 635, 635, 635, 635, 0, 635, 635, -- 635, 636, 636, 636, 636, 636, 636, 636, 636, 636, -- 636, 636, 636, 636, 636, 636, 636, 637, 637, 0, -- 637, 0, 637, 637, 637, 637, 637, 637, 637, 637, -- 637, 637, 637, 638, 638, 638, 638, 638, 638, 638, -- 638, 638, 638, 638, 638, 638, 638, 638, 638, 639, -- -- 639, 0, 639, 639, 639, 639, 639, 639, 639, 639, -- 639, 639, 639, 639, 639, 640, 0, 0, 0, 0, -- 640, 0, 0, 640, 640, 640, 0, 0, 640, 640, -- 640, 641, 0, 0, 641, 641, 0, 641, 0, 641, -- 641, 641, 0, 0, 641, 641, 641, 642, 642, 0, -- 0, 0, 642, 643, 643, 643, 0, 0, 0, 643, -- 644, 0, 0, 644, 644, 0, 644, 0, 644, 644, -- 644, 0, 0, 644, 644, 644, 645, 645, 645, 645, -- 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, -- 645, 645, 646, 646, 0, 0, 0, 646, 647, 647, -- -- 647, 0, 0, 0, 647, 648, 648, 0, 0, 0, -- 648, 649, 649, 0, 0, 0, 649, 650, 650, 0, -- 0, 0, 650, 651, 651, 651, 0, 0, 0, 651, -- 652, 652, 0, 0, 0, 652, 653, 653, 0, 0, -- 0, 653, 654, 654, 0, 0, 0, 654, 655, 655, -- 655, 0, 0, 0, 655, 656, 656, 656, 656, 0, -- 0, 0, 656, 657, 657, 0, 0, 0, 657, 658, -- 658, 0, 0, 0, 658, 659, 659, 0, 0, 0, -- 659, 660, 660, 660, 0, 0, 0, 660, 661, 661, -- 661, 661, 0, 0, 0, 661, 662, 662, 0, 0, -- -- 0, 662, 663, 663, 0, 0, 0, 663, 664, 664, -- 664, 0, 0, 0, 664, 665, 665, 665, 665, 0, -- 0, 0, 665, 666, 666, 0, 0, 0, 666, 667, -- 0, 667, 667, 0, 0, 0, 667, 668, 668, 668, -- 0, 0, 0, 668, 669, 669, 669, 669, 0, 0, -- 0, 669, 670, 670, 0, 0, 0, 670, 671, 0, -- 671, 671, 0, 0, 0, 671, 672, 672, 672, 0, -- 0, 0, 672, 673, 673, 673, 0, 0, 0, 0, -- 673, 674, 674, 674, 674, 674, 674, 674, 674, 674, -- 674, 674, 674, 674, 674, 674, 674, 675, 675, 0, -- -- 675, 675, 675, 0, 0, 675, 675, 675, 0, 0, -- 675, 675, 675, 676, 676, 0, 676, 676, 676, 0, -- 0, 676, 676, 676, 0, 0, 676, 676, 676, 677, -- 677, 0, 0, 0, 677, 678, 0, 678, 678, 0, -- 0, 0, 678, 679, 679, 0, 0, 0, 0, 679, -- 680, 680, 0, 0, 0, 680, 681, 0, 681, 681, -- 0, 0, 0, 681, 682, 682, 0, 0, 0, 682, -- 683, 0, 683, 0, 0, 0, 0, 683, 684, 684, -- 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, -- 684, 684, 684, 684, 621, 621, 621, 621, 621, 621, -- -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, -- 621, 621 -+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -+ 8, 8, 8, 8, 13, 13, 13, 13, 13, 13, -+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -+ 13, 13, 13, 13, 21, 125, 153, 797, 82, 168, -+ 168, 270, 153, 178, 21, 784, 125, 21, 21, 21, -+ -+ 21, 21, 21, 21, 21, 21, 21, 28, 82, 28, -+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -+ 152, 180, 180, 28, 28, 28, 28, 28, 151, 270, -+ 289, 57, 57, 152, 82, 57, 57, 123, 123, 123, -+ 123, 123, 123, 178, 151, 28, 154, 28, 28, 28, -+ 28, 28, 28, 34, 289, 57, 154, 500, 246, 34, -+ 246, 500, 34, 34, 313, 34, 34, 34, 34, 34, -+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 57, -+ 313, 34, 34, 34, 34, 34, 34, 34, 34, 34, -+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -+ -+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -+ 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, -+ 37, 37, 37, 37, 219, 783, 242, 37, 37, 37, -+ 37, 37, 245, 150, 236, 219, 37, 107, 107, 107, -+ 107, 107, 107, 107, 107, 107, 107, 247, 236, 245, -+ 303, 37, 37, 37, 37, 37, 37, 44, 44, 44, -+ 44, 44, 247, 44, 44, 311, 311, 44, 121, 121, -+ 121, 121, 121, 121, 121, 121, 121, 121, 150, 242, -+ 108, 44, 44, 44, 45, 303, 45, 45, 45, 45, -+ -+ 45, 45, 45, 45, 45, 45, 48, 66, 66, 66, -+ 108, 66, 304, 110, 370, 66, 48, 66, 304, 48, -+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 132, -+ 243, 66, 66, 110, 132, 243, 108, 281, 132, 171, -+ 132, 83, 171, 171, 370, 138, 138, 83, 281, 171, -+ 83, 114, 114, 83, 83, 114, 114, 66, 182, 110, -+ 780, 302, 175, 175, 171, 48, 67, 83, 291, 83, -+ 183, 235, 235, 291, 235, 114, 67, 249, 182, 67, -+ 67, 67, 67, 67, 67, 67, 67, 67, 67, 302, -+ 183, 249, 83, 83, 84, 138, 777, 84, 84, 114, -+ -+ 84, 84, 84, 84, 182, 235, 84, 84, 111, 775, -+ 111, 111, 175, 314, 111, 111, 183, 369, 111, 314, -+ 84, 84, 84, 122, 122, 122, 122, 122, 122, 122, -+ 122, 122, 122, 111, 111, 156, 156, 156, 156, 156, -+ 156, 156, 156, 156, 156, 84, 84, 85, 310, 369, -+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -+ 85, 85, 85, 85, 322, 357, 85, 85, 85, 85, -+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -+ 85, 85, 85, 85, 85, 85, 85, 85, 322, 357, -+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -+ -+ 85, 85, 85, 85, 85, 85, 85, 88, 310, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, -+ 278, 278, 278, 88, 88, 88, 88, 88, 266, 266, -+ 113, 266, 113, 113, 113, 330, 113, 113, 330, 371, -+ 113, 196, 196, 196, 196, 196, 196, 88, 88, 88, -+ 88, 88, 88, 89, 113, 113, 113, 89, 89, 89, -+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -+ 453, 371, 89, 89, 89, 89, 89, 89, 89, 89, -+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -+ 89, 89, 89, 89, 453, 89, 89, 89, 89, 89, -+ -+ 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, -+ 89, 89, 89, 92, 92, 92, 92, 92, 92, 92, -+ 92, 92, 92, 92, 377, 444, 378, 92, 92, 92, -+ 92, 92, 203, 344, 158, 158, 92, 203, 158, 158, -+ 323, 203, 444, 203, 344, 323, 301, 142, 378, 301, -+ 457, 92, 92, 92, 92, 92, 92, 97, 158, 97, -+ 97, 97, 97, 97, 97, 97, 97, 97, 97, 116, -+ 766, 116, 116, 116, 457, 116, 116, 142, 142, 116, -+ 301, 142, 158, 214, 214, 214, 214, 214, 214, 142, -+ 372, 377, 142, 116, 116, 116, 117, 117, 117, 117, -+ -+ 117, 117, 117, 117, 117, 117, 167, 167, 167, 167, -+ 167, 167, 167, 167, 167, 167, 346, 346, 765, 160, -+ 379, 160, 160, 160, 372, 160, 160, 764, 346, 160, -+ 400, 379, 117, 118, 118, 118, 118, 118, 118, 118, -+ 118, 118, 118, 160, 160, 160, 458, 118, 118, 118, -+ 118, 118, 191, 191, 191, 191, 191, 191, 191, 191, -+ 191, 191, 273, 273, 273, 273, 427, 427, 400, 755, -+ 458, 118, 118, 118, 118, 118, 118, 126, 126, 126, -+ 126, 126, 126, 126, 126, 126, 126, 126, 312, 498, -+ 754, 126, 126, 126, 126, 126, 194, 194, 194, 194, -+ -+ 194, 194, 194, 194, 194, 194, 285, 285, 285, 285, -+ 285, 285, 752, 498, 312, 126, 126, 126, 126, 126, -+ 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, -+ 127, 127, 312, 562, 562, 127, 127, 127, 127, 127, -+ 184, 409, 184, 184, 373, 186, 184, 184, 380, 373, -+ 184, 186, 409, 380, 186, 348, 348, 186, 186, 127, -+ 127, 127, 127, 127, 127, 184, 184, 348, 413, 497, -+ 428, 186, 428, 186, 188, 497, 188, 188, 188, 413, -+ 188, 188, 429, 751, 188, 195, 195, 195, 195, 195, -+ 195, 195, 195, 195, 195, 526, 186, 186, 188, 188, -+ -+ 188, 189, 615, 615, 189, 189, 429, 189, 189, 189, -+ 189, 190, 431, 189, 189, 190, 502, 431, 414, 414, -+ 502, 190, 415, 415, 429, 433, 430, 189, 189, 189, -+ 414, 430, 526, 430, 415, 190, 190, 210, 210, 210, -+ 210, 210, 210, 210, 210, 210, 210, 432, 508, 433, -+ 432, 523, 189, 189, 192, 192, 192, 192, 192, 192, -+ 192, 192, 192, 192, 749, 508, 523, 433, 192, 192, -+ 192, 192, 192, 211, 211, 211, 211, 211, 211, 211, -+ 211, 211, 211, 319, 511, 319, 319, 319, 319, 319, -+ 319, 439, 192, 192, 192, 192, 192, 192, 197, 748, -+ -+ 513, 439, 197, 197, 197, 197, 197, 197, 197, 197, -+ 197, 197, 197, 197, 197, 442, 513, 197, 197, 197, -+ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, -+ 197, 197, 197, 197, 197, 197, 197, 197, 197, 511, -+ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, -+ 197, 197, 197, 197, 197, 197, 197, 197, 198, 198, -+ 198, 198, 198, 198, 198, 198, 198, 198, 198, 442, -+ 504, 506, 198, 198, 198, 198, 198, 213, 213, 213, -+ 213, 213, 213, 213, 213, 213, 213, 354, 354, 354, -+ 354, 354, 354, 434, 504, 506, 198, 198, 198, 198, -+ -+ 198, 198, 212, 747, 212, 212, 212, 212, 212, 212, -+ 212, 212, 212, 212, 248, 454, 737, 434, 248, 514, -+ 454, 561, 736, 561, 248, 282, 282, 282, 282, 282, -+ 282, 282, 282, 282, 282, 434, 514, 727, 248, 248, -+ 212, 215, 443, 215, 215, 215, 215, 215, 215, 215, -+ 215, 215, 215, 443, 564, 584, 564, 215, 215, 215, -+ 215, 215, 284, 284, 284, 284, 284, 284, 284, 284, -+ 284, 284, 423, 423, 423, 423, 423, 423, 571, 584, -+ 571, 215, 215, 215, 215, 215, 215, 218, 218, 218, -+ 218, 218, 218, 218, 218, 218, 218, 218, 589, 589, -+ -+ 589, 218, 218, 218, 218, 218, 315, 315, 315, 315, -+ 315, 315, 315, 315, 315, 315, 450, 725, 450, 450, -+ 450, 450, 450, 450, 724, 218, 218, 218, 218, 218, -+ 218, 220, 220, 220, 220, 220, 220, 220, 220, 220, -+ 220, 220, 220, 565, 616, 616, 220, 220, 220, 220, -+ 220, 345, 345, 345, 345, 345, 345, 345, 345, 345, -+ 345, 466, 466, 466, 466, 466, 466, 565, 623, 623, -+ 220, 220, 220, 220, 220, 220, 221, 221, 221, 221, -+ 221, 221, 221, 221, 221, 221, 221, 566, 625, 565, -+ 221, 221, 221, 221, 221, 347, 347, 347, 347, 347, -+ -+ 347, 347, 347, 347, 347, 473, 473, 473, 473, 473, -+ 473, 566, 625, 723, 221, 221, 221, 221, 221, 221, -+ 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, -+ 222, 631, 631, 566, 222, 222, 222, 222, 222, 351, -+ 351, 351, 351, 351, 351, 351, 351, 622, 711, 622, -+ 403, 351, 403, 403, 403, 403, 403, 403, 222, 222, -+ 222, 222, 222, 222, 253, 627, 253, 253, 253, 253, -+ 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, -+ 254, 254, 254, 254, 254, 254, 254, 710, 403, 627, -+ 254, 254, 254, 254, 254, 353, 353, 353, 353, 353, -+ -+ 353, 353, 353, 353, 353, 480, 708, 480, 480, 480, -+ 480, 480, 480, 707, 254, 254, 254, 254, 254, 254, -+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -+ 529, 529, 529, 529, 256, 256, 256, 256, 256, 416, -+ 416, 416, 416, 416, 416, 416, 416, 416, 416, 492, -+ 492, 492, 492, 492, 492, 674, 674, 700, 256, 256, -+ 256, 256, 256, 256, 269, 269, 269, 269, 269, 269, -+ 269, 269, 269, 269, 417, 417, 420, 420, 420, 420, -+ 420, 420, 420, 420, 680, 680, 417, 535, 420, 422, -+ 422, 422, 422, 422, 422, 422, 422, 422, 422, 535, -+ -+ 269, 277, 277, 277, 277, 277, 277, 277, 277, 277, -+ 277, 277, 283, 283, 283, 283, 283, 283, 283, 283, -+ 283, 283, 283, 283, 283, 445, 683, 683, 283, 283, -+ 283, 283, 283, 570, 570, 445, 446, 446, 446, 446, -+ 446, 446, 446, 446, 446, 446, 541, 541, 541, 541, -+ 541, 541, 283, 283, 283, 283, 283, 283, 286, 286, -+ 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, -+ 679, 698, 679, 286, 286, 286, 286, 286, 465, 465, -+ 465, 465, 465, 465, 465, 465, 465, 465, 570, 563, -+ 697, 624, 620, 481, 563, 620, 624, 286, 286, 286, -+ -+ 286, 286, 286, 287, 481, 287, 287, 287, 287, 287, -+ 287, 287, 287, 287, 287, 320, 320, 320, 320, 320, -+ 320, 320, 320, 320, 320, 696, 621, 640, 643, 320, -+ 320, 320, 320, 320, 470, 470, 470, 470, 470, 470, -+ 470, 470, 470, 470, 558, 558, 558, 558, 558, 558, -+ 621, 640, 643, 320, 320, 320, 320, 320, 320, 321, -+ 321, 321, 321, 321, 321, 321, 321, 321, 321, 643, -+ 630, 693, 621, 321, 321, 321, 321, 321, 472, 472, -+ 472, 472, 472, 472, 472, 472, 472, 472, 648, 648, -+ 648, 648, 630, 482, 630, 630, 691, 321, 321, 321, -+ -+ 321, 321, 321, 334, 482, 334, 334, 334, 334, 334, -+ 334, 334, 334, 334, 334, 335, 595, 335, 335, 335, -+ 335, 335, 335, 335, 335, 335, 335, 336, 595, 336, -+ 336, 336, 336, 336, 336, 336, 336, 336, 336, 339, -+ 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, -+ 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, -+ 349, 349, 349, 572, 685, 633, 349, 349, 349, 349, -+ 349, 476, 476, 476, 476, 476, 476, 476, 476, 476, -+ 476, 633, 731, 824, 731, 572, 824, 572, 572, 645, -+ 349, 349, 349, 349, 349, 349, 352, 352, 352, 352, -+ -+ 352, 352, 352, 352, 352, 352, 352, 352, 352, 483, -+ 483, 572, 352, 352, 352, 352, 352, 484, 484, 486, -+ 486, 483, 496, 501, 503, 733, 733, 645, 685, 484, -+ 676, 486, 496, 501, 686, 503, 352, 352, 352, 352, -+ 352, 352, 355, 355, 355, 355, 355, 355, 355, 355, -+ 355, 355, 355, 355, 676, 682, 641, 355, 355, 355, -+ 355, 355, 485, 485, 485, 485, 485, 485, 485, 485, -+ 485, 485, 604, 604, 604, 604, 604, 604, 512, 632, -+ 641, 355, 355, 355, 355, 355, 355, 356, 512, 356, -+ 356, 356, 356, 356, 356, 356, 356, 356, 356, 383, -+ -+ 641, 383, 383, 383, 383, 383, 383, 383, 383, 383, -+ 383, 384, 384, 384, 384, 384, 384, 384, 384, 384, -+ 384, 762, 762, 781, 781, 384, 384, 384, 384, 384, -+ 489, 489, 489, 489, 489, 489, 489, 489, 632, 882, -+ 882, 611, 489, 611, 611, 611, 611, 611, 611, 384, -+ 384, 384, 384, 384, 384, 399, 399, 399, 399, 399, -+ 399, 399, 399, 399, 399, 491, 491, 491, 491, 491, -+ 491, 491, 491, 491, 491, 532, 532, 532, 532, 532, -+ 532, 532, 532, 532, 532, 639, 681, 639, 639, 639, -+ 649, 399, 401, 596, 401, 401, 401, 401, 401, 401, -+ -+ 401, 401, 401, 401, 402, 596, 402, 402, 402, 402, -+ 402, 402, 402, 402, 402, 402, 408, 408, 408, 408, -+ 408, 408, 408, 408, 408, 408, 408, 701, 649, 728, -+ 408, 408, 408, 408, 408, 534, 534, 534, 534, 534, -+ 534, 534, 534, 534, 534, 675, 836, 742, 787, 836, -+ 547, 701, 673, 728, 408, 408, 408, 408, 408, 408, -+ 412, 547, 412, 412, 412, 412, 412, 412, 412, 412, -+ 412, 412, 418, 418, 418, 418, 418, 418, 418, 418, -+ 418, 418, 418, 418, 418, 742, 787, 670, 418, 418, -+ 418, 418, 418, 538, 598, 538, 538, 538, 538, 538, -+ -+ 538, 827, 827, 827, 669, 538, 598, 634, 739, 634, -+ 634, 634, 418, 418, 418, 418, 418, 418, 421, 421, -+ 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, -+ 421, 853, 739, 853, 421, 421, 421, 421, 421, 540, -+ 540, 540, 540, 540, 540, 540, 540, 540, 540, 578, -+ 578, 578, 578, 578, 578, 578, 656, 634, 421, 421, -+ 421, 421, 421, 421, 424, 424, 424, 424, 424, 424, -+ 424, 424, 424, 424, 424, 424, 548, 549, 549, 424, -+ 424, 424, 424, 424, 550, 550, 612, 548, 613, 549, -+ 552, 552, 844, 844, 844, 655, 550, 612, 657, 613, -+ -+ 759, 642, 552, 424, 424, 424, 424, 424, 424, 425, -+ 657, 425, 425, 425, 425, 425, 425, 425, 425, 425, -+ 425, 426, 653, 768, 759, 642, 854, 426, 854, 916, -+ 426, 426, 916, 426, 426, 426, 426, 426, 426, 426, -+ 426, 426, 426, 426, 426, 426, 642, 768, 652, 426, -+ 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, -+ 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, -+ 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, -+ 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, -+ 426, 464, 464, 464, 464, 464, 464, 464, 464, 464, -+ -+ 464, 464, 555, 555, 555, 555, 555, 555, 555, 555, -+ 865, 651, 865, 658, 555, 557, 557, 557, 557, 557, -+ 557, 557, 557, 557, 557, 658, 883, 883, 464, 471, -+ 660, 471, 471, 471, 471, 471, 471, 471, 471, 471, -+ 471, 471, 660, 637, 702, 471, 471, 471, 471, 471, -+ 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, -+ 619, 619, 619, 619, 619, 619, 619, 619, 702, 471, -+ 471, 471, 471, 471, 471, 474, 474, 474, 474, 474, -+ 474, 474, 474, 474, 474, 474, 778, 636, 702, 474, -+ 474, 474, 474, 474, 587, 587, 587, 587, 587, 587, -+ -+ 587, 587, 587, 587, 866, 870, 866, 870, 614, 614, -+ 778, 894, 894, 474, 474, 474, 474, 474, 474, 475, -+ 614, 475, 475, 475, 475, 475, 475, 475, 475, 475, -+ 475, 487, 487, 487, 487, 487, 487, 487, 487, 487, -+ 487, 487, 487, 487, 678, 629, 703, 487, 487, 487, -+ 487, 487, 588, 588, 588, 588, 588, 588, 588, 588, -+ 588, 588, 635, 610, 635, 635, 635, 871, 678, 871, -+ 703, 487, 487, 487, 487, 487, 487, 490, 490, 490, -+ 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, -+ 678, 703, 740, 490, 490, 490, 490, 490, 597, 597, -+ -+ 597, 597, 597, 597, 597, 597, 597, 597, 875, 878, -+ 875, 878, 635, 888, 609, 888, 740, 490, 490, 490, -+ 490, 490, 490, 493, 493, 493, 493, 493, 493, 493, -+ 493, 493, 493, 493, 608, 889, 740, 889, 493, 493, -+ 493, 493, 493, 601, 594, 601, 601, 601, 601, 601, -+ 601, 897, 592, 897, 654, 601, 654, 654, 654, 654, -+ 654, 654, 493, 493, 493, 493, 493, 493, 494, 712, -+ 494, 494, 494, 494, 494, 494, 494, 494, 494, 494, -+ 495, 712, 898, 901, 898, 901, 495, 692, 692, 495, -+ 495, 692, 495, 495, 495, 495, 495, 495, 495, 495, -+ -+ 495, 495, 495, 495, 495, 692, 692, 692, 495, 495, -+ 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, -+ 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, -+ 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, -+ 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, -+ 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, -+ 517, 522, 913, 913, 713, 522, 522, 522, 522, 522, -+ 522, 522, 522, 522, 522, 522, 713, 522, 914, 914, -+ 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, -+ 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, -+ -+ 522, 522, 591, 522, 522, 522, 522, 522, 522, 522, -+ 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, -+ 522, 525, 525, 525, 525, 525, 525, 525, 525, 525, -+ 525, 603, 603, 603, 603, 603, 603, 603, 603, 603, -+ 603, 607, 607, 607, 607, 607, 607, 607, 607, 607, -+ 607, 666, 666, 666, 666, 666, 666, 525, 527, 527, -+ 527, 527, 527, 527, 527, 527, 527, 527, 527, 650, -+ 650, 650, 650, 650, 650, 650, 650, 650, 650, 659, -+ 659, 659, 659, 659, 659, 659, 659, 659, 659, 721, -+ 721, 721, 721, 721, 721, 527, 536, 715, 536, 536, -+ -+ 536, 536, 536, 536, 536, 536, 536, 536, 536, 715, -+ 590, 582, 536, 536, 536, 536, 536, 663, 753, 663, -+ 663, 663, 663, 663, 663, 907, 908, 907, 908, 663, -+ 753, 687, 672, 687, 687, 687, 536, 536, 536, 536, -+ 536, 536, 539, 672, 539, 539, 539, 539, 539, 539, -+ 539, 539, 539, 539, 539, 730, 581, 580, 539, 539, -+ 539, 539, 539, 665, 665, 665, 665, 665, 665, 665, -+ 665, 665, 665, 688, 579, 688, 688, 688, 910, 730, -+ 910, 687, 539, 539, 539, 539, 539, 539, 542, 542, -+ 542, 542, 542, 542, 542, 542, 542, 542, 542, 577, -+ -+ 576, 730, 542, 542, 542, 542, 542, 695, 695, 695, -+ 695, 695, 695, 695, 695, 695, 695, 794, 794, 794, -+ 794, 794, 794, 688, 575, 573, 542, 542, 542, 542, -+ 542, 542, 543, 569, 543, 543, 543, 543, 543, 543, -+ 543, 543, 543, 543, 546, 568, 546, 546, 546, 546, -+ 546, 546, 546, 546, 546, 546, 553, 553, 553, 553, -+ 553, 553, 553, 553, 553, 553, 553, 553, 553, 567, -+ 551, 761, 553, 553, 553, 553, 553, 689, 545, 689, -+ 689, 689, 690, 544, 690, 690, 690, 699, 531, 699, -+ 699, 699, 699, 699, 699, 761, 553, 553, 553, 553, -+ -+ 553, 553, 556, 556, 556, 556, 556, 556, 556, 556, -+ 556, 556, 556, 556, 918, 530, 918, 761, 556, 556, -+ 556, 556, 556, 919, 923, 919, 923, 689, 924, 929, -+ 924, 929, 690, 726, 726, 726, 726, 726, 726, 726, -+ 524, 521, 556, 556, 556, 556, 556, 556, 559, 520, -+ 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, -+ 560, 694, 519, 694, 694, 694, 560, 694, 694, 560, -+ 560, 694, 560, 560, 560, 560, 560, 560, 560, 560, -+ 560, 560, 560, 560, 560, 694, 694, 694, 560, 560, -+ 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, -+ -+ 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, -+ 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, -+ 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, -+ 583, 750, 518, 750, 750, 750, 750, 750, 750, 583, -+ 930, 516, 930, 583, 583, 583, 583, 583, 583, 583, -+ 583, 583, 583, 583, 583, 583, 515, 510, 583, 583, -+ 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, -+ 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, -+ 509, 583, 583, 583, 583, 583, 583, 583, 583, 583, -+ 583, 583, 583, 583, 583, 583, 583, 583, 583, 586, -+ -+ 479, 586, 586, 586, 586, 586, 586, 586, 586, 586, -+ 586, 714, 714, 714, 714, 714, 714, 714, 714, 714, -+ 714, 718, 478, 718, 718, 718, 718, 718, 718, 922, -+ 477, 469, 922, 718, 468, 467, 922, 586, 593, 463, -+ 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, -+ 599, 456, 599, 599, 599, 599, 599, 599, 599, 599, -+ 599, 599, 599, 455, 452, 451, 599, 599, 599, 599, -+ 599, 720, 720, 720, 720, 720, 720, 720, 720, 720, -+ 720, 758, 449, 758, 758, 758, 758, 758, 758, 448, -+ 599, 599, 599, 599, 599, 599, 602, 447, 602, 602, -+ -+ 602, 602, 602, 602, 602, 602, 602, 602, 602, 441, -+ 440, 438, 602, 602, 602, 602, 602, 734, 734, 734, -+ 734, 734, 734, 734, 734, 734, 734, 767, 437, 767, -+ 767, 767, 767, 767, 767, 436, 602, 602, 602, 602, -+ 602, 602, 605, 605, 605, 605, 605, 605, 605, 605, -+ 605, 605, 605, 435, 411, 410, 605, 605, 605, 605, -+ 605, 735, 735, 735, 735, 735, 735, 735, 735, 735, -+ 735, 407, 745, 406, 745, 745, 745, 745, 745, 745, -+ 605, 605, 605, 605, 605, 605, 606, 405, 606, 606, -+ 606, 606, 606, 606, 606, 606, 606, 606, 617, 617, -+ -+ 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, -+ 745, 404, 398, 397, 617, 617, 617, 617, 617, 746, -+ 746, 746, 746, 746, 746, 746, 746, 746, 746, 800, -+ 396, 800, 800, 800, 800, 800, 800, 395, 617, 617, -+ 617, 617, 617, 617, 638, 394, 638, 638, 638, 638, -+ 638, 638, 638, 638, 638, 638, 644, 644, 644, 644, -+ 644, 644, 644, 644, 644, 644, 763, 763, 763, 763, -+ 763, 763, 763, 763, 763, 763, 772, 772, 772, 772, -+ 772, 772, 772, 772, 772, 772, 812, 812, 812, 812, -+ 812, 812, 644, 646, 393, 646, 646, 646, 646, 646, -+ -+ 646, 646, 646, 646, 646, 773, 773, 773, 773, 773, -+ 773, 773, 773, 773, 773, 774, 774, 774, 774, 774, -+ 774, 774, 774, 774, 774, 392, 928, 391, 390, 928, -+ 389, 646, 661, 928, 661, 661, 661, 661, 661, 661, -+ 661, 661, 661, 661, 661, 388, 387, 386, 661, 661, -+ 661, 661, 661, 790, 385, 790, 790, 790, 790, 790, -+ 790, 792, 792, 792, 792, 792, 792, 792, 792, 792, -+ 792, 382, 661, 661, 661, 661, 661, 661, 664, 381, -+ 664, 664, 664, 664, 664, 664, 664, 664, 664, 664, -+ 664, 790, 376, 375, 664, 664, 664, 664, 664, 793, -+ -+ 793, 793, 793, 793, 793, 793, 793, 793, 793, 374, -+ 368, 366, 365, 364, 363, 362, 361, 360, 664, 664, -+ 664, 664, 664, 664, 667, 667, 667, 667, 667, 667, -+ 667, 667, 667, 667, 359, 343, 342, 341, 667, 667, -+ 667, 667, 667, 796, 796, 796, 796, 796, 796, 796, -+ 796, 796, 796, 340, 338, 337, 809, 809, 809, 809, -+ 809, 809, 667, 667, 667, 667, 667, 667, 668, 333, -+ 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, -+ 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, -+ 671, 704, 809, 704, 704, 704, 704, 704, 704, 704, -+ -+ 704, 704, 704, 705, 332, 705, 705, 705, 705, 705, -+ 705, 705, 705, 705, 705, 706, 331, 706, 706, 706, -+ 706, 706, 706, 706, 706, 706, 706, 709, 329, 709, -+ 709, 709, 709, 709, 709, 709, 709, 709, 709, 716, -+ 328, 716, 716, 716, 716, 716, 716, 716, 716, 716, -+ 716, 716, 327, 326, 325, 716, 716, 716, 716, 716, -+ 804, 804, 804, 804, 804, 804, 804, 804, 804, 804, -+ 324, 318, 317, 316, 309, 308, 307, 306, 305, 716, -+ 716, 716, 716, 716, 716, 719, 299, 719, 719, 719, -+ 719, 719, 719, 719, 719, 719, 719, 297, 296, 295, -+ -+ 294, 719, 719, 719, 719, 719, 805, 805, 805, 805, -+ 805, 805, 805, 805, 805, 805, 293, 292, 290, 288, -+ 280, 279, 276, 275, 268, 719, 719, 719, 719, 719, -+ 719, 738, 267, 738, 738, 738, 738, 738, 738, 738, -+ 738, 738, 738, 741, 265, 741, 741, 741, 741, 741, -+ 741, 741, 741, 741, 741, 743, 264, 743, 743, 743, -+ 743, 743, 743, 743, 743, 743, 743, 744, 263, 744, -+ 744, 744, 744, 744, 744, 744, 744, 744, 744, 756, -+ 262, 756, 756, 756, 756, 756, 756, 756, 756, 756, -+ 756, 769, 261, 769, 769, 769, 769, 769, 769, 769, -+ -+ 769, 769, 769, 770, 260, 770, 770, 770, 770, 770, -+ 770, 770, 770, 770, 770, 771, 259, 771, 771, 771, -+ 771, 771, 771, 771, 771, 771, 771, 785, 258, 785, -+ 785, 785, 785, 785, 785, 785, 785, 785, 785, 786, -+ 255, 786, 786, 786, 786, 786, 786, 786, 786, 786, -+ 786, 788, 252, 788, 788, 788, 788, 788, 788, 788, -+ 788, 788, 788, 789, 251, 789, 789, 789, 789, 789, -+ 789, 789, 789, 789, 789, 801, 801, 801, 801, 801, -+ 801, 801, 801, 801, 801, 806, 806, 806, 806, 806, -+ 806, 806, 806, 806, 806, 811, 811, 811, 811, 811, -+ -+ 811, 811, 811, 811, 811, 250, 244, 241, 240, 239, -+ 238, 801, 802, 802, 802, 802, 802, 802, 802, 802, -+ 802, 802, 237, 234, 233, 232, 231, 230, 229, 228, -+ 227, 226, 225, 224, 223, 217, 216, 209, 208, 207, -+ 206, 205, 204, 202, 201, 199, 193, 185, 802, 803, -+ 803, 803, 803, 803, 803, 803, 803, 803, 803, 181, -+ 177, 176, 174, 170, 163, 159, 157, 155, 147, 146, -+ 145, 144, 143, 137, 136, 135, 134, 133, 131, 130, -+ 129, 128, 124, 120, 119, 803, 808, 808, 808, 808, -+ 808, 808, 808, 808, 808, 808, 115, 112, 109, 104, -+ -+ 103, 102, 100, 96, 95, 94, 93, 90, 77, 70, -+ 63, 59, 58, 56, 55, 53, 51, 43, 42, 41, -+ 39, 35, 808, 814, 814, 814, 814, 814, 814, 814, -+ 814, 814, 814, 814, 814, 814, 814, 814, 814, 814, -+ 814, 814, 814, 814, 815, 815, 815, 815, 815, 815, -+ 815, 815, 815, 815, 815, 815, 815, 815, 815, 815, -+ 815, 815, 815, 815, 815, 816, 816, 816, 816, 816, -+ 816, 816, 816, 816, 816, 816, 816, 816, 816, 816, -+ 816, 816, 816, 816, 816, 816, 817, 817, 817, 817, -+ 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, -+ -+ 817, 817, 817, 817, 817, 817, 817, 818, 31, 25, -+ 19, 17, 16, 15, 818, 0, 818, 818, 818, 818, -+ 0, 0, 818, 818, 818, 818, 818, 818, 819, 819, -+ 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, -+ 819, 819, 819, 819, 819, 819, 819, 819, 819, 820, -+ 0, 0, 0, 0, 820, 0, 820, 0, 820, 820, -+ 820, 820, 820, 0, 820, 820, 820, 820, 820, 820, -+ 821, 0, 0, 0, 0, 0, 0, 821, 0, 821, -+ 821, 821, 821, 0, 0, 821, 821, 821, 821, 821, -+ 821, 822, 0, 0, 822, 822, 0, 822, 822, 0, -+ -+ 822, 822, 822, 822, 0, 0, 822, 822, 822, 822, -+ 822, 822, 823, 823, 0, 823, 0, 0, 0, 823, -+ 825, 0, 0, 825, 825, 0, 825, 825, 0, 825, -+ 825, 825, 825, 0, 0, 825, 825, 825, 825, 825, -+ 825, 826, 0, 0, 826, 826, 0, 826, 826, 0, -+ 826, 826, 826, 826, 0, 826, 826, 826, 0, 826, -+ 826, 826, 828, 0, 0, 828, 0, 0, 828, 828, -+ 0, 828, 828, 828, 828, 828, 0, 828, 828, 828, -+ 828, 828, 828, 829, 829, 829, 829, 829, 829, 829, -+ 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, -+ -+ 829, 829, 829, 829, 830, 830, 0, 830, 0, 830, -+ 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, -+ 830, 830, 830, 830, 830, 831, 0, 0, 0, 0, -+ 831, 0, 831, 0, 831, 831, 831, 831, 831, 0, -+ 831, 831, 831, 831, 831, 831, 832, 0, 0, 0, -+ 0, 0, 0, 832, 0, 832, 832, 832, 832, 0, -+ 832, 832, 832, 832, 832, 832, 832, 833, 0, 0, -+ 833, 833, 0, 833, 833, 0, 833, 833, 833, 833, -+ 0, 833, 833, 833, 833, 833, 833, 833, 834, 834, -+ 834, 834, 834, 834, 834, 834, 834, 834, 834, 834, -+ -+ 834, 834, 834, 834, 834, 834, 834, 834, 834, 835, -+ 835, 0, 835, 835, 835, 835, 835, 835, 835, 835, -+ 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, -+ 837, 0, 0, 837, 837, 0, 837, 837, 0, 837, -+ 837, 837, 837, 0, 0, 837, 837, 837, 837, 837, -+ 837, 838, 838, 0, 838, 0, 0, 0, 838, 839, -+ 839, 0, 839, 0, 0, 0, 839, 840, 840, 840, -+ 0, 840, 0, 0, 0, 840, 841, 0, 0, 841, -+ 841, 0, 841, 841, 0, 841, 841, 841, 841, 0, -+ 0, 841, 841, 841, 841, 841, 841, 842, 0, 0, -+ -+ 842, 842, 0, 842, 842, 0, 842, 842, 842, 842, -+ 0, 0, 842, 842, 842, 842, 842, 842, 843, 0, -+ 0, 843, 843, 0, 843, 843, 0, 843, 843, 843, -+ 843, 0, 843, 843, 843, 0, 843, 843, 843, 845, -+ 0, 0, 845, 0, 0, 845, 845, 0, 845, 845, -+ 845, 845, 845, 0, 845, 845, 845, 845, 845, 845, -+ 846, 0, 0, 0, 0, 0, 0, 846, 0, 846, -+ 846, 846, 846, 0, 0, 846, 846, 846, 846, 846, -+ 846, 847, 0, 0, 0, 0, 0, 0, 847, 0, -+ 847, 847, 847, 847, 0, 847, 847, 847, 847, 847, -+ -+ 847, 847, 848, 0, 0, 848, 848, 0, 848, 848, -+ 0, 848, 848, 848, 848, 0, 848, 848, 848, 848, -+ 848, 848, 848, 849, 0, 0, 849, 849, 0, 849, -+ 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, -+ 850, 850, 850, 850, 850, 850, 850, 850, 850, 850, -+ 850, 851, 851, 0, 851, 0, 0, 0, 851, 852, -+ 852, 852, 0, 852, 0, 0, 0, 852, 855, 855, -+ 0, 855, 0, 0, 0, 855, 856, 856, 0, 856, -+ 0, 0, 0, 856, 857, 857, 0, 857, 0, 0, -+ 0, 857, 858, 858, 858, 0, 858, 0, 0, 0, -+ -+ 858, 859, 0, 0, 859, 859, 0, 859, 860, 860, -+ 0, 860, 0, 0, 0, 860, 861, 861, 0, 861, -+ 0, 0, 0, 861, 862, 862, 0, 862, 0, 0, -+ 0, 862, 863, 863, 863, 0, 863, 0, 0, 0, -+ 863, 864, 864, 864, 864, 0, 864, 0, 0, 0, -+ 864, 867, 867, 0, 867, 0, 0, 0, 867, 868, -+ 868, 0, 868, 0, 0, 0, 868, 869, 869, 0, -+ 869, 0, 0, 0, 869, 872, 872, 872, 0, 872, -+ 0, 0, 0, 872, 873, 873, 873, 873, 0, 873, -+ 0, 0, 0, 873, 874, 874, 874, 874, 874, 874, -+ -+ 874, 874, 874, 874, 874, 874, 874, 874, 874, 874, -+ 874, 874, 874, 874, 874, 876, 876, 0, 876, 0, -+ 0, 0, 876, 877, 877, 0, 877, 0, 0, 0, -+ 877, 879, 879, 879, 0, 879, 0, 0, 0, 879, -+ 880, 880, 880, 880, 0, 880, 0, 0, 0, 880, -+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, -+ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881, -+ 881, 884, 0, 0, 884, 884, 0, 884, 885, 0, -+ 0, 0, 885, 885, 0, 885, 885, 885, 0, 0, -+ 885, 885, 886, 886, 0, 886, 0, 0, 0, 886, -+ -+ 887, 0, 887, 887, 0, 887, 0, 0, 0, 887, -+ 890, 890, 890, 0, 890, 0, 0, 0, 890, 891, -+ 891, 891, 891, 0, 891, 0, 0, 0, 891, 892, -+ 892, 0, 0, 892, 0, 0, 0, 892, 893, 893, -+ 893, 893, 893, 893, 893, 893, 893, 893, 893, 893, -+ 893, 893, 893, 893, 893, 893, 893, 893, 893, 895, -+ 0, 0, 895, 895, 0, 895, 896, 0, 0, 0, -+ 896, 896, 0, 896, 896, 896, 0, 0, 896, 896, -+ 899, 899, 0, 899, 0, 0, 0, 899, 900, 0, -+ 900, 900, 0, 900, 0, 0, 0, 900, 902, 902, -+ -+ 902, 0, 902, 0, 0, 0, 902, 903, 903, 903, -+ 0, 0, 903, 0, 0, 0, 903, 904, 904, 904, -+ 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, -+ 904, 904, 904, 904, 904, 904, 904, 904, 905, 905, -+ 0, 905, 905, 905, 0, 905, 0, 905, 905, 905, -+ 905, 0, 0, 905, 905, 905, 905, 905, 905, 906, -+ 906, 0, 906, 906, 906, 0, 906, 0, 906, 906, -+ 906, 906, 0, 0, 906, 906, 906, 906, 906, 906, -+ 909, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 909, 909, 0, 909, 909, 0, 909, 911, 911, -+ -+ 0, 911, 0, 0, 0, 911, 912, 0, 912, 912, -+ 0, 912, 0, 0, 0, 912, 915, 915, 0, 0, -+ 915, 0, 0, 0, 915, 917, 0, 0, 0, 0, -+ 0, 0, 917, 0, 917, 917, 917, 917, 0, 0, -+ 917, 917, 917, 917, 917, 917, 920, 920, 0, 920, -+ 0, 0, 0, 920, 921, 0, 921, 921, 0, 921, -+ 0, 0, 0, 921, 925, 925, 0, 925, 0, 0, -+ 0, 925, 926, 0, 926, 0, 0, 926, 0, 0, -+ 0, 926, 927, 927, 927, 927, 927, 927, 927, 927, -+ 927, 927, 927, 927, 927, 927, 927, 927, 927, 927, -+ -+ 927, 927, 927, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, -+ 813, 813, 813, 813 - } ; - - static yy_state_type yy_last_accepting_state; - static char *yy_last_accepting_cpos; - -+extern int yy_flex_debug; -+int yy_flex_debug = 0; -+ - /* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -@@ -1391,7 +1993,6 @@ static char *yy_last_accepting_cpos; - #define YY_RESTORE_YY_MORE_OFFSET - char *yytext; - #line 1 "toke.l" --#define INITIAL 0 - #line 2 "toke.l" - /* - * Copyright (c) 1996, 1998-2005, 2007-2012 -@@ -1466,6 +2067,7 @@ char *yytext; - #include "toke.h" - #include - #include "lbuf.h" -+#include "filedigest.h" - #include "secure_path.h" - - extern YYSTYPE yylval; -@@ -1483,6 +2085,7 @@ gid_t sudoers_gid = SUDOERS_GID; - - static bool continued, sawspace; - static int prev_state; -+static int digest_len; - - static bool _push_include(char *, bool); - static bool pop_include(void); -@@ -1500,18 +2103,64 @@ int (*trace_print)(const char *msg) = su - #define push_include(_p) (_push_include((_p), false)) - #define push_includedir(_p) (_push_include((_p), true)) - #define YY_NO_INPUT 1 --#define YY_NO_UNPUT 1 --#define GOTDEFS 1 - --#define GOTCMND 2 - --#define STARTDEFS 3 - --#define INDEFS 4 - -+ -+ -+#line 2112 "lex.yy.c" -+ -+#define INITIAL 0 -+#define GOTDEFS 1 -+#define GOTCMND 2 -+#define STARTDEFS 3 -+#define INDEFS 4 - #define INSTR 5 -+#define WANTDIGEST 6 -+ -+#ifndef YY_NO_UNISTD_H -+/* Special case for "unistd.h", since it is non-ANSI. We include it way -+ * down here because we want the user's section 1 to have been scanned first. -+ * The user has a chance to override it with an option. -+ */ -+#include -+#endif -+ -+#ifndef YY_EXTRA_TYPE -+#define YY_EXTRA_TYPE void * -+#endif -+ -+static int yy_init_globals (void ); -+ -+/* Accessor methods to globals. -+ These are made visible to non-reentrant scanners for convenience. */ -+ -+int yylex_destroy (void ); - --#line 1514 "lex.yy.c" -+int yyget_debug (void ); -+ -+void yyset_debug (int debug_flag ); -+ -+YY_EXTRA_TYPE yyget_extra (void ); -+ -+void yyset_extra (YY_EXTRA_TYPE user_defined ); -+ -+FILE *yyget_in (void ); -+ -+void yyset_in (FILE * in_str ); -+ -+FILE *yyget_out (void ); -+ -+void yyset_out (FILE * out_str ); -+ -+yy_size_t yyget_leng (void ); -+ -+char *yyget_text (void ); -+ -+int yyget_lineno (void ); -+ -+void yyset_lineno (int line_number ); - - /* Macros after this point can all be overridden by user definitions in - * section 1. -@@ -1519,65 +2168,28 @@ int (*trace_print)(const char *msg) = su - - #ifndef YY_SKIP_YYWRAP - #ifdef __cplusplus --extern "C" int yywrap YY_PROTO(( void )); -+extern "C" int yywrap (void ); - #else --extern int yywrap YY_PROTO(( void )); --#endif -+extern int yywrap (void ); - #endif -- --#ifndef YY_NO_UNPUT --static void yyunput YY_PROTO(( int c, char *buf_ptr )); - #endif - - #ifndef yytext_ptr --static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -+static void yy_flex_strncpy (char *,yyconst char *,int ); - #endif - - #ifdef YY_NEED_STRLEN --static int yy_flex_strlen YY_PROTO(( yyconst char * )); -+static int yy_flex_strlen (yyconst char * ); - #endif - - #ifndef YY_NO_INPUT --#ifdef __cplusplus --static int yyinput YY_PROTO(( void )); --#else --static int input YY_PROTO(( void )); --#endif --#endif -- --#if defined(YY_STACK_USED) && YY_STACK_USED --static int yy_start_stack_ptr = 0; --static int yy_start_stack_depth = 0; --static int *yy_start_stack = 0; --#ifndef YY_NO_PUSH_STATE --static void yy_push_state YY_PROTO(( int new_state )); --#endif --#ifndef YY_NO_POP_STATE --static void yy_pop_state YY_PROTO(( void )); --#endif --#ifndef YY_NO_TOP_STATE --static int yy_top_state YY_PROTO(( void )); --#endif - -+#ifdef __cplusplus -+static int yyinput (void ); - #else --#define YY_NO_PUSH_STATE 1 --#define YY_NO_POP_STATE 1 --#define YY_NO_TOP_STATE 1 -+static int input (void ); - #endif - --#ifdef YY_MALLOC_DECL --YY_MALLOC_DECL --#else --#ifdef __STDC__ --#ifndef __cplusplus --#include --#endif --#else --/* Just try to get by without declaring the routines. This will fail -- * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) -- * or sizeof(void*) != sizeof(int). -- */ --#endif - #endif - - /* Amount of stuff to slurp up with each read. */ -@@ -1586,12 +2198,11 @@ YY_MALLOC_DECL - #endif - - /* Copy whatever the last rule matched to the standard output. */ -- - #ifndef ECHO - /* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ --#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) - #endif - - /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, -@@ -1599,9 +2210,10 @@ YY_MALLOC_DECL - */ - #ifndef YY_INPUT - #define YY_INPUT(buf,result,max_size) \ -- if ( yy_current_buffer->yy_is_interactive ) \ -+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ -- int c = '*', n; \ -+ int c = '*'; \ -+ size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ -@@ -1611,9 +2223,22 @@ YY_MALLOC_DECL - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ -- else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ -- && ferror( yyin ) ) \ -- YY_FATAL_ERROR( "input in flex scanner failed" ); -+ else \ -+ { \ -+ errno=0; \ -+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ -+ { \ -+ if( errno != EINTR) \ -+ { \ -+ YY_FATAL_ERROR( "input in flex scanner failed" ); \ -+ break; \ -+ } \ -+ errno=0; \ -+ clearerr(yyin); \ -+ } \ -+ }\ -+\ -+ - #endif - - /* No semi-colon after return; correct usage is to write "yyterminate();" - -@@ -1634,12 +2259,18 @@ YY_MALLOC_DECL - #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) - #endif - -+/* end tables serialization structures and prototypes */ -+ - /* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ - #ifndef YY_DECL --#define YY_DECL int yylex YY_PROTO(( void )) --#endif -+#define YY_DECL_IS_OURS 1 -+ -+extern int yylex (void); -+ -+#define YY_DECL int yylex (void) -+#endif /* !YY_DECL */ - - /* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. -@@ -1655,30 +2286,32 @@ YY_MALLOC_DECL - - #define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ -- yy_current_buffer->yy_at_bol = \ -+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -+/** The main scanner function which does all the work. -+ */ - YY_DECL -- { -+{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; -+ -+#line 135 "toke.l" - --#line 132 "toke.l" -+#line 2303 "lex.yy.c" - --#line 1670 "lex.yy.c" -- -- if ( yy_init ) -+ if ( !(yy_init) ) - { -- yy_init = 0; -+ (yy_init) = 1; - - #ifdef YY_USER_INIT - YY_USER_INIT; - #endif - -- if ( ! yy_start ) -- yy_start = 1; /* first start state */ -+ if ( ! (yy_start) ) -+ (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; -@@ -1686,26 +2319,28 @@ YY_DECL - if ( ! yyout ) - yyout = stdout; - -- if ( ! yy_current_buffer ) -- yy_current_buffer = -- yy_create_buffer( yyin, YY_BUF_SIZE ); -+ if ( ! YY_CURRENT_BUFFER ) { -+ yyensure_buffer_stack (); -+ YY_CURRENT_BUFFER_LVALUE = -+ yy_create_buffer(yyin,YY_BUF_SIZE ); -+ } - -- yy_load_buffer_state(); -+ yy_load_buffer_state( ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { -- yy_cp = yy_c_buf_p; -+ yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ -- *yy_cp = yy_hold_char; -+ *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - -- yy_current_state = yy_start; -+ yy_current_state = (yy_start); - yy_current_state += YY_AT_BOL(); - yy_match: - do -@@ -1713,47 +2348,45 @@ yy_match: - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { -- yy_last_accepting_state = yy_current_state; -- yy_last_accepting_cpos = yy_cp; -+ (yy_last_accepting_state) = yy_current_state; -+ (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 622 ) -+ if ( yy_current_state >= 814 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } -- while ( yy_base[yy_current_state] != 3595 ); -+ while ( yy_base[yy_current_state] != 5604 ); - - yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ -- yy_cp = yy_last_accepting_cpos; -- yy_current_state = yy_last_accepting_state; -+ yy_cp = (yy_last_accepting_cpos); -+ yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -- - do_action: /* This label is used only to access EOF actions. */ - -- - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ -- *yy_cp = yy_hold_char; -- yy_cp = yy_last_accepting_cpos; -- yy_current_state = yy_last_accepting_state; -+ *yy_cp = (yy_hold_char); -+ yy_cp = (yy_last_accepting_cpos); -+ yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - - case 1: - YY_RULE_SETUP --#line 133 "toke.l" -+#line 136 "toke.l" - { - LEXTRACE(", "); - LEXRETURN(','); -@@ -1761,12 +2394,12 @@ YY_RULE_SETUP - YY_BREAK - case 2: - YY_RULE_SETUP --#line 138 "toke.l" -+#line 141 "toke.l" - BEGIN STARTDEFS; - YY_BREAK - case 3: - YY_RULE_SETUP --#line 140 "toke.l" -+#line 143 "toke.l" - { - BEGIN INDEFS; - LEXTRACE("DEFVAR "); -@@ -1778,7 +2411,7 @@ YY_RULE_SETUP - - case 4: - YY_RULE_SETUP --#line 149 "toke.l" -+#line 152 "toke.l" - { - BEGIN STARTDEFS; - LEXTRACE(", "); -@@ -1787,7 +2420,7 @@ YY_RULE_SETUP - YY_BREAK - case 5: - YY_RULE_SETUP --#line 155 "toke.l" -+#line 158 "toke.l" - { - LEXTRACE("= "); - LEXRETURN('='); -@@ -1795,7 +2428,7 @@ YY_RULE_SETUP - YY_BREAK - case 6: - YY_RULE_SETUP --#line 160 "toke.l" -+#line 163 "toke.l" - { - LEXTRACE("+= "); - LEXRETURN('+'); -@@ -1803,7 +2436,7 @@ YY_RULE_SETUP - YY_BREAK - case 7: - YY_RULE_SETUP --#line 165 "toke.l" -+#line 168 "toke.l" - { - LEXTRACE("-= "); - LEXRETURN('-'); -@@ -1811,7 +2444,7 @@ YY_RULE_SETUP - YY_BREAK - case 8: - YY_RULE_SETUP --#line 170 "toke.l" -+#line 173 "toke.l" - { - LEXTRACE("BEGINSTR "); - yylval.string = NULL; -@@ -1821,7 +2454,7 @@ YY_RULE_SETUP - YY_BREAK - case 9: - YY_RULE_SETUP --#line 177 "toke.l" -+#line 180 "toke.l" - { - LEXTRACE("WORD(2) "); - if (!fill(yytext, yyleng)) -@@ -1832,8 +2465,9 @@ YY_RULE_SETUP - - - case 10: -+/* rule 10 can match eol */ - YY_RULE_SETUP --#line 186 "toke.l" -+#line 189 "toke.l" - { - /* Line continuation char followed by newline. */ - sudolineno++; -@@ -1842,7 +2476,7 @@ YY_RULE_SETUP - YY_BREAK - case 11: - YY_RULE_SETUP --#line 192 "toke.l" -+#line 195 "toke.l" - { - LEXTRACE("ENDSTR "); - BEGIN prev_state; -@@ -1877,7 +2511,7 @@ YY_RULE_SETUP - YY_BREAK - case 12: - YY_RULE_SETUP --#line 224 "toke.l" -+#line 227 "toke.l" - { - LEXTRACE("BACKSLASH "); - if (!append(yytext, yyleng)) -@@ -1886,7 +2520,7 @@ YY_RULE_SETUP - YY_BREAK - case 13: - YY_RULE_SETUP --#line 230 "toke.l" -+#line 233 "toke.l" - { - LEXTRACE("STRBODY "); - if (!append(yytext, yyleng)) -@@ -1897,7 +2531,7 @@ YY_RULE_SETUP - - case 14: - YY_RULE_SETUP --#line 238 "toke.l" -+#line 241 "toke.l" - { - /* quoted fnmatch glob char, pass verbatim */ - LEXTRACE("QUOTEDCHAR "); -@@ -1908,7 +2542,7 @@ YY_RULE_SETUP - YY_BREAK - case 15: - YY_RULE_SETUP --#line 246 "toke.l" -+#line 249 "toke.l" - { - /* quoted sudoers special char, strip backslash */ - LEXTRACE("QUOTEDCHAR "); -@@ -1918,8 +2552,9 @@ YY_RULE_SETUP - } - YY_BREAK - case 16: -+/* rule 16 can match eol */ - YY_RULE_SETUP --#line 254 "toke.l" -+#line 257 "toke.l" - { - BEGIN INITIAL; - yyless(0); -@@ -1928,7 +2563,7 @@ YY_RULE_SETUP - YY_BREAK - case 17: - YY_RULE_SETUP --#line 260 "toke.l" -+#line 263 "toke.l" - { - LEXTRACE("ARG "); - if (!fill_args(yytext, yyleng, sawspace)) -@@ -1939,7 +2574,48 @@ YY_RULE_SETUP - - case 18: - YY_RULE_SETUP --#line 268 "toke.l" -+#line 271 "toke.l" -+{ -+ /* Only return DIGEST if the length is correct. */ -+ if (yyleng == digest_len * 2) { -+ if (!fill(yytext, yyleng)) -+ yyterminate(); -+ BEGIN INITIAL; -+ LEXTRACE("DIGEST "); -+ LEXRETURN(DIGEST); -+ } -+ BEGIN INITIAL; -+ yyless(yyleng); -+ } /* hex digest */ -+ YY_BREAK -+case 19: -+YY_RULE_SETUP -+#line 284 "toke.l" -+{ -+ /* Only return DIGEST if the length is correct. */ -+ size_t len; -+ if (yytext[yyleng - 1] == '=') { -+ /* use padding */ -+ len = 4 * ((digest_len + 2) / 3); -+ } else { -+ /* no padding */ -+ len = (4 * digest_len + 2) / 3; -+ } -+ if (yyleng == len) { -+ if (!fill(yytext, yyleng)) -+ yyterminate(); -+ BEGIN INITIAL; -+ LEXTRACE("DIGEST "); -+ LEXRETURN(DIGEST); -+ } -+ BEGIN INITIAL; -+ yyless(yyleng); -+ } /* base64 digest */ -+ YY_BREAK -+case 20: -+/* rule 20 can match eol */ -+YY_RULE_SETUP -+#line 305 "toke.l" - { - char *path; - -@@ -1958,9 +2634,10 @@ YY_RULE_SETUP - yyterminate(); - } - YY_BREAK --case 19: -+case 21: -+/* rule 21 can match eol */ - YY_RULE_SETUP --#line 286 "toke.l" -+#line 323 "toke.l" - { - char *path; - -@@ -1982,9 +2659,9 @@ YY_RULE_SETUP - yyterminate(); - } - YY_BREAK --case 20: -+case 22: - YY_RULE_SETUP --#line 307 "toke.l" -+#line 344 "toke.l" - { - char deftype; - int n; -@@ -2025,9 +2702,9 @@ YY_RULE_SETUP - } - } - YY_BREAK --case 21: -+case 23: - YY_RULE_SETUP --#line 347 "toke.l" -+#line 384 "toke.l" - { - int n; - -@@ -2054,100 +2731,100 @@ YY_RULE_SETUP - } - } - YY_BREAK --case 22: -+case 24: - YY_RULE_SETUP --#line 373 "toke.l" -+#line 410 "toke.l" - { - /* cmnd does not require passwd for this user */ - LEXTRACE("NOPASSWD "); - LEXRETURN(NOPASSWD); - } - YY_BREAK --case 23: -+case 25: - YY_RULE_SETUP --#line 379 "toke.l" -+#line 416 "toke.l" - { - /* cmnd requires passwd for this user */ - LEXTRACE("PASSWD "); - LEXRETURN(PASSWD); - } - YY_BREAK --case 24: -+case 26: - YY_RULE_SETUP --#line 385 "toke.l" -+#line 422 "toke.l" - { - LEXTRACE("NOEXEC "); - LEXRETURN(NOEXEC); - } - YY_BREAK --case 25: -+case 27: - YY_RULE_SETUP --#line 390 "toke.l" -+#line 427 "toke.l" - { - LEXTRACE("EXEC "); - LEXRETURN(EXEC); - } - YY_BREAK --case 26: -+case 28: - YY_RULE_SETUP --#line 395 "toke.l" -+#line 432 "toke.l" - { - LEXTRACE("SETENV "); - LEXRETURN(SETENV); - } - YY_BREAK --case 27: -+case 29: - YY_RULE_SETUP --#line 400 "toke.l" -+#line 437 "toke.l" - { - LEXTRACE("NOSETENV "); - LEXRETURN(NOSETENV); - } - YY_BREAK --case 28: -+case 30: - YY_RULE_SETUP --#line 405 "toke.l" -+#line 442 "toke.l" - { - LEXTRACE("LOG_OUTPUT "); - LEXRETURN(LOG_OUTPUT); - } - YY_BREAK --case 29: -+case 31: - YY_RULE_SETUP --#line 410 "toke.l" -+#line 447 "toke.l" - { - LEXTRACE("NOLOG_OUTPUT "); - LEXRETURN(NOLOG_OUTPUT); - } - YY_BREAK --case 30: -+case 32: - YY_RULE_SETUP --#line 415 "toke.l" -+#line 452 "toke.l" - { - LEXTRACE("LOG_INPUT "); - LEXRETURN(LOG_INPUT); - } - YY_BREAK --case 31: -+case 33: - YY_RULE_SETUP --#line 420 "toke.l" -+#line 457 "toke.l" - { - LEXTRACE("NOLOG_INPUT "); - LEXRETURN(NOLOG_INPUT); - } - YY_BREAK --case 32: -+case 34: - YY_RULE_SETUP --#line 425 "toke.l" -+#line 462 "toke.l" - { - /* empty group or netgroup */ - LEXTRACE("ERROR "); - LEXRETURN(ERROR); - } - YY_BREAK --case 33: -+case 35: - YY_RULE_SETUP --#line 431 "toke.l" -+#line 468 "toke.l" - { - /* netgroup */ - if (!fill(yytext, yyleng)) -@@ -2156,9 +2833,9 @@ YY_RULE_SETUP - LEXRETURN(NETGROUP); - } - YY_BREAK --case 34: -+case 36: - YY_RULE_SETUP --#line 439 "toke.l" -+#line 476 "toke.l" - { - /* group */ - if (!fill(yytext, yyleng)) -@@ -2167,9 +2844,9 @@ YY_RULE_SETUP - LEXRETURN(USERGROUP); - } - YY_BREAK --case 35: -+case 37: - YY_RULE_SETUP --#line 447 "toke.l" -+#line 484 "toke.l" - { - if (!fill(yytext, yyleng)) - yyterminate(); -@@ -2177,9 +2854,9 @@ YY_RULE_SETUP - LEXRETURN(NTWKADDR); - } - YY_BREAK --case 36: -+case 38: - YY_RULE_SETUP --#line 454 "toke.l" -+#line 491 "toke.l" - { - if (!fill(yytext, yyleng)) - yyterminate(); -@@ -2187,9 +2864,9 @@ YY_RULE_SETUP - LEXRETURN(NTWKADDR); - } - YY_BREAK --case 37: -+case 39: - YY_RULE_SETUP --#line 461 "toke.l" -+#line 498 "toke.l" - { - if (!ipv6_valid(yytext)) { - LEXTRACE("ERROR "); -@@ -2201,9 +2878,9 @@ YY_RULE_SETUP - LEXRETURN(NTWKADDR); - } - YY_BREAK --case 38: -+case 40: - YY_RULE_SETUP --#line 472 "toke.l" -+#line 509 "toke.l" - { - if (!ipv6_valid(yytext)) { - LEXTRACE("ERROR "); -@@ -2215,18 +2892,18 @@ YY_RULE_SETUP - LEXRETURN(NTWKADDR); - } - YY_BREAK --case 39: -+case 41: - YY_RULE_SETUP --#line 483 "toke.l" -+#line 520 "toke.l" - { - LEXTRACE("ALL "); - LEXRETURN(ALL); - - } - YY_BREAK --case 40: -+case 42: - YY_RULE_SETUP --#line 489 "toke.l" -+#line 526 "toke.l" - { - #ifdef HAVE_SELINUX - LEXTRACE("ROLE "); -@@ -2236,9 +2913,9 @@ YY_RULE_SETUP - #endif - } - YY_BREAK --case 41: -+case 43: - YY_RULE_SETUP --#line 498 "toke.l" -+#line 535 "toke.l" - { - #ifdef HAVE_SELINUX - LEXTRACE("TYPE "); -@@ -2248,9 +2925,9 @@ YY_RULE_SETUP - #endif - } - YY_BREAK --case 42: -+case 44: - YY_RULE_SETUP --#line 506 "toke.l" -+#line 543 "toke.l" - { - #ifdef HAVE_PRIV_SET - LEXTRACE("PRIVS "); -@@ -2260,9 +2937,9 @@ YY_RULE_SETUP - #endif - } - YY_BREAK --case 43: -+case 45: - YY_RULE_SETUP --#line 515 "toke.l" -+#line 552 "toke.l" - { - #ifdef HAVE_PRIV_SET - LEXTRACE("LIMITPRIVS "); -@@ -2272,9 +2949,9 @@ YY_RULE_SETUP - #endif - } - YY_BREAK --case 44: -+case 46: - YY_RULE_SETUP --#line 524 "toke.l" -+#line 561 "toke.l" - { - got_alias: - if (!fill(yytext, yyleng)) -@@ -2283,10 +2960,11 @@ YY_RULE_SETUP - LEXRETURN(ALIAS); - } - YY_BREAK --case 45: -+case 47: - YY_RULE_SETUP --#line 532 "toke.l" -+#line 569 "toke.l" - { -+ /* XXX - no way to specify digest for command */ - /* no command args allowed for Defaults!/path */ - if (!fill_cmnd(yytext, yyleng)) - yyterminate(); -@@ -2294,9 +2972,49 @@ YY_RULE_SETUP - LEXRETURN(COMMAND); - } - YY_BREAK --case 46: -+case 48: -+YY_RULE_SETUP -+#line 578 "toke.l" -+{ -+ digest_len = SUDO_SHA224_DIGEST_LENGTH; -+ BEGIN WANTDIGEST; -+ LEXTRACE("SHA224 "); -+ LEXRETURN(SHA224); -+ } -+ YY_BREAK -+case 49: -+YY_RULE_SETUP -+#line 585 "toke.l" -+{ -+ digest_len = SUDO_SHA256_DIGEST_LENGTH; -+ BEGIN WANTDIGEST; -+ LEXTRACE("SHA256 "); -+ LEXRETURN(SHA256); -+ } -+ YY_BREAK -+case 50: -+YY_RULE_SETUP -+#line 592 "toke.l" -+{ -+ digest_len = SUDO_SHA384_DIGEST_LENGTH; -+ BEGIN WANTDIGEST; -+ LEXTRACE("SHA384 "); -+ LEXRETURN(SHA384); -+ } -+ YY_BREAK -+case 51: -+YY_RULE_SETUP -+#line 599 "toke.l" -+{ -+ digest_len = SUDO_SHA512_DIGEST_LENGTH; -+ BEGIN WANTDIGEST; -+ LEXTRACE("SHA512 "); -+ LEXRETURN(SHA512); -+ } -+ YY_BREAK -+case 52: - YY_RULE_SETUP --#line 540 "toke.l" -+#line 606 "toke.l" - { - BEGIN GOTCMND; - LEXTRACE("COMMAND "); -@@ -2304,9 +3022,9 @@ YY_RULE_SETUP - yyterminate(); - } /* sudo -e */ - YY_BREAK --case 47: -+case 53: - YY_RULE_SETUP --#line 547 "toke.l" -+#line 613 "toke.l" - { - /* directories can't have args... */ - if (yytext[yyleng - 1] == '/') { -@@ -2322,9 +3040,9 @@ YY_RULE_SETUP - } - } /* a pathname */ - YY_BREAK --case 48: -+case 54: - YY_RULE_SETUP --#line 562 "toke.l" -+#line 628 "toke.l" - { - LEXTRACE("BEGINSTR "); - yylval.string = NULL; -@@ -2332,9 +3050,9 @@ YY_RULE_SETUP - BEGIN INSTR; - } - YY_BREAK --case 49: -+case 55: - YY_RULE_SETUP --#line 569 "toke.l" -+#line 635 "toke.l" - { - /* a word */ - if (!fill(yytext, yyleng)) -@@ -2343,49 +3061,49 @@ YY_RULE_SETUP - LEXRETURN(WORD); - } - YY_BREAK --case 50: -+case 56: - YY_RULE_SETUP --#line 577 "toke.l" -+#line 643 "toke.l" - { - LEXTRACE("( "); - LEXRETURN('('); - } - YY_BREAK --case 51: -+case 57: - YY_RULE_SETUP --#line 582 "toke.l" -+#line 648 "toke.l" - { - LEXTRACE(") "); - LEXRETURN(')'); - } - YY_BREAK --case 52: -+case 58: - YY_RULE_SETUP --#line 587 "toke.l" -+#line 653 "toke.l" - { - LEXTRACE(", "); - LEXRETURN(','); - } /* return ',' */ - YY_BREAK --case 53: -+case 59: - YY_RULE_SETUP --#line 592 "toke.l" -+#line 658 "toke.l" - { - LEXTRACE("= "); - LEXRETURN('='); - } /* return '=' */ - YY_BREAK --case 54: -+case 60: - YY_RULE_SETUP --#line 597 "toke.l" -+#line 663 "toke.l" - { - LEXTRACE(": "); - LEXRETURN(':'); - } /* return ':' */ - YY_BREAK --case 55: -+case 61: - YY_RULE_SETUP --#line 602 "toke.l" -+#line 668 "toke.l" - { - if (yyleng & 1) { - LEXTRACE("!"); -@@ -2393,9 +3111,10 @@ YY_RULE_SETUP - } - } - YY_BREAK --case 56: -+case 62: -+/* rule 62 can match eol */ - YY_RULE_SETUP --#line 609 "toke.l" -+#line 675 "toke.l" - { - if (YY_START == INSTR) { - LEXTRACE("ERROR "); -@@ -2408,25 +3127,27 @@ YY_RULE_SETUP - LEXRETURN(COMMENT); - } /* return newline */ - YY_BREAK --case 57: -+case 63: - YY_RULE_SETUP --#line 621 "toke.l" -+#line 687 "toke.l" - { /* throw away space/tabs */ - sawspace = true; /* but remember for fill_args */ - } - YY_BREAK --case 58: -+case 64: -+/* rule 64 can match eol */ - YY_RULE_SETUP --#line 625 "toke.l" -+#line 691 "toke.l" - { - sawspace = true; /* remember for fill_args */ - sudolineno++; - continued = true; - } /* throw away EOL after \ */ - YY_BREAK --case 59: -+case 65: -+/* rule 65 can match eol */ - YY_RULE_SETUP --#line 631 "toke.l" -+#line 697 "toke.l" - { - BEGIN INITIAL; - sudolineno++; -@@ -2435,9 +3156,9 @@ YY_RULE_SETUP - LEXRETURN(COMMENT); - } /* comment, not uid/gid */ - YY_BREAK --case 60: -+case 66: - YY_RULE_SETUP --#line 639 "toke.l" -+#line 705 "toke.l" - { - LEXTRACE("ERROR "); - LEXRETURN(ERROR); -@@ -2449,7 +3170,8 @@ case YY_STATE_EOF(GOTCMND): - case YY_STATE_EOF(STARTDEFS): - case YY_STATE_EOF(INDEFS): - case YY_STATE_EOF(INSTR): --#line 644 "toke.l" -+case YY_STATE_EOF(WANTDIGEST): -+#line 710 "toke.l" - { - if (YY_START != INITIAL) { - BEGIN INITIAL; -@@ -2460,36 +3182,36 @@ case YY_STATE_EOF(INSTR): - yyterminate(); - } - YY_BREAK --case 61: -+case 67: - YY_RULE_SETUP --#line 654 "toke.l" -+#line 720 "toke.l" - ECHO; - YY_BREAK --#line 2468 "lex.yy.c" -+#line 3190 "lex.yy.c" - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ -- int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; -+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ -- *yy_cp = yy_hold_char; -+ *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - -- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) -+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure -- * consistency between yy_current_buffer and our -+ * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ -- yy_n_chars = yy_current_buffer->yy_n_chars; -- yy_current_buffer->yy_input_file = yyin; -- yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; -+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; -+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; -+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position -@@ -2499,13 +3221,13 @@ ECHO; - * end-of-buffer state). Contrast this with the test - * in input(). - */ -- if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) -+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - -- yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; -+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - -- yy_current_state = yy_get_previous_state(); -+ yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have -@@ -2518,30 +3240,30 @@ ECHO; - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - -- yy_bp = yytext_ptr + YY_MORE_ADJ; -+ yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ -- yy_cp = ++yy_c_buf_p; -+ yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { -- yy_cp = yy_c_buf_p; -+ yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - -- else switch ( yy_get_next_buffer() ) -+ else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { -- yy_did_buffer_switch_on_eof = 0; -+ (yy_did_buffer_switch_on_eof) = 0; - -- if ( yywrap() ) -+ if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up -@@ -2552,7 +3274,7 @@ ECHO; - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ -- yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; -+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; -@@ -2560,30 +3282,30 @@ ECHO; - - else - { -- if ( ! yy_did_buffer_switch_on_eof ) -+ if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: -- yy_c_buf_p = -- yytext_ptr + yy_amount_of_matched_text; -+ (yy_c_buf_p) = -+ (yytext_ptr) + yy_amount_of_matched_text; - -- yy_current_state = yy_get_previous_state(); -+ yy_current_state = yy_get_previous_state( ); - -- yy_cp = yy_c_buf_p; -- yy_bp = yytext_ptr + YY_MORE_ADJ; -+ yy_cp = (yy_c_buf_p); -+ yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: -- yy_c_buf_p = -- &yy_current_buffer->yy_ch_buf[yy_n_chars]; -+ (yy_c_buf_p) = -+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - -- yy_current_state = yy_get_previous_state(); -+ yy_current_state = yy_get_previous_state( ); - -- yy_cp = yy_c_buf_p; -- yy_bp = yytext_ptr + YY_MORE_ADJ; -+ yy_cp = (yy_c_buf_p); -+ yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; -@@ -2594,8 +3316,7 @@ ECHO; - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -- } /* end of yylex */ -- -+} /* end of yylex */ - - /* yy_get_next_buffer - try to read in a new buffer - * -@@ -2604,21 +3325,20 @@ ECHO; - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -- --static int yy_get_next_buffer() -- { -- register char *dest = yy_current_buffer->yy_ch_buf; -- register char *source = yytext_ptr; -+static int yy_get_next_buffer (void) -+{ -+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -+ register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; - -- if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) -+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - -- if ( yy_current_buffer->yy_fill_buffer == 0 ) -+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ -- if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) -+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. -@@ -2638,38 +3358,34 @@ static int yy_get_next_buffer() - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ -- number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; -+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - -- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) -+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ -- yy_current_buffer->yy_n_chars = yy_n_chars = 0; -+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { -- int num_to_read = -- yy_current_buffer->yy_buf_size - number_to_move - 1; -+ yy_size_t num_to_read = -+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ --#ifdef YY_USES_REJECT -- YY_FATAL_ERROR( --"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); --#else - - /* just a shorter name for the current buffer */ -- YY_BUFFER_STATE b = yy_current_buffer; -+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = -- (int) (yy_c_buf_p - b->yy_ch_buf); -+ (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { -- int new_size = b->yy_buf_size * 2; -+ yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; -@@ -2678,8 +3394,7 @@ static int yy_get_next_buffer() - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ -- yy_flex_realloc( (void *) b->yy_ch_buf, -- b->yy_buf_size + 2 ); -+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ -@@ -2689,35 +3404,35 @@ static int yy_get_next_buffer() - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - -- yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; -+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - -- num_to_read = yy_current_buffer->yy_buf_size - -+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; --#endif -+ - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ -- YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), -- yy_n_chars, num_to_read ); -+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), -+ (yy_n_chars), num_to_read ); - -- yy_current_buffer->yy_n_chars = yy_n_chars; -+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - -- if ( yy_n_chars == 0 ) -+ if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; -- yyrestart( yyin ); -+ yyrestart(yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; -- yy_current_buffer->yy_buffer_status = -+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } -@@ -2725,154 +3440,109 @@ static int yy_get_next_buffer() - else - ret_val = EOB_ACT_CONTINUE_SCAN; - -- yy_n_chars += number_to_move; -- yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; -- yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; -+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { -+ /* Extend the array by 50%, plus the number we really need. */ -+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); -+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); -+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) -+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); -+ } - -- yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; -+ (yy_n_chars) += number_to_move; -+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; -+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - -- return ret_val; -- } -+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - -+ return ret_val; -+} - - /* yy_get_previous_state - get the state just before the EOB char was reached */ - --static yy_state_type yy_get_previous_state() -- { -+ static yy_state_type yy_get_previous_state (void) -+{ - register yy_state_type yy_current_state; - register char *yy_cp; -- -- yy_current_state = yy_start; -+ -+ yy_current_state = (yy_start); - yy_current_state += YY_AT_BOL(); - -- for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) -+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { -- yy_last_accepting_state = yy_current_state; -- yy_last_accepting_cpos = yy_cp; -+ (yy_last_accepting_state) = yy_current_state; -+ (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 622 ) -+ if ( yy_current_state >= 814 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -- } -- -+} - - /* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ -- --#ifdef YY_USE_PROTOS --static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) --#else --static yy_state_type yy_try_NUL_trans( yy_current_state ) --yy_state_type yy_current_state; --#endif -- { -+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -+{ - register int yy_is_jam; -- register char *yy_cp = yy_c_buf_p; -+ register char *yy_cp = (yy_c_buf_p); - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { -- yy_last_accepting_state = yy_current_state; -- yy_last_accepting_cpos = yy_cp; -+ (yy_last_accepting_state) = yy_current_state; -+ (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 622 ) -+ if ( yy_current_state >= 814 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 621); -- -- return yy_is_jam ? 0 : yy_current_state; -- } -- -- --#ifndef YY_NO_UNPUT --#ifdef YY_USE_PROTOS --static void yyunput( int c, register char *yy_bp ) --#else --static void yyunput( c, yy_bp ) --int c; --register char *yy_bp; --#endif -- { -- register char *yy_cp = yy_c_buf_p; -- -- /* undo effects of setting up yytext */ -- *yy_cp = yy_hold_char; -- -- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) -- { /* need to shift things up to make room */ -- /* +2 for EOB chars. */ -- register int number_to_move = yy_n_chars + 2; -- register char *dest = &yy_current_buffer->yy_ch_buf[ -- yy_current_buffer->yy_buf_size + 2]; -- register char *source = -- &yy_current_buffer->yy_ch_buf[number_to_move]; -- -- while ( source > yy_current_buffer->yy_ch_buf ) -- *--dest = *--source; -- -- yy_cp += (int) (dest - source); -- yy_bp += (int) (dest - source); -- yy_current_buffer->yy_n_chars = -- yy_n_chars = yy_current_buffer->yy_buf_size; -- -- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) -- YY_FATAL_ERROR( "flex scanner push-back overflow" ); -- } -- -- *--yy_cp = (char) c; -- -- -- yytext_ptr = yy_bp; -- yy_hold_char = *yy_cp; -- yy_c_buf_p = yy_cp; -- } --#endif /* ifndef YY_NO_UNPUT */ -+ yy_is_jam = (yy_current_state == 813); - -+ return yy_is_jam ? 0 : yy_current_state; -+} - - #ifndef YY_NO_INPUT - #ifdef __cplusplus --static int yyinput() -+ static int yyinput (void) - #else --static int input() -+ static int input (void) - #endif -- { -- int c; - -- *yy_c_buf_p = yy_hold_char; -+{ -+ int c; -+ -+ *(yy_c_buf_p) = (yy_hold_char); - -- if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) -+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ -- if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) -+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ -- *yy_c_buf_p = '\0'; -+ *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ -- int offset = yy_c_buf_p - yytext_ptr; -- ++yy_c_buf_p; -+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); -+ ++(yy_c_buf_p); - -- switch ( yy_get_next_buffer() ) -+ switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() -@@ -2886,16 +3556,16 @@ static int input() - */ - - /* Reset buffer status. */ -- yyrestart( yyin ); -+ yyrestart(yyin ); - -- /* fall through */ -+ /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { -- if ( yywrap() ) -+ if ( yywrap( ) ) - return EOF; - -- if ( ! yy_did_buffer_switch_on_eof ) -+ if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - #ifdef __cplusplus - return yyinput(); -@@ -2905,92 +3575,94 @@ static int input() - } - - case EOB_ACT_CONTINUE_SCAN: -- yy_c_buf_p = yytext_ptr + offset; -+ (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - -- c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ -- *yy_c_buf_p = '\0'; /* preserve yytext */ -- yy_hold_char = *++yy_c_buf_p; -+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ -+ *(yy_c_buf_p) = '\0'; /* preserve yytext */ -+ (yy_hold_char) = *++(yy_c_buf_p); - -- yy_current_buffer->yy_at_bol = (c == '\n'); -+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); - - return c; -- } -+} - #endif /* ifndef YY_NO_INPUT */ - -- --#ifdef YY_USE_PROTOS --void yyrestart( FILE *input_file ) --#else --void yyrestart( input_file ) --FILE *input_file; --#endif -- { -- if ( ! yy_current_buffer ) -- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); -- -- yy_init_buffer( yy_current_buffer, input_file ); -- yy_load_buffer_state(); -+/** Immediately switch to a different input stream. -+ * @param input_file A readable stream. -+ * -+ * @note This function does not reset the start condition to @c INITIAL . -+ */ -+ void yyrestart (FILE * input_file ) -+{ -+ -+ if ( ! YY_CURRENT_BUFFER ){ -+ yyensure_buffer_stack (); -+ YY_CURRENT_BUFFER_LVALUE = -+ yy_create_buffer(yyin,YY_BUF_SIZE ); - } - -+ yy_init_buffer(YY_CURRENT_BUFFER,input_file ); -+ yy_load_buffer_state( ); -+} - --#ifdef YY_USE_PROTOS --void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) --#else --void yy_switch_to_buffer( new_buffer ) --YY_BUFFER_STATE new_buffer; --#endif -- { -- if ( yy_current_buffer == new_buffer ) -+/** Switch to a different input buffer. -+ * @param new_buffer The new input buffer. -+ * -+ */ -+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -+{ -+ -+ /* TODO. We should be able to replace this entire function body -+ * with -+ * yypop_buffer_state(); -+ * yypush_buffer_state(new_buffer); -+ */ -+ yyensure_buffer_stack (); -+ if ( YY_CURRENT_BUFFER == new_buffer ) - return; - -- if ( yy_current_buffer ) -+ if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ -- *yy_c_buf_p = yy_hold_char; -- yy_current_buffer->yy_buf_pos = yy_c_buf_p; -- yy_current_buffer->yy_n_chars = yy_n_chars; -+ *(yy_c_buf_p) = (yy_hold_char); -+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); -+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - -- yy_current_buffer = new_buffer; -- yy_load_buffer_state(); -+ YY_CURRENT_BUFFER_LVALUE = new_buffer; -+ yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ -- yy_did_buffer_switch_on_eof = 1; -- } -- -- --#ifdef YY_USE_PROTOS --void yy_load_buffer_state( void ) --#else --void yy_load_buffer_state() --#endif -- { -- yy_n_chars = yy_current_buffer->yy_n_chars; -- yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; -- yyin = yy_current_buffer->yy_input_file; -- yy_hold_char = *yy_c_buf_p; -- } -+ (yy_did_buffer_switch_on_eof) = 1; -+} - -+static void yy_load_buffer_state (void) -+{ -+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; -+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; -+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; -+ (yy_hold_char) = *(yy_c_buf_p); -+} - --#ifdef YY_USE_PROTOS --YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) --#else --YY_BUFFER_STATE yy_create_buffer( file, size ) --FILE *file; --int size; --#endif -- { -+/** Allocate and initialize an input buffer state. -+ * @param file A readable stream. -+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. -+ * -+ * @return the allocated buffer state. -+ */ -+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -+{ - YY_BUFFER_STATE b; -- -- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); -+ -+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - -@@ -2999,83 +3671,71 @@ int size; - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ -- b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); -+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - -- yy_init_buffer( b, file ); -+ yy_init_buffer(b,file ); - - return b; -- } -- -+} - --#ifdef YY_USE_PROTOS --void yy_delete_buffer( YY_BUFFER_STATE b ) --#else --void yy_delete_buffer( b ) --YY_BUFFER_STATE b; --#endif -- { -+/** Destroy the buffer. -+ * @param b a buffer created with yy_create_buffer() -+ * -+ */ -+ void yy_delete_buffer (YY_BUFFER_STATE b ) -+{ -+ - if ( ! b ) - return; - -- if ( b == yy_current_buffer ) -- yy_current_buffer = (YY_BUFFER_STATE) 0; -+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ -+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) -- yy_flex_free( (void *) b->yy_ch_buf ); -- -- yy_flex_free( (void *) b ); -- } -- -+ yyfree((void *) b->yy_ch_buf ); - --#ifndef YY_ALWAYS_INTERACTIVE --#ifndef YY_NEVER_INTERACTIVE --#include --#endif --#endif -- --#ifdef YY_USE_PROTOS --void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) --#else --void yy_init_buffer( b, file ) --YY_BUFFER_STATE b; --FILE *file; --#endif -+ yyfree((void *) b ); -+} - -+/* Initializes or reinitializes a buffer. -+ * This function is sometimes called more than once on the same buffer, -+ * such as during a yyrestart() or at EOF. -+ */ -+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -- { -+{ - int oerrno = errno; -- -- yy_flush_buffer( b ); -+ -+ yy_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - --#if defined(YY_ALWAYS_INTERACTIVE) && YY_ALWAYS_INTERACTIVE -- b->yy_is_interactive = 1; --#else --#if defined(YY_NEVER_INTERACTIVE) && YY_NEVER_INTERACTIVE -- b->yy_is_interactive = 0; --#else -- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; --#endif --#endif -- errno = oerrno; -- } -- -+ /* If b is the current buffer, then yy_init_buffer was _probably_ -+ * called from yyrestart() or through yy_get_next_buffer. -+ * In that case, we don't want to reset the lineno or column. -+ */ -+ if (b != YY_CURRENT_BUFFER){ -+ b->yy_bs_lineno = 1; -+ b->yy_bs_column = 0; -+ } - --#ifdef YY_USE_PROTOS --void yy_flush_buffer( YY_BUFFER_STATE b ) --#else --void yy_flush_buffer( b ) --YY_BUFFER_STATE b; --#endif -+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -+ -+ errno = oerrno; -+} - -- { -- if ( ! b ) -+/** Discard all buffered characters. On the next scan, YY_INPUT will be called. -+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. -+ * -+ */ -+ void yy_flush_buffer (YY_BUFFER_STATE b ) -+{ -+ if ( ! b ) - return; - - b->yy_n_chars = 0; -@@ -3092,29 +3752,125 @@ YY_BUFFER_STATE b; - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - -- if ( b == yy_current_buffer ) -- yy_load_buffer_state(); -+ if ( b == YY_CURRENT_BUFFER ) -+ yy_load_buffer_state( ); -+} -+ -+/** Pushes the new state onto the stack. The new state becomes -+ * the current state. This function will allocate the stack -+ * if necessary. -+ * @param new_buffer The new state. -+ * -+ */ -+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -+{ -+ if (new_buffer == NULL) -+ return; -+ -+ yyensure_buffer_stack(); -+ -+ /* This block is copied from yy_switch_to_buffer. */ -+ if ( YY_CURRENT_BUFFER ) -+ { -+ /* Flush out information for old buffer. */ -+ *(yy_c_buf_p) = (yy_hold_char); -+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); -+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); -+ } -+ -+ /* Only push if top exists. Otherwise, replace top. */ -+ if (YY_CURRENT_BUFFER) -+ (yy_buffer_stack_top)++; -+ YY_CURRENT_BUFFER_LVALUE = new_buffer; -+ -+ /* copied from yy_switch_to_buffer. */ -+ yy_load_buffer_state( ); -+ (yy_did_buffer_switch_on_eof) = 1; -+} -+ -+/** Removes and deletes the top of the stack, if present. -+ * The next element becomes the new top. -+ * -+ */ -+void yypop_buffer_state (void) -+{ -+ if (!YY_CURRENT_BUFFER) -+ return; -+ -+ yy_delete_buffer(YY_CURRENT_BUFFER ); -+ YY_CURRENT_BUFFER_LVALUE = NULL; -+ if ((yy_buffer_stack_top) > 0) -+ --(yy_buffer_stack_top); -+ -+ if (YY_CURRENT_BUFFER) { -+ yy_load_buffer_state( ); -+ (yy_did_buffer_switch_on_eof) = 1; - } -+} - -+/* Allocates the stack if it does not exist. -+ * Guarantees space for at least one push. -+ */ -+static void yyensure_buffer_stack (void) -+{ -+ yy_size_t num_to_alloc; -+ -+ if (!(yy_buffer_stack)) { -+ -+ /* First allocation is just for 2 elements, since we don't know if this -+ * scanner will even need a stack. We use 2 instead of 1 to avoid an -+ * immediate realloc on the next call. -+ */ -+ num_to_alloc = 1; -+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc -+ (num_to_alloc * sizeof(struct yy_buffer_state*) -+ ); -+ if ( ! (yy_buffer_stack) ) -+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); -+ -+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); -+ -+ (yy_buffer_stack_max) = num_to_alloc; -+ (yy_buffer_stack_top) = 0; -+ return; -+ } - --#ifndef YY_NO_SCAN_BUFFER --#ifdef YY_USE_PROTOS --YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) --#else --YY_BUFFER_STATE yy_scan_buffer( base, size ) --char *base; --yy_size_t size; --#endif -- { -- YY_BUFFER_STATE b; -+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - -+ /* Increase the buffer to prepare for a possible push. */ -+ int grow_size = 8 /* arbitrary grow size */; -+ -+ num_to_alloc = (yy_buffer_stack_max) + grow_size; -+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc -+ ((yy_buffer_stack), -+ num_to_alloc * sizeof(struct yy_buffer_state*) -+ ); -+ if ( ! (yy_buffer_stack) ) -+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); -+ -+ /* zero only the new slots.*/ -+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); -+ (yy_buffer_stack_max) = num_to_alloc; -+ } -+} -+ -+/** Setup the input buffer state to scan directly from a user-specified character buffer. -+ * @param base the character buffer -+ * @param size the size in bytes of the character buffer -+ * -+ * @return the newly allocated buffer state object. -+ */ -+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -+{ -+ YY_BUFFER_STATE b; -+ - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - -- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); -+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - -@@ -3128,56 +3884,51 @@ yy_size_t size; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - -- yy_switch_to_buffer( b ); -+ yy_switch_to_buffer(b ); - - return b; -- } --#endif -- -- --#ifndef YY_NO_SCAN_STRING --#ifdef YY_USE_PROTOS --YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) --#else --YY_BUFFER_STATE yy_scan_string( yy_str ) --yyconst char *yy_str; --#endif -- { -- int len; -- for ( len = 0; yy_str[len]; ++len ) -- ; -- -- return yy_scan_bytes( yy_str, len ); -- } --#endif -+} - -+/** Setup the input buffer state to scan a string. The next call to yylex() will -+ * scan from a @e copy of @a str. -+ * @param yystr a NUL-terminated string to scan -+ * -+ * @return the newly allocated buffer state object. -+ * @note If you want to scan bytes that may contain NUL values, then use -+ * yy_scan_bytes() instead. -+ */ -+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) -+{ -+ -+ return yy_scan_bytes(yystr,strlen(yystr) ); -+} - --#ifndef YY_NO_SCAN_BYTES --#ifdef YY_USE_PROTOS --YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) --#else --YY_BUFFER_STATE yy_scan_bytes( bytes, len ) --yyconst char *bytes; --int len; --#endif -- { -+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will -+ * scan from a @e copy of @a bytes. -+ * @param yybytes the byte buffer to scan -+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. -+ * -+ * @return the newly allocated buffer state object. -+ */ -+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) -+{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; -- int i; -- -+ yy_size_t i; -+ - /* Get memory for full buffer, including space for trailing EOB's. */ -- n = len + 2; -- buf = (char *) yy_flex_alloc( n ); -+ n = _yybytes_len + 2; -+ buf = (char *) yyalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - -- for ( i = 0; i < len; ++i ) -- buf[i] = bytes[i]; -+ for ( i = 0; i < _yybytes_len; ++i ) -+ buf[i] = yybytes[i]; - -- buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; -+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - -- b = yy_scan_buffer( buf, n ); -+ b = yy_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - -@@ -3187,148 +3938,196 @@ int len; - b->yy_is_our_buffer = 1; - - return b; -- } -+} -+ -+#ifndef YY_EXIT_FAILURE -+#define YY_EXIT_FAILURE 2 - #endif - -+static void yy_fatal_error (yyconst char* msg ) -+{ -+ (void) fprintf( stderr, "%s\n", msg ); -+ exit( YY_EXIT_FAILURE ); -+} - --#ifndef YY_NO_PUSH_STATE --#ifdef YY_USE_PROTOS --static void yy_push_state( int new_state ) --#else --static void yy_push_state( new_state ) --int new_state; --#endif -- { -- if ( yy_start_stack_ptr >= yy_start_stack_depth ) -- { -- yy_size_t new_size; -+/* Redefine yyless() so it works in section 3 code. */ - -- yy_start_stack_depth += YY_START_STACK_INCR; -- new_size = yy_start_stack_depth * sizeof( int ); -+#undef yyless -+#define yyless(n) \ -+ do \ -+ { \ -+ /* Undo effects of setting up yytext. */ \ -+ int yyless_macro_arg = (n); \ -+ YY_LESS_LINENO(yyless_macro_arg);\ -+ yytext[yyleng] = (yy_hold_char); \ -+ (yy_c_buf_p) = yytext + yyless_macro_arg; \ -+ (yy_hold_char) = *(yy_c_buf_p); \ -+ *(yy_c_buf_p) = '\0'; \ -+ yyleng = yyless_macro_arg; \ -+ } \ -+ while ( 0 ) - -- if ( ! yy_start_stack ) -- yy_start_stack = (int *) yy_flex_alloc( new_size ); -+/* Accessor methods (get/set functions) to struct members. */ - -- else -- yy_start_stack = (int *) yy_flex_realloc( -- (void *) yy_start_stack, new_size ); -+/** Get the current line number. -+ * -+ */ -+int yyget_lineno (void) -+{ -+ -+ return yylineno; -+} - -- if ( ! yy_start_stack ) -- YY_FATAL_ERROR( -- "out of memory expanding start-condition stack" ); -- } -+/** Get the input stream. -+ * -+ */ -+FILE *yyget_in (void) -+{ -+ return yyin; -+} - -- yy_start_stack[yy_start_stack_ptr++] = YY_START; -+/** Get the output stream. -+ * -+ */ -+FILE *yyget_out (void) -+{ -+ return yyout; -+} - -- BEGIN(new_state); -- } --#endif -+/** Get the length of the current token. -+ * -+ */ -+yy_size_t yyget_leng (void) -+{ -+ return yyleng; -+} - -+/** Get the current token. -+ * -+ */ - --#ifndef YY_NO_POP_STATE --static void yy_pop_state() -- { -- if ( --yy_start_stack_ptr < 0 ) -- YY_FATAL_ERROR( "start-condition stack underflow" ); -+char *yyget_text (void) -+{ -+ return yytext; -+} - -- BEGIN(yy_start_stack[yy_start_stack_ptr]); -- } --#endif -+/** Set the current line number. -+ * @param line_number -+ * -+ */ -+void yyset_lineno (int line_number ) -+{ -+ -+ yylineno = line_number; -+} - -+/** Set the input stream. This does not discard the current -+ * input buffer. -+ * @param in_str A readable stream. -+ * -+ * @see yy_switch_to_buffer -+ */ -+void yyset_in (FILE * in_str ) -+{ -+ yyin = in_str ; -+} - --#ifndef YY_NO_TOP_STATE --static int yy_top_state() -- { -- return yy_start_stack[yy_start_stack_ptr - 1]; -- } --#endif -+void yyset_out (FILE * out_str ) -+{ -+ yyout = out_str ; -+} - --#ifndef YY_EXIT_FAILURE --#define YY_EXIT_FAILURE 2 --#endif -+int yyget_debug (void) -+{ -+ return yy_flex_debug; -+} -+ -+void yyset_debug (int bdebug ) -+{ -+ yy_flex_debug = bdebug ; -+} - --#ifdef YY_USE_PROTOS --static void yy_fatal_error( yyconst char msg[] ) -+static int yy_init_globals (void) -+{ -+ /* Initialization is the same as for the non-reentrant scanner. -+ * This function is called from yylex_destroy(), so don't allocate here. -+ */ -+ -+ (yy_buffer_stack) = 0; -+ (yy_buffer_stack_top) = 0; -+ (yy_buffer_stack_max) = 0; -+ (yy_c_buf_p) = (char *) 0; -+ (yy_init) = 0; -+ (yy_start) = 0; -+ -+/* Defined in main.c */ -+#ifdef YY_STDINIT -+ yyin = stdin; -+ yyout = stdout; - #else --static void yy_fatal_error( msg ) --char msg[]; -+ yyin = (FILE *) 0; -+ yyout = (FILE *) 0; - #endif -- { -- (void) fprintf( stderr, "%s\n", msg ); -- exit( YY_EXIT_FAILURE ); -- } - -+ /* For future reference: Set errno on error, since we are called by -+ * yylex_init() -+ */ -+ return 0; -+} - -+/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -+int yylex_destroy (void) -+{ -+ -+ /* Pop the buffer stack, destroying each element. */ -+ while(YY_CURRENT_BUFFER){ -+ yy_delete_buffer(YY_CURRENT_BUFFER ); -+ YY_CURRENT_BUFFER_LVALUE = NULL; -+ yypop_buffer_state(); -+ } -+ -+ /* Destroy the stack itself. */ -+ yyfree((yy_buffer_stack) ); -+ (yy_buffer_stack) = NULL; -+ -+ /* Reset the globals. This is important in a non-reentrant scanner so the next time -+ * yylex() is called, initialization will occur. */ -+ yy_init_globals( ); - --/* Redefine yyless() so it works in section 3 code. */ -- --#undef yyless --#define yyless(n) \ -- do \ -- { \ -- /* Undo effects of setting up yytext. */ \ -- yytext[yyleng] = yy_hold_char; \ -- yy_c_buf_p = yytext + n; \ -- yy_hold_char = *yy_c_buf_p; \ -- *yy_c_buf_p = '\0'; \ -- yyleng = n; \ -- } \ -- while ( 0 ) -- -+ return 0; -+} - --/* Internal utility routines. */ -+/* -+ * Internal utility routines. -+ */ - - #ifndef yytext_ptr --#ifdef YY_USE_PROTOS --static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) --#else --static void yy_flex_strncpy( s1, s2, n ) --char *s1; --yyconst char *s2; --int n; --#endif -- { -+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -+{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -- } -+} - #endif - - #ifdef YY_NEED_STRLEN --#ifdef YY_USE_PROTOS --static int yy_flex_strlen( yyconst char *s ) --#else --static int yy_flex_strlen( s ) --yyconst char *s; --#endif -- { -+static int yy_flex_strlen (yyconst char * s ) -+{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -- } -+} - #endif - -- --#ifdef YY_USE_PROTOS --static void *yy_flex_alloc( yy_size_t size ) --#else --static void *yy_flex_alloc( size ) --yy_size_t size; --#endif -- { -+void *yyalloc (yy_size_t size ) -+{ - return (void *) malloc( size ); -- } -+} - --#ifdef YY_USE_PROTOS --static void *yy_flex_realloc( void *ptr, yy_size_t size ) --#else --static void *yy_flex_realloc( ptr, size ) --void *ptr; --yy_size_t size; --#endif -- { -+void *yyrealloc (void * ptr, yy_size_t size ) -+{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter -@@ -3337,26 +4136,17 @@ yy_size_t size; - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -- } -+} - --#ifdef YY_USE_PROTOS --static void yy_flex_free( void *ptr ) --#else --static void yy_flex_free( ptr ) --void *ptr; --#endif -- { -- free( ptr ); -- } -+void yyfree (void * ptr ) -+{ -+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -+} -+ -+#define YYTABLES_NAME "yytables" -+ -+#line 720 "toke.l" - --#if defined(YY_MAIN) && YY_MAIN --int main() -- { -- yylex(); -- return 0; -- } --#endif --#line 654 "toke.l" - - struct path_list { - char *path; -@@ -3598,7 +4388,7 @@ _push_include(char *path, bool isdir) - idepth++; - sudolineno = 1; - sudoers = path; -- yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); -+ yy_switch_to_buffer(yy_create_buffer(fp,YY_BUF_SIZE)); ++#ifndef HAVE_LIBGCRYPT + func->init(&ctx); ++#endif /* !HAVE_LIBGCRYPT */ + while ((nread = fread(buf, 1, sizeof(buf), fp)) != 0) { + #ifdef HAVE_FEXECVE + /* Check for #! cookie and set is_script. */ +@@ -679,21 +725,24 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd) + is_script = true; + } + #endif /* HAVE_FEXECVE */ ++#ifndef HAVE_LIBGCRYPT + func->update(&ctx, buf, nread); ++#endif /* !HAVE_LIBGCRYPT */ + } + if (ferror(fp)) { + sudo_warnx(U_("%s: read error"), file); + fclose(fp); +- debug_return_bool(false); ++ goto clean_up; + } ++#ifndef HAVE_LIBGCRYPT + func->final(file_digest, &ctx); +- +- if (memcmp(file_digest, sudoers_digest, func->digest_len) != 0) { ++#endif /* !HAVE_LIBGCRYPT */ ++ if (memcmp(file_digest, sudoers_digest, digest_size) != 0) { + fclose(fp); + sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO, + "%s digest mismatch for %s, expecting %s", +- func->digest_name, file, sd->digest_str); +- debug_return_bool(false); ++ digesttype2str(sd->digest_type), file, sd->digest_str); ++ goto clean_up; + } + #ifdef HAVE_FEXECVE +@@ -705,7 +754,7 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd) + sudo_debug_printf(SUDO_DEBUG_INFO, "unable to dup %s: %s", + file, strerror(errno)); + fclose(fp); +- debug_return_bool(false); ++ goto clean_up; + } + /* + * Shell scripts go through namei twice and so we can't set the close +@@ -715,10 +764,17 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd) + (void)fcntl(*fd, F_SETFD, FD_CLOEXEC); + #endif /* HAVE_FEXECVE */ + fclose(fp); ++ free(file_digest); ++ free(sudoers_digest); debug_return_bool(true); + bad_format: + sudo_warnx(U_("digest for %s (%s) is not in %s form"), file, +- sd->digest_str, func->digest_name); ++ sd->digest_str, digesttype2str(sd->digest_type)); ++clean_up: ++ if (file_digest) ++ free(file_digest); ++ if (sudoers_digest) ++ free(sudoers_digest); + debug_return_bool(false); } -@@ -3624,7 +4414,7 @@ pop_include(void) - efree(sudoers); - sudoers = pl->path; - sudolineno = 1; -- yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); -+ yy_switch_to_buffer(yy_create_buffer(fp,YY_BUF_SIZE)); - efree(pl); - break; - } -@@ -3740,3 +4530,4 @@ sudoers_trace_print(const char *msg) - return 0; - } - #endif /* TRACELEXER */ -+ -diff -up sudo-1.8.6p7/plugins/sudoers/toke.l.digest-backport sudo-1.8.6p7/plugins/sudoers/toke.l ---- sudo-1.8.6p7/plugins/sudoers/toke.l.digest-backport 2015-07-06 11:42:33.115904997 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/toke.l 2015-07-06 11:42:33.135904696 +0200 -@@ -72,6 +72,7 @@ - #include "toke.h" - #include - #include "lbuf.h" -+#include "filedigest.h" - #include "secure_path.h" - - extern YYSTYPE yylval; -@@ -89,6 +90,7 @@ gid_t sudoers_gid = SUDOERS_GID; - - static bool continued, sawspace; - static int prev_state; -+static int digest_len; - - static bool _push_include(char *, bool); - static bool pop_include(void); -@@ -128,6 +130,7 @@ DEFVAR [a-z_]+ - %x STARTDEFS - %x INDEFS - %x INSTR -+%s WANTDIGEST - - %% - [[:blank:]]*,[[:blank:]]* { -@@ -265,6 +268,40 @@ DEFVAR [a-z_]+ - } /* a command line arg */ - } - -+[[:xdigit:]]+ { -+ /* Only return DIGEST if the length is correct. */ -+ if (yyleng == digest_len * 2) { -+ if (!fill(yytext, yyleng)) -+ yyterminate(); -+ BEGIN INITIAL; -+ LEXTRACE("DIGEST "); -+ LEXRETURN(DIGEST); -+ } -+ BEGIN INITIAL; -+ yyless(yyleng); -+ } /* hex digest */ -+ -+[A-Za-z0-9\+/=]+ { -+ /* Only return DIGEST if the length is correct. */ -+ size_t len; -+ if (yytext[yyleng - 1] == '=') { -+ /* use padding */ -+ len = 4 * ((digest_len + 2) / 3); -+ } else { -+ /* no padding */ -+ len = (4 * digest_len + 2) / 3; -+ } -+ if (yyleng == len) { -+ if (!fill(yytext, yyleng)) -+ yyterminate(); -+ BEGIN INITIAL; -+ LEXTRACE("DIGEST "); -+ LEXRETURN(DIGEST); -+ } -+ BEGIN INITIAL; -+ yyless(yyleng); -+ } /* base64 digest */ -+ - ^#include[[:blank:]]+.*\n { - char *path; - -@@ -530,6 +567,7 @@ ALL { - } - - ({PATH}|sudoedit) { -+ /* XXX - no way to specify digest for command */ - /* no command args allowed for Defaults!/path */ - if (!fill_cmnd(yytext, yyleng)) - yyterminate(); -@@ -537,6 +575,34 @@ ALL { - LEXRETURN(COMMAND); - } -+sha224 { -+ digest_len = SUDO_SHA224_DIGEST_LENGTH; -+ BEGIN WANTDIGEST; -+ LEXTRACE("SHA224 "); -+ LEXRETURN(SHA224); -+ } -+ -+sha256 { -+ digest_len = SUDO_SHA256_DIGEST_LENGTH; -+ BEGIN WANTDIGEST; -+ LEXTRACE("SHA256 "); -+ LEXRETURN(SHA256); -+ } -+ -+sha384 { -+ digest_len = SUDO_SHA384_DIGEST_LENGTH; -+ BEGIN WANTDIGEST; -+ LEXTRACE("SHA384 "); -+ LEXRETURN(SHA384); -+ } -+ -+sha512 { -+ digest_len = SUDO_SHA512_DIGEST_LENGTH; -+ BEGIN WANTDIGEST; -+ LEXTRACE("SHA512 "); -+ LEXRETURN(SHA512); -+ } -+ - sudoedit { - BEGIN GOTCMND; - LEXTRACE("COMMAND "); -diff -up sudo-1.8.6p7/plugins/sudoers/toke_util.c.digest-backport sudo-1.8.6p7/plugins/sudoers/toke_util.c ---- sudo-1.8.6p7/plugins/sudoers/toke_util.c.digest-backport 2013-02-25 20:42:45.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/toke_util.c 2015-07-06 11:42:33.135904696 +0200 -@@ -57,51 +57,6 @@ - static int arg_len = 0; - static int arg_size = 0; - --static int --hexchar(const char *s) --{ -- int i, result = 0; -- debug_decl(hexchar, SUDO_DEBUG_PARSER) -- -- s += 2; /* skip \\x */ -- for (i = 0; i < 2; i++) { -- switch (*s) { -- case 'A': -- case 'a': -- result += 10; -- break; -- case 'B': -- case 'b': -- result += 11; -- break; -- case 'C': -- case 'c': -- result += 12; -- break; -- case 'D': -- case 'd': -- result += 13; -- break; -- case 'E': -- case 'e': -- result += 14; -- break; -- case 'F': -- case 'f': -- result += 15; -- break; -- default: -- result += *s - '0'; -- break; -- } -- if (i == 0) { -- result *= 16; -- s++; -- } -- } -- debug_return_int(result); --} -- - bool - fill_txt(const char *src, int len, int olen) - { -@@ -122,7 +77,7 @@ fill_txt(const char *src, int len, int o - if (src[1] == 'x' && len >= 3 && - isxdigit((unsigned char) src[2]) && - isxdigit((unsigned char) src[3])) { -- *dst++ = hexchar(src); -+ *dst++ = hexchar(src + 2); - src += 4; - len -= 3; - } else { +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.6p7-digest_race_doc.patch b/SOURCES/sudo-1.8.6p7-digest_race_doc.patch deleted file mode 100644 index 32544b3..0000000 --- a/SOURCES/sudo-1.8.6p7-digest_race_doc.patch +++ /dev/null @@ -1,88 +0,0 @@ -diff -up sudo-1.8.6p7/doc/sudoers.cat.digest_race_doc sudo-1.8.6p7/doc/sudoers.cat ---- sudo-1.8.6p7/doc/sudoers.cat.digest_race_doc 2016-05-11 13:53:51.125141217 +0200 -+++ sudo-1.8.6p7/doc/sudoers.cat 2016-05-11 13:56:10.678178899 +0200 -@@ -301,13 +301,11 @@ SSUUDDOOEERRSS FFIILLEE FFO - - If a command name is prefixed with a Digest_Spec, the command will only - match successfully if it can be verified using the specified SHA-2 -- digest. This may be useful in situations where the user invoking ssuuddoo -- has write access to the command or its parent directory. The following -- digest formats are supported: sha224, sha256, sha384 and sha512. The -- string may be specified in either hex or base64 format (base64 is more -- compact). There are several utilities capable of generating SHA-2 -- digests in hex format such as openssl, shasum, sha224sum, sha256sum, -- sha384sum, sha512sum. -+ digest. The following digest formats are supported: sha224, sha256, -+ sha384 and sha512. The string may be specified in either hex or base64 -+ format (base64 is more compact). There are several utilities capable of -+ generating SHA-2 digests in hex format such as openssl, shasum, -+ sha224sum, sha256sum, sha384sum, sha512sum. - - For example, using openssl: - -@@ -319,6 +317,11 @@ SSUUDDOOEERRSS FFIILLEE FFO - $ openssl dgst -binary -sha224 /bin/ls | openssl base64 - EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ== - -+ If the user has write access to either the command itself or the -+ directory in which the command is located (directly or via a ssuuddoo -+ command) it may be possible for the user to replace the command after the -+ digest check has been performed but before the command is executed. -+ - DDeeffaauullttss - Certain configuration options may be changed from their default values at - run-time via one or more Default_Entry lines. These may affect all users -diff -up sudo-1.8.6p7/doc/sudoers.man.in.digest_race_doc sudo-1.8.6p7/doc/sudoers.man.in ---- sudo-1.8.6p7/doc/sudoers.man.in.digest_race_doc 2016-05-11 13:54:01.005002291 +0200 -+++ sudo-1.8.6p7/doc/sudoers.man.in 2016-05-11 13:58:28.541240345 +0200 -@@ -679,9 +679,6 @@ is prefixed with a - \fRDigest_Spec\fR, - the command will only match successfully if it can be verified - using the specified SHA-2 digest. --This may be useful in situations where the user invoking --\fBsudo\fR --has write access to the command or its parent directory. - The following digest formats are supported: sha224, sha256, sha384 and sha512. - The string may be specified in either hex or base64 format - (base64 is more compact). -@@ -705,6 +702,13 @@ $ openssl dgst -binary -sha224 /bin/ls | - EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ== - .RE - .fi -+.PP -+If the user has write access to either the command itself or the -+directory in which the command is located (directly or via a -+\fBsudo\fR -+command) it may be possible for the user to replace the command -+after the digest check has been performed but before the command -+is executed. - .SS "Defaults" - Certain configuration options may be changed from their default - values at run-time via one or more -diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.digest_race_doc sudo-1.8.6p7/doc/sudoers.mdoc.in ---- sudo-1.8.6p7/doc/sudoers.mdoc.in.digest_race_doc 2016-05-11 13:54:07.749907447 +0200 -+++ sudo-1.8.6p7/doc/sudoers.mdoc.in 2016-05-11 13:59:22.263484933 +0200 -@@ -655,9 +655,6 @@ is prefixed with a - .Li Digest_Spec , - the command will only match successfully if it can be verified - using the specified SHA-2 digest. --This may be useful in situations where the user invoking --.Nm sudo --has write access to the command or its parent directory. - The following digest formats are supported: sha224, sha256, sha384 and sha512. - The string may be specified in either hex or base64 format - (base64 is more compact). -@@ -675,6 +672,13 @@ It is also possible to use openssl to ge - $ openssl dgst -binary -sha224 /bin/ls | openssl base64 - EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ== - .Ed -+.Pp -+If the user has write access to either the command itself or the -+directory in which the command is located (directly or via a -+.Nm sudo -+command) it may be possible for the user to replace the command -+after the digest check has been performed but before the command -+is executed. - .Ss Defaults - Certain configuration options may be changed from their default - values at run-time via one or more diff --git a/SOURCES/sudo-1.8.6p7-digestmessagesfix.patch b/SOURCES/sudo-1.8.6p7-digestmessagesfix.patch deleted file mode 100644 index 929d526..0000000 --- a/SOURCES/sudo-1.8.6p7-digestmessagesfix.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/match.c.digestmessagesfix sudo-1.8.6p7/plugins/sudoers/match.c ---- sudo-1.8.6p7/plugins/sudoers/match.c.digestmessagesfix 2015-09-01 15:33:27.493054381 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/match.c 2015-09-01 15:33:31.327054279 +0200 -@@ -566,6 +566,21 @@ base64_decode(const char *in, unsigned c - return io; - } - -+static const char *digesttype2str(int digest_type) -+{ -+ switch(digest_type) { -+ case SUDO_DIGEST_SHA224: -+ return "SHA224"; -+ case SUDO_DIGEST_SHA256: -+ return "SHA256"; -+ case SUDO_DIGEST_SHA384: -+ return "SHA384"; -+ case SUDO_DIGEST_SHA512: -+ return "SHA512"; -+ } -+ return ""; -+} -+ - static bool - digest_matches(char *file, struct sudo_digest *sd) - { -@@ -597,7 +612,7 @@ digest_matches(char *file, struct sudo_d - if (!isxdigit((unsigned char)sd->digest_str[i + i]) || - !isxdigit((unsigned char)sd->digest_str[i + i + 1])) { - warningx(_("digest for %s (%s) is not in %s form"), file, -- sd->digest_str, sd->digest_str); -+ sd->digest_str, digesttype2str(sd->digest_type)); - goto bad_format; - } - sudoers_digest[i] = hexchar(&sd->digest_str[i + i]); -@@ -619,7 +634,7 @@ digest_matches(char *file, struct sudo_d - debug_return_bool(match); - bad_format: - warningx(_("digest for %s (%s) is not in %s form"), file, -- sd->digest_str, sd->digest_str); -+ sd->digest_str, digesttype2str(sd->digest_type)); - if (sudoers_digest) - efree(sudoers_digest); - if (file_digest) diff --git a/SOURCES/sudo-1.8.6p7-duplicatenssfix.patch b/SOURCES/sudo-1.8.6p7-duplicatenssfix.patch deleted file mode 100644 index 547eb41..0000000 --- a/SOURCES/sudo-1.8.6p7-duplicatenssfix.patch +++ /dev/null @@ -1,47 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/sudo_nss.c.duplicatenssfix sudo-1.8.6p7/plugins/sudoers/sudo_nss.c ---- sudo-1.8.6p7/plugins/sudoers/sudo_nss.c.duplicatenssfix 2014-09-29 15:30:35.243303099 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sudo_nss.c 2014-09-29 15:33:13.669439300 +0200 -@@ -88,16 +88,16 @@ sudo_read_nss(void) - for ((cp = strtok(cp + 8, " \t")); cp != NULL; (cp = strtok(NULL, " \t"))) { - if (strcasecmp(cp, "files") == 0 && !saw_files) { - tq_append(&snl, &sudo_nss_file); -- got_match = true; -+ got_match = saw_files = true; - #ifdef HAVE_LDAP - } else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) { - tq_append(&snl, &sudo_nss_ldap); -- got_match = true; -+ got_match = saw_ldap = true; - #endif - #ifdef HAVE_SSSD - } else if (strcasecmp(cp, "sss") == 0 && !saw_sss) { - tq_append(&snl, &sudo_nss_sss); -- got_match = true; -+ got_match = saw_sss = true; - #endif - } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) { - /* NOTFOUND affects the most recent entry */ -@@ -171,20 +171,20 @@ sudo_read_nss(void) - if (!saw_files && strncasecmp(cp, "files", 5) == 0 && - (isspace((unsigned char)cp[5]) || cp[5] == '\0')) { - tq_append(&snl, &sudo_nss_file); -- got_match = true; -+ got_match = saw_files = true; - ep = &cp[5]; - #ifdef HAVE_LDAP - } else if (!saw_ldap && strncasecmp(cp, "ldap", 4) == 0 && - (isspace((unsigned char)cp[4]) || cp[4] == '\0')) { - tq_append(&snl, &sudo_nss_ldap); -- got_match = true; -+ got_match = saw_ldap = true; - ep = &cp[4]; - #endif - #ifdef HAVE_SSSD - } else if (!saw_sss && strncasecmp(cp, "sss", 3) == 0 && - (isspace((unsigned char)cp[3]) || cp[3] == '\0')) { - tq_append(&snl, &sudo_nss_sss); -- got_match = true; -+ got_match = saw_sss = true; - ep = &cp[3]; - #endif - } else { diff --git a/SOURCES/sudo-1.8.6p7-ipahostname.patch b/SOURCES/sudo-1.8.6p7-ipahostname.patch deleted file mode 100644 index c17b78b..0000000 --- a/SOURCES/sudo-1.8.6p7-ipahostname.patch +++ /dev/null @@ -1,192 +0,0 @@ -diff -up sudo-1.8.6p7/configure.in.ipahostname sudo-1.8.6p7/configure.in ---- sudo-1.8.6p7/configure.in.ipahostname 2014-09-29 11:14:38.393846226 +0200 -+++ sudo-1.8.6p7/configure.in 2014-09-29 11:14:38.428845807 +0200 -@@ -309,7 +309,7 @@ dnl Handle SSSD support. - dnl - AC_ARG_WITH(sssd, [AS_HELP_STRING([--with-sssd], [enable SSSD support])], - [case $with_sssd in -- yes) SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo" -+ yes) SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo ipa_hostname.lo" - AC_DEFINE(HAVE_SSSD) - ;; - no) ;; -diff -up sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c.ipahostname sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c ---- sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c.ipahostname 2014-09-29 11:14:38.429845795 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c 2014-09-29 11:14:38.429845795 +0200 -@@ -0,0 +1,88 @@ -+/* -+ * Copyright 2013 Red Hat Inc., Durham, North Carolina. -+ * All Rights Reserved. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Authors: -+ * Daniel Kopecek -+ */ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+ -+static const char *sssd_conf_path = "/etc/sssd/sssd.conf"; -+ -+char *ipa_hostname(void) -+{ -+ static char hname[MAXHOSTNAMELEN+1]; -+ size_t hname_len = 0; -+ char *line = NULL; -+ ssize_t line_len = 0; -+ size_t line_buflen = 0; -+ FILE *fp; -+ -+ if ((fp = fopen(sssd_conf_path, "r")) == NULL) -+ return NULL; -+ while ((line_len = getline(&line, &line_buflen, fp)) > 0) { -+ char *keyword_loc; -+ if ((keyword_loc = strstr(line, "ipa_hostname")) != NULL) { -+ size_t i; -+ char *value_loc; -+ size_t value_len; -+ -+ value_loc = keyword_loc + strlen("ipa_hostname") + 1; -+ value_len = line_len - (size_t)(value_loc - line); -+ -+ /* Skip spaces and the assignment operator */ -+ for (i = 0; i < value_len; ++i) { -+ if (isspace(value_loc[i]) || value_loc[i] == '=') { -+ continue; -+ } else { -+ break; -+ } -+ } -+ -+ value_loc += i; -+ value_len -= i; -+ -+ if (value_len <= MAXHOSTNAMELEN) { -+ memcpy(hname, value_loc, value_len * sizeof(char)); -+ free(line); -+ fclose(fp); -+ hname_len = value_len; -+ hname[hname_len] = '\0'; -+ /* Remove spaces from the end of the string */ -+ for (i = hname_len - 1; i > 0; --i) { -+ if (isspace(hname[i])) { -+ hname[i] = '\0'; -+ --hname_len; -+ } else { -+ break; -+ } -+ } -+ return hname; -+ } -+ } -+ free(line); -+ line = NULL; -+ } -+ -+ fclose(fp); -+ return NULL; -+} -diff -up sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h.ipahostname sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h ---- sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h.ipahostname 2014-09-29 11:14:38.429845795 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h 2014-09-29 11:14:38.429845795 +0200 -@@ -0,0 +1,27 @@ -+/* -+ * Copyright 2013 Red Hat Inc., Durham, North Carolina. -+ * All Rights Reserved. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Authors: -+ * Daniel Kopecek -+ */ -+#ifndef _IPA_HOSTNAME_H_ -+#define _IPA_HOSTNAME_H_ -+ -+char *ipa_hostname(void); -+ -+#endif /* _IPA_HOSTNAME_H_ */ -diff -up sudo-1.8.6p7/plugins/sudoers/Makefile.in.ipahostname sudo-1.8.6p7/plugins/sudoers/Makefile.in ---- sudo-1.8.6p7/plugins/sudoers/Makefile.in.ipahostname 2014-09-29 11:14:38.429845795 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/Makefile.in 2014-09-29 11:16:54.923210160 +0200 -@@ -728,6 +728,9 @@ sia.lo: $(authdir)/sia.c $(top_builddir) - $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \ - $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h - $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(authdir)/sia.c -+ipa_hostname.lo: $(srcdir)/ipa_hostname.c $(srcdir)/ipa_hostname.h -+ $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/ipa_hostname.c -+ - sssd.lo: $(srcdir)/sssd.c $(top_builddir)/config.h \ - $(top_srcdir)/compat/dlfcn.h $(srcdir)/sudoers.h \ - $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \ -diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.ipahostname sudo-1.8.6p7/plugins/sudoers/sssd.c ---- sudo-1.8.6p7/plugins/sudoers/sssd.c.ipahostname 2014-09-29 11:14:38.424845855 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2014-09-29 11:14:38.429845795 +0200 -@@ -60,6 +60,7 @@ - #include "parse.h" - #include "lbuf.h" - #include "sudo_debug.h" -+#include "ipa_hostname.h" - - /* SSSD <--> SUDO interface - do not change */ - struct sss_sudo_attr { -@@ -549,6 +550,24 @@ sudo_sss_check_runas(struct sudo_sss_han - debug_return_bool(ret); - } - -+static bool sudo_sss_ipa_hostname_matches(const char *hostname_val) -+{ -+ bool ret = false; -+ char *ipa_hostname_val; -+ debug_decl(sudo_sss_ipa_hostname_matches, SUDO_DEBUG_SSSD) -+ -+ if ((ipa_hostname_val = ipa_hostname()) != NULL) { -+ ret = hostname_matches(ipa_hostname_val, ipa_hostname_val, hostname_val) || \ -+ netgr_matches(hostname_val, ipa_hostname_val, ipa_hostname_val, NULL); -+ } -+ -+ sudo_debug_printf(SUDO_DEBUG_TRACE, "IPA hostname (%s) matches %s => %s", -+ ipa_hostname_val ? ipa_hostname_val : "", hostname_val, -+ ret ? "true" : "false"); -+ -+ debug_return_bool(ret); -+} -+ - static bool - sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) - { -@@ -580,6 +599,7 @@ sudo_sss_check_host(struct sudo_sss_hand - - /* match any or address or netgroup or hostname */ - if (!strcmp(val, "ALL") || addr_matches(val) || -+ sudo_sss_ipa_hostname_matches(val) || - netgr_matches(val, user_host, user_shost, NULL) || - hostname_matches(user_shost, user_host, val)) - ret = true; diff --git a/SOURCES/sudo-1.8.6p7-ldap_sssd_parse_whitespaces.patch b/SOURCES/sudo-1.8.6p7-ldap_sssd_parse_whitespaces.patch deleted file mode 100644 index 5f0a575..0000000 --- a/SOURCES/sudo-1.8.6p7-ldap_sssd_parse_whitespaces.patch +++ /dev/null @@ -1,91 +0,0 @@ -diff -up sudo-1.8.6p7/common/fmt_string.c.ldap_sssd_parse_whitespaces sudo-1.8.6p7/common/fmt_string.c ---- sudo-1.8.6p7/common/fmt_string.c.ldap_sssd_parse_whitespaces 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/common/fmt_string.c 2016-05-11 10:31:30.206090322 +0200 -@@ -38,6 +38,8 @@ - # include - #endif /* HAVE_STRINGS_H */ - -+#include -+ - #include "missing.h" - #include "sudo_debug.h" - -@@ -64,3 +66,17 @@ fmt_string(const char *var, const char * - - debug_return_str(str); - } -+ -+char * rm_whitespaces(char * str){ -+ int state = 1; -+ char * c; -+ for (c = str ; *c != '\0' ; c++){ -+ if (state && isspace(*c))str++; -+ else if (!isspace(*c))state = 0; -+ else if (!state && isspace(*c)){ -+ *c = '\0'; -+ break; -+ } -+ } -+ return str; -+} -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.ldap_sssd_parse_whitespaces sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.ldap_sssd_parse_whitespaces 2016-05-11 10:31:30.202090379 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2016-05-11 10:31:30.207090307 +0200 -@@ -1012,17 +1012,17 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMe - if (op == '+' || op == '-') { - *(val - 2) = '\0'; /* found, remove extra char */ - /* case var+=val or var-=val */ -- set_default(var, strunquote(val), (int) op); -+ set_default(rm_whitespaces(var), strunquote(val), (int) op); - } else { - /* case var=val */ -- set_default(var, strunquote(val), true); -+ set_default(rm_whitespaces(var), strunquote(val), true); - } - } else if (*var == '!') { - /* case !var Boolean False */ -- set_default(var + 1, NULL, false); -+ set_default(rm_whitespaces(var + 1), NULL, false); - } else { - /* case var Boolean True */ -- set_default(var, NULL, true); -+ set_default(rm_whitespaces(var), NULL, true); - } - efree(var); - } -diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.ldap_sssd_parse_whitespaces sudo-1.8.6p7/plugins/sudoers/sssd.c ---- sudo-1.8.6p7/plugins/sudoers/sssd.c.ldap_sssd_parse_whitespaces 2016-05-11 10:31:30.202090379 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2016-05-11 10:31:30.207090307 +0200 -@@ -1004,17 +1004,17 @@ sudo_sss_parse_options(struct sudo_sss_h - if (op == '+' || op == '-') { - *(val - 2) = '\0'; /* found, remove extra char */ - /* case var+=val or var-=val */ -- set_default(v, strunquote(val), (int) op); -+ set_default(rm_whitespaces(v), strunquote(val), (int) op); - } else { - /* case var=val */ -- set_default(v, strunquote(val), true); -+ set_default(rm_whitespaces(v), strunquote(val), true); - } - } else if (*v == '!') { - /* case !var Boolean False */ -- set_default(v + 1, NULL, false); -+ set_default(rm_whitespaces(v + 1), NULL, false); - } else { - /* case var Boolean True */ -- set_default(v, NULL, true); -+ set_default(rm_whitespaces(v), NULL, true); - } - efree(v); - } -diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.ldap_sssd_parse_whitespaces sudo-1.8.6p7/plugins/sudoers/sudoers.h ---- sudo-1.8.6p7/plugins/sudoers/sudoers.h.ldap_sssd_parse_whitespaces 2016-05-11 10:31:30.204090350 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sudoers.h 2016-05-11 10:31:30.207090307 +0200 -@@ -346,6 +346,7 @@ int sudoers_hook_unsetenv(const char *na - - /* fmt_string.c */ - char *fmt_string(const char *, const char *); -+char *rm_whitespaces(char * str); - - /* sudoers.c */ - void plugin_cleanup(int); diff --git a/SOURCES/sudo-1.8.6p7-ldapsearchuidfix.patch b/SOURCES/sudo-1.8.6p7-ldapsearchuidfix.patch index 5d5e933..d3991f0 100644 --- a/SOURCES/sudo-1.8.6p7-ldapsearchuidfix.patch +++ b/SOURCES/sudo-1.8.6p7-ldapsearchuidfix.patch @@ -1,7 +1,81 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.ldapsearchuidfix sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.ldapsearchuidfix 2015-07-07 15:02:41.504731613 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2015-07-07 15:07:57.991777302 +0200 -@@ -1211,8 +1211,8 @@ sudo_ldap_build_pass1(struct passwd *pw) +From b1f3fcf8d6e9a8e5326771a12fac8e08ed81f766 Mon Sep 17 00:00:00 2001 +From: Tomas Sykora +Date: Fri, 19 Aug 2016 10:21:27 +0200 +Subject: [PATCH] Sudo with ldap doesn't work with 'user id' + +in sudoUser option. + +Rebased from: +Patch39: sudo-1.8.6p7-ldapsearchuidfix.patch + +Resolves: +rhbz#1135539 +--- + plugins/sudoers/def_data.c | 4 ++++ + plugins/sudoers/def_data.h | 2 ++ + plugins/sudoers/def_data.in | 3 +++ + plugins/sudoers/defaults.c | 2 ++ + plugins/sudoers/ldap.c | 10 ++++++++-- + plugins/sudoers/sudoers.c | 4 ++++ + 6 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c +index d8b1ada..3926fed 100644 +--- a/plugins/sudoers/def_data.c ++++ b/plugins/sudoers/def_data.c +@@ -439,6 +439,10 @@ struct sudo_defs_types sudo_defs_table[] = { + N_("Don't fork and wait for the command to finish, just exec it"), + NULL, + }, { ++ "legacy_group_processing", T_FLAG, ++ N_("Don't pre-resolve all group names"), ++ NULL, ++ }, { + NULL, 0, NULL + } + }; +diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h +index 1b6be3d..5246e41 100644 +--- a/plugins/sudoers/def_data.h ++++ b/plugins/sudoers/def_data.h +@@ -206,6 +206,8 @@ + #define def_iolog_mode (sudo_defs_table[I_IOLOG_MODE].sd_un.mode) + #define I_CMND_NO_WAIT 103 + #define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag) ++#define I_LEGACY_GROUP_PROCESSING 104 ++#define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag) + + enum def_tuple { + never, +diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in +index 5200fe3..f1c9265 100644 +--- a/plugins/sudoers/def_data.in ++++ b/plugins/sudoers/def_data.in +@@ -325,3 +325,6 @@ iolog_mode + cmnd_no_wait + T_FLAG + "Don't fork and wait for the command to finish, just exec it" ++legacy_group_processing ++ T_FLAG ++ "Don't pre-resolve all group names" +diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c +index 5eaf8ea..9e60d94 100644 +--- a/plugins/sudoers/defaults.c ++++ b/plugins/sudoers/defaults.c +@@ -450,6 +450,8 @@ init_defaults(void) + } + + /* First initialize the flags. */ ++ def_legacy_group_processing = true; ++ def_match_group_by_gid = true; + #ifdef LONG_OTP_PROMPT + def_long_otp_prompt = true; + #endif +diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c +index 3fe27c7..96a0709 100644 +--- a/plugins/sudoers/ldap.c ++++ b/plugins/sudoers/ldap.c +@@ -1666,8 +1666,8 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw) if (ldap_conf.search_filter) sz += strlen(ldap_conf.search_filter); @@ -12,9 +86,9 @@ diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.ldapsearchuidfix sudo-1.8.6p7/plugi /* Add space for primary and supplementary groups and gids */ if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) { -@@ -1253,6 +1253,12 @@ sudo_ldap_build_pass1(struct passwd *pw) - (void) sudo_ldap_value_cat(buf, pw->pw_name, sz); - (void) strlcat(buf, ")", sz); +@@ -1730,6 +1730,12 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw) + CHECK_LDAP_VCAT(buf, pw->pw_name, sz); + CHECK_STRLCAT(buf, ")", sz); + /* Append user uid */ + (void) snprintf(gidbuf, sizeof(gidbuf), "%u", (unsigned int)pw->pw_uid); @@ -24,4 +98,22 @@ diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.ldapsearchuidfix sudo-1.8.6p7/plugi + /* Append primary group and gid */ if (grp != NULL) { - (void) strlcat(buf, "(sudoUser=%", sz); + CHECK_STRLCAT(buf, "(sudoUser=%", sz); +diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c +index 539177a..673ee5d 100644 +--- a/plugins/sudoers/sudoers.c ++++ b/plugins/sudoers/sudoers.c +@@ -208,6 +208,10 @@ sudoers_policy_init(void *info, char * const envp[]) + if (set_loginclass(runas_pw ? runas_pw : sudo_user.pw)) + ret = true; + ++ if (!def_match_group_by_gid || !def_legacy_group_processing) { ++ def_match_group_by_gid = false; ++ def_legacy_group_processing = false; ++ } + cleanup: + if (!restore_perms()) + ret = -1; +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.6p7-ldapusermatchfix.patch b/SOURCES/sudo-1.8.6p7-ldapusermatchfix.patch deleted file mode 100644 index c922924..0000000 --- a/SOURCES/sudo-1.8.6p7-ldapusermatchfix.patch +++ /dev/null @@ -1,47 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.ldapusermatchfix sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.ldapusermatchfix 2016-05-09 15:33:10.933510674 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2016-05-09 15:33:10.937510618 +0200 -@@ -2735,22 +2735,37 @@ sudo_ldap_result_get(struct sudo_nss *ns - result = NULL; - rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt, - NULL, 0, NULL, NULL, tvp, 0, &result); -- if (rc != LDAP_SUCCESS) { -+ if (rc != LDAP_SUCCESS || result == NULL) { - DPRINTF(("nothing found for '%s'", filt), 1); - continue; - } -- lres->user_matches = true; -+ -+ DPRINTF(("search result has %d entries (do_netgr=%s)", -+ ldap_count_entries(ld, result), do_netgr ? "true" : "false"), 1); -+ /* -+ * Only set user_matches if we got some results back and if we are -+ * NOT searching for netgroup entries. For the netgroup case, user_maches -+ * will be set only if a netgroup match was found. -+ */ -+ lres->user_matches = lres->user_matches ? true : ldap_count_entries(ld, result) > 0 && !do_netgr; - - /* Add the seach result to list of search results. */ - DPRINTF(("adding search result"), 1); - sudo_ldap_result_add_search(lres, ld, result); - LDAP_FOREACH(entry, ld, result) { -- if ((!do_netgr || -- sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) && -+ if (do_netgr) { -+ if (sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name) && - sudo_ldap_check_host(ld, entry)) { -- lres->host_matches = true; -- sudo_ldap_result_add_entry(lres, entry); -+ lres->host_matches = true; -+ lres->user_matches = true; -+ sudo_ldap_result_add_entry(lres, entry); -+ } -+ } else { -+ if (sudo_ldap_check_host(ld, entry)) { -+ lres->host_matches = true; -+ sudo_ldap_result_add_entry(lres, entry); - } -+ } - } - DPRINTF(("result now has %d entries", lres->nentries), 1); - } diff --git a/SOURCES/sudo-1.8.6p7-legacy-group-processing.patch b/SOURCES/sudo-1.8.6p7-legacy-group-processing.patch deleted file mode 100644 index 3e018fb..0000000 --- a/SOURCES/sudo-1.8.6p7-legacy-group-processing.patch +++ /dev/null @@ -1,224 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/defaults.c.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/defaults.c ---- sudo-1.8.6p7/plugins/sudoers/defaults.c.legacy-group-processing 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/defaults.c 2015-08-28 10:52:13.658671686 +0200 -@@ -362,6 +362,7 @@ init_defaults(void) - } - - /* First initialize the flags. */ -+ def_legacy_group_processing = true; - #ifdef LONG_OTP_PROMPT - def_long_otp_prompt = true; - #endif -diff -up sudo-1.8.6p7/plugins/sudoers/def_data.c.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/def_data.c ---- sudo-1.8.6p7/plugins/sudoers/def_data.c.legacy-group-processing 2015-08-28 10:52:13.604671687 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/def_data.c 2015-08-28 10:52:13.658671686 +0200 -@@ -355,6 +355,10 @@ struct sudo_defs_types sudo_defs_table[] - N_("Don't fork and wait for the command to finish, just exec it"), - NULL, - }, { -+ "legacy_group_processing", T_FLAG, -+ N_("Don't pre-resolve all group names"), -+ NULL, -+ }, { - NULL, 0, NULL - } - }; -diff -up sudo-1.8.6p7/plugins/sudoers/def_data.h.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/def_data.h ---- sudo-1.8.6p7/plugins/sudoers/def_data.h.legacy-group-processing 2015-08-28 10:52:13.604671687 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/def_data.h 2015-08-28 10:52:13.658671686 +0200 -@@ -164,6 +164,8 @@ - #define I_LIMITPRIVS 81 - #define def_cmnd_no_wait (sudo_defs_table[82].sd_un.flag) - #define I_CMND_NO_WAIT 82 -+#define def_legacy_group_processing (sudo_defs_table[83].sd_un.flag) -+#define I_LEGACY_GROUP_PROCESSING 83 - - enum def_tuple { - never, -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.legacy-group-processing 2015-08-28 10:52:13.656671686 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2015-08-28 10:52:13.659671686 +0200 -@@ -1220,6 +1220,15 @@ sudo_ldap_build_pass1(struct passwd *pw) - } - sz += 13 + MAX_UID_T_LEN; - if ((grlist = sudo_get_grlist(pw)) != NULL) { -+ if (!grlist->groups_resolved) { -+ int rc = sudo_resolve_gids(grlist->gids, grlist->ngids, -+ grlist->groups, grlist->groups_buffer); -+ if (rc < 0) { -+ return NULL; -+ } -+ grlist->ngroups = rc; -+ grlist->groups_resolved = true; -+ } - for (i = 0; i < grlist->ngroups; i++) { - if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0) - continue; -diff -up sudo-1.8.6p7/plugins/sudoers/pwutil.c.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/pwutil.c ---- sudo-1.8.6p7/plugins/sudoers/pwutil.c.legacy-group-processing 2015-08-28 10:52:13.633671686 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/pwutil.c 2015-08-28 10:52:13.659671686 +0200 -@@ -542,10 +542,9 @@ static struct cache_item * - make_grlist_item(const char *user, GETGROUPS_T *gids, int ngids) - { - char *cp; -- size_t i, nsize, ngroups, total, len; -+ size_t i, nsize, total; - struct cache_item_grlist *grlitem; - struct group_list *grlist; -- struct group *grp; - debug_decl(make_grlist_item, SUDO_DEBUG_NSS) - - #ifdef HAVE_SETAUTHDB -@@ -559,7 +558,6 @@ make_grlist_item(const char *user, GETGR - total += sizeof(gid_t *) * ngids; - total += GROUPNAME_LEN * ngids; - --again: - grlitem = ecalloc(1, total); - - /* -@@ -587,27 +585,26 @@ again: - for (i = 0; i < ngids; i++) - grlist->gids[i] = gids[i]; - grlist->ngids = ngids; -+ grlist->groups_buffer = cp; - - /* -- * Resolve and store group names by ID. -+ * Resolve and store group names by ID if legacy_group_processing is off. - */ -- ngroups = 0; -- for (i = 0; i < ngids; i++) { -- if ((grp = sudo_getgrgid(gids[i])) != NULL) { -- len = strlen(grp->gr_name) + 1; -- if (cp - (char *)grlitem + len > total) { -- total += len + GROUPNAME_LEN; -- efree(grlitem); -- sudo_gr_delref(grp); -- goto again; -- } -- memcpy(cp, grp->gr_name, len); -- grlist->groups[ngroups++] = cp; -- cp += len; -- sudo_gr_delref(grp); -- } -+ if (def_legacy_group_processing) { -+ for (i = 0; i < ngids; i++) { -+ grlist->groups[i] = NULL; -+ } -+ grlist->ngroups = 0; -+ grlist->groups_resolved = false; -+ } else { -+ int rc = sudo_resolve_gids(gids, ngids, grlist->groups, grlist->groups_buffer); -+ if (rc < 0) { -+ efree(grlitem); -+ return NULL; -+ } -+ grlist->ngroups = rc; -+ grlist->groups_resolved = true; - } -- grlist->ngroups = ngroups; - - #ifdef HAVE_SETAUTHDB - aix_restoreauthdb(); -@@ -616,6 +613,35 @@ again: - debug_return_ptr(&grlitem->cache); - } - -+int sudo_resolve_gids(GETGROUPS_T *gids, int ngids, char **groups, char *group_buffer) -+{ -+ struct group *grp; -+ int space_left = ngids * GROUPNAME_LEN; -+ int ngroups = 0; -+ int i; -+ char *cp = group_buffer; -+ debug_decl(sudo_resolve_gids, SUDO_DEBUG_NSS) -+ -+ for (i = 0; i < ngids; i++) { -+ if ((grp = sudo_getgrgid(gids[i])) != NULL) { -+ int len = strlen(grp->gr_name) + 1; -+ -+ if (space_left < len) { -+ sudo_gr_delref(grp); -+ debug_return_int(-1); -+ } -+ -+ memcpy(cp, grp->gr_name, len); -+ groups[ngroups++] = cp; -+ cp += len; -+ space_left -= len; -+ sudo_gr_delref(grp); -+ } -+ } -+ -+ debug_return_int(ngroups); -+} -+ - void - sudo_gr_addref(struct group *gr) - { -@@ -917,8 +943,22 @@ user_in_group(const struct passwd *pw, c - /* - * If it could be a sudo-style group ID check gids first. - */ -+ bool do_gid_lookup = false; -+ gid_t gid; -+ - if (group[0] == '#') { -- gid_t gid = atoi(group + 1); -+ gid = atoi(group + 1); -+ do_gid_lookup = true; -+ } else if (def_legacy_group_processing) { -+ struct group *grent = sudo_getgrnam(group); -+ if (grent == NULL) { -+ goto done; -+ } -+ gid = grent->gr_gid; -+ do_gid_lookup = true; -+ } -+ -+ if (do_gid_lookup) { - if (gid == pw->pw_gid) { - matched = true; - goto done; -@@ -931,6 +971,19 @@ user_in_group(const struct passwd *pw, c - } - } - -+ if (def_legacy_group_processing) { -+ goto done; -+ } -+ if (!grlist->groups_resolved) { -+ int rc = sudo_resolve_gids(grlist->gids, grlist->ngids, -+ grlist->groups, grlist->groups_buffer); -+ if (rc < 0) { -+ goto done; -+ } -+ grlist->ngroups = rc; -+ grlist->groups_resolved = true; -+ } -+ - /* - * Next check the supplementary group vector. - * It usually includes the password db group too. -diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/sudoers.h ---- sudo-1.8.6p7/plugins/sudoers/sudoers.h.legacy-group-processing 2015-08-28 10:52:13.634671686 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sudoers.h 2015-08-28 10:52:13.659671686 +0200 -@@ -52,6 +52,8 @@ struct group_list { - GETGROUPS_T *gids; - int ngroups; - int ngids; -+ int groups_resolved; -+ char *groups_buffer; - }; - - /* -@@ -289,6 +291,8 @@ __dso_public struct group *sudo_getgrnam - __dso_public void sudo_gr_addref(struct group *); - __dso_public void sudo_gr_delref(struct group *); - bool user_in_group(const struct passwd *, const char *); -+int sudo_resolve_gids(GETGROUPS_T *gids, int ngids, char **groups, char *group_buffer); -+ - struct group *sudo_fakegrnam(const char *); - struct group_list *sudo_get_grlist(const struct passwd *pw); - struct passwd *sudo_fakepwnam(const char *, gid_t); diff --git a/SOURCES/sudo-1.8.6p7-logsudouser.patch b/SOURCES/sudo-1.8.6p7-logsudouser.patch index 59e577f..c3742a0 100644 --- a/SOURCES/sudo-1.8.6p7-logsudouser.patch +++ b/SOURCES/sudo-1.8.6p7-logsudouser.patch @@ -1,16 +1,34 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/logging.c.logsudouser sudo-1.8.6p7/plugins/sudoers/logging.c ---- sudo-1.8.6p7/plugins/sudoers/logging.c.logsudouser 2013-02-25 20:46:09.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/logging.c 2016-05-09 16:24:10.831703862 +0200 -@@ -146,7 +146,7 @@ do_syslog(int pri, char *msg) +From 06b46ae226fecd4188af372ac0ccd7aa582e21c8 Mon Sep 17 00:00:00 2001 +From: Tomas Sykora +Date: Wed, 17 Aug 2016 10:12:11 +0200 +Subject: [PATCH] Sudo logs username root instead of realuser + +RHEL7 sudo logs username root instead of realuser in /var/log/secure + +Rebased from: +Patch50: sudo-1.8.6p7-logsudouser.patch + +Resolves: +rhbz#1312486 +--- + plugins/sudoers/logging.c | 14 +++++++------- + plugins/sudoers/sudoers.h | 1 + + 2 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c +index 45cae67..74b2220 100644 +--- a/plugins/sudoers/logging.c ++++ b/plugins/sudoers/logging.c +@@ -104,7 +104,7 @@ do_syslog(int pri, char *msg) * Log the full line, breaking into multiple syslog(3) calls if necessary */ - fmt = _(FMT_FIRST); -- maxlen = MAXSYSLOGLEN - (strlen(fmt) - 5 + strlen(user_name)); -+ maxlen = MAXSYSLOGLEN - (strlen(fmt) - 5 + strlen(sudo_user_name)); + fmt = _("%8s : %s"); +- maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name)); ++ maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(sudo_user_name)); for (p = msg; *p != '\0'; ) { len = strlen(p); if (len > maxlen) { -@@ -162,7 +162,7 @@ do_syslog(int pri, char *msg) +@@ -120,7 +120,7 @@ do_syslog(int pri, char *msg) save = *tmp; *tmp = '\0'; @@ -19,55 +37,47 @@ diff -up sudo-1.8.6p7/plugins/sudoers/logging.c.logsudouser sudo-1.8.6p7/plugins *tmp = save; /* restore saved character */ -@@ -170,11 +170,11 @@ do_syslog(int pri, char *msg) +@@ -128,11 +128,11 @@ do_syslog(int pri, char *msg) for (p = tmp; *p == ' '; p++) - ; + continue; } else { - mysyslog(pri, fmt, user_name, p); + mysyslog(pri, fmt, sudo_user_name, p); p += len; } - fmt = _(FMT_CONTD); -- maxlen = MAXSYSLOGLEN - (strlen(fmt) - 5 + strlen(user_name)); -+ maxlen = MAXSYSLOGLEN - (strlen(fmt) - 5 + strlen(sudo_user_name)); + fmt = _("%8s : (command continued) %s"); +- maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name)); ++ maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(sudo_user_name)); } - #ifdef HAVE_SETLOCALE -@@ -216,17 +216,17 @@ do_logfile(char *msg) - /* Don't pretty-print long log file lines (hard to grep) */ - if (def_log_host) - (void) fprintf(fp, "%s : %s : HOST=%s : %s\n", -- get_timestr(now, def_log_year), user_name, user_shost, msg); -+ get_timestr(now, def_log_year), sudo_user_name, user_shost, msg); - else - (void) fprintf(fp, "%s : %s : %s\n", -- get_timestr(now, def_log_year), user_name, msg); -+ get_timestr(now, def_log_year), sudo_user_name, msg); - } else { - if (def_log_host) - len = easprintf(&full_line, "%s : %s : HOST=%s : %s", -- get_timestr(now, def_log_year), user_name, user_shost, msg); -+ get_timestr(now, def_log_year), sudo_user_name, user_shost, msg); - else - len = easprintf(&full_line, "%s : %s : %s", -- get_timestr(now, def_log_year), user_name, msg); -+ get_timestr(now, def_log_year), sudo_user_name, msg); - - /* - * Print out full_line with word wrap around def_loglinelen chars. -@@ -689,7 +689,7 @@ send_mail(const char *fmt, ...) - #endif /* HAVE_NL_LANGINFO */ + sudoers_setlocale(oldlocale, NULL); +@@ -179,10 +179,10 @@ do_logfile(const char *msg) + timestr = "invalid date"; + if (def_log_host) { + len = asprintf(&full_line, "%s : %s : HOST=%s : %s", +- timestr, user_name, user_srunhost, msg); ++ timestr, sudo_user_name, user_srunhost, msg); + } else { + len = asprintf(&full_line, "%s : %s : %s", +- timestr, user_name, msg); ++ timestr, sudo_user_name, msg); + } + if (len == -1) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); +@@ -746,7 +746,7 @@ send_mail(const char *fmt, ...) - (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, -- get_timestr(time(NULL), def_log_year), user_name); -+ get_timestr(time(NULL), def_log_year), sudo_user_name); + if ((timestr = get_timestr(time(NULL), def_log_year)) == NULL) + timestr = "invalid date"; +- (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, timestr, user_name); ++ (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, timestr, sudo_user_name); va_start(ap, fmt); (void) vfprintf(mail, fmt, ap); va_end(ap); -diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.logsudouser sudo-1.8.6p7/plugins/sudoers/sudoers.h ---- sudo-1.8.6p7/plugins/sudoers/sudoers.h.logsudouser 2016-05-09 16:24:10.815704088 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sudoers.h 2016-05-09 16:24:10.831703862 +0200 -@@ -171,6 +171,7 @@ struct sudo_user { +diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h +index cfd5abb..c69a043 100644 +--- a/plugins/sudoers/sudoers.h ++++ b/plugins/sudoers/sudoers.h +@@ -180,6 +180,7 @@ struct sudo_user { /* * Shortcuts for sudo_user contents. */ @@ -75,3 +85,6 @@ diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.logsudouser sudo-1.8.6p7/plugins #define user_name (sudo_user.name) #define user_uid (sudo_user.uid) #define user_gid (sudo_user.gid) +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.6p7-manfix-usepty.patch b/SOURCES/sudo-1.8.6p7-manfix-usepty.patch deleted file mode 100644 index 0da67ec..0000000 --- a/SOURCES/sudo-1.8.6p7-manfix-usepty.patch +++ /dev/null @@ -1,107 +0,0 @@ -diff -up sudo-1.8.6p7/doc/fixmdoc.sh.manfix-usepty sudo-1.8.6p7/doc/fixmdoc.sh ---- sudo-1.8.6p7/doc/fixmdoc.sh.manfix-usepty 2015-07-07 09:06:37.893592317 +0200 -+++ sudo-1.8.6p7/doc/fixmdoc.sh 2015-07-07 09:07:40.575602754 +0200 -@@ -1,4 +1,19 @@ - #!/bin/sh -+# -+# Copyright (c) 2012-2014 Todd C. Miller -+# -+# 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. -+# - - OUTFILE="$1" - rm -f "$OUTFILE" -@@ -18,11 +33,9 @@ case "$OUTFILE" in - # BSD auth - BA_FLAG= - if [ X"$BAMAN" != X"1" ]; then -- BA_FLAG='/^.*\n\.Op Fl a Ar auth_type/{;N;/^.*\n\.Ek$/d;};' -+ BA_FLAG='/^.*\n\.Op Fl a Ar type/{;N;/^.*\n\.Ek$/d;};' - cat >>"$OUTFILE" <<-'EOF' -- /^\.It Fl a Ar type/,/BSD authentication\.$/ { -- d -- } -+ /^\.It Fl a Ar type/,/BSD authentication\.$/d - EOF - fi - -@@ -31,9 +44,7 @@ case "$OUTFILE" in - if [ X"$LCMAN" != X"1" ]; then - LC_FLAG='/^.*\n\.Op Fl c Ar class/{;N;/^.*\n\.Ek$/d;};' - cat >>"$OUTFILE" <<-'EOF' -- /^\.It Fl c Ar class/,/BSD login classes\.$/ { -- d -- } -+ /^\.It Fl c Ar class/,/BSD login classes\.$/d - /^\.Xr login_cap 3 ,$/d - /^BSD login class$/ { - N -@@ -47,12 +58,8 @@ case "$OUTFILE" in - if [ X"$SEMAN" != X"1" ]; then - SE_FLAG='/^.*\n\.Op Fl r Ar role/{;N;/^.*\n\.Ek$/d;};/^.*\n\.Op Fl t Ar type/{;N;/^.*\n\.Ek$/d;};' - cat >>"$OUTFILE" <<-'EOF' -- /^\.It Fl r Ar role/,/newline character\.$/ { -- d -- } -- /^\.It Fl t Ar type/,/specified role\.$/ { -- d -- } -+ /^\.It Fl r Ar role/,/^\.Ar role \.$/d -+ /^\.It Fl t Ar type/,/derived from the role\.$/d - /^SELinux role and type$/ { - N - /^SELinux role and type\n\.It$/d -@@ -103,12 +110,8 @@ case "$OUTFILE" in - # BSD login class - if [ X"$LCMAN" != X"1" ]; then - cat >>"$OUTFILE" <<-'EOF' -- /^On BSD systems/,/\.$/ { -- d -- } -- /^\.It use_loginclass$/,/^\.It/ { -- /^\.It [^u][^s][^e][^_][^l]/!d -- } -+ /^On BSD systems/,/\.$/d -+ /^\.It use_loginclass$/,/^by default\./d - EOF - fi - -@@ -120,15 +123,8 @@ case "$OUTFILE" in - N - d - } -- /^\.It limitprivs$/,/^\.It/ { -- /^\.It [^l][^i][^m][^i][^t]/!d -- } -- /^\.It privs$/,/^\.It/ { -- /^\.It [^p][^r][^i][^v][^s]$/!d -- } -- /^On Solaris 10/,/^\.Pp/ { -- d -- } -+ /^\.It \(limit\)*privs$/,/is built on Solaris 10 or higher\.$/d -+ /^On Solaris 10/,/^\.Pp/d - EOF - fi - -@@ -140,9 +136,7 @@ case "$OUTFILE" in - N - d - } -- /^\.It [rt][oy][lp]e$/,/^\.It/ { -- /^\.It [^rt][^oy][^lp][^e]$/!d -- } -+ /^\.It [rt][oy][lp]e$/,/is built with SELinux support\.$/d - EOF - fi - ;; diff --git a/SOURCES/sudo-1.8.6p7-netgroup_tuple.patch b/SOURCES/sudo-1.8.6p7-netgroup_tuple.patch deleted file mode 100644 index 42f3ac2..0000000 --- a/SOURCES/sudo-1.8.6p7-netgroup_tuple.patch +++ /dev/null @@ -1,194 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/defaults.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/defaults.c ---- sudo-1.8.6p7/plugins/sudoers/defaults.c.netgroup_tuple 2016-05-09 15:34:41.059246583 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/defaults.c 2016-05-09 15:34:41.066246485 +0200 -@@ -362,6 +362,7 @@ init_defaults(void) - } - - /* First initialize the flags. */ -+ def_netgroup_tuple = false; - def_legacy_group_processing = true; - #ifdef LONG_OTP_PROMPT - def_long_otp_prompt = true; -diff -up sudo-1.8.6p7/plugins/sudoers/def_data.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/def_data.c ---- sudo-1.8.6p7/plugins/sudoers/def_data.c.netgroup_tuple 2016-05-09 15:34:41.059246583 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/def_data.c 2016-05-09 15:34:41.066246485 +0200 -@@ -359,6 +359,10 @@ struct sudo_defs_types sudo_defs_table[] - N_("Don't pre-resolve all group names"), - NULL, - }, { -+ "netgroup_tuple", T_FLAG, -+ N_("Use both user and host/domain fields when matching netgroups"), -+ NULL, -+ }, { - NULL, 0, NULL - } - }; -diff -up sudo-1.8.6p7/plugins/sudoers/def_data.h.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/def_data.h ---- sudo-1.8.6p7/plugins/sudoers/def_data.h.netgroup_tuple 2016-05-09 15:34:41.059246583 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/def_data.h 2016-05-09 15:34:41.066246485 +0200 -@@ -166,6 +166,8 @@ - #define I_CMND_NO_WAIT 82 - #define def_legacy_group_processing (sudo_defs_table[83].sd_un.flag) - #define I_LEGACY_GROUP_PROCESSING 83 -+#define def_netgroup_tuple (sudo_defs_table[84].sd_un.flag) -+#define I_NETGROUP_TUPLE 84 - - enum def_tuple { - never, -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.netgroup_tuple 2016-05-09 15:34:41.065246499 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2016-05-09 15:34:41.066246485 +0200 -@@ -636,8 +636,12 @@ sudo_ldap_check_user_netgroup(LDAP *ld, - for (p = bv; *p != NULL && !ret; p++) { - val = (*p)->bv_val; - /* match any */ -- if (netgr_matches(val, NULL, NULL, user)) -- ret = true; -+ if (netgr_matches(val, -+ def_netgroup_tuple ? user_host : NULL, -+ def_netgroup_tuple ? user_shost : NULL, -+ user)) { -+ ret = true; -+ } - DPRINTF(("ldap sudoUser netgroup '%s' ... %s", val, - ret ? "MATCH!" : "not"), 2 + ((ret) ? 0 : 1)); - } -@@ -652,7 +656,7 @@ sudo_ldap_check_user_netgroup(LDAP *ld, - * host match, else false. - */ - static bool --sudo_ldap_check_host(LDAP *ld, LDAPMessage *entry) -+sudo_ldap_check_host(LDAP *ld, LDAPMessage *entry, char *user) - { - struct berval **bv, **p; - char *val; -@@ -672,7 +676,7 @@ sudo_ldap_check_host(LDAP *ld, LDAPMessa - val = (*p)->bv_val; - /* match any or address or netgroup or hostname */ - if (!strcmp(val, "ALL") || addr_matches(val) || -- netgr_matches(val, user_host, user_shost, NULL) || -+ netgr_matches(val, user_host, user_shost, def_netgroup_tuple ? user : NULL) || - hostname_matches(user_shost, user_host, val)) - ret = true; - DPRINTF(("ldap sudoHost '%s' ... %s", val, -@@ -729,7 +733,10 @@ sudo_ldap_check_runas_user(LDAP *ld, LDA - val = (*p)->bv_val; - switch (val[0]) { - case '+': -- if (netgr_matches(val, NULL, NULL, runas_pw->pw_name)) -+ if (netgr_matches(val, -+ def_netgroup_tuple ? user_host : NULL, -+ def_netgroup_tuple ? user_shost : NULL, -+ runas_pw->pw_name)) - ret = true; - break; - case '%': -@@ -2755,13 +2762,13 @@ sudo_ldap_result_get(struct sudo_nss *ns - LDAP_FOREACH(entry, ld, result) { - if (do_netgr) { - if (sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name) && -- sudo_ldap_check_host(ld, entry)) { -+ sudo_ldap_check_host(ld, entry, pw->pw_name)) { - lres->host_matches = true; - lres->user_matches = true; - sudo_ldap_result_add_entry(lres, entry); - } - } else { -- if (sudo_ldap_check_host(ld, entry)) { -+ if (sudo_ldap_check_host(ld, entry, pw->pw_name)) { - lres->host_matches = true; - sudo_ldap_result_add_entry(lres, entry); - } -diff -up sudo-1.8.6p7/plugins/sudoers/match.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/match.c ---- sudo-1.8.6p7/plugins/sudoers/match.c.netgroup_tuple 2016-05-09 15:34:41.062246541 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/match.c 2016-05-09 15:34:41.067246471 +0200 -@@ -117,7 +117,10 @@ userlist_matches(struct passwd *pw, stru - matched = !m->negated; - break; - case NETGROUP: -- if (netgr_matches(m->name, NULL, NULL, pw->pw_name)) -+ if (netgr_matches(m->name, -+ def_netgroup_tuple ? user_host : NULL, -+ def_netgroup_tuple ? user_shost : NULL, -+ pw->pw_name)) - matched = !m->negated; - break; - case USERGROUP: -@@ -172,7 +175,10 @@ runaslist_matches(struct member_list *us - user_matched = !m->negated; - break; - case NETGROUP: -- if (netgr_matches(m->name, NULL, NULL, runas_pw->pw_name)) -+ if (netgr_matches(m->name, -+ def_netgroup_tuple ? user_host : NULL, -+ def_netgroup_tuple ? user_shost : NULL, -+ runas_pw->pw_name)) - user_matched = !m->negated; - break; - case USERGROUP: -@@ -269,7 +275,7 @@ hostlist_matches(struct member_list *lis - matched = !m->negated; - break; - case NETGROUP: -- if (netgr_matches(m->name, user_host, user_shost, NULL)) -+ if (netgr_matches(m->name, user_host, user_shost, def_netgroup_tuple ? user_name : NULL)) - matched = !m->negated; - break; - case NTWKADDR: -diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/sssd.c ---- sudo-1.8.6p7/plugins/sudoers/sssd.c.netgroup_tuple 2016-05-09 15:34:41.056246625 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2016-05-09 15:34:41.067246471 +0200 -@@ -452,7 +452,10 @@ sudo_sss_check_runas_user(struct sudo_ss - switch (val[0]) { - case '+': - sudo_debug_printf(SUDO_DEBUG_DEBUG, "netgr_"); -- if (netgr_matches(val, NULL, NULL, runas_pw->pw_name)) { -+ if (netgr_matches(val, -+ def_netgroup_tuple ? user_host : NULL, -+ def_netgroup_tuple ? user_shost : NULL, -+ runas_pw->pw_name)) { - sudo_debug_printf(SUDO_DEBUG_DEBUG, "=> match"); - ret = true; - } -@@ -551,7 +554,7 @@ sudo_sss_check_runas(struct sudo_sss_han - debug_return_bool(ret); - } - --static bool sudo_sss_ipa_hostname_matches(const char *hostname_val) -+static bool sudo_sss_ipa_hostname_matches(const char *hostname_val, char *user) - { - bool ret = false; - char *ipa_hostname_val; -@@ -559,7 +562,7 @@ static bool sudo_sss_ipa_hostname_matche - - if ((ipa_hostname_val = ipa_hostname()) != NULL) { - ret = hostname_matches(ipa_hostname_val, ipa_hostname_val, hostname_val) || \ -- netgr_matches(hostname_val, ipa_hostname_val, ipa_hostname_val, NULL); -+ netgr_matches(hostname_val, ipa_hostname_val, ipa_hostname_val, def_netgroup_tuple ? user : NULL); - } - - sudo_debug_printf(SUDO_DEBUG_TRACE, "IPA hostname (%s) matches %s => %s", -@@ -600,8 +603,9 @@ sudo_sss_check_host(struct sudo_sss_hand - - /* match any or address or netgroup or hostname */ - if (!strcmp(val, "ALL") || addr_matches(val) || -- sudo_sss_ipa_hostname_matches(val) || -- netgr_matches(val, user_host, user_shost, NULL) || -+ sudo_sss_ipa_hostname_matches(val, handle->pw->pw_name) || -+ netgr_matches(val, user_host, user_shost, -+ def_netgroup_tuple ? handle->pw->pw_name : NULL) || - hostname_matches(user_shost, user_host, val)) - ret = true; - -@@ -649,7 +653,10 @@ bool sudo_sss_filter_sudoUser(struct sud - sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val); - if (*val == '+') { - /* Netgroup spec found, check netgroup membership */ -- if (netgr_matches(val, NULL, NULL, handle->pw->pw_name)) { -+ if (netgr_matches(val, -+ def_netgroup_tuple ? user_host : NULL, -+ def_netgroup_tuple ? user_shost : NULL, -+ handle->pw->pw_name)) { - ret = true; - sudo_debug_printf(SUDO_DEBUG_DIAG, - "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, handle->pw->pw_name); diff --git a/SOURCES/sudo-1.8.6p7-newbase64decoder.patch b/SOURCES/sudo-1.8.6p7-newbase64decoder.patch deleted file mode 100644 index d224f3c..0000000 --- a/SOURCES/sudo-1.8.6p7-newbase64decoder.patch +++ /dev/null @@ -1,104 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/match.c.newbase64decoder sudo-1.8.6p7/plugins/sudoers/match.c ---- sudo-1.8.6p7/plugins/sudoers/match.c.newbase64decoder 2015-09-01 13:35:42.746241825 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/match.c 2015-09-01 13:40:52.360233611 +0200 -@@ -510,53 +510,60 @@ command_matches_glob(char *sudoers_cmnd, - } - - /* -+ * base64 decoder -+ * PUBLIC DOMAIN - Jon Mayo - November 13, 2003 -+ */ -+static const uint8_t base64dec_tab[256]= { -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, -+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, -+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, -+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, -+}; -+ -+/* - * Decode a NUL-terminated string in base64 format and store the - * result in dst. - */ - size_t --base64_decode(const char *str, unsigned char *dst, size_t dsize) -+base64_decode(const char *in, unsigned char *out, size_t out_len) - { -- static const char b64[] = -- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -- const unsigned char *dst0 = dst; -- const unsigned char *dend = dst + dsize; -- unsigned char ch[4]; -- char *pos; -- int i; -- debug_decl(base64_decode, SUDO_DEBUG_MATCH) -+ size_t in_len = strlen(in); -+ size_t ii, io; -+ uint_least32_t v; -+ size_t rem; - -- /* -- * Convert from base64 to binary. Each base64 char holds 6 bits of data -- * so 4 base64 chars equals 3 chars of data. -- * Padding (with the '=' char) may or may not be present. -- */ -- while (*str != '\0') { -- for (i = 0; i < 4; i++) { -- switch (*str) { -- case '=': -- str++; -- /* FALLTHROUGH */ -- case '\0': -- ch[i] = '='; -- break; -- default: -- if ((pos = strchr(b64, *str++)) == NULL) -- debug_return_size_t((size_t)-1); -- ch[i] = (unsigned char)(pos - b64); -- break; -- } -- } -- if (ch[0] == '=' || ch[1] == '=' || dst == dend) -- break; -- *dst++ = (ch[0] << 2) | ((ch[1] & 0x30) >> 4); -- if (ch[2] == '=' || dst == dend) -- break; -- *dst++ = ((ch[1] & 0x0f) << 4) | ((ch[2] & 0x3c) >> 2); -- if (ch[3] == '=' || dst == dend) -- break; -- *dst++ = ((ch[2] & 0x03) << 6) | ch[3]; -+ for(io=0,ii=0,v=0,rem=0;ii=8) { -+ rem-=8; -+ if(io>=out_len) return -1; /* truncation is failure */ -+ out[io++]=(v>>rem)&255; - } -- debug_return_size_t((size_t)(dst - dst0)); -+ } -+ if(rem>=8) { -+ rem-=8; -+ if(io>=out_len) return -1; /* truncation is failure */ -+ out[io++]=(v>>rem)&255; -+ } -+ return io; - } - - static bool diff --git a/SOURCES/sudo-1.8.6p7-noexec-update.patch b/SOURCES/sudo-1.8.6p7-noexec-update.patch deleted file mode 100644 index 4005794..0000000 --- a/SOURCES/sudo-1.8.6p7-noexec-update.patch +++ /dev/null @@ -1,422 +0,0 @@ -diff --git a/config.h.in b/config.h.in -index 106af3a..30c3928 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -87,6 +87,10 @@ - don't. */ - #undef HAVE_DECL_H_ERRNO - -+/* Define to 1 if you have the declaration of `SECCOMP_SET_MODE_FILTER', and -+ to 0 if you don't. */ -+#undef HAVE_DECL_SECCOMP_SET_MODE_FILTER -+ - /* Define to 1 if you have the declaration of `sys_sigabbrev', and to 0 if you - don't. */ - #undef HAVE_DECL_SYS_SIGABBREV -@@ -134,9 +138,21 @@ - /* Define to 1 if the compiler supports the __visibility__ attribute. */ - #undef HAVE_DSO_VISIBILITY - -+/* Define to 1 if you have the `exect' function. */ -+#undef HAVE_EXECT -+ -+/* Define to 1 if you have the `execvp' function. */ -+#undef HAVE_EXECVP -+ -+/* Define to 1 if you have the `execvpe' function. */ -+#undef HAVE_EXECVPE -+ - /* Define to 1 if your system has the F_CLOSEM fcntl. */ - #undef HAVE_FCNTL_CLOSEM - -+/* Define to 1 if you have the `fexecve' function. */ -+#undef HAVE_FEXECVE -+ - /* Define to 1 if you have the `fgetln' function. */ - #undef HAVE_FGETLN - -@@ -421,6 +437,12 @@ - /* Define to 1 if you have the `posix_openpt' function. */ - #undef HAVE_POSIX_OPENPT - -+/* Define to 1 if you have the `posix_spawn' function. */ -+#undef HAVE_POSIX_SPAWN -+ -+/* Define to 1 if you have the `posix_spawnp' function. */ -+#undef HAVE_POSIX_SPAWNP -+ - /* Define to 1 if you have the `priv_set' function. */ - #undef HAVE_PRIV_SET - -@@ -703,6 +725,12 @@ - /* Define to 1 if you have the `vsnprintf' function. */ - #undef HAVE_VSNPRINTF - -+/* Define to 1 if you have the `wordexp' function. */ -+#undef HAVE_WORDEXP -+ -+/* Define to 1 if you have the header file. */ -+#undef HAVE_WORDEXP_H -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_ZLIB_H - -diff --git a/configure.in b/configure.in -index 06b4722..945284e 100644 ---- a/configure.in -+++ b/configure.in -@@ -1824,6 +1824,14 @@ case "$host" in - shadow_funcs="getspnam" - shadow_libs_optional="-lshadow" - test -z "$with_pam" && AUTH_EXCL_DEF="PAM" -+ # Check for SECCOMP_SET_MODE_FILTER in linux/seccomp.h -+ AC_CHECK_DECLS([SECCOMP_SET_MODE_FILTER], [], [], [ -+#include -+#include -+#include -+#include -+#include -+ ]) - ;; - *-convex-bsd*) - OSDEFS="${OSDEFS} -D_CONVEX_SOURCE" -@@ -2091,7 +2099,7 @@ AC_HEADER_DIRENT - AC_HEADER_TIME - AC_HEADER_STDBOOL - AC_HEADER_MAJOR --AC_CHECK_HEADERS(malloc.h netgroup.h paths.h spawn.h utime.h utmpx.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h) -+AC_CHECK_HEADERS(malloc.h netgroup.h paths.h spawn.h utime.h utmpx.h wordexp.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h) - AC_CHECK_HEADERS([procfs.h] [sys/procfs.h], [AC_CHECK_MEMBERS(struct psinfo.pr_ttydev, [AC_CHECK_FUNCS(_ttyname_dev)], [], [AC_INCLUDES_DEFAULT - #ifdef HAVE_PROCFS_H - #include -@@ -2226,7 +2234,8 @@ dnl - AC_FUNC_GETGROUPS - AC_CHECK_FUNCS(glob strrchr sysconf tzset strftime setenv \ - regcomp setlocale nl_langinfo mbr_check_membership \ -- setrlimit64) -+ setrlimit64 \ -+ wordexp exect execvp execvpe fexecve posix_spawn posix_spawnp) - AC_REPLACE_FUNCS(getgrouplist) - AC_CHECK_FUNCS(getline, [], [ - AC_LIBOBJ(getline) -diff --git a/include/missing.h b/include/missing.h -index fda151b..cac8088 100644 ---- a/include/missing.h -+++ b/include/missing.h -@@ -198,6 +198,13 @@ typedef struct sigaction sigaction_t; - #endif - - /* -+ * The nitems macro may be defined in sys/param.h -+ */ -+#ifndef nitems -+# define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) -+#endif -+ -+/* - * If dirfd() does not exists, hopefully dd_fd does. - */ - #if !defined(HAVE_DIRFD) && defined(HAVE_DD_FD) -diff --git a/src/Makefile.in b/src/Makefile.in -index 918cf04..079aa3e 100644 ---- a/src/Makefile.in -+++ b/src/Makefile.in -@@ -109,7 +109,7 @@ sudo: $(OBJS) $(LT_LIBS) - $(LIBTOOL) --mode=link $(CC) -o $@ $(OBJS) $(LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) - - libsudo_noexec.la: sudo_noexec.lo -- $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir) -+ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) @LIBDL@ -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir) - - sesh: sesh.o error.o exec_common.o @LIBINTL@ $(LT_LIBS) - $(LIBTOOL) --mode=link $(CC) -o $@ sesh.o error.o exec_common.o $(LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) @LIBINTL@ $(LIBS) -diff --git a/src/sudo_noexec.c b/src/sudo_noexec.c -index 2872501..f04b277 100644 ---- a/src/sudo_noexec.c -+++ b/src/sudo_noexec.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2004-2005, 2010-2011 Todd C. Miller -+ * Copyright (c) 2004-2005, 2010-2016 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above -@@ -18,20 +18,64 @@ - - #include - -+#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER -+# include -+# include -+# include -+# include -+#endif -+ - #include - #include -+#include -+#include -+#include - #ifdef HAVE_SPAWN_H - #include - #endif -+#ifdef HAVE_STRING_H -+# include -+#endif /* HAVE_STRING_H */ -+#ifdef HAVE_STRINGS_H -+# include -+#endif /* HAVE_STRINGS_H */ -+#ifdef HAVE_WORDEXP_H -+#include -+#endif -+#if defined(HAVE_SHL_LOAD) -+# include -+#elif defined(HAVE_DLOPEN) -+# include -+#endif - - #include "missing.h" -+#include "pathnames.h" - -+#ifdef HAVE___INTERPOSE - /* -- * Dummy versions of the execve() family of syscalls. We don't need -- * to stub out all of them, just the ones that correspond to actual -- * system calls (which varies by OS). Note that it is still possible -- * to access the real syscalls via the syscall() interface but very -- * few programs actually do that. -+ * Mac OS X 10.4 and above has support for library symbol interposition. -+ * There is a good explanation of this in the Mac OS X Internals book. -+ */ -+typedef struct interpose_s { -+ void *new_func; -+ void *orig_func; -+} interpose_t; -+ -+# define FN_NAME(fn) dummy_ ## fn -+# define INTERPOSE(fn) \ -+ __attribute__((__used__)) static const interpose_t interpose_ ## fn \ -+ __attribute__((__section__("__DATA,__interpose"))) = \ -+ { (void *)dummy_ ## fn, (void *)fn }; -+#else -+# define FN_NAME(fn) fn -+# define INTERPOSE(fn) -+#endif -+ -+/* -+ * Dummy versions of the exec(3) family of syscalls. It is not enough to -+ * just dummy out execve(2) since many C libraries do not call the public -+ * execve(2) interface. Note that it is still possible to access the real -+ * syscalls via the syscall(2) interface, but that is rarely done. - */ - - #define DUMMY_BODY \ -@@ -40,61 +84,172 @@ - return -1; \ - } - -+#define DUMMY1(fn, t1) \ -+__dso_public int \ -+FN_NAME(fn)(t1 a1) \ -+DUMMY_BODY \ -+INTERPOSE(fn) -+ - #define DUMMY2(fn, t1, t2) \ - __dso_public int \ --fn(t1 a1, t2 a2) \ --DUMMY_BODY -+FN_NAME(fn)(t1 a1, t2 a2) \ -+DUMMY_BODY \ -+INTERPOSE(fn) - - #define DUMMY3(fn, t1, t2, t3) \ - __dso_public int \ --fn(t1 a1, t2 a2, t3 a3) \ --DUMMY_BODY -+FN_NAME(fn)(t1 a1, t2 a2, t3 a3) \ -+DUMMY_BODY \ -+INTERPOSE(fn) - - #define DUMMY6(fn, t1, t2, t3, t4, t5, t6) \ - __dso_public int \ --fn(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ --DUMMY_BODY -+FN_NAME(fn)(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ -+DUMMY_BODY \ -+INTERPOSE(fn) - - #define DUMMY_VA(fn, t1, t2) \ - __dso_public int \ --fn(t1 a1, t2 a2, ...) \ --DUMMY_BODY -+FN_NAME(fn)(t1 a1, t2 a2, ...) \ -+DUMMY_BODY \ -+INTERPOSE(fn) - -+/* -+ * Standard exec(3) family of functions. -+ */ - DUMMY_VA(execl, const char *, const char *) --DUMMY_VA(_execl, const char *, const char *) --DUMMY_VA(__execl, const char *, const char *) - DUMMY_VA(execle, const char *, const char *) --DUMMY_VA(_execle, const char *, const char *) --DUMMY_VA(__execle, const char *, const char *) - DUMMY_VA(execlp, const char *, const char *) --DUMMY_VA(_execlp, const char *, const char *) --DUMMY_VA(__execlp, const char *, const char *) --DUMMY3(exect, const char *, char * const *, char * const *) --DUMMY3(_exect, const char *, char * const *, char * const *) --DUMMY3(__exect, const char *, char * const *, char * const *) - DUMMY2(execv, const char *, char * const *) --DUMMY2(_execv, const char *, char * const *) --DUMMY2(__execv, const char *, char * const *) - DUMMY2(execvp, const char *, char * const *) --DUMMY2(_execvp, const char *, char * const *) --DUMMY2(__execvp, const char *, char * const *) --DUMMY3(execvP, const char *, const char *, char * const *) --DUMMY3(_execvP, const char *, const char *, char * const *) --DUMMY3(__execvP, const char *, const char *, char * const *) - DUMMY3(execve, const char *, char * const *, char * const *) --DUMMY3(_execve, const char *, char * const *, char * const *) --DUMMY3(__execve, const char *, char * const *, char * const *) -+ -+/* -+ * Non-standard exec(3) functions and corresponding private versions. -+ */ -+#ifdef HAVE_EXECVP -+DUMMY3(execvP, const char *, const char *, char * const *) -+#endif -+#ifdef HAVE_EXECVPE - DUMMY3(execvpe, const char *, char * const *, char * const *) --DUMMY3(_execvpe, const char *, char * const *, char * const *) --DUMMY3(__execvpe, const char *, char * const *, char * const *) -+#endif -+#ifdef HAVE_EXECT -+DUMMY3(exect, const char *, char * const *, char * const *) -+#endif -+ -+/* -+ * Not all systems support fexecve(2), posix_spawn(2) and posix_spawnp(2). -+ */ -+#ifdef HAVE_FEXECVE - DUMMY3(fexecve, int , char * const *, char * const *) --DUMMY3(_fexecve, int , char * const *, char * const *) --DUMMY3(__fexecve, int , char * const *, char * const *) --#ifdef HAVE_SPAWN_H -+#endif -+#ifdef HAVE_POSIX_SPAWN - DUMMY6(posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) --DUMMY6(_posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) --DUMMY6(__posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) -+#endif -+#ifdef HAVE_POSIX_SPAWNP - DUMMY6(posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) --DUMMY6(_posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) --DUMMY6(__posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) --#endif /* HAVE_SPAWN_H */ -+#endif -+ -+/* -+ * system(3) and popen(3). -+ * We can't use a wrapper for popen since it returns FILE *, not int. -+ */ -+DUMMY1(system, const char *) -+ -+__dso_public FILE * -+FN_NAME(popen)(const char *c, const char *t) -+{ -+ errno = EACCES; -+ return NULL; -+} -+INTERPOSE(popen) -+ -+#if defined(HAVE_WORDEXP) && (defined(RTLD_NEXT) || defined(HAVE_SHL_LOAD) || defined(HAVE___INTERPOSE)) -+/* -+ * We can't use a wrapper for wordexp(3) since we still want to call -+ * the real wordexp(3) but with WRDE_NOCMD added to the flags argument. -+ */ -+typedef int (*sudo_fn_wordexp_t)(const char *, wordexp_t *, int); -+ -+__dso_public int -+FN_NAME(wordexp)(const char *words, wordexp_t *we, int flags) -+{ -+#if defined(HAVE___INTERPOSE) -+ return wordexp(words, we, flags | WRDE_NOCMD); -+#else -+# if defined(HAVE_DLOPEN) -+ void *fn = dlsym(RTLD_NEXT, "wordexp"); -+# elif defined(HAVE_SHL_LOAD) -+ const char *name, *myname = _PATH_SUDO_NOEXEC; -+ struct shl_descriptor *desc; -+ void *fn = NULL; -+ int idx = 0; -+ -+ name = strrchr(myname, '/'); -+ if (name != NULL) -+ myname = name + 1; -+ -+ /* Search for wordexp() but skip this shared object. */ -+ while (shl_get(idx++, &desc) == 0) { -+ name = strrchr(desc->filename, '/'); -+ if (name == NULL) -+ name = desc->filename; -+ else -+ name++; -+ if (strcmp(name, myname) == 0) -+ continue; -+ if (shl_findsym(&desc->handle, "wordexp", TYPE_PROCEDURE, &fn) == 0) -+ break; -+ } -+# else -+ void *fn = NULL; -+# endif -+ if (fn == NULL) { -+ errno = EACCES; -+ return -1; -+ } -+ return ((sudo_fn_wordexp_t)fn)(words, we, flags | WRDE_NOCMD); -+#endif /* HAVE___INTERPOSE */ -+} -+INTERPOSE(wordexp) -+#endif /* HAVE_WORDEXP && (RTLD_NEXT || HAVE_SHL_LOAD || HAVE___INTERPOSE) */ -+ -+/* -+ * On Linux we can use a seccomp() filter to disable exec. -+ */ -+#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER -+ -+/* Older systems may not support execveat(2). */ -+#ifndef __NR_execveat -+# define __NR_execveat -1 -+#endif -+ -+static void noexec_ctor(void) __attribute__((constructor)); -+ -+static void -+noexec_ctor(void) -+{ -+ struct sock_filter exec_filter[] = { -+ /* Load syscall number into the accumulator */ -+ BPF_STMT(BPF_LD | BPF_ABS, offsetof(struct seccomp_data, nr)), -+ /* Jump to deny for execve/execveat */ -+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 2, 0), -+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 1, 0), -+ /* Allow non-matching syscalls */ -+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), -+ /* Deny execve/execveat syscall */ -+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (EACCES & SECCOMP_RET_DATA)) -+ }; -+ const struct sock_fprog exec_fprog = { -+ nitems(exec_filter), -+ exec_filter -+ }; -+ -+ /* -+ * SECCOMP_MODE_FILTER will fail unless the process has -+ * CAP_SYS_ADMIN or the no_new_privs bit is set. -+ */ -+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == 0) -+ (void)prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &exec_fprog); -+} -+#endif /* HAVE_DECL_SECCOMP_SET_MODE_FILTER */ diff --git a/SOURCES/sudo-1.8.6p7-nproc-nowait.patch b/SOURCES/sudo-1.8.6p7-nproc-nowait.patch deleted file mode 100644 index 0d75031..0000000 --- a/SOURCES/sudo-1.8.6p7-nproc-nowait.patch +++ /dev/null @@ -1,48 +0,0 @@ -diff -up sudo-1.8.6p7/src/exec.c.nproc-nowait sudo-1.8.6p7/src/exec.c ---- sudo-1.8.6p7/src/exec.c.nproc-nowait 2016-05-11 12:56:58.694022525 +0200 -+++ sudo-1.8.6p7/src/exec.c 2016-05-11 12:56:58.759021618 +0200 -@@ -298,6 +298,7 @@ sudo_execute(struct command_details *det - */ - if (details->flags & CD_DONTWAIT) { - if (exec_setup(details, NULL, -1) == true) { -+ restore_nproc(); - /* headed for execve() */ - sudo_debug_execve(SUDO_DEBUG_INFO, details->command, - details->argv, details->envp); -diff -up sudo-1.8.6p7/src/sudo.c.nproc-nowait sudo-1.8.6p7/src/sudo.c ---- sudo-1.8.6p7/src/sudo.c.nproc-nowait 2016-05-11 12:56:58.758021632 +0200 -+++ sudo-1.8.6p7/src/sudo.c 2016-05-11 13:12:21.833116202 +0200 -@@ -145,6 +145,7 @@ static struct rlimit corelimit; - #endif /* RLIMIT_CORE */ - #if defined(__linux__) - static struct rlimit nproclimit; -+static struct rlimit orig_nproc_limit; - #endif - - int -@@ -853,6 +854,17 @@ unlimit_nproc(void) - debug_return; - } - -+void restore_nproc(void) -+{ -+ debug_decl(restore_nproc, SUDO_DEBUG_EXEC); -+#if defined(__linux__) -+ if (setrlimit(RLIMIT_NPROC, &orig_nproc_limit) != 0) { -+ errorx(1, _("Cannot restore nproc rlimit: errno=%d"), errno); -+ } -+#endif -+ debug_return; -+} -+ - #ifdef HAVE_PROJECT_H - static void - set_project(struct passwd *pw) -@@ -1089,6 +1101,7 @@ exec_setup(struct command_details *detai - */ - #if defined(__linux__) && defined(_SC_CHILD_MAX) - { -+ getrlimit(RLIMIT_NPROC, &orig_nproc_limit); - struct rlimit rl; - long l; - errno = 0; diff --git a/SOURCES/sudo-1.8.6p7-null_exception.patch b/SOURCES/sudo-1.8.6p7-null_exception.patch deleted file mode 100644 index f48b952..0000000 --- a/SOURCES/sudo-1.8.6p7-null_exception.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up sudo-1.8.6p7/src/sudo.c.null_exception sudo-1.8.6p7/src/sudo.c ---- sudo-1.8.6p7/src/sudo.c.null_exception 2016-05-11 10:39:56.466888652 +0200 -+++ sudo-1.8.6p7/src/sudo.c 2016-05-11 10:39:56.530887742 +0200 -@@ -483,6 +483,9 @@ get_user_info(struct user_details *ud) - errorx(1, _("unable to allocate memory")); - ud->cwd = user_info[i] + sizeof("cwd=") - 1; - } -+ else { -+ errorx(1, _("unable to resolve current working directory")); -+ } - - if ((cp = get_process_ttyname()) != NULL) { - user_info[++i] = fmt_string("tty", cp); diff --git a/SOURCES/sudo-1.8.6p7-pam_servicebackport.patch b/SOURCES/sudo-1.8.6p7-pam_servicebackport.patch deleted file mode 100644 index 53017f2..0000000 --- a/SOURCES/sudo-1.8.6p7-pam_servicebackport.patch +++ /dev/null @@ -1,221 +0,0 @@ -diff -up sudo-1.8.6p7/configure.in.pam_servicebackport sudo-1.8.6p7/configure.in ---- sudo-1.8.6p7/configure.in.pam_servicebackport 2016-05-09 15:36:30.213715598 +0200 -+++ sudo-1.8.6p7/configure.in 2016-05-09 15:36:30.237715261 +0200 -@@ -121,6 +121,7 @@ AC_SUBST([nsswitch_conf]) - AC_SUBST([netsvc_conf]) - AC_SUBST([secure_path]) - AC_SUBST([editor]) -+AC_SUBST([pam_login_service]) - # - # Begin initial values for man page substitution - # -@@ -160,6 +161,7 @@ netsvc_conf=/etc/netsvc.conf - noexec_file=/usr/local/libexec/sudo_noexec.so - nsswitch_conf=/etc/nsswitch.conf - secure_path="not set" -+pam_login_service=sudo - # - # End initial values for man page substitution - # -@@ -2717,6 +2719,7 @@ if test ${with_pam-"no"} != "no"; then - yes) AC_DEFINE([HAVE_PAM_LOGIN]) - AC_MSG_CHECKING(whether to use PAM login) - AC_MSG_RESULT(yes) -+ pam_login_service="sudo-i" - ;; - no) ;; - *) AC_MSG_ERROR(["--with-pam-login does not take an argument."]) -diff -up sudo-1.8.6p7/configure.pam_servicebackport sudo-1.8.6p7/configure ---- sudo-1.8.6p7/configure.pam_servicebackport 2013-02-25 20:48:02.000000000 +0100 -+++ sudo-1.8.6p7/configure 2016-05-09 15:36:30.238715247 +0200 -@@ -658,6 +658,7 @@ OBJEXT - EXEEXT - ac_ct_CC - CC -+pam_login_service - editor - secure_path - netsvc_conf -@@ -2959,6 +2960,7 @@ netsvc_conf=/etc/netsvc.conf - noexec_file=/usr/local/libexec/sudo_noexec.so - nsswitch_conf=/etc/nsswitch.conf - secure_path="not set" -+pam_login_service=sudo - # - # End initial values for man page substitution - # -@@ -18631,6 +18633,7 @@ if test "${with_pam_login+set}" = set; t - $as_echo_n "checking whether to use PAM login... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 - $as_echo "yes" >&6; } -+ pam_login_service="sudo-i" - ;; - no) ;; - *) as_fn_error $? "\"--with-pam-login does not take an argument.\"" "$LINENO" 5 -diff -up sudo-1.8.6p7/doc/sudoers.cat.pam_servicebackport sudo-1.8.6p7/doc/sudoers.cat ---- sudo-1.8.6p7/doc/sudoers.cat.pam_servicebackport 2016-05-09 15:36:30.222715472 +0200 -+++ sudo-1.8.6p7/doc/sudoers.cat 2016-05-09 15:36:30.239715233 +0200 -@@ -1245,6 +1245,18 @@ SSUUDDOOEERRSS OOPPTTIIOONN - noexec file should now be set in the _/_e_t_c_/_s_u_d_o_._c_o_n_f - file. - -+ pam_login_service -+ On systems that use PAM for authentication, this is the -+ service name used when the -^H-i^Hi option is specified. The -+ default value is ``sudo''. See the description of -+ _^Hp_^Ha_^Hm_^H__^Hs_^He_^Hr_^Hv_^Hi_^Hc_^He for more information. -+ -+ pam_service On systems that use PAM for authentication, the service -+ name specifies the PAM policy to apply. This usually -+ corresponds to an entry in the _^Hp_^Ha_^Hm_^H._^Hc_^Ho_^Hn_^Hf file or a fi -+ in the _^H/_^He_^Ht_^Hc_^H/_^Hp_^Ha_^Hm_^H._^Hd directory. The default valu -+ ``sudo''. -+ - passprompt The default prompt to use when asking for a password; - can be overridden via the --pp option or the SUDO_PROMPT - environment variable. The following percent (`%') -diff -up sudo-1.8.6p7/doc/sudoers.man.in.pam_servicebackport sudo-1.8.6p7/doc/sudoers.man.in ---- sudo-1.8.6p7/doc/sudoers.man.in.pam_servicebackport 2016-05-09 15:36:30.223715458 +0200 -+++ sudo-1.8.6p7/doc/sudoers.man.in 2016-05-09 15:36:30.239715233 +0200 -@@ -2628,6 +2628,29 @@ The path to the noexec file should now b - \fI@sysconfdir@/sudo.conf\fR - file. - .TP 18n -+pam_login_service -+.br -+On systems that use PAM for authentication, this is the service -+name used when the -+\fB\-i\fR -+option is specified. -+The default value is -+``\fR@pam_login_service@\fR''. -+See the description of -+\fIpam_service\fR -+for more information. -+.TP 18n -+pam_service -+On systems that use PAM for authentication, the service name -+specifies the PAM policy to apply. -+This usually corresponds to an entry in the -+\fIpam.conf\fR -+file or a file in the -+\fI/etc/pam.d\fR -+directory. -+The default value is -+``\fRsudo\fR''. -+.TP 18n - passprompt - The default prompt to use when asking for a password; can be overridden via the - \fB\-p\fR -diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.pam_servicebackport sudo-1.8.6p7/doc/sudoers.mdoc.in ---- sudo-1.8.6p7/doc/sudoers.mdoc.in.pam_servicebackport 2016-05-09 15:36:30.223715458 +0200 -+++ sudo-1.8.6p7/doc/sudoers.mdoc.in 2016-05-09 15:36:30.240715219 +0200 -@@ -2464,6 +2464,26 @@ This option is no longer supported. - The path to the noexec file should now be set in the - .Pa @sysconfdir@/sudo.conf - file. -+.It pam_login_service -+On systems that use PAM for authentication, this is the service -+name used when the -+.Fl i -+option is specified. -+The default value is -+.Dq Li @pam_login_service@ . -+See the description of -+.Em pam_service -+for more information. -+.It pam_service -+On systems that use PAM for authentication, the service name -+specifies the PAM policy to apply. -+This usually corresponds to an entry in the -+.Pa pam.conf -+file or a file in the -+.Pa /etc/pam.d -+directory. -+The default value is -+.Dq Li sudo . - .It passprompt - The default prompt to use when asking for a password; can be overridden via the - .Fl p -diff -up sudo-1.8.6p7/plugins/sudoers/auth/pam.c.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/auth/pam.c ---- sudo-1.8.6p7/plugins/sudoers/auth/pam.c.pam_servicebackport 2016-05-09 15:36:30.202715752 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/auth/pam.c 2016-05-09 15:36:30.240715219 +0200 -@@ -90,12 +90,8 @@ sudo_pam_init(struct passwd *pw, sudo_au - if (auth != NULL) - auth->data = (void *) &pam_status; - pam_conv.conv = converse; --#ifdef HAVE_PAM_LOGIN -- if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) -- pam_status = pam_start("sudo-i", pw->pw_name, &pam_conv, &pamh); -- else --#endif -- pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh); -+ pam_status = pam_start(ISSET(sudo_mode, MODE_LOGIN_SHELL) ? -+ def_pam_login_service : def_pam_service, pw->pw_name, &pam_conv, &pamh); - if (pam_status != PAM_SUCCESS) { - log_error(USE_ERRNO|NO_MAIL, _("unable to initialize PAM")); - debug_return_int(AUTH_FATAL); -diff -up sudo-1.8.6p7/plugins/sudoers/defaults.c.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/defaults.c ---- sudo-1.8.6p7/plugins/sudoers/defaults.c.pam_servicebackport 2016-05-09 15:36:30.234715304 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/defaults.c 2016-05-09 15:36:30.240715219 +0200 -@@ -424,6 +424,13 @@ init_defaults(void) - def_env_reset = ENV_RESET; - def_set_logname = true; - def_closefrom = STDERR_FILENO + 1; -+ def_pam_service = estrdup("sudo"); -+#ifdef HAVE_PAM_LOGIN -+ def_pam_login_service = estrdup("sudo-i"); -+#else -+ def_pam_login_service = estrdup("sudo"); -+#endif -+ - - /* Syslog options need special care since they both strings and ints */ - #if (LOGGING & SLOG_SYSLOG) -diff -up sudo-1.8.6p7/plugins/sudoers/def_data.c.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/def_data.c ---- sudo-1.8.6p7/plugins/sudoers/def_data.c.pam_servicebackport 2016-05-09 15:36:30.234715304 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/def_data.c 2016-05-09 15:36:30.240715219 +0200 -@@ -363,6 +363,14 @@ struct sudo_defs_types sudo_defs_table[] - N_("Use both user and host/domain fields when matching netgroups"), - NULL, - }, { -+ "pam_service", T_STR, -+ N_("PAM service name to use"), -+ NULL, -+ }, { -+ "pam_login_service", T_STR, -+ N_("PAM service name to use for login shells"), -+ NULL, -+ }, { - NULL, 0, NULL - } - }; -diff -up sudo-1.8.6p7/plugins/sudoers/def_data.h.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/def_data.h ---- sudo-1.8.6p7/plugins/sudoers/def_data.h.pam_servicebackport 2016-05-09 15:36:30.235715289 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/def_data.h 2016-05-09 15:36:30.240715219 +0200 -@@ -168,6 +168,11 @@ - #define I_LEGACY_GROUP_PROCESSING 83 - #define def_netgroup_tuple (sudo_defs_table[84].sd_un.flag) - #define I_NETGROUP_TUPLE 84 -+#define def_pam_service (sudo_defs_table[85].sd_un.str) -+#define I_PAM_SERVICE 85 -+#define def_pam_login_service (sudo_defs_table[86].sd_un.str) -+#define I_PAM_LOGIN_SERVICE 86 -+ - - enum def_tuple { - never, -diff -up sudo-1.8.6p7/plugins/sudoers/def_data.in.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/def_data.in ---- sudo-1.8.6p7/plugins/sudoers/def_data.in.pam_servicebackport 2013-02-25 20:42:44.000000000 +0100 -+++ sudo-1.8.6p7/plugins/sudoers/def_data.in 2016-05-09 15:36:30.240715219 +0200 -@@ -259,3 +259,10 @@ privs - limitprivs - T_STR - "Set of limit privileges" -+pam_service -+ T_STR -+ "PAM service name to use" -+pam_login_service -+ T_STR -+ "PAM service name to use for login shells" -+ diff --git a/SOURCES/sudo-1.8.6p7-segfault-null-group-list.patch b/SOURCES/sudo-1.8.6p7-segfault-null-group-list.patch deleted file mode 100644 index 609c872..0000000 --- a/SOURCES/sudo-1.8.6p7-segfault-null-group-list.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/match.c.segfault-null-group-list sudo-1.8.6p7/plugins/sudoers/match.c ---- sudo-1.8.6p7/plugins/sudoers/match.c.segfault-null-group-list 2016-05-11 10:22:29.201786896 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/match.c 2016-05-11 10:22:29.212786739 +0200 -@@ -164,6 +164,9 @@ runaslist_matches(struct member_list *us - int group_matched = UNSPEC; - debug_decl(runaslist_matches, SUDO_DEBUG_MATCH) - -+ if (user_list == NULL)user_list = ∅ -+ if (group_list == NULL)group_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)) diff --git a/SOURCES/sudo-1.8.6p7-sesh_loginshell.patch b/SOURCES/sudo-1.8.6p7-sesh_loginshell.patch deleted file mode 100644 index dde9491..0000000 --- a/SOURCES/sudo-1.8.6p7-sesh_loginshell.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up sudo-1.8.6p7/src/sesh.c.sesh_loginshell sudo-1.8.6p7/src/sesh.c ---- sudo-1.8.6p7/src/sesh.c.sesh_loginshell 2014-02-26 12:37:59.735214882 +0100 -+++ sudo-1.8.6p7/src/sesh.c 2014-02-26 12:38:05.535235487 +0100 -@@ -214,6 +214,8 @@ cleanup_0: - if (argv[-1][0] == '-') { - if ((cp = strrchr(argv[0], '/')) == NULL) - cp = argv[0]; -+ else -+ argv[0] = cp; - *cp = '-'; - } - sudo_execve(cmnd, argv, envp, noexec); diff --git a/SOURCES/sudo-1.8.6p7-strunquote.patch b/SOURCES/sudo-1.8.6p7-strunquote.patch deleted file mode 100644 index 63aa964..0000000 --- a/SOURCES/sudo-1.8.6p7-strunquote.patch +++ /dev/null @@ -1,137 +0,0 @@ -diff -up sudo-1.8.6p7/common/Makefile.in.strunquote sudo-1.8.6p7/common/Makefile.in ---- sudo-1.8.6p7/common/Makefile.in.strunquote 2013-02-25 20:46:09.000000000 +0100 -+++ sudo-1.8.6p7/common/Makefile.in 2015-07-07 14:30:09.267181200 +0200 -@@ -63,7 +63,7 @@ SHELL = @SHELL@ - - LTOBJS = alloc.lo atobool.lo fileops.lo fmt_string.lo lbuf.lo list.lo \ - secure_path.lo setgroups.lo sudo_conf.lo sudo_debug.lo term.lo \ -- ttysize.lo zero_bytes.lo @COMMON_OBJS@ -+ ttysize.lo zero_bytes.lo strunquote.lo @COMMON_OBJS@ - - all: libcommon.la - -@@ -164,3 +164,6 @@ ttysize.lo: $(srcdir)/ttysize.c $(top_bu - zero_bytes.lo: $(srcdir)/zero_bytes.c $(top_builddir)/config.h \ - $(incdir)/missing.h - $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/zero_bytes.c -+strunquote.lo: $(srcdir)/strunquote.c $(top_builddir)/config.h \ -+ $(incdir)/missing.h -+ $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/strunquote.c -diff -up sudo-1.8.6p7/common/strunquote.c.strunquote sudo-1.8.6p7/common/strunquote.c ---- sudo-1.8.6p7/common/strunquote.c.strunquote 2015-07-07 14:30:09.267181200 +0200 -+++ sudo-1.8.6p7/common/strunquote.c 2015-07-07 14:31:05.403649285 +0200 -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (c) 2015 Daniel Kopecek -+ * -+ * 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 -+#include -+ -+char *strunquote(char *arg) -+{ -+ char *str = arg; -+ if (str == NULL) { -+ return NULL; -+ } -+ const size_t len = strlen(str); -+ char *strend = str + len - 1; -+ -+ /* Remove blanks */ -+ for (; isblank((unsigned char)*str); str++); -+ for (; isblank((unsigned char)*strend) && strend > str; strend--); -+ /* -+ * Check that the string is double-quoted. -+ * If not, we are done. -+ */ -+ if (*str != '"' || *strend != '"' || str == strend) { -+ /* Return the original argument if we didn't touch it */ -+ return arg; -+ } -+ -+ /* Remove the double-quotes */ -+ *strend = '\0'; -+ ++str; -+ -+ return str; -+} -diff -up sudo-1.8.6p7/include/strunquote.h.strunquote sudo-1.8.6p7/include/strunquote.h ---- sudo-1.8.6p7/include/strunquote.h.strunquote 2015-07-07 14:30:09.267181200 +0200 -+++ sudo-1.8.6p7/include/strunquote.h 2015-07-07 14:30:09.267181200 +0200 -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (c) 2015 Daniel Kopecek -+ * -+ * 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. -+ */ -+ -+char *strunquote(char *arg); -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.strunquote sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.strunquote 2015-07-07 14:30:09.259181276 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2015-07-07 14:30:09.267181200 +0200 -@@ -79,6 +79,7 @@ - #include "sudoers.h" - #include "parse.h" - #include "lbuf.h" -+#include "strunquote.h" - - /* Older Netscape LDAP SDKs don't prototype ldapssl_set_strength() */ - #if defined(HAVE_LDAPSSL_SET_STRENGTH) && !defined(HAVE_LDAP_SSL_H) && !defined(HAVE_MPS_LDAP_SSL_H) -@@ -1004,10 +1005,10 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMe - if (op == '+' || op == '-') { - *(val - 2) = '\0'; /* found, remove extra char */ - /* case var+=val or var-=val */ -- set_default(var, val, (int) op); -+ set_default(var, strunquote(val), (int) op); - } else { - /* case var=val */ -- set_default(var, val, true); -+ set_default(var, strunquote(val), true); - } - } else if (*var == '!') { - /* case !var Boolean False */ -diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.strunquote sudo-1.8.6p7/plugins/sudoers/sssd.c ---- sudo-1.8.6p7/plugins/sudoers/sssd.c.strunquote 2015-07-07 14:30:09.260181267 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2015-07-07 14:30:09.268181191 +0200 -@@ -61,6 +61,7 @@ - #include "lbuf.h" - #include "sudo_debug.h" - #include "ipa_hostname.h" -+#include "strunquote.h" - - /* SSSD <--> SUDO interface - do not change */ - struct sss_sudo_attr { -@@ -996,10 +997,10 @@ sudo_sss_parse_options(struct sudo_sss_h - if (op == '+' || op == '-') { - *(val - 2) = '\0'; /* found, remove extra char */ - /* case var+=val or var-=val */ -- set_default(v, val, (int) op); -+ set_default(v, strunquote(val), (int) op); - } else { - /* case var=val */ -- set_default(v, val, true); -+ set_default(v, strunquote(val), true); - } - } else if (*v == '!') { - /* case !var Boolean False */ diff --git a/SOURCES/sudo-1.8.6p7-sudoconfman.patch b/SOURCES/sudo-1.8.6p7-sudoconfman.patch deleted file mode 100644 index 3d621ce..0000000 --- a/SOURCES/sudo-1.8.6p7-sudoconfman.patch +++ /dev/null @@ -1,1263 +0,0 @@ -diff -up sudo-1.8.6p7/doc/Makefile.in.sudoconfman sudo-1.8.6p7/doc/Makefile.in ---- sudo-1.8.6p7/doc/Makefile.in.sudoconfman 2013-07-30 13:57:00.000004193 +0200 -+++ sudo-1.8.6p7/doc/Makefile.in 2013-07-30 13:58:25.732323525 +0200 -@@ -64,12 +64,13 @@ DEVEL = @DEVEL@ - - SHELL = @SHELL@ - --DOCS = sudo.$(mantype) visudo.$(mantype) sudoers.$(mantype) \ -- sudoers.ldap.$(mantype) sudoers.$(mantype) \ -+DOCS = sudo.$(mantype) visudo.$(mantype) sudo.conf.$(mantype) \ -+ sudoers.$(mantype) sudoers.ldap.$(mantype) sudoers.$(mantype) \ - sudoreplay.$(mantype) sudo_plugin.$(mantype) - - DEVDOCS = $(srcdir)/sudo.man.in $(srcdir)/sudo.cat \ - $(srcdir)/visudo.man.in $(srcdir)/visudo.cat \ -+ $(srcdir)/sudo.conf.man.in $(srcdir)/sudo.conf.cat \ - $(srcdir)/sudoers.man.in $(srcdir)/sudoers.cat \ - $(srcdir)/sudoers.ldap.man.in $(srcdir)/sudoers.ldap.cat \ - $(srcdir)/sudoers.man.in $(srcdir)/sudoers.cat \ -@@ -158,6 +159,34 @@ $(srcdir)/visudo.cat: varsub $(srcdir)/v - - visudo.cat: $(srcdir)/visudo.cat - -+$(srcdir)/sudo.conf.man.in: $(srcdir)/sudo.conf.mdoc.in -+ @if [ -n "$(DEVEL)" ]; then \ -+ echo "Generating $@"; \ -+ mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ -+ mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ -+ printf '.\\" DO NOT EDIT THIS FILE, IT IS NOT THE MASTER!\n' > $@; \ -+ printf '.\\" IT IS GENERATED AUTOMATICALLY FROM sudo.conf.mdoc.in\n' >> $@; \ -+ $(SED) -n -e '/^.Dd/q' -e '/^\.\\/p' $(srcdir)/sudo.conf.mdoc.in >> $@; \ -+ $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo.conf.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "VISUDO" \)"8"\(.*"\)OpenBSD \(.*\)/\1"'$$mansectsu'"\2\3/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" >> $@; \ -+ fi -+ -+sudo.conf.man.sed: $(srcdir)/fixman.sh -+ $(SHELL) $(srcdir)/fixman.sh $@ -+ -+sudo.conf.man: $(srcdir)/sudo.conf.man.in sudo.conf.man.sed -+ (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/$@.in | $(SED) -f $@.sed > $@ -+ -+sudo.conf.mdoc: $(srcdir)/sudo.conf.mdoc.in -+ (cd $(top_builddir) && $(SHELL) config.status --file=doc/$@) -+ -+$(srcdir)/sudo.conf.cat: varsub $(srcdir)/sudo.conf.mdoc.in -+ @if [ -n "$(DEVEL)" ]; then \ -+ echo "Generating $@"; \ -+ $(SED) -f varsub $(srcdir)/sudo.conf.mdoc.in | $(MANDOC) -mdoc | $(SED) -e 's/ OpenBSD \([^ ].* \)/ \1 /' -e 's/(5)/(4)/g' -e 's/(8)/(1m)/g' > $@; \ -+ fi -+ -+sudo.conf.cat: $(srcdir)/sudo.conf.cat -+ - $(srcdir)/sudoers.man.in: $(srcdir)/sudoers.mdoc.in - @if [ -n "$(DEVEL)" ]; then \ - echo "Generating $@"; \ -@@ -292,10 +321,11 @@ install-doc: install-dirs - $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0644 @mansrcdir@/sudo_plugin.$(mantype) $(DESTDIR)$(mandirsu)/sudo_plugin.$(mansectsu) - $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0644 @mansrcdir@/sudoreplay.$(mantype) $(DESTDIR)$(mandirsu)/sudoreplay.$(mansectsu) - $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0644 @mansrcdir@/visudo.$(mantype) $(DESTDIR)$(mandirsu)/visudo.$(mansectsu) -+ $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0644 @mansrcdir@/sudo.conf.$(mantype) $(DESTDIR)$(mandirform)/sudo.conf.$(mansectform) - $(INSTALL) -O $(install_uid) -G $(install_gid) -m 0644 @mansrcdir@/sudoers.$(mantype) $(DESTDIR)$(mandirform)/sudoers.$(mansectform) - @LDAP@$(INSTALL) -O $(install_uid) -G $(install_gid) -m 0644 @mansrcdir@/sudoers.ldap.$(mantype) $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform) - @if test -n "$(MANCOMPRESS)"; then \ -- for f in $(mandirsu)/sudo.$(mansectsu) $(mandirsu)/sudo_plugin.$(mansectsu) $(mandirsu)/sudoreplay.$(mansectsu) $(mandirsu)/visudo.$(mansectsu) $(mandirform)/sudoers.$(mansectform) $(mandirform)/sudoers.ldap.$(mansectform); do \ -+ for f in $(mandirsu)/sudo.$(mansectsu) $(mandirsu)/sudo_plugin.$(mansectsu) $(mandirsu)/sudoreplay.$(mansectsu) $(mandirsu)/visudo.$(mansectsu) $(mandirform)/sudo.conf.$(mansectform) $(mandirform)/sudoers.$(mansectform) $(mandirform)/sudoers.ldap.$(mansectform); do \ - if test -f $(DESTDIR)$$f; then \ - echo $(MANCOMPRESS) -f $(DESTDIR)$$f; \ - $(MANCOMPRESS) -f $(DESTDIR)$$f; \ -@@ -319,6 +349,7 @@ uninstall: - $(DESTDIR)$(mandirsu)/sudo_plugin.$(mansectsu) \ - $(DESTDIR)$(mandirsu)/sudoreplay.$(mansectsu) \ - $(DESTDIR)$(mandirsu)/visudo.$(mansectsu) \ -+ $(DESTDIR)$(mandirform)/sudo.conf.$(mansectform) \ - $(DESTDIR)$(mandirform)/sudoers.$(mansectform) \ - $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform) - -diff -up sudo-1.8.6p7/doc/sudo.conf.cat.sudoconfman sudo-1.8.6p7/doc/sudo.conf.cat ---- sudo-1.8.6p7/doc/sudo.conf.cat.sudoconfman 2013-07-30 13:58:15.401285217 +0200 -+++ sudo-1.8.6p7/doc/sudo.conf.cat 2013-07-30 13:58:25.733323538 +0200 -@@ -0,0 +1,263 @@ -+SUDO(4) Programmer's Manual SUDO(4) -+ -+NNAAMMEE -+ ssuuddoo..ccoonnff - configuration for sudo front end -+ -+DDEESSCCRRIIPPTTIIOONN -+ The ssuuddoo..ccoonnff file is used to configure the ssuuddoo front end. It specifies -+ the security policy and I/O logging plugins, debug flags as well as -+ plugin-agnostic path names and settings. -+ -+ The ssuuddoo..ccoonnff file supports the following directives, described in detail -+ below. -+ -+ Plugin a security policy or I/O logging plugin -+ -+ Path a plugin-agnostic path -+ -+ Set a front end setting, such as _d_i_s_a_b_l_e___c_o_r_e_d_u_m_p or _g_r_o_u_p___s_o_u_r_c_e -+ -+ Debug debug flags to aid in debugging ssuuddoo, ssuuddoorreeppllaayy, vviissuuddoo, and -+ the ssuuddooeerrss plugin. -+ -+ The pound sign (`#') is used to indicate a comment. Both the comment -+ character and any text after it, up to the end of the line, are ignored. -+ -+ Non-comment lines that don't begin with Plugin, Path, Debug, or Set are -+ silently ignored. -+ -+ The ssuuddoo..ccoonnff file is always parsed in the ``C'' locale. -+ -+ PPlluuggiinn ccoonnffiigguurraattiioonn -+ ssuuddoo supports a plugin architecture for security policies and -+ input/output logging. Third parties can develop and distribute their own -+ policy and I/O logging plugins to work seamlessly with the ssuuddoo front -+ end. Plugins are dynamically loaded based on the contents of ssuuddoo..ccoonnff. -+ -+ A Plugin line consists of the Plugin keyword, followed by the _s_y_m_b_o_l___n_a_m_e -+ and the _p_a_t_h to the shared object containing the plugin. The _s_y_m_b_o_l___n_a_m_e -+ is the name of the struct policy_plugin or struct io_plugin in the plugin -+ shared object. The _p_a_t_h may be fully qualified or relative. If not -+ fully qualified, it is relative to the _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c directory. In -+ other words: -+ -+ Plugin sudoers_policy sudoers.so -+ -+ is equivalent to: -+ -+ Plugin sudoers_policy /usr/local/libexec/sudoers.so -+ -+ Any additional parameters after the _p_a_t_h are passed as arguments to the -+ plugin's _o_p_e_n function. For example, to override the compile-time -+ default sudoers file mode: -+ -+ Plugin sudoers_policy sudoers.so sudoers_mode=0440 -+ -+ If no ssuuddoo..ccoonnff file is present, or if it contains no Plugin lines, the -+ ssuuddooeerrss plugin will be used as the default security policy and for I/O -+ logging (if enabled by the policy). This is equivalent to the following: -+ -+ Plugin policy_plugin sudoers.so -+ Plugin io_plugin sudoers.so -+ -+ For more information on the ssuuddoo plugin architecture, see the -+ sudo_plugin(1m) manual. -+ -+ PPaatthh sseettttiinnggss -+ A Path line consists of the Path keyword, followed by the name of the -+ path to set and its value. For example: -+ -+ Path noexec /usr/local/libexec/sudo_noexec.so -+ Path askpass /usr/X11R6/bin/ssh-askpass -+ -+ The following plugin-agnostic paths may be set in the _/_e_t_c_/_s_u_d_o_._c_o_n_f -+ file: -+ -+ askpass The fully qualified path to a helper program used to read the -+ user's password when no terminal is available. This may be the -+ case when ssuuddoo is executed from a graphical (as opposed to -+ text-based) application. The program specified by _a_s_k_p_a_s_s -+ should display the argument passed to it as the prompt and -+ write the user's password to the standard output. The value of -+ _a_s_k_p_a_s_s may be overridden by the SUDO_ASKPASS environment -+ variable. -+ -+ noexec The fully-qualified path to a shared library containing dummy -+ versions of the eexxeeccvv(), eexxeeccvvee() and ffeexxeeccvvee() library -+ functions that just return an error. This is used to implement -+ the _n_o_e_x_e_c functionality on systems that support LD_PRELOAD or -+ its equivalent. The default value is: -+ _/_u_s_r_/_l_o_c_a_l_/_l_i_b_e_x_e_c_/_s_u_d_o___n_o_e_x_e_c_._s_o. -+ -+ OOtthheerr sseettttiinnggss -+ The ssuuddoo..ccoonnff file also supports the following front end settings: -+ -+ disable_coredump -+ Core dumps of ssuuddoo itself are disabled by default. To aid in -+ debugging ssuuddoo crashes, you may wish to re-enable core dumps by -+ setting ``disable_coredump'' to false in ssuuddoo..ccoonnff as follows: -+ -+ Set disable_coredump false -+ -+ Note that most operating systems disable core dumps from setuid -+ programs, including ssuuddoo. To actually get a ssuuddoo core file you -+ will likely need to enable core dumps for setuid processes. On -+ BSD and Linux systems this is accomplished via the sysctl -+ command. On Solaris, the coreadm command is used to configure -+ core dump behavior. -+ -+ This setting is only available in ssuuddoo version 1.8.4 and -+ higher. -+ -+ DDeebbuugg ffllaaggss -+ ssuuddoo versions 1.8.4 and higher support a flexible debugging framework -+ that can help track down what ssuuddoo is doing internally if there is a -+ problem. -+ -+ A Debug line consists of the Debug keyword, followed by the name of the -+ program (or plugin) to debug (ssuuddoo, vviissuuddoo, ssuuddoorreeppllaayy, ssuuddooeerrss), the -+ debug file name and a comma-separated list of debug flags. The debug -+ flag syntax used by ssuuddoo and the ssuuddooeerrss plugin is _s_u_b_s_y_s_t_e_m@_p_r_i_o_r_i_t_y but -+ a plugin is free to use a different format so long as it does not include -+ a comma (`,'). -+ -+ For example: -+ -+ Debug sudo /var/log/sudo_debug all@warn,plugin@info -+ -+ would log all debugging statements at the _w_a_r_n level and higher in -+ addition to those at the _i_n_f_o level for the plugin subsystem. -+ -+ Currently, only one Debug entry per program is supported. The ssuuddoo Debug -+ entry is shared by the ssuuddoo front end, ssuuddooeeddiitt and the plugins. A -+ future release may add support for per-plugin Debug lines and/or support -+ for multiple debugging files for a single program. -+ -+ The priorities used by the ssuuddoo front end, in order of decreasing -+ severity, are: _c_r_i_t, _e_r_r, _w_a_r_n, _n_o_t_i_c_e, _d_i_a_g, _i_n_f_o, _t_r_a_c_e and _d_e_b_u_g. -+ Each priority, when specified, also includes all priorities higher than -+ it. For example, a priority of _n_o_t_i_c_e would include debug messages -+ logged at _n_o_t_i_c_e and higher. -+ -+ The following subsystems are used by the ssuuddoo front-end: -+ -+ _a_l_l matches every subsystem -+ -+ _a_r_g_s command line argument processing -+ -+ _c_o_n_v user conversation -+ -+ _e_d_i_t sudoedit -+ -+ _e_x_e_c command execution -+ -+ _m_a_i_n ssuuddoo main function -+ -+ _n_e_t_i_f network interface handling -+ -+ _p_c_o_m_m communication with the plugin -+ -+ _p_l_u_g_i_n plugin configuration -+ -+ _p_t_y pseudo-tty related code -+ -+ _s_e_l_i_n_u_x SELinux-specific handling -+ -+ _u_t_i_l utility functions -+ -+ _u_t_m_p utmp handling -+ -+FFIILLEESS -+ _/_e_t_c_/_s_u_d_o_._c_o_n_f ssuuddoo front end configuration -+ -+EEXXAAMMPPLLEESS -+ # -+ # Default /etc/sudo.conf file -+ # -+ # Format: -+ # Plugin plugin_name plugin_path plugin_options ... -+ # Path askpass /path/to/askpass -+ # Path noexec /path/to/sudo_noexec.so -+ # Debug sudo /var/log/sudo_debug all@warn -+ # Set disable_coredump true -+ # -+ # The plugin_path is relative to /usr/local/libexec unless -+ # fully qualified. -+ # The plugin_name corresponds to a global symbol in the plugin -+ # that contains the plugin interface structure. -+ # The plugin_options are optional. -+ # -+ # The sudoers plugin is used by default if no Plugin lines are -+ # present. -+ Plugin policy_plugin sudoers.so -+ Plugin io_plugin sudoers.so -+ -+ # -+ # Sudo askpass: -+ # -+ # An askpass helper program may be specified to provide a graphical -+ # password prompt for "sudo -A" support. Sudo does not ship with -+ # its own askpass program but can use the OpenSSH askpass. -+ # -+ # Use the OpenSSH askpass -+ #Path askpass /usr/X11R6/bin/ssh-askpass -+ # -+ # Use the Gnome OpenSSH askpass -+ #Path askpass /usr/libexec/openssh/gnome-ssh-askpass -+ -+ # -+ # Sudo noexec: -+ # -+ # Path to a shared library containing dummy versions of the execv(), -+ # execve() and fexecve() library functions that just return an error. -+ # This is used to implement the "noexec" functionality on systems that -+ # support C or its equivalent. -+ # The compiled-in value is usually sufficient and should only be -+ # changed if you rename or move the sudo_noexec.so file. -+ # -+ #Path noexec /usr/local/libexec/sudo_noexec.so -+ -+ # -+ # Core dumps: -+ # -+ # By default, sudo disables core dumps while it is executing -+ # (they are re-enabled for the command that is run). -+ # To aid in debugging sudo problems, you may wish to enable core -+ # dumps by setting "disable_coredump" to false. -+ # -+ #Set disable_coredump false -+ -+SSEEEE AALLSSOO -+ sudoers(4), sudo(1m), sudo_plugin(1m), -+ -+HHIISSTTOORRYY -+ See the HISTORY file in the ssuuddoo distribution -+ (http://www.sudo.ws/sudo/history.html) for a brief history of sudo. -+ -+AAUUTTHHOORRSS -+ Many people have worked on ssuuddoo over the years; this version consists of -+ code written primarily by: -+ -+ Todd C. Miller -+ -+ See the CONTRIBUTORS file in the ssuuddoo distribution -+ (http://www.sudo.ws/sudo/contributors.html) for an exhaustive list of -+ people who have contributed to ssuuddoo. -+ -+BBUUGGSS -+ If you feel you have found a bug in ssuuddoo, please submit a bug report at -+ http://www.sudo.ws/sudo/bugs/ -+ -+SSUUPPPPOORRTT -+ Limited free support is available via the sudo-users mailing list, see -+ http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search the -+ archives. -+ -+DDIISSCCLLAAIIMMEERR -+ ssuuddoo is provided ``AS IS'' and any express or implied warranties, -+ including, but not limited to, the implied warranties of merchantability -+ and fitness for a particular purpose are disclaimed. See the LICENSE -+ file distributed with ssuuddoo or http://www.sudo.ws/sudo/license.html for -+ complete details. -+ -+Sudo 1.8.6p7 February 1, 2013 Sudo 1.8.6p7 -diff -up sudo-1.8.6p7/doc/sudo.conf.man.in.sudoconfman sudo-1.8.6p7/doc/sudo.conf.man.in ---- sudo-1.8.6p7/doc/sudo.conf.man.in.sudoconfman 2013-07-30 13:58:15.401285217 +0200 -+++ sudo-1.8.6p7/doc/sudo.conf.man.in 2013-07-30 13:58:25.733323538 +0200 -@@ -0,0 +1,470 @@ -+.\" DO NOT EDIT THIS FILE, IT IS NOT THE MASTER! -+.\" IT IS GENERATED AUTOMATICALLY FROM sudo.conf.mdoc.in -+.\" -+.\" Copyright (c) 2010-2013 Todd C. Miller -+.\" -+.\" 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. -+.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+.\" -+.TH "SUDO" "5" "February 1, 2013" "Sudo @PACKAGE_VERSION@" "OpenBSD Programmer's Manual" -+.nh -+.if n .ad l -+.SH "NAME" -+\fBsudo.conf\fR -+\- configuration for sudo front end -+.SH "DESCRIPTION" -+The -+\fBsudo.conf\fR -+file is used to configure the -+\fBsudo\fR -+front end. -+It specifies the security policy and I/O logging plugins, debug flags -+as well as plugin-agnostic path names and settings. -+.PP -+The -+\fBsudo.conf\fR -+file supports the following directives, described in detail below. -+.TP 10n -+Plugin -+a security policy or I/O logging plugin -+.TP 10n -+Path -+a plugin-agnostic path -+.TP 10n -+Set -+a front end setting, such as -+\fIdisable_coredump\fR -+or -+\fIgroup_source\fR -+.TP 10n -+Debug -+debug flags to aid in debugging -+\fBsudo\fR, -+\fBsudoreplay\fR, -+\fBvisudo\fR, -+and the -+\fBsudoers\fR -+plugin. -+.PP -+The pound sign -+(`#') -+is used to indicate a comment. -+Both the comment character and any text after it, up to the end of -+the line, are ignored. -+.PP -+Non-comment lines that don't begin with -+\fRPlugin\fR, -+\fRPath\fR, -+\fRDebug\fR, -+or -+\fRSet\fR -+are silently ignored. -+.PP -+The -+\fBsudo.conf\fR -+file is always parsed in the -+``\fRC\fR'' -+locale. -+.SS "Plugin configuration" -+\fBsudo\fR -+supports a plugin architecture for security policies and input/output -+logging. -+Third parties can develop and distribute their own policy and I/O -+logging plugins to work seamlessly with the -+\fBsudo\fR -+front end. -+Plugins are dynamically loaded based on the contents of -+\fBsudo.conf\fR. -+.PP -+A -+\fRPlugin\fR -+line consists of the -+\fRPlugin\fR -+keyword, followed by the -+\fIsymbol_name\fR -+and the -+\fIpath\fR -+to the shared object containing the plugin. -+The -+\fIsymbol_name\fR -+is the name of the -+\fRstruct policy_plugin\fR -+or -+\fRstruct io_plugin\fR -+in the plugin shared object. -+The -+\fIpath\fR -+may be fully qualified or relative. -+If not fully qualified, it is relative to the -+\fI@PLUGINDIR@\fR -+directory. -+In other words: -+.nf -+.sp -+.RS 6n -+Plugin sudoers_policy sudoers.so -+.RE -+.fi -+.PP -+is equivalent to: -+.nf -+.sp -+.RS 6n -+Plugin sudoers_policy @PLUGINDIR@/sudoers.so -+.RE -+.fi -+.PP -+Any additional parameters after the -+\fIpath\fR -+are passed as arguments to the plugin's -+\fIopen\fR -+function. -+For example, to override the compile-time default sudoers file mode: -+.nf -+.sp -+.RS 6n -+Plugin sudoers_policy sudoers.so sudoers_mode=0440 -+.RE -+.fi -+.PP -+If no -+\fBsudo.conf\fR -+file is present, or if it contains no -+\fRPlugin\fR -+lines, the -+\fBsudoers\fR -+plugin will be used as the default security policy and for I/O logging -+(if enabled by the policy). -+This is equivalent to the following: -+.nf -+.sp -+.RS 6n -+Plugin policy_plugin sudoers.so -+Plugin io_plugin sudoers.so -+.RE -+.fi -+.PP -+For more information on the -+\fBsudo\fR -+plugin architecture, see the -+sudo_plugin(@mansectsu@) -+manual. -+.SS "Path settings" -+A -+\fRPath\fR -+line consists of the -+\fRPath\fR -+keyword, followed by the name of the path to set and its value. -+For example: -+.nf -+.sp -+.RS 6n -+Path noexec @noexec_file@ -+Path askpass /usr/X11R6/bin/ssh-askpass -+.RE -+.fi -+.PP -+The following plugin-agnostic paths may be set in the -+\fI@sysconfdir@/sudo.conf\fR -+file: -+.TP 10n -+askpass -+The fully qualified path to a helper program used to read the user's -+password when no terminal is available. -+This may be the case when -+\fBsudo\fR -+is executed from a graphical (as opposed to text-based) application. -+The program specified by -+\fIaskpass\fR -+should display the argument passed to it as the prompt and write -+the user's password to the standard output. -+The value of -+\fIaskpass\fR -+may be overridden by the -+\fRSUDO_ASKPASS\fR -+environment variable. -+.TP 10n -+noexec -+The fully-qualified path to a shared library containing dummy -+versions of the -+\fBexecv\fR(), -+\fBexecve\fR() -+and -+\fBfexecve\fR() -+library functions that just return an error. -+This is used to implement the -+\fInoexec\fR -+functionality on systems that support -+\fRLD_PRELOAD\fR -+or its equivalent. -+The default value is: -+\fI@noexec_file@\fR. -+.SS "Other settings" -+The -+\fBsudo.conf\fR -+file also supports the following front end settings: -+.TP 10n -+disable_coredump -+Core dumps of -+\fBsudo\fR -+itself are disabled by default. -+To aid in debugging -+\fBsudo\fR -+crashes, you may wish to re-enable core dumps by setting -+``disable_coredump'' -+to false in -+\fBsudo.conf\fR -+as follows: -+.RS -+.nf -+.sp -+.RS 6n -+Set disable_coredump false -+.RE -+.fi -+.sp -+Note that most operating systems disable core dumps from setuid programs, -+including -+\fBsudo\fR. -+To actually get a -+\fBsudo\fR -+core file you will likely need to enable core dumps for setuid processes. -+On BSD and Linux systems this is accomplished via the -+sysctl -+command. -+On Solaris, the -+coreadm -+command is used to configure core dump behavior. -+.sp -+This setting is only available in -+\fBsudo\fR -+version 1.8.4 and higher. -+.PP -+.RE -+.SS "Debug flags" -+\fBsudo\fR -+versions 1.8.4 and higher support a flexible debugging framework -+that can help track down what -+\fBsudo\fR -+is doing internally if there is a problem. -+.PP -+A -+\fRDebug\fR -+line consists of the -+\fRDebug\fR -+keyword, followed by the name of the program (or plugin) to debug -+(\fBsudo\fR, \fBvisudo\fR, \fBsudoreplay\fR, \fBsudoers\fR), -+the debug file name and a comma-separated list of debug flags. -+The debug flag syntax used by -+\fBsudo\fR -+and the -+\fBsudoers\fR -+plugin is -+\fIsubsystem\fR@\fIpriority\fR -+but a plugin is free to use a different format so long as it does -+not include a comma -+(`\&,'). -+.PP -+For example: -+.nf -+.sp -+.RS 6n -+Debug sudo /var/log/sudo_debug all@warn,plugin@info -+.RE -+.fi -+.PP -+would log all debugging statements at the -+\fIwarn\fR -+level and higher in addition to those at the -+\fIinfo\fR -+level for the plugin subsystem. -+.PP -+Currently, only one -+\fRDebug\fR -+entry per program is supported. -+The -+\fBsudo\fR -+\fRDebug\fR -+entry is shared by the -+\fBsudo\fR -+front end, -+\fBsudoedit\fR -+and the plugins. -+A future release may add support for per-plugin -+\fRDebug\fR -+lines and/or support for multiple debugging files for a single -+program. -+.PP -+The priorities used by the -+\fBsudo\fR -+front end, in order of decreasing severity, are: -+\fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR, \fIinfo\fR, \fItrace\fR -+and -+\fIdebug\fR. -+Each priority, when specified, also includes all priorities higher -+than it. -+For example, a priority of -+\fInotice\fR -+would include debug messages logged at -+\fInotice\fR -+and higher. -+.PP -+The following subsystems are used by the -+\fBsudo\fR -+front-end: -+.TP 12n -+\fIall\fR -+matches every subsystem -+.TP 12n -+\fIargs\fR -+command line argument processing -+.TP 12n -+\fIconv\fR -+user conversation -+.TP 12n -+\fIedit\fR -+sudoedit -+.TP 12n -+\fIexec\fR -+command execution -+.TP 12n -+\fImain\fR -+\fBsudo\fR -+main function -+.TP 12n -+\fInetif\fR -+network interface handling -+.TP 12n -+\fIpcomm\fR -+communication with the plugin -+.TP 12n -+\fIplugin\fR -+plugin configuration -+.TP 12n -+\fIpty\fR -+pseudo-tty related code -+.TP 12n -+\fIselinux\fR -+SELinux-specific handling -+.TP 12n -+\fIutil\fR -+utility functions -+.TP 12n -+\fIutmp\fR -+utmp handling -+.SH "FILES" -+.TP 26n -+\fI@sysconfdir@/sudo.conf\fR -+\fBsudo\fR -+front end configuration -+.SH "EXAMPLES" -+.nf -+.RS 0n -+# -+# Default @sysconfdir@/sudo.conf file -+# -+# Format: -+# Plugin plugin_name plugin_path plugin_options ... -+# Path askpass /path/to/askpass -+# Path noexec /path/to/sudo_noexec.so -+# Debug sudo /var/log/sudo_debug all@warn -+# Set disable_coredump true -+# -+# The plugin_path is relative to @PLUGINDIR@ unless -+# fully qualified. -+# The plugin_name corresponds to a global symbol in the plugin -+# that contains the plugin interface structure. -+# The plugin_options are optional. -+# -+# The sudoers plugin is used by default if no Plugin lines are -+# present. -+Plugin policy_plugin sudoers.so -+Plugin io_plugin sudoers.so -+ -+# -+# Sudo askpass: -+# -+# An askpass helper program may be specified to provide a graphical -+# password prompt for "sudo -A" support. Sudo does not ship with -+# its own askpass program but can use the OpenSSH askpass. -+# -+# Use the OpenSSH askpass -+#Path askpass /usr/X11R6/bin/ssh-askpass -+# -+# Use the Gnome OpenSSH askpass -+#Path askpass /usr/libexec/openssh/gnome-ssh-askpass -+ -+# -+# Sudo noexec: -+# -+# Path to a shared library containing dummy versions of the execv(), -+# execve() and fexecve() library functions that just return an error. -+# This is used to implement the "noexec" functionality on systems that -+# support C or its equivalent. -+# The compiled-in value is usually sufficient and should only be -+# changed if you rename or move the sudo_noexec.so file. -+# -+#Path noexec @noexec_file@ -+ -+# -+# Core dumps: -+# -+# By default, sudo disables core dumps while it is executing -+# (they are re-enabled for the command that is run). -+# To aid in debugging sudo problems, you may wish to enable core -+# dumps by setting "disable_coredump" to false. -+# -+#Set disable_coredump false -+.RE -+.fi -+.SH "SEE ALSO" -+sudoers(@mansectform@), -+sudo(@mansectsu@), -+sudo_plugin(@mansectsu@), -+.SH "HISTORY" -+See the HISTORY file in the -+\fBsudo\fR -+distribution (http://www.sudo.ws/sudo/history.html) for a brief -+history of sudo. -+.SH "AUTHORS" -+Many people have worked on -+\fBsudo\fR -+over the years; this version consists of code written primarily by: -+.sp -+.RS 6n -+Todd C. Miller -+.RE -+.PP -+See the CONTRIBUTORS file in the -+\fBsudo\fR -+distribution (http://www.sudo.ws/sudo/contributors.html) for an -+exhaustive list of people who have contributed to -+\fBsudo\fR. -+.SH "BUGS" -+If you feel you have found a bug in -+\fBsudo\fR, -+please submit a bug report at http://www.sudo.ws/sudo/bugs/ -+.SH "SUPPORT" -+Limited free support is available via the sudo-users mailing list, -+see http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or -+search the archives. -+.SH "DISCLAIMER" -+\fBsudo\fR -+is provided -+``AS IS'' -+and any express or implied warranties, including, but not limited -+to, the implied warranties of merchantability and fitness for a -+particular purpose are disclaimed. -+See the LICENSE file distributed with -+\fBsudo\fR -+or http://www.sudo.ws/sudo/license.html for complete details. -diff -up sudo-1.8.6p7/doc/sudo.conf.mdoc.in.sudoconfman sudo-1.8.6p7/doc/sudo.conf.mdoc.in ---- sudo-1.8.6p7/doc/sudo.conf.mdoc.in.sudoconfman 2013-07-30 13:58:15.401285217 +0200 -+++ sudo-1.8.6p7/doc/sudo.conf.mdoc.in 2013-07-30 13:58:25.734323547 +0200 -@@ -0,0 +1,430 @@ -+.\" -+.\" Copyright (c) 2010-2013 Todd C. Miller -+.\" -+.\" 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. -+.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+.\" -+.Dd February 5, 2013 -+.Dt SUDO @mansectform@ -+.Os Sudo @PACKAGE_VERSION@ -+.Sh NAME -+.Nm sudo.conf -+.Nd configuration for sudo front end -+.Sh DESCRIPTION -+The -+.Nm sudo.conf -+file is used to configure the -+.Nm sudo -+front end. -+It specifies the security policy and I/O logging plugins, debug flags -+as well as plugin-agnostic path names and settings. -+.Pp -+The -+.Nm sudo.conf -+file supports the following directives, described in detail below. -+.Bl -tag -width 8n -+.It Plugin -+a security policy or I/O logging plugin -+.It Path -+a plugin-agnostic path -+.It Set -+a front end setting, such as -+.Em disable_coredump -+or -+.Em group_source -+.It Debug -+debug flags to aid in debugging -+.Nm sudo , -+.Nm sudoreplay , -+.Nm visudo , -+and the -+.Nm sudoers -+plugin. -+.El -+.Pp -+The pound sign -+.Pq Ql # -+is used to indicate a comment. -+Both the comment character and any text after it, up to the end of -+the line, are ignored. -+.Pp -+Non-comment lines that don't begin with -+.Li Plugin , -+.Li Path , -+.Li Debug , -+or -+.Li Set -+are silently ignored. -+.Pp -+The -+.Nm sudo.conf -+file is always parsed in the -+.Dq Li C -+locale. -+.Ss Plugin configuration -+.Nm sudo -+supports a plugin architecture for security policies and input/output -+logging. -+Third parties can develop and distribute their own policy and I/O -+logging plugins to work seamlessly with the -+.Nm sudo -+front end. -+Plugins are dynamically loaded based on the contents of -+.Nm sudo.conf . -+.Pp -+A -+.Li Plugin -+line consists of the -+.Li Plugin -+keyword, followed by the -+.Em symbol_name -+and the -+.Em path -+to the shared object containing the plugin. -+The -+.Em symbol_name -+is the name of the -+.Li struct policy_plugin -+or -+.Li struct io_plugin -+in the plugin shared object. -+The -+.Em path -+may be fully qualified or relative. -+If not fully qualified, it is relative to the -+.Pa @PLUGINDIR@ -+directory. -+In other words: -+.Bd -literal -offset indent -+Plugin sudoers_policy sudoers.so -+.Ed -+.Pp -+is equivalent to: -+.Bd -literal -offset indent -+Plugin sudoers_policy @PLUGINDIR@/sudoers.so -+.Ed -+.Pp -+Any additional parameters after the -+.Em path -+are passed as arguments to the plugin's -+.Em open -+function. -+For example, to override the compile-time default sudoers file mode: -+.Bd -literal -offset indent -+Plugin sudoers_policy sudoers.so sudoers_mode=0440 -+.Ed -+.Pp -+If no -+.Nm sudo.conf -+file is present, or if it contains no -+.Li Plugin -+lines, the -+.Nm sudoers -+plugin will be used as the default security policy and for I/O logging -+(if enabled by the policy). -+This is equivalent to the following: -+.Bd -literal -offset indent -+Plugin policy_plugin sudoers.so -+Plugin io_plugin sudoers.so -+.Ed -+.Pp -+For more information on the -+.Nm sudo -+plugin architecture, see the -+.Xr sudo_plugin @mansectsu@ -+manual. -+.Ss Path settings -+A -+.Li Path -+line consists of the -+.Li Path -+keyword, followed by the name of the path to set and its value. -+For example: -+.Bd -literal -offset indent -+Path noexec @noexec_file@ -+Path askpass /usr/X11R6/bin/ssh-askpass -+.Ed -+.Pp -+The following plugin-agnostic paths may be set in the -+.Pa @sysconfdir@/sudo.conf -+file: -+.Bl -tag -width 8n -+.It askpass -+The fully qualified path to a helper program used to read the user's -+password when no terminal is available. -+This may be the case when -+.Nm sudo -+is executed from a graphical (as opposed to text-based) application. -+The program specified by -+.Em askpass -+should display the argument passed to it as the prompt and write -+the user's password to the standard output. -+The value of -+.Em askpass -+may be overridden by the -+.Ev SUDO_ASKPASS -+environment variable. -+.It noexec -+The fully-qualified path to a shared library containing dummy -+versions of the -+.Fn execv , -+.Fn execve -+and -+.Fn fexecve -+library functions that just return an error. -+This is used to implement the -+.Em noexec -+functionality on systems that support -+.Ev LD_PRELOAD -+or its equivalent. -+The default value is: -+.Pa @noexec_file@ . -+.El -+.Ss Other settings -+The -+.Nm sudo.conf -+file also supports the following front end settings: -+.Bl -tag -width 8n -+.It disable_coredump -+Core dumps of -+.Nm sudo -+itself are disabled by default. -+To aid in debugging -+.Nm sudo -+crashes, you may wish to re-enable core dumps by setting -+.Dq disable_coredump -+to false in -+.Nm sudo.conf -+as follows: -+.Bd -literal -offset indent -+Set disable_coredump false -+.Ed -+.Pp -+Note that most operating systems disable core dumps from setuid programs, -+including -+.Nm sudo . -+To actually get a -+.Nm sudo -+core file you will likely need to enable core dumps for setuid processes. -+On BSD and Linux systems this is accomplished via the -+.Xr sysctl -+command. -+On Solaris, the -+.Xr coreadm -+command is used to configure core dump behavior. -+.Pp -+This setting is only available in -+.Nm sudo -+version 1.8.4 and higher. -+.El -+.Ss Debug flags -+.Nm sudo -+versions 1.8.4 and higher support a flexible debugging framework -+that can help track down what -+.Nm sudo -+is doing internally if there is a problem. -+.Pp -+A -+.Li Debug -+line consists of the -+.Li Debug -+keyword, followed by the name of the program (or plugin) to debug -+.Pq Nm sudo , Nm visudo , Nm sudoreplay , Nm sudoers , -+the debug file name and a comma-separated list of debug flags. -+The debug flag syntax used by -+.Nm sudo -+and the -+.Nm sudoers -+plugin is -+.Em subsystem Ns No @ Ns Em priority -+but a plugin is free to use a different format so long as it does -+not include a comma -+.Pq Ql \&, . -+.Pp -+For example: -+.Bd -literal -offset indent -+Debug sudo /var/log/sudo_debug all@warn,plugin@info -+.Ed -+.Pp -+would log all debugging statements at the -+.Em warn -+level and higher in addition to those at the -+.Em info -+level for the plugin subsystem. -+.Pp -+Currently, only one -+.Li Debug -+entry per program is supported. -+The -+.Nm sudo -+.Li Debug -+entry is shared by the -+.Nm sudo -+front end, -+.Nm sudoedit -+and the plugins. -+A future release may add support for per-plugin -+.Li Debug -+lines and/or support for multiple debugging files for a single -+program. -+.Pp -+The priorities used by the -+.Nm sudo -+front end, in order of decreasing severity, are: -+.Em crit , err , warn , notice , diag , info , trace -+and -+.Em debug . -+Each priority, when specified, also includes all priorities higher -+than it. -+For example, a priority of -+.Em notice -+would include debug messages logged at -+.Em notice -+and higher. -+.Pp -+The following subsystems are used by the -+.Nm sudo -+front-end: -+.Bl -tag -width Fl -+.It Em all -+matches every subsystem -+.It Em args -+command line argument processing -+.It Em conv -+user conversation -+.It Em edit -+sudoedit -+.It Em exec -+command execution -+.It Em main -+.Nm sudo -+main function -+.It Em netif -+network interface handling -+.It Em pcomm -+communication with the plugin -+.It Em plugin -+plugin configuration -+.It Em pty -+pseudo-tty related code -+.It Em selinux -+SELinux-specific handling -+.It Em util -+utility functions -+.It Em utmp -+utmp handling -+.El -+.Sh FILES -+.Bl -tag -width 24n -+.It Pa @sysconfdir@/sudo.conf -+.Nm sudo -+front end configuration -+.El -+.Sh EXAMPLES -+.Bd -literal -+# -+# Default @sysconfdir@/sudo.conf file -+# -+# Format: -+# Plugin plugin_name plugin_path plugin_options ... -+# Path askpass /path/to/askpass -+# Path noexec /path/to/sudo_noexec.so -+# Debug sudo /var/log/sudo_debug all@warn -+# Set disable_coredump true -+# -+# The plugin_path is relative to @PLUGINDIR@ unless -+# fully qualified. -+# The plugin_name corresponds to a global symbol in the plugin -+# that contains the plugin interface structure. -+# The plugin_options are optional. -+# -+# The sudoers plugin is used by default if no Plugin lines are -+# present. -+Plugin policy_plugin sudoers.so -+Plugin io_plugin sudoers.so -+ -+# -+# Sudo askpass: -+# -+# An askpass helper program may be specified to provide a graphical -+# password prompt for "sudo -A" support. Sudo does not ship with -+# its own askpass program but can use the OpenSSH askpass. -+# -+# Use the OpenSSH askpass -+#Path askpass /usr/X11R6/bin/ssh-askpass -+# -+# Use the Gnome OpenSSH askpass -+#Path askpass /usr/libexec/openssh/gnome-ssh-askpass -+ -+# -+# Sudo noexec: -+# -+# Path to a shared library containing dummy versions of the execv(), -+# execve() and fexecve() library functions that just return an error. -+# This is used to implement the "noexec" functionality on systems that -+# support C or its equivalent. -+# The compiled-in value is usually sufficient and should only be -+# changed if you rename or move the sudo_noexec.so file. -+# -+#Path noexec @noexec_file@ -+ -+# -+# Core dumps: -+# -+# By default, sudo disables core dumps while it is executing -+# (they are re-enabled for the command that is run). -+# To aid in debugging sudo problems, you may wish to enable core -+# dumps by setting "disable_coredump" to false. -+# -+#Set disable_coredump false -+.Ed -+.Sh SEE ALSO -+.Xr sudoers @mansectform@ , -+.Xr sudo @mansectsu@ , -+.Xr sudo_plugin @mansectsu@ -+.Sh HISTORY -+See the HISTORY file in the -+.Nm sudo -+distribution (http://www.sudo.ws/sudo/history.html) for a brief -+history of sudo. -+.Sh AUTHORS -+Many people have worked on -+.Nm sudo -+over the years; this version consists of code written primarily by: -+.Bd -ragged -offset indent -+Todd C. Miller -+.Ed -+.Pp -+See the CONTRIBUTORS file in the -+.Nm sudo -+distribution (http://www.sudo.ws/sudo/contributors.html) for an -+exhaustive list of people who have contributed to -+.Nm sudo . -+.Sh BUGS -+If you feel you have found a bug in -+.Nm sudo , -+please submit a bug report at http://www.sudo.ws/sudo/bugs/ -+.Sh SUPPORT -+Limited free support is available via the sudo-users mailing list, -+see http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or -+search the archives. -+.Sh DISCLAIMER -+.Nm sudo -+is provided -+.Dq AS IS -+and any express or implied warranties, including, but not limited -+to, the implied warranties of merchantability and fitness for a -+particular purpose are disclaimed. -+See the LICENSE file distributed with -+.Nm sudo -+or http://www.sudo.ws/sudo/license.html for complete details. -diff -up sudo-1.8.6p7/MANIFEST.sudoconfman sudo-1.8.6p7/MANIFEST ---- sudo-1.8.6p7/MANIFEST.sudoconfman 2013-07-30 13:56:49.585965170 +0200 -+++ sudo-1.8.6p7/MANIFEST 2013-07-30 13:58:25.731323515 +0200 -@@ -348,6 +348,9 @@ src/tgetpass.c - src/ttyname.c - src/utmp.c - sudo.pp -+sudo/sudo.conf.cat -+sudo/sudo.conf.man.in -+sudo/sudo.conf.mdoc.in - zlib/Makefile.in - zlib/adler32.c - zlib/compress.c diff --git a/SOURCES/sudo-1.8.6p7-sudoldapconfman.patch b/SOURCES/sudo-1.8.6p7-sudoldapconfman.patch index 6ac4042..8d46dbe 100644 --- a/SOURCES/sudo-1.8.6p7-sudoldapconfman.patch +++ b/SOURCES/sudo-1.8.6p7-sudoldapconfman.patch @@ -1,24 +1,41 @@ -diff -up sudo-1.8.6p7/doc/Makefile.in.sudoldapconfman sudo-1.8.6p7/doc/Makefile.in ---- sudo-1.8.6p7/doc/Makefile.in.sudoldapconfman 2013-08-05 17:05:30.125020088 +0200 -+++ sudo-1.8.6p7/doc/Makefile.in 2013-08-05 17:15:29.787058494 +0200 -@@ -334,10 +334,16 @@ install-doc: install-dirs +From 447b3f0c91f019c1d30b5703c61316b583f5bce1 Mon Sep 17 00:00:00 2001 +From: Tomas Sykora +Date: Mon, 15 Aug 2016 15:15:40 +0200 +Subject: [PATCH] RHEL7 failed RPMdiff testing + +Package sudo-1.8.3p1-7.el7 failed RHEL7 RPMdiff testing + +Rebased from: +Patch16: sudo-1.8.6p7-sudoldapconfman.patch + +Resolves: +rhbz#881258 +--- + doc/Makefile.in | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/doc/Makefile.in b/doc/Makefile.in +index a6f2ea2..e27c6e0 100644 +--- a/doc/Makefile.in ++++ b/doc/Makefile.in +@@ -319,10 +319,16 @@ install-doc: install-dirs rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \ echo ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \ ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \ + rm -f $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \ -+ echo ln -s sudoers.ldap.$(mansectform)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \ -+ ln -s sudoers.ldap.$(mansectform)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \ ++ echo ln -s sudoers.ldap.$(mansectform)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \ ++ ln -s sudoers.ldap.$(mansectform)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \ else \ rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \ echo ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \ ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \ + rm -f $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \ -+ echo ln -s sudoers.ldap.$(mansectform) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \ -+ ln -s sudoers.ldap.$(mansectform) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \ ++ echo ln -s sudoers.ldap.$(mansectform) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \ ++ ln -s sudoers.ldap.$(mansectform) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \ fi install-plugin: -@@ -351,7 +357,8 @@ uninstall: +@@ -336,7 +342,8 @@ uninstall: $(DESTDIR)$(mandirsu)/visudo.$(mansectsu) \ $(DESTDIR)$(mandirform)/sudo.conf.$(mansectform) \ $(DESTDIR)$(mandirform)/sudoers.$(mansectform) \ @@ -26,5 +43,8 @@ diff -up sudo-1.8.6p7/doc/Makefile.in.sudoldapconfman sudo-1.8.6p7/doc/Makefile. + $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform) \ + $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform) - check: + splint: +-- +2.7.4 + diff --git a/SOURCES/sudo-1.8.6p7-tty-name-parsing.patch b/SOURCES/sudo-1.8.6p7-tty-name-parsing.patch deleted file mode 100644 index fb852a4..0000000 --- a/SOURCES/sudo-1.8.6p7-tty-name-parsing.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff -up sudo-1.8.6p7/src/ttyname.c.get_process_ttyname sudo-1.8.6p7/src/ttyname.c ---- sudo-1.8.6p7/src/ttyname.c.get_process_ttyname 2013-02-25 20:46:09.000000000 +0100 -+++ sudo-1.8.6p7/src/ttyname.c 2017-05-25 10:23:28.720850944 +0200 -@@ -171,6 +171,8 @@ static char *search_devs[] = { - - static char *ignore_devs[] = { - "/dev/fd/", -+ "/dev/mqueue/", -+ "/dev/shm/", - "/dev/stdin", - "/dev/stdout", - "/dev/stderr", -@@ -437,9 +439,13 @@ get_process_ttyname(void) - len = getline(&line, &linesize, fp); - fclose(fp); - if (len != -1) { -- /* Field 7 is the tty dev (0 if no tty) */ -- char *cp = line; -- int field = 1; -+ /* -+ * Field 7 is the tty dev (0 if no tty). -+ * Since the process name at field 2 "(comm)" may include spaces, -+ * start at the last ')' found. -+ */ -+ char *cp = strrchr(line, ')'); -+ int field = 2; - while (*cp != '\0') { - if (*cp++ == ' ') { - if (++field == 7) { diff --git a/SOURCES/sudo-1.8.6p7-unprivileged-list-fix.patch b/SOURCES/sudo-1.8.6p7-unprivileged-list-fix.patch deleted file mode 100644 index 231ac8f..0000000 --- a/SOURCES/sudo-1.8.6p7-unprivileged-list-fix.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.unprivileged-list-fix sudo-1.8.6p7/plugins/sudoers/ldap.c ---- sudo-1.8.6p7/plugins/sudoers/ldap.c.unprivileged-list-fix 2016-05-09 15:58:36.581120998 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2016-05-09 15:58:36.588120900 +0200 -@@ -2494,12 +2494,12 @@ sudo_ldap_lookup(struct sudo_nss *nss, i - /* Only check the command when listing another user. */ - if (user_uid == 0 || list_pw == NULL || - user_uid == list_pw->pw_uid || -- sudo_ldap_check_command(ld, entry, NULL)) { -+ sudo_ldap_check_command(ld, entry, NULL) == true) { - matched = true; - break; - } - } -- if (matched || user_uid == 0) { -+ if (matched == true || user_uid == 0) { - SET(ret, VALIDATE_OK); - CLR(ret, VALIDATE_NOT_OK); - if (def_authenticate) { -diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.unprivileged-list-fix sudo-1.8.6p7/plugins/sudoers/sssd.c ---- sudo-1.8.6p7/plugins/sudoers/sssd.c.unprivileged-list-fix 2016-05-09 15:58:36.581120998 +0200 -+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2016-05-09 15:58:36.589120886 +0200 -@@ -1062,13 +1062,13 @@ sudo_sss_lookup(struct sudo_nss *nss, in - /* Only check the command when listing another user. */ - if (user_uid == 0 || list_pw == NULL || - user_uid == list_pw->pw_uid || -- sudo_sss_check_command(handle, rule, NULL)) { -+ sudo_sss_check_command(handle, rule, NULL) == true) { - matched = true; - break; - } - } - } -- if (matched || user_uid == 0) { -+ if (matched == true || user_uid == 0) { - SET(ret, VALIDATE_OK); - CLR(ret, VALIDATE_NOT_OK); - if (def_authenticate) { diff --git a/SOURCES/sudo-1.8.6p7-visudocontent.patch b/SOURCES/sudo-1.8.6p7-visudocontent.patch deleted file mode 100644 index 1177797..0000000 --- a/SOURCES/sudo-1.8.6p7-visudocontent.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff -up ./plugins/sudoers/visudo.c.fix ./plugins/sudoers/visudo.c ---- ./plugins/sudoers/visudo.c.fix 2015-09-15 10:00:25.957642667 +0200 -+++ ./plugins/sudoers/visudo.c 2015-09-15 12:37:43.478306234 +0200 -@@ -479,6 +479,7 @@ reparse_sudoers(char *editor, char *args - * Parse the edited sudoers files and do sanity checking - */ - do { -+ parse_error = NULL; - sp = tq_first(&sudoerslist); - last = tq_last(&sudoerslist); - fp = fopen(sp->tpath, "r+"); -@@ -544,7 +545,7 @@ reparse_sudoers(char *editor, char *args - continue; - edit_sudoers(sp, editor, args, errorlineno); - } -- } while (parse_error && sp != NULL); -+ } while (parse_error); - - debug_return; - } diff --git a/SOURCES/sudoers b/SOURCES/sudoers index 9737a8b..2fdc62f 100644 --- a/SOURCES/sudoers +++ b/SOURCES/sudoers @@ -62,6 +62,7 @@ Defaults !visiblepw # env_reset is disabled or HOME is present in the env_keep list. # Defaults always_set_home +Defaults match_group_by_gid Defaults env_reset Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS" diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec index 7f47ede..05ad9b2 100644 --- a/SPECS/sudo.spec +++ b/SPECS/sudo.spec @@ -1,7 +1,7 @@ Summary: Allows restricted root access for specified users Name: sudo -Version: 1.8.6p7 -Release: 23%{?dist} +Version: 1.8.19p2 +Release: 10%{?dist} License: ISC Group: Applications/System URL: http://www.courtesan.com/sudo/ @@ -10,7 +10,7 @@ Source1: sudoers Source2: sudo-ldap.conf Source3: sudo.conf Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Requires: /etc/pam.d/system-auth, vim-minimal +Requires: /etc/pam.d/system-auth, vim-minimal, libgcrypt BuildRequires: pam-devel BuildRequires: groff @@ -19,6 +19,7 @@ BuildRequires: flex BuildRequires: bison BuildRequires: automake autoconf libtool BuildRequires: audit-libs-devel libcap-devel +BuildRequires: libgcrypt-devel BuildRequires: libselinux-devel BuildRequires: /usr/sbin/sendmail BuildRequires: gettext @@ -29,127 +30,39 @@ BuildRequires: libgcrypt-devel Patch1: sudo-1.6.7p5-strip.patch # configure.in fix Patch2: sudo-1.7.2p1-envdebug.patch -# show the editor being executed by `sudo -e' in audit messages -Patch3: sudo-1.8.6p3-auditeditor.patch -# fix manpage typo (#726634) -Patch4: sudo-1.8.6p3-mantypo.patch -# correct SELinux handling in sudoedit mode (#697775) -Patch5: sudo-1.8.6p3-sudoedit-selinux.patch -# [RFE] Fix visudo -s to be backwards compatible (#604297) -Patch6: sudo-1.8.6p3-aliaswarnonly.patch -# log failed user role changes (#665131) -Patch7: sudo-1.8.6p3-auditrolechange.patch # 840980 - sudo creates a new parent process # Adds cmnd_no_wait Defaults option -Patch8: sudo-1.8.6p3-nowaitopt.patch -# 876578 - erealloc3 error on sssd sudoHost netgroup mismatch -Patch9: sudo-1.8.6p3-emallocfail.patch -# 876208 - sudoRunAsUser #uid specification doesn't work -Patch10: sudo-1.8.6p3-ldap-sssd-usermatch.patch -# 879675 - sudo parse ldap.conf incorrectly -Patch11: sudo-1.8.6p3-ldapconfparse.patch -# 879633 - sudo + sssd + local user sends e-mail to administrator -Patch12: sudo-1.8.6p3-sssd-noise.patch -# 856901 - Defauts:! syntax in sudoers doesn't seem to work as expected -Patch13: sudo-1.8.6p3-ALL-with-negation-manupdate.patch -# 947276 - Cannot set RLIMIT_NPROC to unlimited via pam_limits when running sudo -Patch14: sudo-1.8.6p3-nprocfix.patch -# 881258 - rpmdiff: added missing sudo.conf manpage -Patch15: sudo-1.8.6p7-sudoconfman.patch +Patch3: sudo-1.8.6p3-nowaitopt.patch # 881258 - rpmdiff: added missing sudo-ldap.conf manpage -Patch16: sudo-1.8.6p7-sudoldapconfman.patch -# 1026904 - Access granted with invalid sudoRunAsUser/sudoRunAsGroup -Patch17: sudo-1.8.6p3-strictuidgid.patch -# 1026890 - Improve error message -Patch18: sudo-1.8.6p3-netgrmatchtrace.patch -# 1007014 - sssd +netgroup sudoUser is always matched -Patch19: sudo-1.8.6p3-sssdfixes.patch -# 1026894 - sudo -u sudo -l show error: glibc detected sudo: realloc(): invalid next size -Patch20: sudo-1.8.6p3-lbufexpandcode.patch -# 994566 - Warning in visudo: cycle in Host_Alias even without cycle -Patch21: sudo-1.8.6p3-cycledetect.patch -# 1065418 - -sesh replaces /path/to/myshell with /path/to-myshell instead of -myshell -Patch22: sudo-1.8.6p7-sesh_loginshell.patch -# 1084488 - sudo should use ipa_hostname in IPA backend when defined -Patch23: sudo-1.8.6p7-ipahostname.patch -# 1096813 - sudo does not handle the "(none)" string, when no domainname is set, which -# breaks when nscd is enabled -Patch24: sudo-1.8.6p3-nonehostname.patch +Patch4: sudo-1.8.6p7-sudoldapconfman.patch # 1092499 - Regression in sudo 1.8.6p3-7 package, double quotes are not accepted in sudoers -Patch25: sudo-1.8.6p3-doublequotefix.patch -# 1088464 - sudo -ll does not list the rule names when sssd is used. -Patch26: sudo-1.8.6p3-sssdrulenames.patch -# 1088825 - With sudo-1.8.6p3-12.el6.x86_64 version, If a sudo rules contains +netgroup -# in sudoUser attribute it result in access denied -# 1147557 - sudo -U listing shows incorrect list when sssd is used. -Patch27: sudo-1.8.6p3-netgrfilterfix.patch -# 1093099 - pam_faillock causes sudo to lock user when user aborts password prompt -Patch28: sudo-1.8.6p3-authinterrupt.patch -# 1147497 - duplicate sss module in nsswitch breaks sudo -Patch29: sudo-1.8.6p7-duplicatenssfix.patch -# Fix compiler warnings about discarting const qualifiers -Patch30: sudo-1.8.6p7-constwarnfix.patch -# 1147616 - New defect found in sudo-1.8.6p7-12.el7 -Patch31: sudo-1.8.6p7-clangfixes.patch -## RHEL 7.2 errata ## -# 1144446 - sudo with ldap doesn't work correctly with 'listpw=all' and 'verifypw=all' in sudoOption entry -Patch32: sudo-1.8.6p7-authlogicfix.patch -# 1235570 - CVE-2014-9680 sudo: unsafe handling of TZ environment variable [rhel-7.2] -Patch33: sudo-1.8.6p7-CVE-2014-9680.patch -# 1138259 - sudoers.ldap man page has typos in description -Patch34: sudo-1.8.6p3-mantypos-ldap.patch +Patch5: sudo-1.8.6p3-doublequotefix.patch # 1183818 - backport of command digest specification feature -Patch35: sudo-1.8.6p7-digest-backport.patch -# 1233607 - In sudoers man page, "use_pty" information is merged with "umask_override". -Patch36: sudo-1.8.6p7-manfix-usepty.patch -# 1183818 - backport of command digest specification feature (documentation part) -Patch37: sudo-1.8.6p7-digest-backport-docs.patch -# 1144419 - sudo with ldap/sssd doesn't respect env_keep,env_check and env_delete variables in sudoOption -Patch38: sudo-1.8.6p7-strunquote.patch +Patch6: sudo-1.8.6p7-digest-backport.patch # 1135539 - sudo with ldap doesn't work with 'user id' in sudoUser option -Patch39: sudo-1.8.6p7-ldapsearchuidfix.patch -# 1254621 - make check broken by missing hexchar.o object file -Patch40: sudo-1.8.6p7-digest-backport-checklinkfix.patch -# 1247591 - Sudo taking a long time when user information is stored externally. -Patch41: sudo-1.8.6p7-legacy-group-processing.patch -# 1183818 - [RFE] store checksum alongside the command being permitted -Patch42: sudo-1.8.6p7-newbase64decoder.patch -# 1183818 - [RFE] store checksum alongside the command being permitted -Patch43: sudo-1.8.6p7-digestmessagesfix.patch -# 1297062 - closefrom_override sudo option not working -Patch44: sudo-1.8.6p7-closefrom-override-fix.patch -# 1334360 - sudo option mail_no_user doesn't work -Patch45: sudo-1.8.6p7-ldapusermatchfix.patch -# 1334331 - [RFE] Implement sudoers option to change netgroup processing semantics -Patch46: sudo-1.8.6p7-netgroup_tuple.patch -# 1247230 - Backport pam_service and pam_login_service sudoers options -Patch47: sudo-1.8.6p7-pam_servicebackport.patch -# 1261998 - visudo accept non valid content -Patch48: sudo-1.8.6p7-visudocontent.patch -# 1313364 - non-root user can list privileges of other users -Patch49: sudo-1.8.6p7-unprivileged-list-fix.patch +Patch7: sudo-1.8.6p7-ldapsearchuidfix.patch # 1312486 - RHEL7 sudo logs username "root" instead of realuser in /var/log/secure -Patch50: sudo-1.8.6p7-logsudouser.patch -# 1268958 - sudo - cmnd_no_wait can cause child processes to ignore SIGPIPE -Patch51: sudo-1.8.6p3-sigpipefix.patch -# 1335039 - sudo segfault segfault at 8 i error 4 in sudoers.so[7f4a87ef1000+45000] -Patch52: sudo-1.8.6p7-segfault-null-group-list.patch -# 1335042 - sudo command throwing error when defaults records are added in ldap based on sudoers2ldif generated ldif. -Patch53: sudo-1.8.6p7-ldap_sssd_parse_whitespaces.patch -# 1335045 - getcwd failed, resulting in Null pointer exception -Patch54: sudo-1.8.6p7-null_exception.patch -# 1273243 - sudo improperly sets RLIMIT_NPROC=0 when using Defaults cmnd_no_wait -Patch55: sudo-1.8.6p7-nproc-nowait.patch -# 1299883 - sudo: document raciness of the digest check -Patch56: sudo-1.8.6p7-digest_race_doc.patch -# 1350828 - [RHEL7] visudo ignores -q flag -Patch57: sudo-1.8.6p3-visudo-quiet-flag.patch -# 1391939 - CVE-2016-7032 CVE-2016-7076 sudo: various flaws [rhel-7.4] -Patch58: sudo-1.8.6p7-noexec-update.patch -# 1455401 - CVE-2017-1000367 sudo: Privilege escalation in via improper get_process_ttyname() parsing [rhel-7.3.z] -Patch59: sudo-1.8.6p7-tty-name-parsing.patch -# 1459410 - CVE-2017-1000368 sudo: Privilege escalation via improper get_process_ttyname() parsing (insufficient fix for CVE-2017-1000367) [rhel-7.3.z] -Patch60: sudo-1.8.6p7-CVE-2017-1000368.patch +Patch8: sudo-1.8.6p7-logsudouser.patch +# fix upstream testsuite - disabling 2 tests, working only with non-root user +Patch9: sudo-1.8.18-testsuitefix.patch +# 1413160 - backport ignore_unknown_defaults flag +Patch10: sudo-1.8.19p2-ignore-unknown-defaults.patch +# 1424575 - backport visudo severity of the message +Patch11: sudo-1.8.19p2-error-warning-visudo-message.patch +# 1369856 - synchronous (real-time) writes in sudo i/o logs +Patch12: sudo-1.8.19p2-iologflush.patch +# 1293306 - Sudo group lookup issue. +Patch13: sudo-1.8.19p2-lookup-issue-doc.patch +# 1360687 - sudo rhel-7 rebase - comment11 +Patch14: sudo-1.8.19p2-upstream-testsuitefix.patch +# 1360687 - sudo rhel-7 rebase - comment13 +Patch15: sudo-1.8.19p2-fqdn-use-after-free.patch +# 1360687 - sudo rhel-7 rebase - comment13 +Patch16: sudo-1.8.19p2-lecture-boolean.patch +# 1455402 - CVE-2017-1000367: Privilege escalation in via improper get_process_ttyname() parsing +Patch17: sudo-1.8.19p2-get_process_ttyname.patch +# 1459152 - CVE-2017-1000368: Privilege escalation via improper get_process_ttyname() parsing (insufficient fix for CVE-2017-1000367) +Patch18: sudo-1.8.19p2-CVE-2017-1000368.patch %description Sudo (superuser do) allows a system administrator to give certain @@ -176,64 +89,22 @@ plugins that use %{name}. %patch1 -p1 -b .strip %patch2 -p1 -b .envdebug -%patch3 -p1 -b .auditeditor -%patch4 -p1 -b .mantypo -%patch5 -p1 -b .sudoedit-selinux -%patch6 -p1 -b .aliaswarnonly -%patch7 -p1 -b .auditrolechange -%patch8 -p1 -b .nowaitopt -%patch9 -p1 -b .emallocfail -%patch10 -p1 -b .ldap-sssd-usermatch -%patch11 -p1 -b .ldapconfparse -%patch12 -p1 -b .sssd-noise -%patch13 -p1 -b .ALL-with-negation-manupdate -%patch14 -p1 -b .nprocfix -%patch15 -p1 -b .sudoconfman -%patch16 -p1 -b .sudoldapconfman -%patch17 -p1 -b .strictuidgid -%patch18 -p1 -b .netgrmatchtrace -%patch19 -p1 -b .sssdfixes -%patch20 -p1 -b .lbufexpandcode -%patch21 -p1 -b .cycledetect -%patch22 -p1 -b .sesh_loginshell -%patch23 -p1 -b .ipahostname -%patch24 -p1 -b .nonehostname -%patch25 -p1 -b .doublequotefix -%patch26 -p1 -b .sssdrulenames -%patch27 -p1 -b .netgrfilterfix -%patch28 -p1 -b .authinterrupt -%patch29 -p1 -b .duplicatenssfix -%patch30 -p1 -b .constwarnfix -%patch31 -p1 -b .clangfixes -%patch32 -p1 -b .authlogicfix -%patch33 -p1 -b .CVE-2014-9680 -%patch34 -p1 -b .mantypos-ldap -%patch35 -p1 -b .digest-backport -%patch36 -p1 -b .manfix-usepty -%patch37 -p1 -b .digest-backport-docs -%patch38 -p1 -b .strunquote -%patch39 -p1 -b .ldapsearchuidfix -%patch40 -p1 -b .checklinkfix -%patch41 -p1 -b .legacy-group-processing -%patch42 -p1 -b .newbase64decoder -%patch43 -p1 -b .digestmessagesfix -%patch44 -p1 -b .closefrom-override-fix -%patch45 -p1 -b .ldapusermatchfix -%patch46 -p1 -b .netgroup_tuple -%patch47 -p1 -b .pam_servicebackport -%patch48 -p1 -b .visudocontent -%patch49 -p1 -b .unprivileged-list-fix -%patch50 -p1 -b .logsudouser -%patch51 -p1 -b .sigpipefix -%patch52 -p1 -b .segfault-null-group-list -%patch53 -p1 -b .ldap_sssd_parse_whitespaces -%patch54 -p1 -b .null_exception -%patch55 -p1 -b .nproc-nowait -%patch56 -p1 -b .digest_race_doc -%patch57 -p1 -b .visudo-quiet-flag -%patch58 -p1 -b .noexec-update -%patch59 -p1 -b .tty-parsing -%patch60 -p1 -b .CVE-2017-1000368 +%patch3 -p1 -b .nowaitopt +%patch4 -p1 -b .sudoldapconfman +%patch5 -p1 -b .doublequotefix +%patch6 -p1 -b .digest-backport +%patch7 -p1 -b .ldapsearchuidfix +%patch8 -p1 -b .logsudouser +%patch9 -p1 -b .testsuite +%patch10 -p1 -b .ignoreunknowndefaults +%patch11 -p1 -b .errorwarningvisudomsg +%patch12 -p1 -b .iologflush +%patch13 -p1 -b .lookup +%patch14 -p1 -b .testsuite +%patch15 -p1 -b .fqdnafterfree +%patch16 -p1 -b .lecture +%patch17 -p1 -b .get_process_ttyname +%patch18 -p1 -b .CVE-2017-1000368 %build autoreconf -I m4 -fv --install @@ -257,6 +128,7 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" SHL --with-pam-login \ --with-editor=/bin/vi \ --with-env-editor \ + --with-gcrypt \ --with-ignore-dot \ --with-tty-tickets \ --with-ldap \ @@ -264,12 +136,13 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" SHL --with-selinux \ --with-passprompt="[sudo] password for %p: " \ --with-linux-audit \ - --with-sssd \ - --with-gcrypt + --with-sssd # --without-kerb5 \ # --without-kerb4 make +make check + %install rm -rf $RPM_BUILD_ROOT @@ -279,6 +152,7 @@ sed -i 's|/etc/ldap\.conf|%{_sysconfdir}/sudo-ldap.conf|g' README.LDAP make install DESTDIR="$RPM_BUILD_ROOT" install_uid=`id -u` install_gid=`id -g` sudoers_uid=`id -u` sudoers_gid=`id -g` chmod 755 $RPM_BUILD_ROOT%{_bindir}/* $RPM_BUILD_ROOT%{_sbindir}/* install -p -d -m 700 $RPM_BUILD_ROOT/var/db/sudo +install -p -d -m 700 $RPM_BUILD_ROOT/var/db/sudo/lectured install -p -d -m 750 $RPM_BUILD_ROOT/etc/sudoers.d install -p -c -m 0440 %{SOURCE1} $RPM_BUILD_ROOT/etc/sudoers install -p -c -m 0640 %{SOURCE3} $RPM_BUILD_ROOT/etc/sudo.conf @@ -287,6 +161,9 @@ install -p -c -m 0640 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sudo-ldap.conf # Remove execute permission on this script so we don't pull in perl deps chmod -x $RPM_BUILD_ROOT%{_docdir}/sudo-*/sudoers2ldif +#Remove all .la files +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' + %find_lang sudo %find_lang sudoers @@ -324,14 +201,20 @@ rm -rf $RPM_BUILD_ROOT %attr(0750,root,root) %dir /etc/sudoers.d/ %config(noreplace) /etc/pam.d/sudo %config(noreplace) /etc/pam.d/sudo-i +%attr(0644,root,root) %{_tmpfilesdir}/sudo.conf %dir /var/db/sudo +%dir /var/db/sudo/lectured %attr(4111,root,root) %{_bindir}/sudo -%attr(4111,root,root) %{_bindir}/sudoedit +%{_bindir}/sudoedit %attr(0111,root,root) %{_bindir}/sudoreplay %attr(0755,root,root) %{_sbindir}/visudo -%attr(0755,root,root) %{_libexecdir}/sesh -%attr(0644,root,root) %{_libexecdir}/sudo_noexec.so -%attr(0644,root,root) %{_libexecdir}/sudoers.so +%attr(0755,root,root) %{_libexecdir}/sudo/sesh +%attr(0644,root,root) %{_libexecdir}/sudo/sudo_noexec.so +%attr(0644,root,root) %{_libexecdir}/sudo/sudoers.so +%attr(0644,root,root) %{_libexecdir}/sudo/group_file.so +%attr(0644,root,root) %{_libexecdir}/sudo/system_group.so +%attr(0644,root,root) %{_libexecdir}/sudo/libsudo_util.so.?.?.? +%{_libexecdir}/sudo/libsudo_util.so.? %{_mandir}/man5/sudoers.5* %{_mandir}/man5/sudoers.ldap.5* %{_mandir}/man5/sudo-ldap.conf.5* @@ -353,20 +236,88 @@ rm -rf $RPM_BUILD_ROOT %doc plugins/sample/sample_plugin.c %{_includedir}/sudo_plugin.h %{_mandir}/man8/sudo_plugin.8* +%{_libexecdir}/sudo/libsudo_util.so %changelog -* Wed Jun 07 2017 Daniel Kopecek - 1.8.6p7-23 -- Fixes CVE-2017-1000367 - Resolves: rhbz#1459410 - -* Mon May 29 2017 Radovan Sroka - 1.8.6p7-22 -- Fixes CVE-2017-1000367 sudo: Privilege escalation in via improper get_process_ttyname() parsing [rhel-7.3.z] - Resolves: rhbz#1455401 +* Wed Jun 07 2017 Daniel Kopecek - 1.8.19p2-10 +- RHEL 7.4 erratum +- Fix CVE-2017-1000368 + Resolves: rhbz#1459411 + +* Tue Jun 06 2017 Radovan Sroka - 1.8.19p2-9 +- RHEL 7.4 erratum +- removed patch for output truncation (1454571) which introduced regression + Resolves: rhbz#1360687 + +* Thu May 25 2017 Jakub Jelen - 1.8.19p2-8 +- RHEL 7.4 erratum +- Fixes CVE-2017-1000367: Privilege escalation in via improper get_process_ttyname() parsing + Resolves: rhbz#1455402 + +* Tue May 23 2017 Daniel Kopecek - 1.8.19p2-7 +- RHEL 7.4 erratum +- added patch to fix output truncation (in some cases) when log_output + option is enabled + Resolves: rhbz#1454571 + +* Thu May 04 2017 Radovan Sroka - 1.8.19p2-6 +- RHEL 7.4 erratum +- added patch that fixes lecture option used as bolean + Resolves rhbz#1360687 + +* Tue Apr 25 2017 Radovan Sroka - 1.8.19p2-5 +- RHEL 7.4 erratum +- added doc patch about sudo lookup issue + Resolves: rhbz#1293306 +- added test suite patch + Resolves: rhbz#1360687 +- fixed use after free fqdn problem + Resolves: rhbz#1360687 + +* Tue Mar 21 2017 Tomas Sykora - 1.8.19p2-4 +- RHEL 7.4 erratum +- fixed cmnd_no_wait patch +- backported iolog_flush sudoers default + Resolves: rhbz#1369856 + Resolves: rhbz#1425853 + +* Wed Mar 08 2017 Tomas Sykora - 1.8.19p2-3 +- RHEL 7.4 eratum +- Fixes semicolon typo in digest backport patch from the previous build + Resolves: rhbz#1360687 + +* Wed Mar 08 2017 Tomas Sykora - 1.8.19p2-2 +- RHEL 7.4 erratum +- Fixes coverity scan issues created by our patches: + - fixed resource leaks and a compiler warning in digest backport patch + - removed needless code from cmnd_no_wait patch causing clang warning + - format of the last changelog message causes problems to rhpkg push, + so don't use that as a commit message + Resolves: rhbz#1360687 + +* Wed Mar 01 2017 Tomas Sykora - 1.8.19p2-1 +- RHEL 7.4 erratum + - Resolves: rhbz#1360687 - rebase to 1.8.19p2 + - Resolves: rhbz#1123526 - performance improvement + - Resolves: rhbz#1308789 - add MAIL and NOMAIL tags + - Resolves: rhbz#1348504 - sudo now parses sudoers with sudoers locale + - Resolves: rhbz#1374417 - "sudo -l command" indicated that the command + was runnable even if denied by sudoers when using LDAP or SSSD backend. + - Resolves: rhbz#1387303 - add ignore_iolog_errors option + - Resolves: rhbz#1389360 - wrong log file group ownership + - Resolves: rhbz#1389735 - add iolog_group, iolog_mode, iolog_user options + - Resolves: rhbz#1397169 - maxseq and ignore_iolog_errors options + - Resolves: rhbz#1403051 - add support for querying netgroups directly via LDAP + - Resolves: rhbz#1410086 - race condition while creating /var/log/sudo-io dir + - Resolves: rhbz#1413160 - add ignore_unknown_defaults flag + - Resolves: rhbz#1254772 - ability to export sudoers in json format + - Resolves: rhbz#1417187 - wrong reference to config file in systax error message + - Resolves: rhbz#1424575 - visudo was not printing severity of error/warning message * Wed Nov 23 2016 Daniel Kopecek - 1.8.6p7-21 - Update noexec syscall blacklist - Fixes CVE-2016-7032 and CVE-2016-7076 - Resolves: rhbz#1391939 + Resolves: rhbz#1391940 * Tue Jul 19 2016 Daniel Kopecek - 1.8.6p7-20 - RHEL 7.3 erratum