Example #1
0
/*
 * Read in /etc/nsswitch.conf
 * Returns a tail queue of matches.
 */
struct sudo_nss_list *
sudo_read_nss(void)
{
    FILE *fp;
    char *cp;
    int saw_files = FALSE;
    int saw_ldap = FALSE;
    int got_match = FALSE;
    static struct sudo_nss_list snl;

    if ((fp = fopen(_PATH_NSSWITCH_CONF, "r")) == NULL)
	goto nomatch;

    while ((cp = sudo_parseln(fp)) != NULL) {
	/* Skip blank or comment lines */
	if (*cp == '\0')
	    continue;

	/* Look for a line starting with "sudoers:" */
	if (strncasecmp(cp, "sudoers:", 8) != 0)
	    continue;

	/* Parse line */
	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;
	    } else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
		tq_append(&snl, &sudo_nss_ldap);
		got_match = TRUE;
	    } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
		/* NOTFOUND affects the most recent entry */
		tq_last(&snl)->ret_if_notfound = TRUE;
		got_match = FALSE;
	    } else
		got_match = FALSE;
	}
	/* Only parse the first "sudoers:" line */
	break;
    }
    fclose(fp);

nomatch:
    /* Default to files only if no matches */
    if (tq_empty(&snl))
	tq_append(&snl, &sudo_nss_file);

    return &snl;
}
Example #2
0
/*
 * Read in /etc/sudo.conf
 * Returns a list of plugins.
 */
static struct plugin_info_list *
sudo_read_conf(const char *conf_file)
{
    FILE *fp;
    char *cp, *name, *path;
    struct plugin_info *info;
    static struct plugin_info_list pil; /* XXX */

    if ((fp = fopen(conf_file, "r")) == NULL)
	goto done;

    while ((cp = sudo_parseln(fp)) != NULL) {
	/* Skip blank or comment lines */
	if (*cp == '\0')
	    continue;

	/* Look for a line starting with "Path" */
	if (strncasecmp(cp, "Path", 4) == 0) {
	    /* Parse line */
	    if ((name = strtok(cp + 4, " \t")) == NULL ||
		(path = strtok(NULL, " \t")) == NULL) {
		continue;
	    }
	    if (strcasecmp(name, "askpass") != 0)
		continue;
	    askpass_path = estrdup(path);
	    continue;
	}

	/* Look for a line starting with "Plugin" */
	if (strncasecmp(cp, "Plugin", 6) == 0) {
	    /* Parse line */
	    if ((name = strtok(cp + 6, " \t")) == NULL ||
		(path = strtok(NULL, " \t")) == NULL) {
		continue;
	    }
	    info = emalloc(sizeof(*info));
	    info->symbol_name = estrdup(name);
	    info->path = estrdup(path);
	    info->prev = info;
	    info->next = NULL;
	    tq_append(&pil, info);
	    continue;
	}
    }
    fclose(fp);

done:
    if (tq_empty(&pil)) {
	/* Default policy plugin */
	info = emalloc(sizeof(*info));
	info->symbol_name = "sudoers_policy";
	info->path = SUDOERS_PLUGIN;
	info->prev = info;
	info->next = NULL;
	tq_append(&pil, info);

	/* Default I/O plugin */
	info = emalloc(sizeof(*info));
	info->symbol_name = "sudoers_io";
	info->path = SUDOERS_PLUGIN;
	info->prev = info;
	info->next = NULL;
	tq_append(&pil, info);
    }

    return &pil;
}
Example #3
0
/*
 * Read in /etc/netsvc.conf (like nsswitch.conf on AIX)
 * Returns a tail queue of matches.
 */
struct sudo_nss_list *
sudo_read_nss(void)
{
    FILE *fp;
    char *cp, *ep;
    int saw_files = FALSE;
    int saw_ldap = FALSE;
    int got_match = FALSE;
    static struct sudo_nss_list snl;

    if ((fp = fopen(_PATH_NETSVC_CONF, "r")) == NULL)
	goto nomatch;

    while ((cp = sudo_parseln(fp)) != NULL) {
	/* Skip blank or comment lines */
	if (*cp == '\0')
	    continue;

	/* Look for a line starting with "sudoers = " */
	if (strncasecmp(cp, "sudoers", 7) != 0)
	    continue;
	cp += 7;
	while (isspace((unsigned char)*cp))
	    cp++;
	if (*cp++ != '=')
	    continue;

	/* Parse line */
	for ((cp = strtok(cp, ",")); cp != NULL; (cp = strtok(NULL, ","))) {
	    /* Trim leading whitespace. */
	    while (isspace((unsigned char)*cp))
		cp++;

	    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;
		ep = &cp[5];
	    } 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;
		ep = &cp[4];
	    } else {
		got_match = FALSE;
	    }

	    /* check for = auth qualifier */
	    if (got_match && *ep) {
		cp = ep;
		while (isspace((unsigned char)*cp) || *cp == '=')
		    cp++;
		if (strncasecmp(cp, "auth", 4) == 0 &&
		    (isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
		    tq_last(&snl)->ret_if_found = TRUE;
		}
	    }
	}
	/* Only parse the first "sudoers" line */
	break;
    }
    fclose(fp);

nomatch:
    /* Default to files only if no matches */
    if (tq_empty(&snl))
	tq_append(&snl, &sudo_nss_file);

    return &snl;
}
Example #4
0
File: match.c Project: CVi/sudo
/*
 * 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, struct member_list *group_list)
{
    struct member *m;
    struct alias *a;
    int rval;
    int user_matched = UNSPEC;
    int group_matched = UNSPEC;

    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))
            return userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw);

        tq_foreach_rev(user_list, m) {
            switch (m->type) {
            case ALL:
                user_matched = !m->negated;
                break;
            case NETGROUP:
                if (netgr_matches(m->name, NULL, NULL, runas_pw->pw_name))
                    user_matched = !m->negated;
                break;
            case USERGROUP:
                if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
                    user_matched = !m->negated;
                break;
            case ALIAS:
                if ((a = alias_find(m->name, RUNASALIAS)) != NULL) {
                    rval = _runaslist_matches(&a->members, &empty);
                    if (rval != UNSPEC)
                        user_matched = m->negated ? !rval : rval;
                    break;
                }
            /* FALLTHROUGH */
            case WORD:
                if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
                    user_matched = !m->negated;
                break;
            }
            if (user_matched != UNSPEC)
                break;
        }
    }

    if (runas_gr != NULL) {
        if (user_matched == UNSPEC) {
            if (runas_pw == NULL || strcmp(runas_pw->pw_name, user_name) == 0)
                user_matched = ALLOW;	/* only changing group */
        }
        tq_foreach_rev(group_list, m) {
            switch (m->type) {
            case ALL:
                group_matched = !m->negated;
                break;
            case ALIAS:
                if ((a = alias_find(m->name, RUNASALIAS)) != NULL) {
                    rval = _runaslist_matches(&a->members, &empty);
                    if (rval != UNSPEC)
                        group_matched = m->negated ? !rval : rval;
                    break;
                }
            /* FALLTHROUGH */
            case WORD:
                if (group_matches(m->name, runas_gr))
                    group_matched = !m->negated;
                break;
            }
            if (group_matched != UNSPEC)
                break;
        }
        if (group_matched == UNSPEC) {
            if (runas_pw != NULL && runas_pw->pw_gid == runas_gr->gr_gid)
                group_matched = ALLOW;	/* runas group matches passwd db */
        }
    }

    if (user_matched == DENY || group_matched == DENY)
        return DENY;
    if (user_matched == group_matched || runas_gr == NULL)
        return user_matched;
    return UNSPEC;
}