Add support for parsing base64-encoded attributes
This commit is contained in:
2
MANIFEST
2
MANIFEST
@@ -429,6 +429,8 @@ plugins/sudoers/regress/cvtsudoers/test23.out.ok
|
|||||||
plugins/sudoers/regress/cvtsudoers/test23.sh
|
plugins/sudoers/regress/cvtsudoers/test23.sh
|
||||||
plugins/sudoers/regress/cvtsudoers/test24.out.ok
|
plugins/sudoers/regress/cvtsudoers/test24.out.ok
|
||||||
plugins/sudoers/regress/cvtsudoers/test24.sh
|
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.out.ok
|
||||||
plugins/sudoers/regress/cvtsudoers/test3.sh
|
plugins/sudoers/regress/cvtsudoers/test3.sh
|
||||||
plugins/sudoers/regress/cvtsudoers/test4.out.ok
|
plugins/sudoers/regress/cvtsudoers/test4.out.ok
|
||||||
|
@@ -27,7 +27,6 @@
|
|||||||
#endif /* HAVE_STRINGS_H */
|
#endif /* HAVE_STRINGS_H */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "sudoers.h"
|
#include "sudoers.h"
|
||||||
#include "sudo_ldap.h"
|
#include "sudo_ldap.h"
|
||||||
@@ -580,6 +579,46 @@ sudo_role_alloc(void)
|
|||||||
debug_return_ptr(role);
|
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
|
* Allocate a struct cvtsudoers_string, store str in it and
|
||||||
* insert into the specified strlist.
|
* 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;
|
struct cvtsudoers_string *ls;
|
||||||
debug_decl(ldif_store_string, SUDOERS_DEBUG_UTIL)
|
debug_decl(ldif_store_string, SUDOERS_DEBUG_UTIL)
|
||||||
|
|
||||||
while (isblank((unsigned char)*str))
|
|
||||||
str++;
|
|
||||||
if ((ls = cvtsudoers_string_alloc(str)) == NULL) {
|
if ((ls = cvtsudoers_string_alloc(str)) == NULL) {
|
||||||
sudo_fatalx(U_("%s: %s"), __func__,
|
sudo_fatalx(U_("%s: %s"), __func__,
|
||||||
U_("unable to allocate memory"));
|
U_("unable to allocate memory"));
|
||||||
@@ -966,8 +1003,7 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
|
|||||||
unsigned numroles = 0;
|
unsigned numroles = 0;
|
||||||
bool in_role = false;
|
bool in_role = false;
|
||||||
size_t linesize = 0;
|
size_t linesize = 0;
|
||||||
char *line = NULL;
|
char *attr, *line = NULL, *savedline = NULL;
|
||||||
char *savedline = NULL;
|
|
||||||
ssize_t savedlen = 0;
|
ssize_t savedlen = 0;
|
||||||
bool mismatch = false;
|
bool mismatch = false;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
@@ -1085,32 +1121,28 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
|
|||||||
if (strncasecmp(line, "dn:", 3) == 0) {
|
if (strncasecmp(line, "dn:", 3) == 0) {
|
||||||
/* Compare dn to base, if specified. */
|
/* Compare dn to base, if specified. */
|
||||||
if (conf->sudoers_base != NULL) {
|
if (conf->sudoers_base != NULL) {
|
||||||
char *cp = line + 3;
|
attr = ldif_parse_attribute(line + 3);
|
||||||
while (isblank((unsigned char)*cp))
|
|
||||||
cp++;
|
|
||||||
/* Skip over cn if present. */
|
/* Skip over cn if present. */
|
||||||
if (strncasecmp(cp, "cn=", 3) == 0) {
|
if (strncasecmp(attr, "cn=", 3) == 0) {
|
||||||
for (cp += 3; *cp != '\0'; cp++) {
|
for (attr += 3; *attr != '\0'; attr++) {
|
||||||
/* Handle escaped ',' chars. */
|
/* Handle escaped ',' chars. */
|
||||||
if (*cp == '\\')
|
if (*attr == '\\')
|
||||||
cp++;
|
attr++;
|
||||||
if (*cp == ',') {
|
if (*attr == ',') {
|
||||||
cp++;
|
attr++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strcasecmp(cp, conf->sudoers_base) != 0) {
|
if (strcasecmp(attr, conf->sudoers_base) != 0) {
|
||||||
/* Doesn't match base, skip the rest of it. */
|
/* Doesn't match base, skip the rest of it. */
|
||||||
mismatch = true;
|
mismatch = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (strncmp(line, "objectClass:", 12) == 0) {
|
} else if (strncmp(line, "objectClass:", 12) == 0) {
|
||||||
char *cp = line + 12;
|
attr = ldif_parse_attribute(line + 12);
|
||||||
while (isblank((unsigned char)*cp))
|
if (strcmp(attr, "sudoRole") == 0)
|
||||||
cp++;
|
|
||||||
if (strcmp(cp, "sudoRole") == 0)
|
|
||||||
in_role = true;
|
in_role = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1120,50 +1152,52 @@ parse_ldif(const char *input_file, struct cvtsudoers_config *conf)
|
|||||||
|
|
||||||
/* Part of a sudoRole, parse it. */
|
/* Part of a sudoRole, parse it. */
|
||||||
if (strncmp(line, "cn:", 3) == 0) {
|
if (strncmp(line, "cn:", 3) == 0) {
|
||||||
char *cp = line + 3;
|
attr = ldif_parse_attribute(line + 3);
|
||||||
while (isblank((unsigned char)*cp))
|
|
||||||
cp++;
|
|
||||||
free(role->cn);
|
free(role->cn);
|
||||||
role->cn = unquote_cn(cp);
|
role->cn = unquote_cn(attr);
|
||||||
if (role->cn == NULL) {
|
if (role->cn == NULL) {
|
||||||
sudo_fatalx(U_("%s: %s"), __func__,
|
sudo_fatalx(U_("%s: %s"), __func__,
|
||||||
U_("unable to allocate memory"));
|
U_("unable to allocate memory"));
|
||||||
}
|
}
|
||||||
} else if (strncmp(line, "sudoUser:", 9) == 0) {
|
} 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) {
|
} 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) {
|
} 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) {
|
} 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) {
|
} 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) {
|
} 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) {
|
} 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) {
|
} else if (strncmp(line, "sudoOrder:", 10) == 0) {
|
||||||
char *ep, *cp = line + 10;
|
char *ep;
|
||||||
role->order = strtod(cp, &ep);
|
attr = ldif_parse_attribute(line + 10);
|
||||||
if (ep == cp || *ep != '\0')
|
role->order = strtod(attr, &ep);
|
||||||
sudo_warnx(U_("invalid sudoOrder attribute: %s"), cp);
|
if (ep == attr || *ep != '\0')
|
||||||
|
sudo_warnx(U_("invalid sudoOrder attribute: %s"), attr);
|
||||||
} else if (strncmp(line, "sudoNotBefore:", 14) == 0) {
|
} else if (strncmp(line, "sudoNotBefore:", 14) == 0) {
|
||||||
char *cp = line + 14;
|
attr = ldif_parse_attribute(line + 14);
|
||||||
while (isblank((unsigned char)*cp))
|
|
||||||
cp++;
|
|
||||||
free(role->notbefore);
|
free(role->notbefore);
|
||||||
role->notbefore = strdup(cp);
|
role->notbefore = strdup(attr);
|
||||||
if (role->notbefore == NULL) {
|
if (role->notbefore == NULL) {
|
||||||
sudo_fatalx(U_("%s: %s"), __func__,
|
sudo_fatalx(U_("%s: %s"), __func__,
|
||||||
U_("unable to allocate memory"));
|
U_("unable to allocate memory"));
|
||||||
}
|
}
|
||||||
} else if (strncmp(line, "sudoNotAfter:", 13) == 0) {
|
} else if (strncmp(line, "sudoNotAfter:", 13) == 0) {
|
||||||
char *cp = line + 13;
|
attr = ldif_parse_attribute(line + 13);
|
||||||
while (isblank((unsigned char)*cp))
|
|
||||||
cp++;
|
|
||||||
free(role->notafter);
|
free(role->notafter);
|
||||||
role->notafter = strdup(cp);
|
role->notafter = strdup(attr);
|
||||||
if (role->notafter == NULL) {
|
if (role->notafter == NULL) {
|
||||||
sudo_fatalx(U_("%s: %s"), __func__,
|
sudo_fatalx(U_("%s: %s"), __func__,
|
||||||
U_("unable to allocate memory"));
|
U_("unable to allocate memory"));
|
||||||
|
31
plugins/sudoers/regress/cvtsudoers/test25.out.ok
Normal file
31
plugins/sudoers/regress/cvtsudoers/test25.out.ok
Normal file
@@ -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
|
||||||
|
|
52
plugins/sudoers/regress/cvtsudoers/test25.sh
Executable file
52
plugins/sudoers/regress/cvtsudoers/test25.sh
Executable file
@@ -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
|
Reference in New Issue
Block a user