Beispiel #1
0
struct passwd *
getpwent(void)
{
    static struct passwd pw;
    static char pwbuf[LINE_MAX];
    size_t len;
    id_t id;
    char *cp, *colon;
    const char *errstr;

next_entry:
    if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
	return NULL;

    memset(&pw, 0, sizeof(pw));
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    pw.pw_name = cp;
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    pw.pw_passwd = cp;
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    id = sudo_strtoid(cp, NULL, NULL, &errstr);
    if (errstr != NULL)
	goto next_entry;
    pw.pw_uid = (uid_t)id;
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    id = sudo_strtoid(cp, NULL, NULL, &errstr);
    if (errstr != NULL)
	goto next_entry;
    pw.pw_gid = (gid_t)id;
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    pw.pw_gecos = cp;
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    pw.pw_dir = cp;
    pw.pw_shell = colon;
    len = strlen(colon);
    if (len > 0 && colon[len - 1] == '\n')
	colon[len - 1] = '\0';
    return &pw;
}
Beispiel #2
0
/*
 * Returns true if "user" is a member of "group", else false.
 */
static int
sysgroup_query(const char *user, const char *group, const struct passwd *pwd)
{
    char **member;
    struct group *grp;

    grp = sysgroup_getgrnam(group);
    if (grp == NULL && group[0] == '#' && group[1] != '\0') {
	const char *errstr;
	gid_t gid = sudo_strtoid(group + 1, NULL, NULL, &errstr);
	if (errstr == NULL)
	    grp = sysgroup_getgrgid(gid);
    }
    if (grp != NULL) {
	if (grp->gr_mem != NULL) {
	    for (member = grp->gr_mem; *member != NULL; member++) {
		if (strcasecmp(user, *member) == 0) {
		    if (sysgroup_gr_delref)
			sysgroup_gr_delref(grp);
		    return true;
		}
	    }
	}
	if (sysgroup_gr_delref)
	    sysgroup_gr_delref(grp);
    }

    return false;
}
Beispiel #3
0
static int
test_strtoid(int *ntests)
{
    struct strtoid_data *d;
    const char *errstr;
    char *ep;
    int errors = 0;
    id_t value;

    for (d = strtoid_data; d->idstr != NULL; d++) {
	(*ntests)++;
	errstr = "some error";
	value = sudo_strtoid(d->idstr, d->sep, &ep, &errstr);
	if (errstr != NULL) {
	    if (d->id != (id_t)-1) {
		sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr);
		errors++;
	    }
	} else if (value != d->id) {
	    sudo_warnx_nodebug("FAIL: %s != %u", d->idstr, (unsigned int)d->id);
	    errors++;
	} else if (d->ep != NULL && ep[0] != d->ep[0]) {
	    sudo_warnx_nodebug("FAIL: ep[0] %d != %d", (int)(unsigned char)ep[0],
		(int)(unsigned char)d->ep[0]);
	    errors++;
	}
    }

    return errors;
}
Beispiel #4
0
/*
 * Take a uid in string form "#123" and return a faked up passwd struct.
 */
struct passwd *
sudo_fakepwnam(const char *user, gid_t gid)
{
    const char *errstr;
    uid_t uid;
    debug_decl(sudo_fakepwnam, SUDOERS_DEBUG_NSS)

    uid = (uid_t) sudo_strtoid(user + 1, NULL, NULL, &errstr);
    if (errstr != NULL) {
	sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_DIAG,
	    "uid %s %s", user, errstr);
	debug_return_ptr(NULL);
    }
    debug_return_ptr(sudo_mkpwent(user, uid, gid, NULL, NULL));
}
Beispiel #5
0
/*
 * Parse a comma-separated list of gids into an allocated array of GETGROUPS_T.
 * If a pointer to the base gid is specified, it is stored as the first element
 * in the array.
 * Returns the number of gids in the allocated array.
 */
int
sudo_parse_gids_v1(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp)
{
    int ngids = 0;
    GETGROUPS_T *gids;
    const char *cp = gidstr;
    const char *errstr;
    char *ep;
    debug_decl(sudo_parse_gids, SUDO_DEBUG_UTIL)

    /* Count groups. */
    if (*cp != '\0') {
	ngids++;
	do {
	    if (*cp++ == ',')
		ngids++;
	} while (*cp != '\0');
    }
    /* Base gid is optional. */
    if (basegid != NULL)
	ngids++;
    /* Allocate and fill in array. */
    if (ngids != 0) {
	gids = reallocarray(NULL, ngids, sizeof(GETGROUPS_T));
	if (gids == NULL) {
	    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
	    debug_return_int(-1);
	}
	ngids = 0;
	if (basegid != NULL)
	    gids[ngids++] = *basegid;
	cp = gidstr;
	do {
	    gids[ngids] = (GETGROUPS_T) sudo_strtoid(cp, ",", &ep, &errstr);
	    if (errstr != NULL) {
		sudo_warnx(U_("%s: %s"), cp, U_(errstr));
		free(gids);
		debug_return_int(-1);
	    }
	    if (basegid == NULL || gids[ngids] != *basegid)
		ngids++;
	    cp = ep + 1;
	} while (*ep != '\0');
	*gidsp = gids;
    }
    debug_return_int(ngids);
}
Beispiel #6
0
struct group *
getgrent(void)
{
    static struct group gr;
    static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
    size_t len;
    id_t id;
    char *cp, *colon;
    const char *errstr;
    int n;

next_entry:
    if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
	return NULL;

    memset(&gr, 0, sizeof(gr));
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    gr.gr_name = cp;
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    gr.gr_passwd = cp;
    if ((colon = strchr(cp = colon, ':')) == NULL)
	goto next_entry;
    *colon++ = '\0';
    id = sudo_strtoid(cp, NULL, NULL, &errstr);
    if (errstr != NULL)
	goto next_entry;
    gr.gr_gid = (gid_t)id;
    len = strlen(colon);
    if (len > 0 && colon[len - 1] == '\n')
	colon[len - 1] = '\0';
    if (*colon != '\0') {
	gr.gr_mem = gr_mem;
	cp = strtok(colon, ",");
	for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
	    gr.gr_mem[n] = cp;
	    cp = strtok(NULL, ",");
	}
	gr.gr_mem[n++] = NULL;
    } else
	gr.gr_mem = NULL;
    return &gr;
}
Beispiel #7
0
/*
 * Deserialize args, settings and user_info arrays.
 * Fills in struct sudo_user and other common sudoers state.
 */
int
sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
{
    struct sudoers_policy_open_info *info = v;
    char * const *cur;
    const char *p, *errstr, *groups = NULL;
    const char *remhost = NULL;
    int flags = 0;
    debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN)

#define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)

    /* Parse sudo.conf plugin args. */
    if (info->plugin_args != NULL) {
	for (cur = info->plugin_args; *cur != NULL; cur++) {
	    if (MATCHES(*cur, "sudoers_file=")) {
		sudoers_file = *cur + sizeof("sudoers_file=") - 1;
		continue;
	    }
	    if (MATCHES(*cur, "sudoers_uid=")) {
		p = *cur + sizeof("sudoers_uid=") - 1;
		sudoers_uid = (uid_t) sudo_strtoid(p, NULL, NULL, &errstr);
		if (errstr != NULL) {
		    sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		    goto bad;
		}
		continue;
	    }
	    if (MATCHES(*cur, "sudoers_gid=")) {
		p = *cur + sizeof("sudoers_gid=") - 1;
		sudoers_gid = (gid_t) sudo_strtoid(p, NULL, NULL, &errstr);
		if (errstr != NULL) {
		    sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		    goto bad;
		}
		continue;
	    }
	    if (MATCHES(*cur, "sudoers_mode=")) {
		p = *cur + sizeof("sudoers_mode=") - 1;
		sudoers_mode = sudo_strtomode(p, &errstr);
		if (errstr != NULL) {
		    sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		    goto bad;
		}
		continue;
	    }
	    if (MATCHES(*cur, "ldap_conf=")) {
		path_ldap_conf = *cur + sizeof("ldap_conf=") - 1;
		continue;
	    }
	    if (MATCHES(*cur, "ldap_secret=")) {
		path_ldap_secret = *cur + sizeof("ldap_secret=") - 1;
		continue;
	    }
	}
    }

    /* Parse command line settings. */
    user_closefrom = -1;
    for (cur = info->settings; *cur != NULL; cur++) {
	if (MATCHES(*cur, "closefrom=")) {
	    errno = 0;
	    p = *cur + sizeof("closefrom=") - 1;
	    user_closefrom = strtonum(p, 4, INT_MAX, &errstr);
	    if (user_closefrom == 0) {
		sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		goto bad;
	    }
	    continue;
	}
	if (MATCHES(*cur, "runas_user="******"runas_user="******"runas_group=")) {
	    *runas_group = *cur + sizeof("runas_group=") - 1;
	    sudo_user.flags |= RUNAS_GROUP_SPECIFIED;
	    continue;
	}
	if (MATCHES(*cur, "prompt=")) {
	    user_prompt = *cur + sizeof("prompt=") - 1;
	    def_passprompt_override = true;
	    continue;
	}
	if (MATCHES(*cur, "set_home=")) {
	    if (sudo_strtobool(*cur + sizeof("set_home=") - 1) == true)
		SET(flags, MODE_RESET_HOME);
	    continue;
	}
	if (MATCHES(*cur, "preserve_environment=")) {
	    if (sudo_strtobool(*cur + sizeof("preserve_environment=") - 1) == true)
		SET(flags, MODE_PRESERVE_ENV);
	    continue;
	}
	if (MATCHES(*cur, "run_shell=")) {
	    if (sudo_strtobool(*cur + sizeof("run_shell=") - 1) == true)
		SET(flags, MODE_SHELL);
	    continue;
	}
	if (MATCHES(*cur, "login_shell=")) {
	    if (sudo_strtobool(*cur + sizeof("login_shell=") - 1) == true) {
		SET(flags, MODE_LOGIN_SHELL);
		def_env_reset = true;
	    }
	    continue;
	}
	if (MATCHES(*cur, "implied_shell=")) {
	    if (sudo_strtobool(*cur + sizeof("implied_shell=") - 1) == true)
		SET(flags, MODE_IMPLIED_SHELL);
	    continue;
	}
	if (MATCHES(*cur, "preserve_groups=")) {
	    if (sudo_strtobool(*cur + sizeof("preserve_groups=") - 1) == true)
		SET(flags, MODE_PRESERVE_GROUPS);
	    continue;
	}
	if (MATCHES(*cur, "ignore_ticket=")) {
	    if (sudo_strtobool(*cur + sizeof("ignore_ticket=") - 1) == true)
		SET(flags, MODE_IGNORE_TICKET);
	    continue;
	}
	if (MATCHES(*cur, "noninteractive=")) {
	    if (sudo_strtobool(*cur + sizeof("noninteractive=") - 1) == true)
		SET(flags, MODE_NONINTERACTIVE);
	    continue;
	}
	if (MATCHES(*cur, "sudoedit=")) {
	    if (sudo_strtobool(*cur + sizeof("sudoedit=") - 1) == true)
		SET(flags, MODE_EDIT);
	    continue;
	}
	if (MATCHES(*cur, "login_class=")) {
	    login_class = *cur + sizeof("login_class=") - 1;
	    def_use_loginclass = true;
	    continue;
	}
#ifdef HAVE_PRIV_SET
	if (MATCHES(*cur, "runas_privs=")) {
	    def_privs = *cur + sizeof("runas_privs=") - 1;
	    continue;
	}
	if (MATCHES(*cur, "runas_limitprivs=")) {
	    def_limitprivs = *cur + sizeof("runas_limitprivs=") - 1;
	    continue;
	}
#endif /* HAVE_PRIV_SET */
#ifdef HAVE_SELINUX
	if (MATCHES(*cur, "selinux_role=")) {
	    user_role = *cur + sizeof("selinux_role=") - 1;
	    continue;
	}
	if (MATCHES(*cur, "selinux_type=")) {
	    user_type = *cur + sizeof("selinux_type=") - 1;
	    continue;
	}
#endif /* HAVE_SELINUX */
#ifdef HAVE_BSD_AUTH_H
	if (MATCHES(*cur, "bsdauth_type=")) {
	    login_style = *cur + sizeof("bsdauth_type=") - 1;
	    continue;
	}
#endif /* HAVE_BSD_AUTH_H */
	if (MATCHES(*cur, "network_addrs=")) {
	    interfaces_string = *cur + sizeof("network_addrs=") - 1;
	    set_interfaces(interfaces_string);
	    continue;
	}
	if (MATCHES(*cur, "max_groups=")) {
	    errno = 0;
	    p = *cur + sizeof("max_groups=") - 1;
	    sudo_user.max_groups = strtonum(p, 1, INT_MAX, &errstr);
	    if (sudo_user.max_groups == 0) {
		sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		goto bad;
	    }
	    continue;
	}
	if (MATCHES(*cur, "remote_host=")) {
	    remhost = *cur + sizeof("remote_host=") - 1;
	    continue;
	}
    }

    for (cur = info->user_info; *cur != NULL; cur++) {
	if (MATCHES(*cur, "user="******"user="******"uid=")) {
	    p = *cur + sizeof("uid=") - 1;
	    user_uid = (uid_t) sudo_strtoid(p, NULL, NULL, &errstr);
	    if (errstr != NULL) {
		sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		goto bad;
	    }
	    continue;
	}
	if (MATCHES(*cur, "gid=")) {
	    p = *cur + sizeof("gid=") - 1;
	    user_gid = (gid_t) sudo_strtoid(p, NULL, NULL, &errstr);
	    if (errstr != NULL) {
		sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		goto bad;
	    }
	    continue;
	}
	if (MATCHES(*cur, "groups=")) {
	    groups = *cur + sizeof("groups=") - 1;
	    continue;
	}
	if (MATCHES(*cur, "cwd=")) {
	    user_cwd = sudo_estrdup(*cur + sizeof("cwd=") - 1);
	    continue;
	}
	if (MATCHES(*cur, "tty=")) {
	    user_tty = user_ttypath = sudo_estrdup(*cur + sizeof("tty=") - 1);
	    if (strncmp(user_tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
		user_tty += sizeof(_PATH_DEV) - 1;
	    continue;
	}
	if (MATCHES(*cur, "host=")) {
	    user_host = user_shost = sudo_estrdup(*cur + sizeof("host=") - 1);
	    if ((p = strchr(user_host, '.')))
		user_shost = sudo_estrndup(user_host, (size_t)(p - user_host));
	    continue;
	}
	if (MATCHES(*cur, "lines=")) {
	    errno = 0;
	    p = *cur + sizeof("lines=") - 1;
	    sudo_user.lines = strtonum(p, 1, INT_MAX, &errstr);
	    if (sudo_user.lines == 0) {
		sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		goto bad;
	    }
	    continue;
	}
	if (MATCHES(*cur, "cols=")) {
	    errno = 0;
	    p = *cur + sizeof("cols=") - 1;
	    sudo_user.cols = strtonum(p, 1, INT_MAX, &errstr);
	    if (sudo_user.lines == 0) {
		sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		goto bad;
	    }
	    continue;
	}
	if (MATCHES(*cur, "sid=")) {
	    p = *cur + sizeof("sid=") - 1;
	    sudo_user.sid = (pid_t) sudo_strtoid(p, NULL, NULL, &errstr);
	    if (errstr != NULL) {
		sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
		goto bad;
	    }
	    continue;
	}
    }
    user_runhost = user_srunhost = sudo_estrdup(remhost ? remhost : user_host);
    if ((p = strchr(user_runhost, '.')))
	user_srunhost = sudo_estrndup(user_runhost, (size_t)(p - user_runhost));
    if (user_cwd == NULL)
	user_cwd = sudo_estrdup("unknown");
    if (user_tty == NULL)
	user_tty = sudo_estrdup("unknown"); /* user_ttypath remains NULL */

    if (groups != NULL && groups[0] != '\0') {
	/* sudo_parse_gids() will print a warning on error. */
	user_ngids = sudo_parse_gids(groups, &user_gid, &user_gids);
	if (user_ngids == -1)
	    goto bad;
    }

    /* Stash initial umask for later use. */
    user_umask = umask(SUDO_UMASK);
    umask(user_umask);

    /* Dump settings and user info (XXX - plugin args) */
    for (cur = info->settings; *cur != NULL; cur++)
	sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur);
    for (cur = info->user_info; *cur != NULL; cur++)
	sudo_debug_printf(SUDO_DEBUG_INFO, "user_info: %s", *cur);

#undef MATCHES
    debug_return_int(flags);

bad:
    debug_return_int(MODE_ERROR);
}