/*
- * Copyright (c) 1996, 1998-2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1996, 1998-2005 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#define _SUDO_MAIN
-#include "config.h"
+#include <config.h>
#include <sys/param.h>
#include <sys/types.h>
#endif /* HAVE_FNMATCH */
#ifndef lint
-static const char rcsid[] = "$Sudo: testsudoers.c,v 1.88 2004/08/02 18:44:58 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: testsudoers.c,v 1.88.2.5 2007/08/25 02:45:09 millert Exp $";
#endif /* lint */
*/
void init_parser __P((void));
void dumpaliases __P((void));
-void set_perms_dummy __P((int));
/*
* Globals
struct sudo_user sudo_user;
extern int clearaliases;
extern int pedantic;
-void (*set_perms) __P((int)) = set_perms_dummy;
/*
* Returns TRUE if "s" has shell meta characters in it,
}
}
-int
-addr_matches(n)
+static int
+addr_matches_if(n)
char *n;
{
int i;
+ struct in_addr addr;
+ struct interface *ifp;
+#ifdef AF_INET6
+ struct in6_addr addr6;
+ int j;
+#endif
+ int family;
+
+#ifdef AF_INET6
+ if (inet_pton(AF_INET6, n, &addr6) > 0) {
+ family = AF_INET6;
+ } else
+#endif
+ {
+ family = AF_INET;
+ addr.s_addr = inet_addr(n);
+ }
+
+ for (i = 0; i < num_interfaces; i++) {
+ ifp = &interfaces[i];
+ if (ifp->family != family)
+ continue;
+ switch(family) {
+ case AF_INET:
+ if (ifp->addr.ip4.s_addr == addr.s_addr ||
+ (ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr)
+ == addr.s_addr)
+ return(TRUE);
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ if (memcmp(ifp->addr.ip6.s6_addr, addr6.s6_addr,
+ sizeof(addr6.s6_addr)) == 0)
+ return(TRUE);
+ for (j = 0; j < sizeof(addr6.s6_addr); j++) {
+ if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr6.s6_addr[j])
+ break;
+ }
+ if (j == sizeof(addr6.s6_addr))
+ return(TRUE);
+#endif /* AF_INET6 */
+ }
+ }
+
+ return(FALSE);
+}
+
+static int
+addr_matches_if_netmask(n, m)
+ char *n;
char *m;
+{
+ int i;
struct in_addr addr, mask;
+ struct interface *ifp;
+#ifdef AF_INET6
+ struct in6_addr addr6, mask6;
+ int j;
+#endif
+ int family;
- /* If there's an explicit netmask, use it. */
- if ((m = strchr(n, '/'))) {
- *m++ = '\0';
+#ifdef AF_INET6
+ if (inet_pton(AF_INET6, n, &addr6) > 0)
+ family = AF_INET6;
+ else
+#endif
+ {
+ family = AF_INET;
addr.s_addr = inet_addr(n);
+ }
+
+ if (family == AF_INET) {
if (strchr(m, '.'))
mask.s_addr = inet_addr(m);
else {
mask.s_addr <<= i;
mask.s_addr = htonl(mask.s_addr);
}
- *(m - 1) = '/';
-
- for (i = 0; i < num_interfaces; i++)
- if ((interfaces[i].addr.s_addr & mask.s_addr) == addr.s_addr)
- return(TRUE);
- } else {
- addr.s_addr = inet_addr(n);
-
- for (i = 0; i < num_interfaces; i++)
- if (interfaces[i].addr.s_addr == addr.s_addr ||
- (interfaces[i].addr.s_addr & interfaces[i].netmask.s_addr)
- == addr.s_addr)
- return(TRUE);
+ }
+#ifdef AF_INET6
+ else {
+ if (inet_pton(AF_INET6, m, &mask6) <= 0) {
+ j = atoi(m);
+ for (i = 0; i < 16; i++) {
+ if (j < i * 8)
+ mask6.s6_addr[i] = 0;
+ else if (i * 8 + 8 <= j)
+ mask6.s6_addr[i] = 0xff;
+ else
+ mask6.s6_addr[i] = 0xff00 >> (j - i * 8);
+ }
+ }
+ }
+#endif /* AF_INET6 */
+
+ for (i = 0; i < num_interfaces; i++) {
+ ifp = &interfaces[i];
+ if (ifp->family != family)
+ continue;
+ switch(family) {
+ case AF_INET:
+ if ((ifp->addr.ip4.s_addr & mask.s_addr) == addr.s_addr)
+ return(TRUE);
+#ifdef AF_INET6
+ case AF_INET6:
+ for (j = 0; j < sizeof(addr6.s6_addr); j++) {
+ if ((ifp->addr.ip6.s6_addr[j] & mask6.s6_addr[j]) != addr6.s6_addr[j])
+ break;
+ }
+ if (j == sizeof(addr6.s6_addr))
+ return(TRUE);
+#endif /* AF_INET6 */
+ }
}
return(FALSE);
}
+/*
+ * Returns TRUE if "n" is one of our ip addresses or if
+ * "n" is a network that we are on, else returns FALSE.
+ */
+int
+addr_matches(n)
+ char *n;
+{
+ char *m;
+ int retval;
+
+ /* If there's an explicit netmask, use it. */
+ if ((m = strchr(n, '/'))) {
+ *m++ = '\0';
+ retval = addr_matches_if_netmask(n, m);
+ *(m - 1) = '/';
+ } else
+ retval = addr_matches_if(n);
+
+ return(retval);
+}
+
int
hostname_matches(shost, lhost, pattern)
char *shost;
domain = (char *) emalloc(MAXHOSTNAMELEN);
if (getdomainname(domain, MAXHOSTNAMELEN) != 0 || *domain == '\0') {
- free(domain);
+ efree(domain);
domain = NULL;
}
}
}
void
-set_perms_dummy(i)
+set_perms(i)
int i;
{
return;