145 lines
3.1 KiB
Diff
145 lines
3.1 KiB
Diff
diff --git a/CHANGELOG b/CHANGELOG
|
|
index 0bb91e9..34fad3e 100644
|
|
--- a/CHANGELOG
|
|
+++ b/CHANGELOG
|
|
@@ -2,6 +2,7 @@
|
|
-----------------------
|
|
- fix return check for getpwuid_r and getgrgid_r.
|
|
- give up trying to update exports list while host is mounted.
|
|
+- fix to "@network" matching.
|
|
|
|
20/2/2007 autofs-5.0.1
|
|
----------------------
|
|
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
|
|
index f51ca82..2c5b5d5 100644
|
|
--- a/lib/rpc_subs.c
|
|
+++ b/lib/rpc_subs.c
|
|
@@ -31,6 +31,7 @@
|
|
#include <rpcsvc/ypclnt.h>
|
|
#include <errno.h>
|
|
#include <sys/ioctl.h>
|
|
+#include <ctype.h>
|
|
#include <pthread.h>
|
|
|
|
#include "mount.h"
|
|
@@ -46,6 +47,8 @@
|
|
#define MAX_IFC_BUF 1024
|
|
#define MAX_ERR_BUF 128
|
|
|
|
+#define MAX_NETWORK_LEN 255
|
|
+
|
|
/* Get numeric value of the n bits starting at position p */
|
|
#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n))
|
|
|
|
@@ -1066,6 +1069,9 @@ static char *inet_fill_net(const char *net_num, char *net)
|
|
char *np;
|
|
unsigned int dots = 3;
|
|
|
|
+ if (strlen(net_num) > INET_ADDRSTRLEN)
|
|
+ return NULL;
|
|
+
|
|
*net = '\0';
|
|
strcpy(net, net_num);
|
|
|
|
@@ -1076,6 +1082,11 @@ static char *inet_fill_net(const char *net_num, char *net)
|
|
if (!*np && dots)
|
|
strcat(net, "0");
|
|
}
|
|
+
|
|
+ if (!isdigit(*np) || dots < 0) {
|
|
+ *net = '\0';
|
|
+ return NULL;
|
|
+ }
|
|
}
|
|
|
|
while (dots--)
|
|
@@ -1088,13 +1099,21 @@ static int match_network(const char *network)
|
|
{
|
|
struct netent *pnent, nent;
|
|
const char *pcnet;
|
|
- char *net, cnet[INET_ADDRSTRLEN + 1], mask[4], *pmask;
|
|
+ char *net, cnet[MAX_NETWORK_LEN], mask[4], *pmask;
|
|
unsigned int size;
|
|
+ size_t l_network = strlen(network) + 1;
|
|
int status;
|
|
|
|
- net = alloca(strlen(network) + 1);
|
|
+ if (l_network > MAX_NETWORK_LEN) {
|
|
+ error(LOGOPT_ANY,
|
|
+ "match string \"%s\" too long", network);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ net = alloca(l_network);
|
|
if (!net)
|
|
return 0;
|
|
+ memset(net, 0, l_network);
|
|
strcpy(net, network);
|
|
|
|
if ((pmask = strchr(net, '/')))
|
|
@@ -1115,32 +1134,48 @@ static int match_network(const char *network)
|
|
if (pnent) {
|
|
uint32_t n_net;
|
|
|
|
- n_net = ntohl(nent.n_net);
|
|
- pcnet = inet_ntop(nent.n_addrtype, &n_net, cnet, INET_ADDRSTRLEN);
|
|
- if (!pcnet)
|
|
+ switch (nent.n_addrtype) {
|
|
+ case AF_INET:
|
|
+ n_net = ntohl(nent.n_net);
|
|
+ pcnet = inet_ntop(AF_INET, &n_net, cnet, INET_ADDRSTRLEN);
|
|
+ if (!pcnet)
|
|
+ return 0;
|
|
+
|
|
+ if (!pmask) {
|
|
+ size = inet_get_net_len(nent.n_net);
|
|
+ if (!size)
|
|
+ return 0;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case AF_INET6:
|
|
return 0;
|
|
|
|
- if (!pmask) {
|
|
- size = inet_get_net_len(nent.n_net);
|
|
- if (!size)
|
|
- return 0;
|
|
+ default:
|
|
+ return 0;
|
|
}
|
|
} else {
|
|
- struct in_addr addr;
|
|
int ret;
|
|
|
|
- pcnet = inet_fill_net(net, cnet);
|
|
- if (!pcnet)
|
|
+ if (strchr(net, ':')) {
|
|
return 0;
|
|
+ } else {
|
|
+ struct in_addr addr;
|
|
|
|
- ret = inet_pton(AF_INET, pcnet, &addr);
|
|
- if (ret <= 0)
|
|
- return 0;
|
|
+ pcnet = inet_fill_net(net, cnet);
|
|
+ if (!pcnet)
|
|
+ return 0;
|
|
|
|
- if (!pmask) {
|
|
- size = inet_get_net_len(htonl(addr.s_addr));
|
|
- if (!size)
|
|
+ ret = inet_pton(AF_INET, pcnet, &addr);
|
|
+ if (ret <= 0)
|
|
return 0;
|
|
+
|
|
+ if (!pmask) {
|
|
+ uint32_t nl_addr = htonl(addr.s_addr);
|
|
+ size = inet_get_net_len(nl_addr);
|
|
+ if (!size)
|
|
+ return 0;
|
|
+ }
|
|
}
|
|
}
|
|
|