示例#1
0
int
main(int argc, char *argv[])
{
    unsigned int lineno = 0;
    size_t linesize = 0;
    char *line = NULL;

    while (sudo_parseln(&line, &linesize, &lineno, stdin) != -1)
	printf("%6u\t%s\n", lineno, line);
    free(line);
    exit(0);
}
示例#2
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;
}
示例#3
0
/*
 * Read in /etc/environment ala AIX and Linux.
 * Lines may be in either of three formats:
 *  NAME=VALUE
 *  NAME="VALUE"
 *  NAME='VALUE'
 * with an optional "export" prefix so the shell can source the file.
 * Invalid lines, blank lines, or lines consisting solely of a comment
 * character are skipped.
 */
void
read_env_file(const char *path, int overwrite)
{
    FILE *fp;
    char *cp, *var, *val;
    size_t var_len, val_len;

    if ((fp = fopen(path, "r")) == NULL)
	return;

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

	/* Skip optional "export " */
	if (strncmp(var, "export", 6) == 0 && isspace((unsigned char) var[6])) {
	    var += 7;
	    while (isspace((unsigned char) *var)) {
		var++;
	    }
	}

	/* Must be of the form name=["']value['"] */
	for (val = var; *val != '\0' && *val != '='; val++)
	    ;
	if (var == val || *val != '=')
	    continue;
	var_len = (size_t)(val - var);
	val_len = strlen(++val);

	/* Strip leading and trailing single/double quotes */
	if ((val[0] == '\'' || val[0] == '\"') && val[0] == val[val_len - 1]) {
	    val[val_len - 1] = '\0';
	    val++;
	    val_len -= 2;
	}

	cp = emalloc(var_len + 1 + val_len + 1);
	memcpy(cp, var, var_len + 1); /* includes '=' */
	memcpy(cp + var_len + 1, val, val_len + 1); /* includes NUL */

	sudo_putenv(cp, TRUE, overwrite);
    }
    fclose(fp);
}
/*
 * Read in /etc/nsswitch.conf
 * Returns a tail queue of matches.
 */
struct sudo_nss_list *
sudo_read_nss(void)
{
    FILE *fp;
    char *cp, *line = NULL;
    size_t linesize = 0;
#ifdef HAVE_SSSD
    bool saw_sss = false;
#endif
    bool saw_files = false;
    bool saw_ldap = false;
    bool got_match = false;
    static struct sudo_nss_list snl = TAILQ_HEAD_INITIALIZER(snl);
    debug_decl(sudo_read_nss, SUDO_DEBUG_NSS)

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

    while (sudo_parseln(&line, &linesize, NULL, fp) != -1) {
	/* Skip blank or comment lines */
	if (*line == '\0')
	    continue;

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

	/* Parse line */
	for ((cp = strtok(line + 8, " \t")); cp != NULL; (cp = strtok(NULL, " \t"))) {
	    if (strcasecmp(cp, "files") == 0 && !saw_files) {
		TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
		got_match = true;
#ifdef HAVE_LDAP
	    } else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
		TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries);
		got_match = true;
#endif
#ifdef HAVE_SSSD
	    } else if (strcasecmp(cp, "sss") == 0 && !saw_sss) {
		TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries);
		got_match = true;
#endif
	    } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
		/* NOTFOUND affects the most recent entry */
		TAILQ_LAST(&snl, sudo_nss_list)->ret_if_notfound = true;
		got_match = false;
	    } else if (strcasecmp(cp, "[SUCCESS=return]") == 0 && got_match) {
		/* SUCCESS affects the most recent entry */
		TAILQ_LAST(&snl, sudo_nss_list)->ret_if_found = true;
		got_match = false;
	    } else
		got_match = false;
	}
	/* Only parse the first "sudoers:" line */
	break;
    }
    free(line);
    fclose(fp);

nomatch:
    /* Default to files only if no matches */
    if (TAILQ_EMPTY(&snl))
	TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);

    debug_return_ptr(&snl);
}
/*
 * 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, *line = NULL;
    size_t linesize = 0;
#ifdef HAVE_SSSD
    bool saw_sss = false;
#endif
    bool saw_files = false;
    bool saw_ldap = false;
    bool got_match = false;
    static struct sudo_nss_list snl = TAILQ_HEAD_INITIALIZER(snl);
    debug_decl(sudo_read_nss, SUDO_DEBUG_NSS)

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

    while (sudo_parseln(&line, &linesize, NULL, fp) != -1) {
	/* Skip blank or comment lines */
	if (*(cp = line) == '\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')) {
		TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
		got_match = true;
		ep = &cp[5];
#ifdef HAVE_LDAP
	    } else if (!saw_ldap && strncasecmp(cp, "ldap", 4) == 0 &&
		(isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
		TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries);
		got_match = 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')) {
		TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries);
		got_match = true;
		ep = &cp[3];
#endif
	    } 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')) {
		    TAILQ_LAST(&snl, sudo_nss_list)->ret_if_found = true;
		}
	    }
	}
	/* Only parse the first "sudoers" line */
	break;
    }
    fclose(fp);

nomatch:
    /* Default to files only if no matches */
    if (TAILQ_EMPTY(&snl))
	TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);

    debug_return_ptr(&snl);
}
示例#6
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;
}
示例#7
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;
}