IPv6 and keyring support

This commit is contained in:
kzak 2006-07-16 22:37:37 +00:00
parent 0778e3bc07
commit 4616de0e31
3 changed files with 756 additions and 2 deletions

611
sudo-1.6.8p12-ipv6.patch Normal file
View File

@ -0,0 +1,611 @@
--- 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;
+ }
+ }
}

View File

@ -0,0 +1,116 @@
--- sudo-1.6.8p12/configure.in.login 2006-07-16 15:25:33.000000000 +0200
+++ sudo-1.6.8p12/configure.in 2006-07-16 15:49:08.000000000 +0200
@@ -357,6 +357,17 @@
;;
esac])
+AC_ARG_WITH(pam-login, [ --with-pam-login enable specific PAM session for sudo -i],
+[case $with_pam_login in
+ yes) AC_DEFINE(HAVE_PAM_LOGIN)
+ AC_MSG_CHECKING(whether to use PAM login)
+ AC_MSG_RESULT(yes)
+ ;;
+ no) ;;
+ *) AC_MSG_ERROR(["--with-pam-login does not take an argument."])
+ ;;
+esac])
+
AC_ARG_WITH(AFS, [ --with-AFS enable AFS support],
[case $with_AFS in
yes) AC_DEFINE(HAVE_AFS)
--- sudo-1.6.8p12/sudo.c.login 2006-07-16 15:39:26.000000000 +0200
+++ sudo-1.6.8p12/sudo.c 2006-07-16 15:41:42.000000000 +0200
@@ -109,7 +109,7 @@
static struct passwd *get_authpw __P((void));
extern int sudo_edit __P((int, char **));
extern void list_matches __P((void));
-extern char **rebuild_env __P((char **, int, int));
+extern char **rebuild_env __P((char **, int));
extern char **zero_env __P((char **));
extern struct passwd *sudo_getpwnam __P((const char *));
extern struct passwd *sudo_getpwuid __P((uid_t));
@@ -140,6 +140,7 @@
#endif /* HAVE_BSD_AUTH_H */
sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp, saved_sa_chld;
void (*set_perms) __P((int));
+int sudo_mode;
int
@@ -151,7 +152,6 @@
int validated;
int fd;
int cmnd_status;
- int sudo_mode;
int pwflag;
char **new_environ;
sigaction_t sa;
@@ -368,7 +368,7 @@
/* Build a new environment that avoids any nasty bits if we have a cmnd. */
if (ISSET(sudo_mode, MODE_RUN))
- new_environ = rebuild_env(envp, sudo_mode, ISSET(validated, FLAG_NOEXEC));
+ new_environ = rebuild_env(envp, ISSET(validated, FLAG_NOEXEC));
else
new_environ = envp;
--- sudo-1.6.8p12/auth/pam.c.login 2006-07-16 15:41:59.000000000 +0200
+++ sudo-1.6.8p12/auth/pam.c 2006-07-16 15:45:15.000000000 +0200
@@ -89,7 +89,12 @@
if (auth != NULL)
auth->data = (VOID *) &pam_status;
pam_conv.conv = sudo_conv;
- pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh);
+#ifdef HAVE_PAM_LOGIN
+ if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
+ pam_status = pam_start("sudo-i", pw->pw_name, &pam_conv, &pamh);
+ else
+#endif
+ pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh);
if (pam_status != PAM_SUCCESS) {
log_error(USE_ERRNO|NO_EXIT|NO_MAIL, "unable to initialize PAM");
return(AUTH_FATAL);
--- sudo-1.6.8p12/env.c.login 2006-07-16 15:40:14.000000000 +0200
+++ sudo-1.6.8p12/env.c 2006-07-16 15:57:19.000000000 +0200
@@ -77,7 +77,7 @@
/*
* Prototypes
*/
-char **rebuild_env __P((char **, int, int));
+char **rebuild_env __P((char **, int));
char **zero_env __P((char **));
static void insert_env __P((char *, int));
static char *format_env __P((char *, ...));
@@ -321,9 +321,8 @@
* Also adds sudo-specific variables (SUDO_*).
*/
char **
-rebuild_env(envp, sudo_mode, noexec)
+rebuild_env(envp, noexec)
char **envp;
- int sudo_mode;
int noexec;
{
char **ep, *cp, *ps1;
--- sudo-1.6.8p12/sudo.h.login 2006-07-16 15:59:08.000000000 +0200
+++ sudo-1.6.8p12/sudo.h 2006-07-16 15:59:38.000000000 +0200
@@ -251,6 +251,7 @@
extern FILE *sudoers_fp;
extern int tgetpass_flags;
extern uid_t timestamp_uid;
+extern int sudo_mode;
extern void (*set_perms) __P((int));
#endif
--- sudo-1.6.8p12/config.h.in.login 2006-07-16 15:32:09.000000000 +0200
+++ sudo-1.6.8p12/config.h.in 2006-07-16 15:32:56.000000000 +0200
@@ -230,6 +230,9 @@
/* Define to 1 if you use PAM authentication. */
#undef HAVE_PAM
+/* Define to 1 if you use specific PAM session for sodo -i. */
+#undef HAVE_PAM_LOGIN
+
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
#undef HAVE_PAM_PAM_APPL_H

View File

@ -1,7 +1,7 @@
Summary: Allows restricted root access for specified users.
Name: sudo
Version: 1.6.8p12
Release: 6.1
Release: 7
License: BSD
Group: Applications/System
Source: http://www.courtesan.com/sudo/dist/sudo-%{version}.tar.gz
@ -12,6 +12,8 @@ Requires: /etc/pam.d/system-auth, vim-minimal
BuildRequires: pam-devel
BuildRequires: groff
BuildRequires: openldap-devel
BuildRequires: flex
BuildRequires: bison
# 154511 - sudo does not use limits.conf
Patch2: sudo-1.6.8p8-pam-sess.patch
@ -21,6 +23,10 @@ Patch3: sudo-1.6.7p5-strip.patch
Patch4: sudo-1.6.8p12-env-reset.patch
# Default sudoers; require tty (#190062)
Patch5: sudo-1.6.8p12-requiretty.patch
# Use specific PAM session for sudo -i (#198755)
Patch6: sudo-1.6.8p12-pam-login.patch
# IPv6 support
Patch7: sudo-1.6.8p12-ipv6.patch
%description
Sudo (superuser do) allows a system administrator to give certain
@ -39,6 +45,8 @@ on many different machines.
%patch3 -p1 -b .strip
%patch4 -p1 -b .env_reset
%patch5 -p1 -b .tty
%patch6 -p1 -b .login
%patch7 -p1 -b .ipv6
%build
%ifarch s390 s390x
@ -47,7 +55,10 @@ F_PIE=-fPIE
F_PIE=-fpie
%endif
export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie"
# Note: there is a problem rebuild the ./configure script (for pam-login patch),
# so we use -DHAVE_PAM_LOGIN rather than --with-pam-login...
# (it's workaround that should be fixed)
export CFLAGS="$RPM_OPT_FLAGS $F_PIE -DHAVE_PAM_LOGIN" LDFLAGS="-pie"
%configure \
--prefix=%{_prefix} \
@ -75,6 +86,16 @@ cat > $RPM_BUILD_ROOT/etc/pam.d/sudo << EOF
auth include system-auth
account include system-auth
password include system-auth
session optional pam_keyinit.so revoke
session required pam_limits.so
EOF
cat > $RPM_BUILD_ROOT/etc/pam.d/sudo-i << EOF
#%PAM-1.0
auth include sudo
account include sudo
password include sudo
session optional pam_keyinit.so force revoke
session required pam_limits.so
EOF
@ -87,6 +108,7 @@ rm -rf $RPM_BUILD_ROOT
%doc BUGS CHANGES HISTORY LICENSE README RUNSON TODO TROUBLESHOOTING UPGRADE *.pod
%attr(0440,root,root) %config(noreplace) /etc/sudoers
%config(noreplace) /etc/pam.d/sudo
%config(noreplace) /etc/pam.d/sudo-i
%dir /var/run/sudo
%attr(4111,root,root) %{_bindir}/sudo
%attr(4111,root,root) %{_bindir}/sudoedit
@ -102,6 +124,11 @@ rm -rf $RPM_BUILD_ROOT
/bin/chmod 0440 /etc/sudoers || :
%changelog
* Sun Jul 16 2006 Karel Zak <kzak@redhat.com> 1.6.8p12-7
- fix #198755 - make login processes (sudo -i) initialise session keyring
(thanks for PAM config files to David Howells)
- add IPv6 support (patch by Milan Zazrivec)
* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 1.6.8p12-6.1
- rebuild