Return to match_addr.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers |
1.1 ! misho 1: /* ! 2: * Copyright (c) 1996, 1998-2005, 2007-2011 ! 3: * Todd C. Miller <Todd.Miller@courtesan.com> ! 4: * ! 5: * Permission to use, copy, modify, and distribute this software for any ! 6: * purpose with or without fee is hereby granted, provided that the above ! 7: * copyright notice and this permission notice appear in all copies. ! 8: * ! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 16: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! 17: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! 18: * ! 19: * Sponsored in part by the Defense Advanced Research Projects ! 20: * Agency (DARPA) and Air Force Research Laboratory, Air Force ! 21: * Materiel Command, USAF, under agreement number F39502-99-1-0512. ! 22: */ ! 23: ! 24: #include <config.h> ! 25: ! 26: #include <sys/types.h> ! 27: #include <sys/socket.h> ! 28: #include <stdio.h> ! 29: #ifdef STDC_HEADERS ! 30: # include <stdlib.h> ! 31: # include <stddef.h> ! 32: #else ! 33: # ifdef HAVE_STDLIB_H ! 34: # include <stdlib.h> ! 35: # endif ! 36: #endif /* STDC_HEADERS */ ! 37: #ifdef HAVE_STRING_H ! 38: # include <string.h> ! 39: #endif /* HAVE_STRING_H */ ! 40: #ifdef HAVE_STRINGS_H ! 41: # include <strings.h> ! 42: #endif /* HAVE_STRINGS_H */ ! 43: #ifdef HAVE_UNISTD_H ! 44: # include <unistd.h> ! 45: #endif /* HAVE_UNISTD_H */ ! 46: #include <netinet/in.h> ! 47: #include <arpa/inet.h> ! 48: #include <netdb.h> ! 49: ! 50: #include "sudoers.h" ! 51: #include "interfaces.h" ! 52: ! 53: static int ! 54: addr_matches_if(char *n) ! 55: { ! 56: union sudo_in_addr_un addr; ! 57: struct interface *ifp; ! 58: #ifdef HAVE_IN6_ADDR ! 59: int j; ! 60: #endif ! 61: int family; ! 62: ! 63: #ifdef HAVE_IN6_ADDR ! 64: if (inet_pton(AF_INET6, n, &addr.ip6) > 0) { ! 65: family = AF_INET6; ! 66: } else ! 67: #endif ! 68: { ! 69: family = AF_INET; ! 70: addr.ip4.s_addr = inet_addr(n); ! 71: } ! 72: ! 73: for (ifp = interfaces; ifp != NULL; ifp = ifp->next) { ! 74: if (ifp->family != family) ! 75: continue; ! 76: switch(family) { ! 77: case AF_INET: ! 78: if (ifp->addr.ip4.s_addr == addr.ip4.s_addr || ! 79: (ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr) ! 80: == addr.ip4.s_addr) ! 81: return TRUE; ! 82: break; ! 83: #ifdef HAVE_IN6_ADDR ! 84: case AF_INET6: ! 85: if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr, ! 86: sizeof(addr.ip6.s6_addr)) == 0) ! 87: return TRUE; ! 88: for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) { ! 89: if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j]) ! 90: break; ! 91: } ! 92: if (j == sizeof(addr.ip6.s6_addr)) ! 93: return TRUE; ! 94: #endif ! 95: } ! 96: } ! 97: ! 98: return FALSE; ! 99: } ! 100: ! 101: static int ! 102: addr_matches_if_netmask(char *n, char *m) ! 103: { ! 104: int i; ! 105: union sudo_in_addr_un addr, mask; ! 106: struct interface *ifp; ! 107: #ifdef HAVE_IN6_ADDR ! 108: int j; ! 109: #endif ! 110: int family; ! 111: ! 112: #ifdef HAVE_IN6_ADDR ! 113: if (inet_pton(AF_INET6, n, &addr.ip6) > 0) ! 114: family = AF_INET6; ! 115: else ! 116: #endif ! 117: { ! 118: family = AF_INET; ! 119: addr.ip4.s_addr = inet_addr(n); ! 120: } ! 121: ! 122: if (family == AF_INET) { ! 123: if (strchr(m, '.')) { ! 124: mask.ip4.s_addr = inet_addr(m); ! 125: } else { ! 126: i = atoi(m); ! 127: if (i == 0) ! 128: mask.ip4.s_addr = 0; ! 129: else if (i == 32) ! 130: mask.ip4.s_addr = 0xffffffff; ! 131: else ! 132: mask.ip4.s_addr = 0xffffffff - (1 << (32 - i)) + 1; ! 133: mask.ip4.s_addr = htonl(mask.ip4.s_addr); ! 134: } ! 135: addr.ip4.s_addr &= mask.ip4.s_addr; ! 136: } ! 137: #ifdef HAVE_IN6_ADDR ! 138: else { ! 139: if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) { ! 140: j = atoi(m); ! 141: for (i = 0; i < sizeof(addr.ip6.s6_addr); i++) { ! 142: if (j < i * 8) ! 143: mask.ip6.s6_addr[i] = 0; ! 144: else if (i * 8 + 8 <= j) ! 145: mask.ip6.s6_addr[i] = 0xff; ! 146: else ! 147: mask.ip6.s6_addr[i] = 0xff00 >> (j - i * 8); ! 148: addr.ip6.s6_addr[i] &= mask.ip6.s6_addr[i]; ! 149: } ! 150: } ! 151: } ! 152: #endif /* HAVE_IN6_ADDR */ ! 153: ! 154: for (ifp = interfaces; ifp != NULL; ifp = ifp->next) { ! 155: if (ifp->family != family) ! 156: continue; ! 157: switch(family) { ! 158: case AF_INET: ! 159: if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr) ! 160: return TRUE; ! 161: #ifdef HAVE_IN6_ADDR ! 162: case AF_INET6: ! 163: for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) { ! 164: if ((ifp->addr.ip6.s6_addr[j] & mask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j]) ! 165: break; ! 166: } ! 167: if (j == sizeof(addr.ip6.s6_addr)) ! 168: return TRUE; ! 169: #endif /* HAVE_IN6_ADDR */ ! 170: } ! 171: } ! 172: ! 173: return FALSE; ! 174: } ! 175: ! 176: /* ! 177: * Returns TRUE if "n" is one of our ip addresses or if ! 178: * "n" is a network that we are on, else returns FALSE. ! 179: */ ! 180: int ! 181: addr_matches(char *n) ! 182: { ! 183: char *m; ! 184: int retval; ! 185: ! 186: /* If there's an explicit netmask, use it. */ ! 187: if ((m = strchr(n, '/'))) { ! 188: *m++ = '\0'; ! 189: retval = addr_matches_if_netmask(n, m); ! 190: *(m - 1) = '/'; ! 191: } else ! 192: retval = addr_matches_if(n); ! 193: ! 194: return retval; ! 195: }