~ubuntu-branches/ubuntu/quantal/sudo/quantal

« back to all changes in this revision

Viewing changes to src/net_ifs.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2011-11-20 12:07:45 UTC
  • mfrom: (1.3.17 sid)
  • Revision ID: package-import@ubuntu.com-20111120120745-o3qpklobmygytndc
Tags: 1.8.3p1-1ubuntu1
* Merge from debian/testing, remaining changes:
  - debian/patches/keep_home_by_default.patch:
    + Set HOME in initial_keepenv_table. (rebased for 1.8.3p1)
  - debian/patches/enable_badpass.patch: turn on "mail_badpass" by default:
    + attempting sudo without knowing a login password is as bad as not
      being listed in the sudoers file, especially if getting the password
      wrong means doing the access-check-email-notification never happens
      (rebased for 1.8.3p1)
  - debian/rules:
    + compile with --without-lecture --with-tty-tickets (Ubuntu specific)
    + install man/man8/sudo_root.8 (Ubuntu specific)
    + install apport hooks
    + The ubuntu-sudo-as-admin-successful.patch was taken upstream by
      Debian however it requires a --enable-admin-flag configure flag to
      actually enable it.
  - debian/sudoers: 
    + grant admin group sudo access
  - debian/sudo-ldap.dirs, debian/sudo.dirs: 
    + add usr/share/apport/package-hooks
  - debian/sudo.preinst:
    + avoid conffile prompt by checking for known default /etc/sudoers
      and if found installing the correct default /etc/sudoers file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1996, 1998-2005, 2007-2010
 
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
 *
 
17
 * Sponsored in part by the Defense Advanced Research Projects
 
18
 * Agency (DARPA) and Air Force Research Laboratory, Air Force
 
19
 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
 
20
 */
 
21
 
 
22
/*
 
23
 * Suppress a warning w/ gcc on Digital UN*X.
 
24
 * The system headers should really do this....
 
25
 */
 
26
#if defined(__osf__) && !defined(__cplusplus)
 
27
struct mbuf;
 
28
struct rtentry;
 
29
#endif
 
30
 
 
31
#include <config.h>
 
32
 
 
33
#include <sys/types.h>
 
34
#include <sys/socket.h>
 
35
#include <sys/param.h>
 
36
#include <sys/time.h>
 
37
#include <sys/ioctl.h>
 
38
#if defined(HAVE_SYS_SOCKIO_H) && !defined(SIOCGIFCONF)
 
39
# include <sys/sockio.h>
 
40
#endif
 
41
#include <stdio.h>
 
42
#ifdef STDC_HEADERS
 
43
# include <stdlib.h>
 
44
# include <stddef.h>
 
45
#else
 
46
# ifdef HAVE_STDLIB_H
 
47
#  include <stdlib.h>
 
48
# endif
 
49
#endif /* STDC_HEADERS */
 
50
#ifdef HAVE_STRING_H
 
51
# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
 
52
#  include <memory.h>
 
53
# endif
 
54
# include <string.h>
 
55
#endif /* HAVE_STRING_H */
 
56
#ifdef HAVE_STRINGS_H
 
57
# include <strings.h>
 
58
#endif /* HAVE_STRINGS_H */
 
59
#ifdef HAVE_UNISTD_H
 
60
# include <unistd.h>
 
61
#endif /* HAVE_UNISTD_H */
 
62
#include <netdb.h>
 
63
#include <errno.h>
 
64
#ifdef _ISC
 
65
# include <sys/stream.h>
 
66
# include <sys/sioctl.h>
 
67
# include <sys/stropts.h>
 
68
# define STRSET(cmd, param, len) {strioctl.ic_cmd=(cmd);\
 
69
                                 strioctl.ic_dp=(param);\
 
70
                                 strioctl.ic_timout=0;\
 
71
                                 strioctl.ic_len=(len);}
 
72
#endif /* _ISC */
 
73
#ifdef _MIPS
 
74
# include <net/soioctl.h>
 
75
#endif /* _MIPS */
 
76
#include <netinet/in.h>
 
77
#include <arpa/inet.h>
 
78
#include <net/if.h>
 
79
#ifdef HAVE_GETIFADDRS
 
80
# include <ifaddrs.h>
 
81
#endif
 
82
 
 
83
#include "missing.h"
 
84
#include "alloc.h"
 
85
#include "error.h"
 
86
 
 
87
#define DEFAULT_TEXT_DOMAIN     "sudo"
 
88
#include "gettext.h"
 
89
 
 
90
/* Minix apparently lacks IFF_LOOPBACK */
 
91
#ifndef IFF_LOOPBACK
 
92
# define IFF_LOOPBACK   0
 
93
#endif
 
94
 
 
95
#ifndef INET6_ADDRSTRLEN
 
96
# define INET6_ADDRSTRLEN 46
 
97
#endif
 
98
 
 
99
#ifdef HAVE_GETIFADDRS
 
100
 
 
101
/*
 
102
 * Fill in the interfaces string with the machine's ip addresses and netmasks
 
103
 * and return the number of interfaces found.
 
104
 */
 
105
int
 
106
get_net_ifs(char **addrinfo)
 
107
{
 
108
    struct ifaddrs *ifa, *ifaddrs;
 
109
    struct sockaddr_in *sin;
 
110
#ifdef HAVE_IN6_ADDR
 
111
    struct sockaddr_in6 *sin6;
 
112
    char addrbuf[INET6_ADDRSTRLEN];
 
113
#endif
 
114
    int ailen, i, len, num_interfaces = 0;
 
115
    char *cp;
 
116
 
 
117
    if (getifaddrs(&ifaddrs))
 
118
        return 0;
 
119
 
 
120
    /* Allocate space for the interfaces info string. */
 
121
    for (ifa = ifaddrs; ifa != NULL; ifa = ifa -> ifa_next) {
 
122
        /* Skip interfaces marked "down" and "loopback". */
 
123
        if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL ||
 
124
            !ISSET(ifa->ifa_flags, IFF_UP) || ISSET(ifa->ifa_flags, IFF_LOOPBACK))
 
125
            continue;
 
126
 
 
127
        switch (ifa->ifa_addr->sa_family) {
 
128
            case AF_INET:
 
129
#ifdef HAVE_IN6_ADDR
 
130
            case AF_INET6:
 
131
#endif
 
132
                num_interfaces++;
 
133
                break;
 
134
        }
 
135
    }
 
136
    if (num_interfaces == 0)
 
137
        return 0;
 
138
    ailen = num_interfaces * 2 * INET6_ADDRSTRLEN;
 
139
    *addrinfo = cp = emalloc(ailen);
 
140
 
 
141
    /* Store the IP addr/netmask pairs. */
 
142
    for (ifa = ifaddrs, i = 0; ifa != NULL; ifa = ifa -> ifa_next) {
 
143
        /* Skip interfaces marked "down" and "loopback". */
 
144
        if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL ||
 
145
            !ISSET(ifa->ifa_flags, IFF_UP) || ISSET(ifa->ifa_flags, IFF_LOOPBACK))
 
146
                continue;
 
147
 
 
148
        switch (ifa->ifa_addr->sa_family) {
 
149
            case AF_INET:
 
150
                sin = (struct sockaddr_in *)ifa->ifa_addr;
 
151
                len = snprintf(cp, ailen - (*addrinfo - cp),
 
152
                    "%s%s/", cp == *addrinfo ? "" : " ",
 
153
                    inet_ntoa(sin->sin_addr));
 
154
                if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
 
155
                    warningx(_("load_interfaces: overflow detected"));
 
156
                    goto done;
 
157
                }
 
158
                cp += len;
 
159
 
 
160
                sin = (struct sockaddr_in *)ifa->ifa_netmask;
 
161
                len = snprintf(cp, ailen - (*addrinfo - cp),
 
162
                    "%s", inet_ntoa(sin->sin_addr));
 
163
                if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
 
164
                    warningx(_("load_interfaces: overflow detected"));
 
165
                    goto done;
 
166
                }
 
167
                cp += len;
 
168
                break;
 
169
#ifdef HAVE_IN6_ADDR
 
170
            case AF_INET6:
 
171
                sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
 
172
                inet_ntop(AF_INET6, &sin6->sin6_addr, addrbuf, sizeof(addrbuf));
 
173
                len = snprintf(cp, ailen - (*addrinfo - cp),
 
174
                    "%s%s/", cp == *addrinfo ? "" : " ", addrbuf);
 
175
                if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
 
176
                    warningx(_("load_interfaces: overflow detected"));
 
177
                    goto done;
 
178
                }
 
179
                cp += len;
 
180
 
 
181
                sin6 = (struct sockaddr_in6 *)ifa->ifa_netmask;
 
182
                inet_ntop(AF_INET6, &sin6->sin6_addr, addrbuf, sizeof(addrbuf));
 
183
                len = snprintf(cp, ailen - (*addrinfo - cp), "%s", addrbuf);
 
184
                if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
 
185
                    warningx(_("load_interfaces: overflow detected"));
 
186
                    goto done;
 
187
                }
 
188
                cp += len;
 
189
                break;
 
190
#endif /* HAVE_IN6_ADDR */
 
191
        }
 
192
    }
 
193
 
 
194
done:
 
195
#ifdef HAVE_FREEIFADDRS
 
196
    freeifaddrs(ifaddrs);
 
197
#else
 
198
    efree(ifaddrs);
 
199
#endif
 
200
    return num_interfaces;
 
201
}
 
202
 
 
203
#elif defined(SIOCGIFCONF) && !defined(STUB_LOAD_INTERFACES)
 
204
 
 
205
/*
 
206
 * Allocate and fill in the interfaces global variable with the
 
207
 * machine's ip addresses and netmasks.
 
208
 */
 
209
int
 
210
get_net_ifs(char **addrinfo)
 
211
{
 
212
    struct ifconf *ifconf;
 
213
    struct ifreq *ifr, ifr_tmp;
 
214
    struct sockaddr_in *sin;
 
215
    int ailen, i, len, n, sock, num_interfaces = 0;
 
216
    size_t buflen = sizeof(struct ifconf) + BUFSIZ;
 
217
    char *cp, *previfname = "", *ifconf_buf = NULL;
 
218
#ifdef _ISC
 
219
    struct strioctl strioctl;
 
220
#endif /* _ISC */
 
221
 
 
222
    sock = socket(AF_INET, SOCK_DGRAM, 0);
 
223
    if (sock < 0)
 
224
        error(1, _("unable to open socket"));
 
225
 
 
226
    /*
 
227
     * Get interface configuration or return.
 
228
     */
 
229
    for (;;) {
 
230
        ifconf_buf = emalloc(buflen);
 
231
        ifconf = (struct ifconf *) ifconf_buf;
 
232
        ifconf->ifc_len = buflen - sizeof(struct ifconf);
 
233
        ifconf->ifc_buf = (caddr_t) (ifconf_buf + sizeof(struct ifconf));
 
234
 
 
235
#ifdef _ISC
 
236
        STRSET(SIOCGIFCONF, (caddr_t) ifconf, buflen);
 
237
        if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0)
 
238
#else
 
239
        /* Note that some kernels return EINVAL if the buffer is too small */
 
240
        if (ioctl(sock, SIOCGIFCONF, (caddr_t) ifconf) < 0 && errno != EINVAL)
 
241
#endif /* _ISC */
 
242
            goto done;
 
243
 
 
244
        /* Break out of loop if we have a big enough buffer. */
 
245
        if (ifconf->ifc_len + sizeof(struct ifreq) < buflen)
 
246
            break;
 
247
        buflen += BUFSIZ;
 
248
        efree(ifconf_buf);
 
249
    }
 
250
 
 
251
    /* Allocate space for the maximum number of interfaces that could exist. */
 
252
    if ((n = ifconf->ifc_len / sizeof(struct ifreq)) == 0)
 
253
        return 0;
 
254
    ailen = n * 2 * INET6_ADDRSTRLEN;
 
255
    *addrinfo = cp = emalloc(ailen);
 
256
 
 
257
    /* For each interface, store the ip address and netmask. */
 
258
    for (i = 0; i < ifconf->ifc_len; ) {
 
259
        /* Get a pointer to the current interface. */
 
260
        ifr = (struct ifreq *) &ifconf->ifc_buf[i];
 
261
 
 
262
        /* Set i to the subscript of the next interface. */
 
263
        i += sizeof(struct ifreq);
 
264
#ifdef HAVE_SA_LEN
 
265
        if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr))
 
266
            i += ifr->ifr_addr.sa_len - sizeof(struct sockaddr);
 
267
#endif /* HAVE_SA_LEN */
 
268
 
 
269
        /* Skip duplicates and interfaces with NULL addresses. */
 
270
        sin = (struct sockaddr_in *) &ifr->ifr_addr;
 
271
        if (sin->sin_addr.s_addr == 0 ||
 
272
            strncmp(previfname, ifr->ifr_name, sizeof(ifr->ifr_name) - 1) == 0)
 
273
            continue;
 
274
 
 
275
        if (ifr->ifr_addr.sa_family != AF_INET)
 
276
                continue;
 
277
 
 
278
#ifdef SIOCGIFFLAGS
 
279
        memset(&ifr_tmp, 0, sizeof(ifr_tmp));
 
280
        strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1);
 
281
        if (ioctl(sock, SIOCGIFFLAGS, (caddr_t) &ifr_tmp) < 0)
 
282
#endif
 
283
            ifr_tmp = *ifr;
 
284
        
 
285
        /* Skip interfaces marked "down" and "loopback". */
 
286
        if (!ISSET(ifr_tmp.ifr_flags, IFF_UP) ||
 
287
            ISSET(ifr_tmp.ifr_flags, IFF_LOOPBACK))
 
288
                continue;
 
289
 
 
290
        sin = (struct sockaddr_in *) &ifr->ifr_addr;
 
291
        len = snprintf(cp, ailen - (*addrinfo - cp),
 
292
            "%s%s/", cp == *addrinfo ? "" : " ",
 
293
            inet_ntoa(sin->sin_addr));
 
294
        if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
 
295
            warningx(_("load_interfaces: overflow detected"));
 
296
            goto done;
 
297
        }
 
298
        cp += len;
 
299
 
 
300
        /* Stash the name of the interface we saved. */
 
301
        previfname = ifr->ifr_name;
 
302
 
 
303
        /* Get the netmask. */
 
304
        memset(&ifr_tmp, 0, sizeof(ifr_tmp));
 
305
        strncpy(ifr_tmp.ifr_name, ifr->ifr_name, sizeof(ifr_tmp.ifr_name) - 1);
 
306
#ifdef _ISC
 
307
        STRSET(SIOCGIFNETMASK, (caddr_t) &ifr_tmp, sizeof(ifr_tmp));
 
308
        if (ioctl(sock, I_STR, (caddr_t) &strioctl) < 0) {
 
309
#else
 
310
        if (ioctl(sock, SIOCGIFNETMASK, (caddr_t) &ifr_tmp) < 0) {
 
311
#endif /* _ISC */
 
312
            sin = (struct sockaddr_in *) &ifr_tmp.ifr_addr;
 
313
            sin->sin_addr.s_addr = htonl(IN_CLASSC_NET);
 
314
        }
 
315
        sin = (struct sockaddr_in *) &ifr_tmp.ifr_addr;
 
316
        len = snprintf(cp, ailen - (*addrinfo - cp),
 
317
            "%s", inet_ntoa(sin->sin_addr));
 
318
        if (len <= 0 || len >= ailen - (*addrinfo - cp)) {
 
319
            warningx(_("load_interfaces: overflow detected"));
 
320
            goto done;
 
321
        }
 
322
        cp += len;
 
323
        num_interfaces++;
 
324
    }
 
325
 
 
326
done:
 
327
    efree(ifconf_buf);
 
328
    (void) close(sock);
 
329
 
 
330
    return num_interfaces;
 
331
}
 
332
 
 
333
#else /* !SIOCGIFCONF || STUB_LOAD_INTERFACES */
 
334
 
 
335
/*
 
336
 * Stub function for those without SIOCGIFCONF or getifaddrs()
 
337
 */
 
338
int
 
339
get_net_ifs(char **addrinfo)
 
340
{
 
341
    return 0;
 
342
}
 
343
 
 
344
#endif /* SIOCGIFCONF && !STUB_LOAD_INTERFACES */