예제 #1
0
static int
from_match(const char *tok, const char *string)
{
    int     tok_len;
    int     str_len;

    /*
     * If a token has the magic value "ALL" the match always succeeds. Return
     * YES if the token fully matches the string. If the token is a domain
     * name, return YES if it matches the last fields of the string. If the
     * token has the magic value "LOCAL", return YES if the string does not
     * contain a "." character. If the token is a network number, return YES
     * if it matches the head of the string.
     */

    if (tok[0] == '@') {			/* netgroup */
        return (netgroup_match(tok + 1, string, NULL));
    } else if (string_match(tok, string)) {	/* ALL or exact match */
        return (YES);
    } else if (tok[0] == '.') {			/* domain: match last fields */
        if ((str_len = strlen(string)) > (tok_len = strlen(tok))
                && strcasecmp(tok, string + str_len - tok_len) == 0)
            return (YES);
    } else if (strcasecmp(tok, "LOCAL") == 0) {	/* local: no dots */
        if (strchr(string, '.') == 0)
            return (YES);
    } else if (tok[(tok_len = strlen(tok)) - 1] == '.'	/* network */
               && strncmp(tok, string, tok_len) == 0) {
        return (YES);
    }
    return (NO);
}
예제 #2
0
static int from_match(char *tok, struct login_info *item)
{
    char   *string = item->from;
    int     tok_len;
    int     str_len;

    /*
     * If a token has the magic value "ALL" the match always succeeds. Return
     * YES if the token fully matches the string. If the token is a domain
     * name, return YES if it matches the last fields of the string. If the
     * token has the magic value "LOCAL", return YES if the string does not
     * contain a "." character. If the token is a network number, return YES
     * if it matches the head of the string.
     */

    if (tok[0] == '@') {			/* netgroup */
	return (netgroup_match(tok + 1, string, (char *) 0));
    } else if (string_match(tok, string)) {	/* ALL or exact match */
	return (YES);
    } else if (tok[0] == '.') {			/* domain: match last fields */
	if ((str_len = strlen(string)) > (tok_len = strlen(tok))
	    && strcasecmp(tok, string + str_len - tok_len) == 0)
	    return (YES);
    } else if (strcasecmp(tok, "LOCAL") == 0) {	/* local: no dots */
	if (strchr(string, '.') == 0)
	    return (YES);
#ifdef BROKEN_NETWORK_MATCH
    } else if (tok[(tok_len = strlen(tok)) - 1] == '.'	/* network */
	       && strncmp(tok, string, tok_len) == 0) {
	return (YES);
#else /*  BROKEN_NETWORK_MATCH */
    } else if (tok[(tok_len = strlen(tok)) - 1] == '.') {
        /*
           The code below does a more correct check if the address specified
           by "string" starts from "tok".
                               1998/01/27  Andrey V. Savochkin <*****@*****.**>
         */

        struct hostent *h;
        char hn[3+1+3+1+3+1+3+1+1];
        int r;

        h = gethostbyname(string);
        if (h == NULL)
	    return (NO);
        if (h->h_addrtype != AF_INET)
	    return (NO);
        if (h->h_length != 4)
	    return (NO); /* only IPv4 addresses (SAW) */
        r = snprintf(hn, sizeof(hn), "%u.%u.%u.%u.",
		     (unsigned char)h->h_addr[0], (unsigned char)h->h_addr[1],
		     (unsigned char)h->h_addr[2], (unsigned char)h->h_addr[3]);
        if (r < 0 || r >= sizeof(hn))
	    return (NO);
        if (!strncmp(tok, hn, tok_len))
	    return (YES);
#endif /*  BROKEN_NETWORK_MATCH */
    }
    return (NO);
}
예제 #3
0
static int user_match(char *tok, struct login_info *item)
{
    char   *string = item->user->pw_name;
    struct login_info fake_item;
    struct group *group;
    int     i;
    char   *at;

    /*
     * If a token has the magic value "ALL" the match always succeeds.
     * Otherwise, return YES if the token fully matches the username, if the
     * token is a group that contains the username, or if the token is the
     * name of the user's primary group.
     */

    if ((at = strchr(tok + 1, '@')) != 0) {	/* split user@host pattern */
	*at = 0;
	fake_item.from = myhostname();
	return (user_match(tok, item) && from_match(at + 1, &fake_item));
    } else if (tok[0] == '@') {			/* netgroup */
	return (netgroup_match(tok + 1, (char *) 0, string));
    } else if (string_match(tok, string)) {	/* ALL or exact match */
	return (YES);
    } else if ((group = getgrnam(tok))) {	/* try group membership */
	if (item->user->pw_gid == group->gr_gid)
	    return (YES);
	for (i = 0; group->gr_mem[i]; i++)
	    if (strcasecmp(string, group->gr_mem[i]) == 0)
		return (YES);
    }
    return (NO);
}
예제 #4
0
static int
user_match (pam_handle_t *pamh, char *tok, struct login_info *item)
{
    char   *string = item->user->pw_name;
    struct login_info fake_item;
    char   *at;
    int    rv;

    if (item->debug)
      pam_syslog (pamh, LOG_DEBUG,
		  "user_match: tok=%s, item=%s", tok, string);

    /*
     * If a token has the magic value "ALL" the match always succeeds.
     * Otherwise, return YES if the token fully matches the username, if the
     * token is a group that contains the username, or if the token is the
     * name of the user's primary group.
     */

    /* Try to split on a pattern (@*[^@]+)(@+.*) */
    for (at = tok; *at == '@'; ++at);

    if ((at = strchr(at, '@')) != NULL) {
        /* split user@host pattern */
	if (item->hostname == NULL)
	    return NO;
	memcpy (&fake_item, item, sizeof(fake_item));
	fake_item.from = item->hostname;
	fake_item.gai_rv = 0;
	fake_item.res = NULL;
	fake_item.from_remote_host = 1; /* hostname should be resolvable */
	*at = 0;
	if (!user_match (pamh, tok, item))
		return NO;
	rv = from_match (pamh, at + 1, &fake_item);
	if (fake_item.gai_rv == 0 && fake_item.res)
		freeaddrinfo(fake_item.res);
	return rv;
    } else if (tok[0] == '@') {			/* netgroup */
	const char *hostname = NULL;
	if (tok[1] == '@') {			/* add hostname to netgroup match */
		if (item->hostname == NULL)
		    return NO;
		++tok;
		hostname = item->hostname;
	}
        return (netgroup_match (pamh, tok + 1, hostname, string, item->debug));
    } else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')')
      return (group_match (pamh, tok, string, item->debug));
    else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */
      return rv;
    else if (item->only_new_group_syntax == NO &&
	     pam_modutil_user_in_group_nam_nam (pamh,
						item->user->pw_name, tok))
      /* try group membership */
      return YES;

    return NO;
}
예제 #5
0
/* user_match - match a username against one token */
static bool user_match (const char *tok, const char *string)
{
	struct group *group;

#ifdef PRIMARY_GROUP_MATCH
	struct passwd *userinf;
#endif
	char *at;

	/*
	 * If a token has the magic value "ALL" the match always succeeds.
	 * Otherwise, return true if the token fully matches the username, or if
	 * the token is a group that contains the username.
	 */
	at = strchr (tok + 1, '@');
	if (NULL != at) {	/* split user@host pattern */
		*at = '\0';
		return (   user_match (tok, string)
		        && from_match (at + 1, myhostname ()));
#if HAVE_INNETGR
	} else if (tok[0] == '@') {	/* netgroup */
		return (netgroup_match (tok + 1, (char *) 0, string));
#endif
	} else if (string_match (tok, string)) {	/* ALL or exact match */
		return true;
	/* local, no need for xgetgrnam */
	} else if ((group = getgrnam (tok)) != NULL) {	/* try group membership */
		int i;
		for (i = 0; NULL != group->gr_mem[i]; i++) {
			if (strcasecmp (string, group->gr_mem[i]) == 0) {
				return true;
			}
		}
#ifdef PRIMARY_GROUP_MATCH
		/*
		 * If the string is an user whose initial GID matches the token,
		 * accept it. May avoid excessively long lines in /etc/group.
		 * Radu-Adrian Feurdean <*****@*****.**>
		 *
		 * XXX - disabled by default for now.  Need to verify that
		 * getpwnam() doesn't have some nasty side effects.  --marekm
		 */
		/* local, no need for xgetpwnam */
		userinf = getpwnam (string);
		if (NULL != userinf) {
			if (userinf->pw_gid == group->gr_gid) {
				return true;
			}
		}
#endif
	}
	return false;
}
예제 #6
0
static int
user_match (pam_handle_t *pamh, char *tok, struct login_info *item)
{
    char   *string = item->user->pw_name;
    struct login_info fake_item;
    char   *at;
    int    rv;

    if (item->debug)
      pam_syslog (pamh, LOG_DEBUG,
		  "user_match: tok=%s, item=%s", tok, string);

    /*
     * If a token has the magic value "ALL" the match always succeeds.
     * Otherwise, return YES if the token fully matches the username, if the
     * token is a group that contains the username, or if the token is the
     * name of the user's primary group.
     */

    if ((at = strchr(tok + 1, '@')) != 0) {	/* split user@host pattern */
	if (item->hostname == NULL)
	    return NO;
	fake_item.from = item->hostname;
	*at = 0;
	return (user_match (pamh, tok, item) &&
		from_match (pamh, at + 1, &fake_item));
    } else if (tok[0] == '@') {			/* netgroup */
	const char *hostname = NULL;
	if (tok[1] == '@') {			/* add hostname to netgroup match */
		if (item->hostname == NULL)
		    return NO;
		++tok;
		hostname = item->hostname;
	}
        return (netgroup_match (pamh, tok + 1, hostname, string, item->debug));
    } else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')')
      return (group_match (pamh, tok, string, item->debug));
    else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */
      return rv;
    else if (item->only_new_group_syntax == NO &&
	     pam_modutil_user_in_group_nam_nam (pamh,
						item->user->pw_name, tok))
      /* try group membership */
      return YES;

    return NO;
}
예제 #7
0
static int
user_match(const char *tok, const char *string)
{
    struct group *group;
    int     i;

    /*
     * If a token has the magic value "ALL" the match always succeeds.
     * Otherwise, return YES if the token fully matches the username, or if
     * the token is a group that contains the username.
     */

    if (tok[0] == '@') {			/* netgroup */
        return (netgroup_match(tok + 1, NULL, string));
    } else if (string_match(tok, string)) {	/* ALL or exact match */
        return (YES);
    } else if ((group = getgrnam(tok)) != NULL) {/* try group membership */
        for (i = 0; group->gr_mem[i]; i++)
            if (strcasecmp(string, group->gr_mem[i]) == 0)
                return (YES);
    }
    return (NO);
}
예제 #8
0
static bool from_match (const char *tok, const char *string)
{
	size_t tok_len;

	/*
	 * If a token has the magic value "ALL" the match always succeeds. Return
	 * true if the token fully matches the string. If the token is a domain
	 * name, return true if it matches the last fields of the string. If the
	 * token has the magic value "LOCAL", return true if the string does not
	 * contain a "." character. If the token is a network number, return true
	 * if it matches the head of the string.
	 */
#if HAVE_INNETGR
	if (tok[0] == '@') {	/* netgroup */
		return (netgroup_match (tok + 1, string, (char *) 0));
	} else
#endif
	if (string_match (tok, string)) {	/* ALL or exact match */
		return true;
	} else if (tok[0] == '.') {	/* domain: match last fields */
		size_t str_len;
		str_len = strlen (string);
		tok_len = strlen (tok);
		if (   (str_len > tok_len)
		    && (strcasecmp (tok, string + str_len - tok_len) == 0)) {
			return true;
		}
	} else if (strcasecmp (tok, "LOCAL") == 0) {	/* local: no dots */
		if (strchr (string, '.') == NULL) {
			return true;
		}
	} else if (   (tok[(tok_len = strlen (tok)) - 1] == '.') /* network */
		   && (strncmp (tok, resolve_hostname (string), tok_len) == 0)) {
		return true;
	}
	return false;
}