version 1.1.1.1, 2012/02/21 16:23:02
|
version 1.1.1.3, 2013/07/22 10:46:12
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (c) 1996, 1998-2005, 2007-2011 | * Copyright (c) 1996, 1998-2005, 2007-2013 |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
Line 45
|
Line 45
|
#endif /* HAVE_UNISTD_H */ |
#endif /* HAVE_UNISTD_H */ |
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <arpa/inet.h> |
#include <arpa/inet.h> |
#include <netdb.h> |
|
|
|
#include "sudoers.h" |
#include "sudoers.h" |
#include "interfaces.h" |
#include "interfaces.h" |
|
|
static int | static bool |
addr_matches_if(char *n) |
addr_matches_if(char *n) |
{ |
{ |
union sudo_in_addr_un addr; |
union sudo_in_addr_un addr; |
struct interface *ifp; |
struct interface *ifp; |
#ifdef HAVE_IN6_ADDR | #ifdef HAVE_STRUCT_IN6_ADDR |
int j; |
int j; |
#endif |
#endif |
int family; |
int family; |
|
debug_decl(addr_matches_if, SUDO_DEBUG_MATCH) |
|
|
#ifdef HAVE_IN6_ADDR | #ifdef HAVE_STRUCT_IN6_ADDR |
if (inet_pton(AF_INET6, n, &addr.ip6) > 0) { |
if (inet_pton(AF_INET6, n, &addr.ip6) > 0) { |
family = AF_INET6; |
family = AF_INET6; |
} else |
} else |
#endif | #endif /* HAVE_STRUCT_IN6_ADDR */ |
{ |
{ |
family = AF_INET; |
family = AF_INET; |
addr.ip4.s_addr = inet_addr(n); |
addr.ip4.s_addr = inet_addr(n); |
} |
} |
|
|
for (ifp = interfaces; ifp != NULL; ifp = ifp->next) { | for (ifp = get_interfaces(); ifp != NULL; ifp = ifp->next) { |
if (ifp->family != family) |
if (ifp->family != family) |
continue; |
continue; |
switch(family) { | switch (family) { |
case AF_INET: |
case AF_INET: |
if (ifp->addr.ip4.s_addr == addr.ip4.s_addr || |
if (ifp->addr.ip4.s_addr == addr.ip4.s_addr || |
(ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr) |
(ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr) |
== addr.ip4.s_addr) |
== addr.ip4.s_addr) |
return TRUE; | debug_return_bool(true); |
break; |
break; |
#ifdef HAVE_IN6_ADDR | #ifdef HAVE_STRUCT_IN6_ADDR |
case AF_INET6: |
case AF_INET6: |
if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr, |
if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr, |
sizeof(addr.ip6.s6_addr)) == 0) |
sizeof(addr.ip6.s6_addr)) == 0) |
return TRUE; | debug_return_bool(true); |
for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) { |
for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) { |
if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j]) |
if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j]) |
break; |
break; |
} |
} |
if (j == sizeof(addr.ip6.s6_addr)) |
if (j == sizeof(addr.ip6.s6_addr)) |
return TRUE; | debug_return_bool(true); |
#endif | break; |
| #endif /* HAVE_STRUCT_IN6_ADDR */ |
} |
} |
} |
} |
|
|
return FALSE; | debug_return_bool(false); |
} |
} |
|
|
static int | static bool |
addr_matches_if_netmask(char *n, char *m) |
addr_matches_if_netmask(char *n, char *m) |
{ |
{ |
int i; |
int i; |
union sudo_in_addr_un addr, mask; |
union sudo_in_addr_un addr, mask; |
struct interface *ifp; |
struct interface *ifp; |
#ifdef HAVE_IN6_ADDR | #ifdef HAVE_STRUCT_IN6_ADDR |
int j; |
int j; |
#endif |
#endif |
int family; |
int family; |
|
debug_decl(addr_matches_if, SUDO_DEBUG_MATCH) |
|
|
#ifdef HAVE_IN6_ADDR | #ifdef HAVE_STRUCT_IN6_ADDR |
if (inet_pton(AF_INET6, n, &addr.ip6) > 0) |
if (inet_pton(AF_INET6, n, &addr.ip6) > 0) |
family = AF_INET6; |
family = AF_INET6; |
else |
else |
#endif | #endif /* HAVE_STRUCT_IN6_ADDR */ |
{ |
{ |
family = AF_INET; |
family = AF_INET; |
addr.ip4.s_addr = inet_addr(n); |
addr.ip4.s_addr = inet_addr(n); |
Line 134 addr_matches_if_netmask(char *n, char *m)
|
Line 136 addr_matches_if_netmask(char *n, char *m)
|
} |
} |
addr.ip4.s_addr &= mask.ip4.s_addr; |
addr.ip4.s_addr &= mask.ip4.s_addr; |
} |
} |
#ifdef HAVE_IN6_ADDR | #ifdef HAVE_STRUCT_IN6_ADDR |
else { |
else { |
if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) { |
if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) { |
j = atoi(m); |
j = atoi(m); |
Line 149 addr_matches_if_netmask(char *n, char *m)
|
Line 151 addr_matches_if_netmask(char *n, char *m)
|
} |
} |
} |
} |
} |
} |
#endif /* HAVE_IN6_ADDR */ | #endif /* HAVE_STRUCT_IN6_ADDR */ |
|
|
for (ifp = interfaces; ifp != NULL; ifp = ifp->next) { | for (ifp = get_interfaces(); ifp != NULL; ifp = ifp->next) { |
if (ifp->family != family) |
if (ifp->family != family) |
continue; |
continue; |
switch(family) { | switch (family) { |
case AF_INET: |
case AF_INET: |
if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr) |
if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr) |
return TRUE; | debug_return_bool(true); |
#ifdef HAVE_IN6_ADDR | break; |
| #ifdef HAVE_STRUCT_IN6_ADDR |
case AF_INET6: |
case AF_INET6: |
for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) { |
for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) { |
if ((ifp->addr.ip6.s6_addr[j] & mask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j]) |
if ((ifp->addr.ip6.s6_addr[j] & mask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j]) |
break; |
break; |
} |
} |
if (j == sizeof(addr.ip6.s6_addr)) |
if (j == sizeof(addr.ip6.s6_addr)) |
return TRUE; | debug_return_bool(true); |
#endif /* HAVE_IN6_ADDR */ | break; |
| #endif /* HAVE_STRUCT_IN6_ADDR */ |
} |
} |
} |
} |
|
|
return FALSE; | debug_return_bool(false); |
} |
} |
|
|
/* |
/* |
* Returns TRUE if "n" is one of our ip addresses or if | * Returns true if "n" is one of our ip addresses or if |
* "n" is a network that we are on, else returns FALSE. | * "n" is a network that we are on, else returns false. |
*/ |
*/ |
int | bool |
addr_matches(char *n) |
addr_matches(char *n) |
{ |
{ |
char *m; |
char *m; |
int retval; | bool retval; |
| debug_decl(addr_matches, SUDO_DEBUG_MATCH) |
|
|
/* If there's an explicit netmask, use it. */ |
/* If there's an explicit netmask, use it. */ |
if ((m = strchr(n, '/'))) { |
if ((m = strchr(n, '/'))) { |
Line 191 addr_matches(char *n)
|
Line 196 addr_matches(char *n)
|
} else |
} else |
retval = addr_matches_if(n); |
retval = addr_matches_if(n); |
|
|
return retval; | debug_return_bool(retval); |
} |
} |