diff options
author | Tomas Mraz <tm@t8m.info> | 2009-02-25 15:50:21 +0000 |
---|---|---|
committer | Tomas Mraz <tm@t8m.info> | 2009-02-25 15:50:21 +0000 |
commit | 1376c1565abb318a5b4d086edd7f295ee3da6b13 (patch) | |
tree | 737d16f94d1a66516090d0bbf8a1ec3aec7afb18 | |
parent | a95722ff38751fe28777846e8fcf115429c759b1 (diff) | |
download | pam-1376c1565abb318a5b4d086edd7f295ee3da6b13.tar.gz pam-1376c1565abb318a5b4d086edd7f295ee3da6b13.tar.bz2 pam-1376c1565abb318a5b4d086edd7f295ee3da6b13.zip |
Relevant BUGIDs:
Purpose of commit: new feature
Commit summary:
---------------
2009-02-25 Tomas Mraz <t8m@centrum.cz>
* xtests/access.conf: Add a line for name resolution test case.
* xtests/tst-pam_access4.c (main): Set PAM_RHOST for testing the LOCAL
keyword. Add a test case for name resolution.
* modules/pam_access/pam_access.c (from_match): Move name resolution
to network_netmask_match().
(network_netmask_match): Do a name resolution of the origin only if
matching against a real network/netmask.
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | modules/pam_access/pam_access.c | 154 | ||||
-rw-r--r-- | xtests/access.conf | 1 | ||||
-rw-r--r-- | xtests/tst-pam_access4.c | 28 |
4 files changed, 111 insertions, 83 deletions
@@ -1,3 +1,14 @@ +2009-02-25 Tomas Mraz <t8m@centrum.cz> + + * xtests/access.conf: Add a line for name resolution test case. + * xtests/tst-pam_access4.c (main): Set PAM_RHOST for testing the LOCAL + keyword. Add a test case for name resolution. + + * modules/pam_access/pam_access.c (from_match): Move name resolution + to network_netmask_match(). + (network_netmask_match): Do a name resolution of the origin only if + matching against a real network/netmask. + 2009-02-25 Fabian Affolter <fabian@bernewireless.net> * po/de.po: Updated translations. diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c index a5c6c6a5..ba8effe3 100644 --- a/modules/pam_access/pam_access.c +++ b/modules/pam_access/pam_access.c @@ -627,44 +627,10 @@ from_match (pam_handle_t *pamh UNUSED, char *tok, struct login_info *item) } freeaddrinfo (res); } - } else if (isipaddr(string, NULL, NULL) == YES) { + } else { /* Assume network/netmask with a IP of a host. */ if (network_netmask_match(pamh, tok, string, item->debug)) return YES; - } else { - /* Assume network/netmask with a name of a host. */ - struct addrinfo *res; - struct addrinfo hint; - - memset (&hint, '\0', sizeof (hint)); - hint.ai_flags = AI_CANONNAME; - hint.ai_family = AF_UNSPEC; - - if (getaddrinfo (string, NULL, &hint, &res) != 0) - return NO; - else - { - struct addrinfo *runp = res; - - while (runp != NULL) - { - char buf[INET6_ADDRSTRLEN]; - - inet_ntop (runp->ai_family, - runp->ai_family == AF_INET - ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr - : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr, - buf, sizeof (buf)); - - if (network_netmask_match(pamh, tok, buf, item->debug)) - { - freeaddrinfo (res); - return YES; - } - runp = runp->ai_next; - } - freeaddrinfo (res); - } } return NO; @@ -701,69 +667,99 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string, /* network_netmask_match - match a string against one token - * where string is an ip (v4,v6) address and tok represents - * whether a single ip (v4,v6) address or a network/netmask + * where string is a hostname or ip (v4,v6) address and tok + * represents either a single ip (v4,v6) address or a network/netmask */ static int network_netmask_match (pam_handle_t *pamh, const char *tok, const char *string, int debug) { - if (debug) + char *netmask_ptr; + char netmask_string[MAXHOSTNAMELEN + 1]; + int addr_type; + + if (debug) pam_syslog (pamh, LOG_DEBUG, "network_netmask_match: tok=%s, item=%s", tok, string); + /* OK, check if tok is of type addr/mask */ + if ((netmask_ptr = strchr(tok, '/')) != NULL) + { + long netmask = 0; - if (isipaddr(string, NULL, NULL) == YES) - { - char *netmask_ptr = NULL; - static char netmask_string[MAXHOSTNAMELEN + 1] = ""; - int addr_type; - - /* OK, check if tok is of type addr/mask */ - if ((netmask_ptr = strchr(tok, '/')) != NULL) - { - long netmask = 0; - - /* YES */ - *netmask_ptr = 0; - netmask_ptr++; + /* YES */ + *netmask_ptr = 0; + netmask_ptr++; - if (isipaddr(tok, &addr_type, NULL) == NO) - { /* no netaddr */ - return(NO); - } + if (isipaddr(tok, &addr_type, NULL) == NO) + { /* no netaddr */ + return NO; + } - /* check netmask */ - if (isipaddr(netmask_ptr, NULL, NULL) == NO) - { /* netmask as integre value */ - char *endptr = NULL; - netmask = strtol(netmask_ptr, &endptr, 0); - if ((endptr == NULL) || (*endptr != '\0')) + /* check netmask */ + if (isipaddr(netmask_ptr, NULL, NULL) == NO) + { /* netmask as integre value */ + char *endptr = NULL; + netmask = strtol(netmask_ptr, &endptr, 0); + if ((endptr == NULL) || (*endptr != '\0')) { /* invalid netmask value */ - return(NO); + return NO; } - if ((netmask < 0) || (netmask >= 128)) + if ((netmask < 0) || (netmask >= 128)) { /* netmask value out of range */ - return(NO); + return NO; } - netmask_ptr = number_to_netmask(netmask, addr_type, - netmask_string, MAXHOSTNAMELEN); - } - - /* Netmask is now an ipv4/ipv6 address. - * This works also if netmask_ptr is NULL. - */ - return (are_addresses_equal(string, tok, netmask_ptr)); + netmask_ptr = number_to_netmask(netmask, addr_type, + netmask_string, MAXHOSTNAMELEN); + } } - else + else /* NO, then check if it is only an addr */ - if (isipaddr(tok, NULL, NULL) == YES) - { /* check if they are the same, no netmask */ - return(are_addresses_equal(string, tok, NULL)); + if (isipaddr(tok, NULL, NULL) != YES) + { + return NO; } - } - return (NO); + if (isipaddr(string, NULL, NULL) != YES) + { + /* Assume network/netmask with a name of a host. */ + struct addrinfo *res; + struct addrinfo hint; + + memset (&hint, '\0', sizeof (hint)); + hint.ai_flags = AI_CANONNAME; + hint.ai_family = AF_UNSPEC; + + if (getaddrinfo (string, NULL, &hint, &res) != 0) + return NO; + else + { + struct addrinfo *runp = res; + + while (runp != NULL) + { + char buf[INET6_ADDRSTRLEN]; + + inet_ntop (runp->ai_family, + runp->ai_family == AF_INET + ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr + : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr, + buf, sizeof (buf)); + + if (are_addresses_equal(buf, tok, netmask_ptr)) + { + freeaddrinfo (res); + return YES; + } + runp = runp->ai_next; + } + freeaddrinfo (res); + } + } + else + return (are_addresses_equal(string, tok, netmask_ptr)); + + return NO; } diff --git a/xtests/access.conf b/xtests/access.conf index 8088ec61..25462dd9 100644 --- a/xtests/access.conf +++ b/xtests/access.conf @@ -1,2 +1,3 @@ -:ALL EXCEPT (tstpamaccess) tstpamaccess3 :LOCAL +-:ALL:127.0.0.1 diff --git a/xtests/tst-pam_access4.c b/xtests/tst-pam_access4.c index 2b887a4d..115217f6 100644 --- a/xtests/tst-pam_access4.c +++ b/xtests/tst-pam_access4.c @@ -34,10 +34,12 @@ /* test case: - Check the following line in access.conf: + Check the following lines in access.conf: -:ALL EXCEPT tstpamaccess3 :LOCAL + -:ALL:127.0.0.1 - pam_authenticate should fail for /dev/tty1 and pass for www.example.com + pam_authenticate should fail for /dev/tty1, pass for www.example.com, + and fail again for localhost */ #ifdef HAVE_CONFIG_H @@ -121,12 +123,12 @@ main(int argc, char *argv[]) return 1; } - retval = pam_set_item (pamh, PAM_TTY, "www.example.com"); + retval = pam_set_item (pamh, PAM_RHOST, "www.example.com"); if (retval != PAM_SUCCESS) { if (debug) fprintf (stderr, - "pam_access4-2: pam_set_item(PAM_TTY) returned %d\n", + "pam_access4-2: pam_set_item(PAM_RHOST) returned %d\n", retval); return 1; } @@ -139,6 +141,24 @@ main(int argc, char *argv[]) return 1; } + retval = pam_set_item (pamh, PAM_RHOST, "localhost"); + if (retval != PAM_SUCCESS) + { + if (debug) + fprintf (stderr, + "pam_access4-3: pam_set_item(PAM_RHOST) returned %d\n", + retval); + return 1; + } + + retval = pam_authenticate (pamh, 0); + if (retval != PAM_PERM_DENIED) + { + if (debug) + fprintf (stderr, "pam_access4-3: pam_authenticate returned %d\n", retval); + return 1; + } + retval = pam_end (pamh,retval); if (retval != PAM_SUCCESS) { |