612 lines
19 KiB
Diff
612 lines
19 KiB
Diff
--- sudo-1.6.8p12/Makefile.in.ipv6 2005-11-08 19:21:58.000000000 +0100
|
|
+++ sudo-1.6.8p12/Makefile.in 2006-07-16 23:33:58.000000000 +0200
|
|
@@ -187,14 +187,14 @@
|
|
@DEV@PARSESRCS = sudo.tab.h sudo.tab.c lex.yy.c def_data.c def_data.h
|
|
|
|
# Uncomment the following if you intend to modify parse.yacc
|
|
-@DEV@sudo.tab.c sudo.tab.h: parse.yacc
|
|
-@DEV@ rm -f sudo.tab.h sudo.tab.c
|
|
-@DEV@ $(YACC) -d -b sudo $(srcdir)/parse.yacc
|
|
+sudo.tab.c sudo.tab.h: parse.yacc
|
|
+ rm -f sudo.tab.h sudo.tab.c
|
|
+ $(YACC) -d -b sudo $(srcdir)/parse.yacc
|
|
|
|
# Uncomment the following if you intend to modify parse.lex
|
|
-@DEV@lex.yy.c: parse.lex
|
|
-@DEV@ rm -f lex.yy.c
|
|
-@DEV@ $(LEX) $(srcdir)/parse.lex
|
|
+lex.yy.c: parse.lex
|
|
+ rm -f lex.yy.c
|
|
+ $(LEX) $(srcdir)/parse.lex
|
|
|
|
# Uncomment the following if you intend to modify def_data.in
|
|
@DEV@def_data.h def_data.c: def_data.in
|
|
--- sudo-1.6.8p12/visudo.c.ipv6 2004-11-25 18:32:40.000000000 +0100
|
|
+++ sudo-1.6.8p12/visudo.c 2006-07-16 23:33:58.000000000 +0200
|
|
@@ -87,6 +87,7 @@
|
|
static int check_syntax __P((int));
|
|
int command_matches __P((char *, char *));
|
|
int addr_matches __P((char *));
|
|
+int addr6_matches __P((char *));
|
|
int hostname_matches __P((char *, char *, char *));
|
|
int netgr_matches __P((char *, char *, char *, char *));
|
|
int usergr_matches __P((char *, char *, struct passwd *));
|
|
@@ -515,6 +516,12 @@
|
|
return(TRUE);
|
|
}
|
|
|
|
+int addr6_matches(n)
|
|
+ char *n;
|
|
+{
|
|
+ return(TRUE);
|
|
+}
|
|
+
|
|
int
|
|
hostname_matches(s, l, p)
|
|
char *s, *l, *p;
|
|
--- sudo-1.6.8p12/parse.lex.ipv6 2004-05-17 22:51:13.000000000 +0200
|
|
+++ sudo-1.6.8p12/parse.lex 2006-07-16 23:33:58.000000000 +0200
|
|
@@ -84,6 +84,29 @@
|
|
|
|
OCTET (1?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5])
|
|
DOTTEDQUAD {OCTET}(\.{OCTET}){3}
|
|
+
|
|
+IPV6_8HEX ([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}
|
|
+
|
|
+IPV6_COMP0 :(:[0-9A-Fa-f]{1,4}){1,7}
|
|
+IPV6_COMP1 ([0-9A-Fa-f]{1,4}){1}:(:[0-9A-Fa-f]{1,4}){0,6}
|
|
+IPV6_COMP2 ([0-9A-Fa-f]{1,4}){2}:(:[0-9A-Fa-f]{1,4}){0,5}
|
|
+IPV6_COMP3 ([0-9A-Fa-f]{1,4}){3}:(:[0-9A-Fa-f]{1,4}){0,4}
|
|
+IPV6_COMP4 ([0-9A-Fa-f]{1,4}){4}:(:[0-9A-Fa-f]{1,4}){0,3}
|
|
+IPV6_COMP5 ([0-9A-Fa-f]{1,4}){5}:(:[0-9A-Fa-f]{1,4}){0,2}
|
|
+IPV6_COMP6 ([0-9A-Fa-f]{1,4}){6}:(:[0-9A-Fa-f]{1,4}){0,1}
|
|
+IPV6_COMPHEX {IPV6_COMP0}|{IPV6_COMP1}|{IPV6_COMP2}|{IPV6_COMP3}|{IPV6_COMP4}|{IPV6_COMP5}|{IPV6_COMP6}
|
|
+
|
|
+IPV6_6H4D [0-9A-Fa-f]{1,4}(:[0-9A-Fa-f]{1,4}){5}{DOTTEDQUAD}
|
|
+
|
|
+IPV6_COMP6H4D0 ([0-9A-Fa-f]{1,4}){1}:(:[0-9A-Fa-f]{1,4}){1,4}:{DOTTEDQUAD}
|
|
+IPV6_COMP6H4D1 ([0-9A-Fa-f]{1,4}){2}:(:[0-9A-Fa-f]{1,4}){1,3}:{DOTTEDQUAD}
|
|
+IPV6_COMP6H4D2 ([0-9A-Fa-f]{1,4}){3}:(:[0-9A-Fa-f]{1,4}){1,2}:{DOTTEDQUAD}
|
|
+IPV6_COMP6H4D3 ([0-9A-Fa-f]{1,4}){4}:(:[0-9A-Fa-f]{1,4}){1}:{DOTTEDQUAD}
|
|
+IPV6_COMP6H4D {IPV6_COMP6H4D0}|{IPV6_COMP6H4D1}|{IPV6_COMP6H4D2}|{IPV6_COMP6H4D3}
|
|
+
|
|
+IPV6ADDR {IPV6_8HEX}|{IPV6_COMPHEX}|{IPV6_6H4D}|{IPV6_COMP6H4D}
|
|
+IPV6PREFIX [1-9]|[1-9][0-9]|10[0-9]|11[0-9]|12[0-8]
|
|
+
|
|
HOSTNAME [[:alnum:]_-]+
|
|
WORD ([^#>@!=:,\(\) \t\n\\]|\\[^\n])+
|
|
ENVAR ([^#!=, \t\n\\]|\\[^\n])([^#=, \t\n\\]|\\[^\n])*
|
|
@@ -253,6 +276,11 @@
|
|
LEXTRACE("NTWKADDR ");
|
|
return(NTWKADDR);
|
|
}
|
|
+{IPV6ADDR}(\/{IPV6PREFIX})? {
|
|
+ fill(yytext, yyleng);
|
|
+ LEXTRACE("NTWKADDR6 ");
|
|
+ return(NTWKADDR6);
|
|
+ }
|
|
|
|
<INITIAL>\( {
|
|
BEGIN GOTRUNAS;
|
|
--- sudo-1.6.8p12/ldap.c.ipv6 2006-07-16 23:45:35.000000000 +0200
|
|
+++ sudo-1.6.8p12/ldap.c 2006-07-16 23:59:56.000000000 +0200
|
|
@@ -160,6 +160,7 @@
|
|
if (
|
|
!strcasecmp(*p,"ALL") ||
|
|
addr_matches(*p) ||
|
|
+ addr6_matches(*p) ||
|
|
netgr_matches(*p,user_host,user_shost,NULL) ||
|
|
!hostname_matches(user_shost,user_host,*p)
|
|
)
|
|
--- sudo-1.6.8p12/parse.h.ipv6 2005-06-19 20:58:19.000000000 +0200
|
|
+++ sudo-1.6.8p12/parse.h 2006-07-16 23:33:58.000000000 +0200
|
|
@@ -93,6 +93,7 @@
|
|
* Prototypes
|
|
*/
|
|
int addr_matches __P((char *));
|
|
+int addr6_matches __P((char *));
|
|
int command_matches __P((char *, char *));
|
|
int hostname_matches __P((char *, char *, char *));
|
|
int netgr_matches __P((char *, char *, char *, char *));
|
|
--- sudo-1.6.8p12/interfaces.h.ipv6 2004-02-13 22:36:43.000000000 +0100
|
|
+++ sudo-1.6.8p12/interfaces.h 2006-07-16 23:33:58.000000000 +0200
|
|
@@ -27,8 +27,11 @@
|
|
* IP address and netmask pairs for checking against local interfaces.
|
|
*/
|
|
struct interface {
|
|
- struct in_addr addr;
|
|
+ struct in_addr addr; /* IPv4 */
|
|
struct in_addr netmask;
|
|
+ struct in6_addr addr6; /* IPv6 */
|
|
+ struct in6_addr netmask6;
|
|
+ sa_family_t sa_family; /* AF_INET ? AF_INET6 */
|
|
};
|
|
|
|
/*
|
|
--- sudo-1.6.8p12/parse.c.ipv6 2005-06-19 22:03:24.000000000 +0200
|
|
+++ sudo-1.6.8p12/parse.c 2006-07-16 23:57:20.000000000 +0200
|
|
@@ -370,38 +370,134 @@
|
|
int i;
|
|
char *m;
|
|
struct in_addr addr, mask;
|
|
+ struct addrinfo hints, *ai;
|
|
+
|
|
+ memset(&hints, '\0', sizeof(hints));
|
|
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
|
|
+ hints.ai_family = AF_INET;
|
|
|
|
/* If there's an explicit netmask, use it. */
|
|
if ((m = strchr(n, '/'))) {
|
|
+
|
|
*m++ = '\0';
|
|
- addr.s_addr = inet_addr(n);
|
|
+ if (getaddrinfo(n, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&addr.s_addr, &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
|
|
+ sizeof(struct in_addr));
|
|
+ freeaddrinfo(ai);
|
|
+
|
|
if (strchr(m, '.'))
|
|
- mask.s_addr = inet_addr(m);
|
|
- else {
|
|
- i = 32 - atoi(m);
|
|
- mask.s_addr = 0xffffffff;
|
|
- mask.s_addr >>= i;
|
|
- mask.s_addr <<= i;
|
|
- mask.s_addr = htonl(mask.s_addr);
|
|
+ {
|
|
+ if (getaddrinfo(m, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&mask.s_addr, /* IPv4 netmask from dotted quad */
|
|
+ &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
|
|
+ sizeof(struct in_addr));
|
|
}
|
|
+ else
|
|
+ {
|
|
+ i = 32 - atoi(m); /* IPv4 netmask from CIDR */
|
|
+ mask.s_addr = 0xffffffff;
|
|
+ mask.s_addr >>= i;
|
|
+ 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);
|
|
+ for (i = 0; i < num_interfaces; ++i)
|
|
+ if (interfaces[i].sa_family == AF_INET) /* IPv4 intf. only */
|
|
+ if ((interfaces[i].addr.s_addr & mask.s_addr) == addr.s_addr)
|
|
+ return (TRUE);
|
|
} else {
|
|
- addr.s_addr = inet_addr(n);
|
|
+ if (getaddrinfo(n, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&addr.s_addr, &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
|
|
+ sizeof(struct in_addr));
|
|
+ freeaddrinfo(ai);
|
|
|
|
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);
|
|
+ if (interfaces[i].sa_family == AF_INET) /* IPv4 intf. only */
|
|
+ if (interfaces[i].addr.s_addr == addr.s_addr ||
|
|
+ (interfaces[i].addr.s_addr & interfaces[i].netmask.s_addr)
|
|
+ == addr.s_addr)
|
|
+ return(TRUE);
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
+int
|
|
+addr6_matches(n)
|
|
+char *n;
|
|
+{
|
|
+ int i, j;
|
|
+ uint32_t msk[4] = {0, 0, 0, 0}; /* 32x4 */
|
|
+ uint32_t addr[4], i_msk[4], i_addr[4];
|
|
+ char *m;
|
|
+ struct addrinfo hints, *ai;
|
|
+
|
|
+ memset(&hints, '\0', sizeof(hints));
|
|
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
|
|
+ hints.ai_family = AF_INET6;
|
|
+
|
|
+ /* we have IPv6 prefix */
|
|
+ if ((m = strchr(n, '/'))) {
|
|
+ *m++ = '\0';
|
|
+ if (getaddrinfo(n, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&addr, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, 16);
|
|
+ freeaddrinfo(ai);
|
|
+
|
|
+ for (i=0; i < (atoi(m)/32); ++i)
|
|
+ msk[i] = 0xffffffff;
|
|
+ if (atoi(m)<128 && (atoi(m) % 32))
|
|
+ {
|
|
+ msk[atoi(m)/32] = 0xffffffff;
|
|
+ msk[atoi(m)/32] >>= ( 32 - (atoi(m) % 32) );
|
|
+ msk[atoi(m)/32] <<= ( 32 - (atoi(m) % 32) );
|
|
+ }
|
|
+ for (i=0; i<4; ++i)
|
|
+ msk[i] = htonl(msk[i]);
|
|
+
|
|
+ *(m - 1) = '/';
|
|
+
|
|
+ for (i=0; i < num_interfaces; i++)
|
|
+ if (interfaces[i].sa_family == AF_INET6) /* compare only IPv6 intf. */
|
|
+ {
|
|
+ /* nasty */
|
|
+ memcpy(&i_addr, &interfaces[i].addr6, 16);
|
|
+ if ( ((i_addr[0] & msk[0]) == addr[0]) &&
|
|
+ ((i_addr[1] & msk[1]) == addr[1]) &&
|
|
+ ((i_addr[2] & msk[2]) == addr[2]) &&
|
|
+ ((i_addr[3] & msk[3]) == addr[3]))
|
|
+ return(TRUE);
|
|
+ }
|
|
+ } else {
|
|
+ if (getaddrinfo(n, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&addr, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, 16);
|
|
+ freeaddrinfo(ai);
|
|
+
|
|
+ for (i=0; i < num_interfaces; ++i)
|
|
+ if (interfaces[i].sa_family == AF_INET6) /* IPv6 intf. only */
|
|
+ {
|
|
+ memcpy(&i_addr, &interfaces[i].addr6, 16);
|
|
+ if ((i_addr[0] == addr[0]) && (i_addr[1] == addr[1]) &&
|
|
+ (i_addr[2] == addr[2]) && (i_addr[3] == addr[3]))
|
|
+ return(TRUE); /* found my own address in sudoers */
|
|
+
|
|
+ memcpy(&i_msk, &interfaces[i].netmask6, 16);
|
|
+ if (((i_addr[0]&i_msk[0]) == addr[0]) &&
|
|
+ ((i_addr[1]&i_msk[1]) == addr[1]) &&
|
|
+ ((i_addr[2]&i_msk[2]) == addr[2]) &&
|
|
+ ((i_addr[3]&i_msk[3]) == addr[3]))
|
|
+ return(TRUE); /* found my netw. address in sudoers */
|
|
+ }
|
|
+ }
|
|
+ return(FALSE);
|
|
+}
|
|
+
|
|
/*
|
|
* Returns 0 if the hostname matches the pattern and non-zero otherwise.
|
|
*/
|
|
--- sudo-1.6.8p12/sudo.c.ipv6 2006-07-16 23:33:58.000000000 +0200
|
|
+++ sudo-1.6.8p12/sudo.c 2006-07-16 23:33:58.000000000 +0200
|
|
@@ -1007,24 +1007,34 @@
|
|
void
|
|
set_fqdn()
|
|
{
|
|
- struct hostent *hp;
|
|
+ struct addrinfo hints, *ai;
|
|
char *p;
|
|
|
|
- if (!(hp = gethostbyname(user_host))) {
|
|
- log_error(MSG_ONLY|NO_EXIT,
|
|
- "unable to lookup %s via gethostbyname()", user_host);
|
|
- } else {
|
|
- if (user_shost != user_host)
|
|
+ memset(&hints, '\0', sizeof(hints));
|
|
+ hints.ai_flags = AI_ADDRCONFIG;
|
|
+
|
|
+ if (getaddrinfo(user_host, NULL, &hints, &ai) != 0)
|
|
+ {
|
|
+ log_error(MSG_ONLY|NO_EXIT,
|
|
+ "unable to lookup %s via gethostbyname()", user_host);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ char h_name[NI_MAXHOST];
|
|
+
|
|
+ if (user_host != user_host)
|
|
free(user_shost);
|
|
+
|
|
+ getnameinfo(ai->ai_addr, ai->ai_addrlen, h_name, sizeof(h_name), NULL, 0, 0);
|
|
free(user_host);
|
|
- user_host = estrdup(hp->h_name);
|
|
+ user_host = estrdup(h_name);
|
|
}
|
|
if ((p = strchr(user_host, '.'))) {
|
|
- *p = '\0';
|
|
- user_shost = estrdup(user_host);
|
|
- *p = '.';
|
|
+ *p = '\0';
|
|
+ user_shost = estrdup(user_host);
|
|
+ *p = '.';
|
|
} else {
|
|
- user_shost = user_host;
|
|
+ user_shost = user_host;
|
|
}
|
|
}
|
|
|
|
--- sudo-1.6.8p12/parse.yacc.ipv6 2005-06-19 20:24:32.000000000 +0200
|
|
+++ sudo-1.6.8p12/parse.yacc 2006-07-16 23:33:58.000000000 +0200
|
|
@@ -250,6 +250,7 @@
|
|
%token <tok> RUNASALIAS /* Runas_Alias keyword */
|
|
%token <tok> ':' '=' ',' '!' '+' '-' /* union member tokens */
|
|
%token <tok> ERROR
|
|
+%token <string> NTWKADDR6 /* IPv6 address */
|
|
|
|
/*
|
|
* NOTE: these are not true booleans as there are actually 4 possible values:
|
|
@@ -395,6 +396,13 @@
|
|
$$ = NOMATCH;
|
|
free($1);
|
|
}
|
|
+ | NTWKADDR6 {
|
|
+ if (addr6_matches($1))
|
|
+ $$ = TRUE;
|
|
+ else
|
|
+ $$ = NOMATCH;
|
|
+ free($1);
|
|
+ }
|
|
| NETGROUP {
|
|
if (netgr_matches($1, user_host, user_shost, NULL))
|
|
$$ = TRUE;
|
|
--- sudo-1.6.8p12/testsudoers.c.ipv6 2004-08-02 20:44:58.000000000 +0200
|
|
+++ sudo-1.6.8p12/testsudoers.c 2006-07-17 00:03:50.000000000 +0200
|
|
@@ -175,6 +175,10 @@
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * 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;
|
|
@@ -182,39 +186,136 @@
|
|
int i;
|
|
char *m;
|
|
struct in_addr addr, mask;
|
|
+ struct addrinfo hints, *ai;
|
|
+
|
|
+ memset(&hints, '\0', sizeof(hints));
|
|
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
|
|
+ hints.ai_family = AF_INET;
|
|
|
|
/* If there's an explicit netmask, use it. */
|
|
if ((m = strchr(n, '/'))) {
|
|
- *m++ = '\0';
|
|
- addr.s_addr = inet_addr(n);
|
|
- if (strchr(m, '.'))
|
|
- mask.s_addr = inet_addr(m);
|
|
- else {
|
|
- i = 32 - atoi(m);
|
|
- mask.s_addr = 0xffffffff;
|
|
- mask.s_addr >>= i;
|
|
- 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);
|
|
+ *m++ = '\0';
|
|
+ if (getaddrinfo(n, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&addr.s_addr, &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
|
|
+ sizeof(struct in_addr));
|
|
+ freeaddrinfo(ai);
|
|
+
|
|
+ if (strchr(m, '.'))
|
|
+ {
|
|
+ if (getaddrinfo(m, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&mask.s_addr, /* IPv4 netmask from dotted quad */
|
|
+ &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
|
|
+ sizeof(struct in_addr));
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ i = 32 - atoi(m); /* IPv4 netmask from CIDR */
|
|
+ mask.s_addr = 0xffffffff;
|
|
+ mask.s_addr >>= i;
|
|
+ mask.s_addr <<= i;
|
|
+ mask.s_addr = htonl(mask.s_addr);
|
|
+ }
|
|
+
|
|
+ *(m - 1) = '/';
|
|
+
|
|
+ for (i = 0; i < num_interfaces; ++i)
|
|
+ if (interfaces[i].sa_family == AF_INET) /* IPv4 intf. only */
|
|
+ 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);
|
|
+ if (getaddrinfo(n, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&addr.s_addr, &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
|
|
+ sizeof(struct in_addr));
|
|
+ freeaddrinfo(ai);
|
|
+
|
|
+ for (i = 0; i < num_interfaces; i++)
|
|
+ if (interfaces[i].sa_family == AF_INET) /* IPv4 intf. only */
|
|
+ if (interfaces[i].addr.s_addr == addr.s_addr ||
|
|
+ (interfaces[i].addr.s_addr & interfaces[i].netmask.s_addr)
|
|
+ == addr.s_addr)
|
|
+ return(TRUE);
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
int
|
|
+addr6_matches(n)
|
|
+char *n;
|
|
+{
|
|
+ int i, j;
|
|
+ uint32_t msk[4] = {0, 0, 0, 0}; /* 32x4 */
|
|
+ uint32_t addr[4], i_msk[4], i_addr[4];
|
|
+ char *m;
|
|
+ struct addrinfo hints, *ai;
|
|
+
|
|
+ memset(&hints, '\0', sizeof(hints));
|
|
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST;
|
|
+ hints.ai_family = AF_INET6;
|
|
+
|
|
+ /* we have IPv6 prefix */
|
|
+ if ((m = strchr(n, '/'))) {
|
|
+ *m++ = '\0';
|
|
+ if (getaddrinfo(n, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&addr, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, 16);
|
|
+ freeaddrinfo(ai);
|
|
+
|
|
+ for (i=0; i < (atoi(m)/32); ++i)
|
|
+ msk[i] = 0xffffffff;
|
|
+ if (atoi(m)<128 && (atoi(m) % 32))
|
|
+ {
|
|
+ msk[atoi(m)/32] = 0xffffffff;
|
|
+ msk[atoi(m)/32] >>= ( 32 - (atoi(m) % 32) );
|
|
+ msk[atoi(m)/32] <<= ( 32 - (atoi(m) % 32) );
|
|
+ }
|
|
+ for (i=0; i<4; ++i)
|
|
+ msk[i] = htonl(msk[i]);
|
|
+
|
|
+ *(m - 1) = '/';
|
|
+
|
|
+ for (i=0; i < num_interfaces; i++)
|
|
+ if (interfaces[i].sa_family == AF_INET6) /* compare only IPv6 intf. */
|
|
+ {
|
|
+ /* nasty */
|
|
+ memcpy(&i_addr, &interfaces[i].addr6, 16);
|
|
+ if ( ((i_addr[0] & msk[0]) == addr[0]) &&
|
|
+ ((i_addr[1] & msk[1]) == addr[1]) &&
|
|
+ ((i_addr[2] & msk[2]) == addr[2]) &&
|
|
+ ((i_addr[3] & msk[3]) == addr[3]))
|
|
+ return (TRUE);
|
|
+ }
|
|
+ } else {
|
|
+ if (getaddrinfo(n, NULL, &hints, &ai)!=0)
|
|
+ return(FALSE);
|
|
+ memcpy(&addr, &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr, 16);
|
|
+ freeaddrinfo(ai);
|
|
+
|
|
+ for (i=0; i < num_interfaces; ++i)
|
|
+ if (interfaces[i].sa_family == AF_INET6) /* IPv6 intf. only */
|
|
+ {
|
|
+ memcpy(&i_addr, &interfaces[i].addr6, 16);
|
|
+ if ((i_addr[0] == addr[0]) && (i_addr[1] == addr[1]) &&
|
|
+ (i_addr[2] == addr[2]) && (i_addr[3] == addr[3]))
|
|
+ return (TRUE); /* found my own address in sudoers */
|
|
+
|
|
+ memcpy(&i_msk, &interfaces[i].netmask6, 16);
|
|
+ if (((i_addr[0]&i_msk[0]) == addr[0]) &&
|
|
+ ((i_addr[1]&i_msk[1]) == addr[1]) &&
|
|
+ ((i_addr[2]&i_msk[2]) == addr[2]) &&
|
|
+ ((i_addr[3]&i_msk[3]) == addr[3]))
|
|
+ return (TRUE); /* found my netw. address in sudoers */
|
|
+ }
|
|
+ }
|
|
+ return(FALSE);
|
|
+}
|
|
+
|
|
+
|
|
+int
|
|
hostname_matches(shost, lhost, pattern)
|
|
char *shost;
|
|
char *lhost;
|
|
--- sudo-1.6.8p12/interfaces.c.ipv6 2004-02-13 22:36:43.000000000 +0100
|
|
+++ sudo-1.6.8p12/interfaces.c 2006-07-16 23:33:58.000000000 +0200
|
|
@@ -102,7 +102,7 @@
|
|
load_interfaces()
|
|
{
|
|
struct ifaddrs *ifa, *ifaddrs;
|
|
- /* XXX - sockaddr_in6 sin6; */
|
|
+ struct sockaddr_in6 *sin6;
|
|
struct sockaddr_in *sin;
|
|
int i;
|
|
|
|
@@ -117,12 +117,15 @@
|
|
continue;
|
|
|
|
switch(ifa->ifa_addr->sa_family) {
|
|
- /* XXX - AF_INET6 */
|
|
case AF_INET:
|
|
num_interfaces++;
|
|
break;
|
|
+ case AF_INET6:
|
|
+ num_interfaces++;
|
|
+ break;
|
|
}
|
|
}
|
|
+
|
|
if (num_interfaces == 0)
|
|
return;
|
|
interfaces =
|
|
@@ -136,8 +139,8 @@
|
|
continue;
|
|
|
|
switch(ifa->ifa_addr->sa_family) {
|
|
- /* XXX - AF_INET6 */
|
|
case AF_INET:
|
|
+ interfaces[i].sa_family = AF_INET;
|
|
sin = (struct sockaddr_in *)ifa->ifa_addr;
|
|
memcpy(&interfaces[i].addr, &sin->sin_addr,
|
|
sizeof(struct in_addr));
|
|
@@ -146,6 +149,16 @@
|
|
sizeof(struct in_addr));
|
|
i++;
|
|
break;
|
|
+ case AF_INET6:
|
|
+ interfaces[i].sa_family = AF_INET6;
|
|
+ sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
|
|
+ memcpy(&interfaces[i].addr6, &sin6->sin6_addr,
|
|
+ sizeof(struct in6_addr));
|
|
+ sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask;
|
|
+ memcpy(&interfaces[i].netmask6, &sin6->sin6_addr,
|
|
+ sizeof(struct in6_addr));
|
|
+ i++;
|
|
+ break;
|
|
}
|
|
}
|
|
#ifdef HAVE_FREEIFADDRS
|
|
@@ -306,10 +319,30 @@
|
|
void
|
|
dump_interfaces()
|
|
{
|
|
- int i;
|
|
+ int i, j, ip6_prefix=0; /* for counting IPv6 prefix length (in bits!!) */
|
|
+ uint8_t u6_addr8[16]; /* for storing IPv6 netmask */
|
|
|
|
puts("Local IP address and netmask pairs:");
|
|
for (i = 0; i < num_interfaces; i++)
|
|
- printf("\t%s / 0x%x\n", inet_ntoa(interfaces[i].addr),
|
|
- (unsigned int)ntohl(interfaces[i].netmask.s_addr));
|
|
+ {
|
|
+ char name[NI_MAXHOST], netmask[NI_MAXHOST];
|
|
+ ip6_prefix=0;
|
|
+
|
|
+ switch (interfaces[i].sa_family)
|
|
+ {
|
|
+ case AF_INET:
|
|
+ inet_ntop(AF_INET, &interfaces[i].addr, name, NI_MAXHOST);
|
|
+ inet_ntop(AF_INET, &interfaces[i].netmask, netmask, NI_MAXHOST);
|
|
+ printf("\t%s / %s\n", name, netmask);
|
|
+ break;
|
|
+ case AF_INET6:
|
|
+ inet_ntop(AF_INET6, &interfaces[i].addr6, name, NI_MAXHOST);
|
|
+ memcpy(u6_addr8, &interfaces[i].netmask6, 16);
|
|
+ for (j=0; j<16; ++j)
|
|
+ if (u6_addr8[j] == 255) /* 255 == 0xff */
|
|
+ ip6_prefix=ip6_prefix+8; /* eight bits */
|
|
+ printf("\t%s / %d\n", name, ip6_prefix);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
}
|