}
/*
- * Walk through search results and return TRUE if we have a command match.
+ * Walk through search results and return TRUE if we have a command match,
+ * FALSE if disallowed and UNSPEC if not matched.
*/
int
sudo_ldap_check_command(ld, entry, setenv_implied)
{
struct berval **bv, **p;
char *allowed_cmnd, *allowed_args, *val;
- int foundbang, ret = FALSE;
+ int foundbang, ret = UNSPEC;
if (!entry)
return(ret);
if (bv == NULL)
return(ret);
- for (p = bv; *p != NULL && ret >= 0; p++) {
+ for (p = bv; *p != NULL && ret != FALSE; p++) {
val = (*p)->bv_val;
/* Match against ALL ? */
if (!strcmp(val, "ALL")) {
* If allowed (no bang) set ret but keep on checking.
* If disallowed (bang), exit loop.
*/
- ret = foundbang ? -1 : TRUE;
+ ret = foundbang ? FALSE : TRUE;
}
DPRINTF(("ldap sudoCommand '%s' ... %s", val,
ret == TRUE ? "MATCH!" : "not"), 2);
ldap_value_free_len(bv); /* more cleanup */
- /* return TRUE if we found at least one ALLOW and no DENY */
- return(ret > 0);
+ return(ret);
}
/*
* like sudoers_lookup() - only LDAP style
*/
int
-sudo_ldap_lookup(nss, pwflag)
+sudo_ldap_lookup(nss, ret, pwflag)
struct sudo_nss *nss;
+ int ret;
int pwflag;
{
LDAP *ld = (LDAP *) nss->handle;
- LDAPMessage *entry = NULL, *result = NULL; /* used for searches */
- char *filt; /* used to parse attributes */
- int do_netgr, rc, ret; /* temp/final return values */
+ LDAPMessage *entry = NULL, *result = NULL;
+ char *filt;
+ int do_netgr, rc, matched;
int setenv_implied;
- int ldap_user_matches = FALSE, ldap_host_matches = FALSE; /* flags */
+ int ldap_user_matches = FALSE, ldap_host_matches = FALSE;
struct passwd *pw = list_pw ? list_pw : sudo_user.pw;
if (ld == NULL)
- return(VALIDATE_NOT_OK | FLAG_NO_HOST | FLAG_NO_USER);
+ return(ret);
if (pwflag) {
int doauth = UNSPEC;
enum def_tupple pwcheck =
(pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
- for (ret = 0, do_netgr = 0; !ret && do_netgr < 2; do_netgr++) {
+ for (matched = 0, do_netgr = 0; !matched && do_netgr < 2; do_netgr++) {
filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
NULL, 0, NULL, NULL, NULL, -1, &result);
if (user_uid == 0 || list_pw == NULL ||
user_uid == list_pw->pw_uid ||
sudo_ldap_check_command(ld, entry, NULL)) {
- ret = 1;
+ matched = 1;
break; /* end foreach */
}
}
ldap_msgfree(result);
result = NULL;
}
- if (ret || user_uid == 0) {
- ret = VALIDATE_OK;
+ if (matched || user_uid == 0) {
+ SET(ret, VALIDATE_OK);
+ CLR(ret, VALIDATE_NOT_OK);
if (def_authenticate) {
switch (pwcheck) {
case always:
* try to match them against the username.
*/
setenv_implied = FALSE;
- for (ret = 0, do_netgr = 0; !ret && do_netgr < 2; do_netgr++) {
+ for (matched = 0, do_netgr = 0; !matched && do_netgr < 2; do_netgr++) {
filt = do_netgr ? estrdup("sudoUser=+*") : sudo_ldap_build_pass1(pw);
DPRINTF(("ldap search '%s'", filt), 1);
rc = ldap_search_ext_s(ld, ldap_conf.base, LDAP_SCOPE_SUBTREE, filt,
sudo_ldap_check_host(ld, entry) &&
/* remember that host matched */
(ldap_host_matches = TRUE) &&
- /* verify command match */
- sudo_ldap_check_command(ld, entry, &setenv_implied) &&
/* verify runas match */
- sudo_ldap_check_runas(ld, entry)
+ sudo_ldap_check_runas(ld, entry) &&
+ /* verify command match */
+ (rc = sudo_ldap_check_command(ld, entry, &setenv_implied)) != UNSPEC
) {
/* We have a match! */
- DPRINTF(("Perfect Match!"), 1);
- /* pick up any options */
- if (setenv_implied)
- def_setenv = TRUE;
- sudo_ldap_parse_options(ld, entry);
- /* make sure we don't reenter loop */
- ret = VALIDATE_OK;
+ DPRINTF(("Command %sallowed", rc == TRUE ? "" : "NOT "), 1);
+ matched = TRUE;
+ if (rc == TRUE) {
+ /* pick up any options */
+ if (setenv_implied)
+ def_setenv = TRUE;
+ sudo_ldap_parse_options(ld, entry);
+ /* make sure we don't reenter loop */
+ SET(ret, VALIDATE_OK);
+ CLR(ret, VALIDATE_NOT_OK);
+ } else {
+ SET(ret, VALIDATE_NOT_OK);
+ CLR(ret, VALIDATE_OK);
+ }
/* break from inside for loop */
break;
}
if (!ISSET(ret, VALIDATE_OK)) {
/* we do not have a match */
- ret = VALIDATE_NOT_OK;
if (pwflag && list_pw == NULL)
SET(ret, FLAG_NO_CHECK);
- else if (!ldap_user_matches)
- SET(ret, FLAG_NO_USER);
- else if (!ldap_host_matches)
- SET(ret, FLAG_NO_HOST);
}
+ if (ldap_user_matches)
+ CLR(ret, FLAG_NO_USER);
+ if (ldap_host_matches)
+ CLR(ret, FLAG_NO_HOST);
DPRINTF(("sudo_ldap_lookup(%d)=0x%02x", pwflag, ret), 1);
return(ret);
* allowed to run the specified command on this host as the target user.
*/
int
-sudo_file_lookup(nss, pwflag)
+sudo_file_lookup(nss, validated, pwflag)
struct sudo_nss *nss;
+ int validated;
int pwflag;
{
- int validated, match, host_match, runas_match, cmnd_match;
+ int match, host_match, runas_match, cmnd_match;
struct cmndspec *cs;
struct cmndtag *tags = NULL;
struct privilege *priv;
struct userspec *us;
- /* Assume the worst. */
- validated = VALIDATE_NOT_OK | FLAG_NO_HOST | FLAG_NO_USER;
-
if (nss->handle == NULL)
return(validated);
matched_pseudo:
if (match == ALLOW || user_uid == 0) {
/* User has an entry for this host. */
- CLR(validated, VALIDATE_NOT_OK);
SET(validated, VALIDATE_OK);
- }
+ } else if (match == DENY)
+ SET(validated, VALIDATE_NOT_OK);
if (pwcheck == always && def_authenticate)
SET(validated, FLAG_CHECK_USER);
else if (pwcheck == never || nopass == TRUE)
}
matched2:
if (match == ALLOW) {
- CLR(validated, VALIDATE_NOT_OK);
SET(validated, VALIDATE_OK);
+ CLR(validated, VALIDATE_NOT_OK);
if (tags != NULL) {
if (tags->nopasswd != UNSPEC)
def_authenticate = !tags->nopasswd;
if (tags->setenv != UNSPEC)
def_setenv = tags->setenv;
}
+ } else if (match == DENY) {
+ SET(validated, VALIDATE_NOT_OK);
+ CLR(validated, VALIDATE_OK);
}
set_perms(PERM_ROOT);
return(validated);
char **argv;
char **envp;
{
- int sources = 0, validated = 0;
+ int sources = 0, validated;
int fd, cmnd_status, sudo_mode, pwflag, rc = 0;
sigaction_t sa;
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
cmnd_status = set_cmnd(sudo_mode);
+ validated = FLAG_NO_USER | FLAG_NO_HOST;
tq_foreach_fwd(snl, nss) {
- rc = nss->lookup(nss, pwflag);
+ validated = nss->lookup(nss, validated, pwflag);
- /* XXX - rethink this logic */
- if (validated == 0 || ISSET(rc, VALIDATE_OK))
- validated = rc;
- else if (ISSET(rc, VALIDATE_NOT_OK) && ISSET(validated, VALIDATE_NOT_OK))
- validated |= rc;
+/*
+ VALIDATE_OK
+ VALIDATE_NOT_OK
+ FLAG_CHECK_USER
+ FLAG_NO_USER
+ FLAG_NO_HOST
+ FLAG_NO_CHECK
+*/
/* Handle [NOTFOUND=return] */
- if (!ISSET(rc, VALIDATE_OK) && nss->ret_notfound)
+ /* XXX - no longer a valid check due to inheriting validated */
+ if (!ISSET(validated, VALIDATE_OK) && nss->ret_notfound)
break;
}
if (safe_cmnd == NULL)
NewArgv[0] = "sh";
NewArgv[1] = safe_cmnd;
execv(_PATH_BSHELL, NewArgv);
- }
- warning("unable to execute %s", safe_cmnd);
+ } warning("unable to execute %s", safe_cmnd);
exit(127);
} else if (ISSET(validated, FLAG_NO_USER) || (validated & FLAG_NO_HOST)) {
log_auth(validated, 1);
exit(1);
- } else if (ISSET(validated, VALIDATE_NOT_OK)) {
+ } else {
if (def_path_info) {
/*
* We'd like to not leak path info at all here, but that can
log_auth(validated, 1);
}
exit(1);
- } else {
- /* should never get here */
- log_auth(validated, 1);
- exit(1);
}
exit(0); /* not reached */
}
int sudo_ldap_open __P((struct sudo_nss *));
int sudo_ldap_close __P((struct sudo_nss *));
int sudo_ldap_setdefs __P((struct sudo_nss *));
-int sudo_ldap_lookup __P((struct sudo_nss *, int));
+int sudo_ldap_lookup __P((struct sudo_nss *, int, int));
int sudo_ldap_parse __P((struct sudo_nss *));
void sudo_ldap_display_privs __P((struct sudo_nss *, struct passwd *));
int sudo_ldap_display_cmnd __P((struct sudo_nss *, struct passwd *));
int sudo_file_open __P((struct sudo_nss *));
int sudo_file_close __P((struct sudo_nss *));
int sudo_file_setdefs __P((struct sudo_nss *));
-int sudo_file_lookup __P((struct sudo_nss *, int));
+int sudo_file_lookup __P((struct sudo_nss *, int, int));
int sudo_file_parse __P((struct sudo_nss *));
void sudo_file_display_privs __P((struct sudo_nss *, struct passwd *));
int sudo_file_display_cmnd __P((struct sudo_nss *, struct passwd *));