]> granicus.if.org Git - sudo/commitdiff
Add support for parsing base64-encoded attributes
authorTodd C. Miller <Todd.Miller@sudo.ws>
Fri, 18 May 2018 16:11:51 +0000 (10:11 -0600)
committerTodd C. Miller <Todd.Miller@sudo.ws>
Fri, 18 May 2018 16:11:51 +0000 (10:11 -0600)
MANIFEST
plugins/sudoers/cvtsudoers_ldif.c
plugins/sudoers/regress/cvtsudoers/test25.out.ok [new file with mode: 0644]
plugins/sudoers/regress/cvtsudoers/test25.sh [new file with mode: 0755]

index 88a6d9b20c2e0f55822ce0366de236fa17000636..49e5f573bfba4b4b6420328d93d891445b4204ed 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -429,6 +429,8 @@ plugins/sudoers/regress/cvtsudoers/test23.out.ok
 plugins/sudoers/regress/cvtsudoers/test23.sh
 plugins/sudoers/regress/cvtsudoers/test24.out.ok
 plugins/sudoers/regress/cvtsudoers/test24.sh
+plugins/sudoers/regress/cvtsudoers/test25.out.ok
+plugins/sudoers/regress/cvtsudoers/test25.sh
 plugins/sudoers/regress/cvtsudoers/test3.out.ok
 plugins/sudoers/regress/cvtsudoers/test3.sh
 plugins/sudoers/regress/cvtsudoers/test4.out.ok
index 973d240b8f92207030c4599d42e1a0505b03d1fd..f56c11a02a02ae7e7a6b190e4b8ab911a0b35ee1 100644 (file)
@@ -27,7 +27,6 @@
 #endif /* HAVE_STRINGS_H */
 #include <unistd.h>
 #include <stdarg.h>
-#include <ctype.h>
 
 #include "sudoers.h"
 #include "sudo_ldap.h"
@@ -580,6 +579,46 @@ sudo_role_alloc(void)
     debug_return_ptr(role);
 }
 
+/*
+ * Parse an LDIF attribute, including base64 support.
+ * See http://www.faqs.org/rfcs/rfc2849.html
+ */
+static char *
+ldif_parse_attribute(char *str)
+{
+    bool encoded = false;
+    char *attr, *ep;
+    size_t len;
+    debug_decl(ldif_parse_attribute, SUDOERS_DEBUG_UTIL)
+
+    /* Check for foo:: base64str. */
+    if (*str == ':') {
+       encoded = true;
+       str++;
+    }
+
+    /* Trim leading and trailing space. */
+    while (*str == ' ')
+       str++;
+
+    ep = str + strlen(str);
+    while (ep > str && ep[-1] == ' ') {
+       /* Don't trim ecaped trailing space if not base64. */
+       if (!encoded && ep != str && ep[-2] == '\\')
+           break;
+       *--ep = '\0';
+    }
+
+    attr = str;
+    if (encoded) {
+       /* decode base64 inline and NUL-terminate */
+       len = base64_decode(str, attr, strlen(str));
+       attr[len] = '\0';
+    }
+
+    debug_return_str(attr);
+}
+
 /*
  * Allocate a struct cvtsudoers_string, store str in it and
  * insert into the specified strlist.
@@ -590,8 +629,6 @@ ldif_store_string(const char *str, struct cvtsudoers_str_list *strlist, bool sor
     struct cvtsudoers_string *ls;
     debug_decl(ldif_store_string, SUDOERS_DEBUG_UTIL)
 
-    while (isblank((unsigned char)*str))
-       str++;
     if ((ls = cvtsudoers_string_alloc(str)) == NULL) {
        sudo_fatalx(U_("%s: %s"), __func__,
            U_("unable to allocate memory"));
@@ -966,8 +1003,7 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
     unsigned numroles = 0;
     bool in_role = false;
     size_t linesize = 0;
-    char *line = NULL;
-    char *savedline = NULL;
+    char *attr, *line = NULL, *savedline = NULL;
     ssize_t savedlen = 0;
     bool mismatch = false;
     FILE *fp;
@@ -1085,32 +1121,28 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
        if (strncasecmp(line, "dn:", 3) == 0) {
            /* Compare dn to base, if specified. */
            if (conf->sudoers_base != NULL) {
-               char *cp = line + 3;
-               while (isblank((unsigned char)*cp))
-                   cp++;
+               attr = ldif_parse_attribute(line + 3);
                /* Skip over cn if present. */
-               if (strncasecmp(cp, "cn=", 3) == 0) {
-                   for (cp += 3; *cp != '\0'; cp++) {
+               if (strncasecmp(attr, "cn=", 3) == 0) {
+                   for (attr += 3; *attr != '\0'; attr++) {
                        /* Handle escaped ',' chars. */
-                       if (*cp == '\\')
-                           cp++;
-                       if (*cp == ',') {
-                           cp++;
+                       if (*attr == '\\')
+                           attr++;
+                       if (*attr == ',') {
+                           attr++;
                            break;
                        }
                    }
                }
-               if (strcasecmp(cp, conf->sudoers_base) != 0) {
+               if (strcasecmp(attr, conf->sudoers_base) != 0) {
                    /* Doesn't match base, skip the rest of it. */
                    mismatch = true;
                    continue;
                }
            }
        } else if (strncmp(line, "objectClass:", 12) == 0) {
-           char *cp = line + 12;
-           while (isblank((unsigned char)*cp))
-               cp++;
-           if (strcmp(cp, "sudoRole") == 0)
+           attr = ldif_parse_attribute(line + 12);
+           if (strcmp(attr, "sudoRole") == 0)
                in_role = true;
        }
 
@@ -1120,50 +1152,52 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
 
        /* Part of a sudoRole, parse it. */
        if (strncmp(line, "cn:", 3) == 0) {
-           char *cp = line + 3;
-           while (isblank((unsigned char)*cp))
-               cp++;
+           attr = ldif_parse_attribute(line + 3);
            free(role->cn);
-           role->cn = unquote_cn(cp);
+           role->cn = unquote_cn(attr);
            if (role->cn == NULL) {
                sudo_fatalx(U_("%s: %s"), __func__,
                    U_("unable to allocate memory"));
            }
        } else if (strncmp(line, "sudoUser:", 9) == 0) {
-           ldif_store_string(line + 9, role->users, true);
+           attr = ldif_parse_attribute(line + 9);
+           ldif_store_string(attr, role->users, true);
        } else if (strncmp(line, "sudoHost:", 9) == 0) {
-           ldif_store_string(line + 9, role->hosts, true);
+           attr = ldif_parse_attribute(line + 9);
+           ldif_store_string(attr, role->hosts, true);
        } else if (strncmp(line, "sudoRunAs:", 10) == 0) {
-           ldif_store_string(line + 10, role->runasusers, true);
+           attr = ldif_parse_attribute(line + 10);
+           ldif_store_string(attr, role->runasusers, true);
        } else if (strncmp(line, "sudoRunAsUser:", 14) == 0) {
-           ldif_store_string(line + 14, role->runasusers, true);
+           attr = ldif_parse_attribute(line + 14);
+           ldif_store_string(attr, role->runasusers, true);
        } else if (strncmp(line, "sudoRunAsGroup:", 15) == 0) {
-           ldif_store_string(line + 15, role->runasgroups, true);
+           attr = ldif_parse_attribute(line + 15);
+           ldif_store_string(attr, role->runasgroups, true);
        } else if (strncmp(line, "sudoCommand:", 12) == 0) {
-           ldif_store_string(line + 12, role->cmnds, false);
+           attr = ldif_parse_attribute(line + 12);
+           ldif_store_string(attr, role->cmnds, false);
        } else if (strncmp(line, "sudoOption:", 11) == 0) {
-           ldif_store_string(line + 11, role->options, false);
+           attr = ldif_parse_attribute(line + 11);
+           ldif_store_string(attr, role->options, false);
        } else if (strncmp(line, "sudoOrder:", 10) == 0) {
-           char *ep, *cp = line + 10;
-           role->order = strtod(cp, &ep);
-           if (ep == cp || *ep != '\0')
-               sudo_warnx(U_("invalid sudoOrder attribute: %s"), cp);
+           char *ep;
+           attr = ldif_parse_attribute(line + 10);
+           role->order = strtod(attr, &ep);
+           if (ep == attr || *ep != '\0')
+               sudo_warnx(U_("invalid sudoOrder attribute: %s"), attr);
        } else if (strncmp(line, "sudoNotBefore:", 14) == 0) {
-           char *cp = line + 14;
-           while (isblank((unsigned char)*cp))
-               cp++;
+           attr = ldif_parse_attribute(line + 14);
            free(role->notbefore);
-           role->notbefore = strdup(cp);
+           role->notbefore = strdup(attr);
            if (role->notbefore == NULL) {
                sudo_fatalx(U_("%s: %s"), __func__,
                    U_("unable to allocate memory"));
            }
        } else if (strncmp(line, "sudoNotAfter:", 13) == 0) {
-           char *cp = line + 13;
-           while (isblank((unsigned char)*cp))
-               cp++;
+           attr = ldif_parse_attribute(line + 13);
            free(role->notafter);
-           role->notafter = strdup(cp);
+           role->notafter = strdup(attr);
            if (role->notafter == NULL) {
                sudo_fatalx(U_("%s: %s"), __func__,
                    U_("unable to allocate memory"));
diff --git a/plugins/sudoers/regress/cvtsudoers/test25.out.ok b/plugins/sudoers/regress/cvtsudoers/test25.out.ok
new file mode 100644 (file)
index 0000000..d404815
--- /dev/null
@@ -0,0 +1,31 @@
+dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption: log_output
+
+dn: cn=root,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoHost: ALL
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoOption: !authenticate
+sudoCommand: ALL
+sudoOrder: 10
+
+dn: cn=%wheel,ou=SUDOers,dc=sudo,dc=ws
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoHost: +sudo-hosts
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoOption: !authenticate
+sudoCommand: ALL
+sudoOrder: 20
+
diff --git a/plugins/sudoers/regress/cvtsudoers/test25.sh b/plugins/sudoers/regress/cvtsudoers/test25.sh
new file mode 100755 (executable)
index 0000000..7d26bb9
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# Test LDAP base filtering.
+#
+
+exec 2>&1
+./cvtsudoers -c "" -i ldif -b "ou=SUDOers,dc=sudo,dc=ws" -I 10 -O 10 <<EOF
+# defaults, SUDOers, sudo.ws
+dn:: Y249ZGVmYXVsdHMsb3U9U1VET2VycyxkYz1zdWRvLGRjPXdz 
+objectClass: top
+objectClass: sudoRole
+cn: defaults
+description: Default sudoOption's go here
+sudoOption:: bG9nX291dHB1dA== 
+
+# root, SUDOers, sudo.ws
+dn::  Y249cm9vdCxvdT1TVURPZXJzLGRjPXN1ZG8sZGM9d3M=
+objectClass: top
+objectClass: sudoRole
+cn: root
+sudoUser: root
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+
+# %wheel, SUDOers, sudo.ws
+dn:: Y249JXdoZWVsLG91PVNVRE9lcnMsZGM9c3VkbyxkYz13cw==
+objectClass: top
+objectClass: sudoRole
+cn: %wheel
+sudoUser: %wheel
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: +sudo-hosts
+sudoCommand: ALL
+sudoOption: !authenticate
+sudoOrder: 10
+
+# millert, SUDOers, other-domain.com
+dn:: Y249bWlsbGVydCxvdT1TVURPZXJzLGRjPW90aGVyLWRvbWFpbixkYz1jb20=
+objectClass: top
+objectClass: sudoRole
+cn: millert
+sudoUser: millert
+sudoRunAsUser: ALL
+sudoRunAsGroup: ALL
+sudoHost: ALL
+sudoOrder: 5
+EOF