[PATCH] ln: --no-target-directory implies --no-dereference
as in GNU coreutils --- coreutils/ln.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/coreutils/ln.c b/coreutils/ln.c index ea2d10eab..f2a1941b9 100644 --- a/coreutils/ln.c +++ b/coreutils/ln.c @@ -85,10 +85,7 @@ int ln_main(int argc, char **argv) src_name = NULL; src = last; - if (is_directory(src, - (opts & LN_NODEREFERENCE) ^ LN_NODEREFERENCE - ) - ) { + if (is_directory(src, !(opts & (LN_NODEREFERENCE|LN_LINKFILE { if (opts & LN_LINKFILE) { bb_error_msg_and_die("'%s' is a directory", src); } -- 2.20.1 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH] ip: print dadfailed flag
Signed-off-by: Kaarle Ritvanen --- networking/libiproute/ipaddress.c | 4 1 file changed, 4 insertions(+) diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 9ec665b69..d088caf4c 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -327,6 +327,10 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, ifa->ifa_flags &= ~IFA_F_TENTATIVE; printf("tentative "); } + if (ifa->ifa_flags & IFA_F_DADFAILED) { + ifa->ifa_flags &= ~IFA_F_DADFAILED; + printf("dadfailed "); + } if (ifa->ifa_flags & IFA_F_DEPRECATED) { ifa->ifa_flags &= ~IFA_F_DEPRECATED; printf("deprecated "); -- 2.20.1 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH] ifupdown: do not fail if interface disappears during ifdown
Interface may not exist because it got deleted by an ifdown hook script earlier. This may happen when a virtual interface, such as VLAN, has multiple iface blocks defined. Signed-off-by: Kaarle Ritvanen <kaarle.ritva...@datakunkku.fi> --- networking/ifupdown.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 534c9f0c7..35d13c5e1 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -141,6 +141,7 @@ #include "libbb.h" #include "common_bufsiz.h" /* After libbb.h, since it needs sys/types.h on some systems */ +#include #include #include @@ -503,6 +504,7 @@ static int FAST_FUNC static_up6(struct interface_defn_t *ifd, execfn *exec) static int FAST_FUNC static_down6(struct interface_defn_t *ifd, execfn *exec) { + if (!if_nametoindex(ifd->iface)) return 1; # if ENABLE_FEATURE_IFUPDOWN_IP return execute("ip link set %iface% down", ifd, exec); # else @@ -598,6 +600,7 @@ static int FAST_FUNC static_up(struct interface_defn_t *ifd, execfn *exec) static int FAST_FUNC static_down(struct interface_defn_t *ifd, execfn *exec) { int result; + if (!if_nametoindex(ifd->iface)) return 2; # if ENABLE_FEATURE_IFUPDOWN_IP /* Optional "label LBL" is necessary if interface is an alias (eth0:0), * otherwise "ip addr flush dev eth0:0" flushes all addresses on eth0. -- 2.14.3 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH 3/3] ash: exec: -a option for setting zeroth arg
On Wed, 12 Apr 2017, Denys Vlasenko wrote: > I committed a change which implements "exec -a" > in a slightly different way. Please try current git. Works for me. Thanks a lot! BR, Kaarle ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH 3/3] ash: exec: -a option for setting zeroth arg
On Wed, 12 Apr 2017, Kang-Che Sung wrote: > Back in January 2017, a person named Patrick Pief has suggested a similar > patch > to add "exec -a" support: > > http://lists.busybox.net/pipermail/busybox/2017-January/085146.html > > Is your patch same as his or is there any difference? My patch parses the '-a' option in execcmd, thus not affecting the behavior of shellexec when called from evalcommand. In addition, my patch uses getopt, making it a bit easier to add more options later. Is there any reason not to merge my or Patrick's patch? If you prefer my patch, I can make the changes requested by Bartosz. BR, Kaarle ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 2/3] ash: shellexec: rename variable
Signed-off-by: Kaarle Ritvanen <kaarle.ritva...@datakunkku.fi> --- shell/ash.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 983f7b1..58ae950 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7748,7 +7748,7 @@ static void shellexec(char **, const char *, int) NORETURN; static void shellexec(char **argv, const char *path, int idx) { - char *cmdname; + char *cmdpath; int e; char **envp; int exerrno; @@ -7772,13 +7772,13 @@ shellexec(char **argv, const char *path, int idx) } else { try_PATH: e = ENOENT; - while ((cmdname = path_advance(, argv[0])) != NULL) { + while ((cmdpath = path_advance(, argv[0])) != NULL) { if (--idx < 0 && pathopt == NULL) { - tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); + tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdpath, argv, envp); if (errno != ENOENT && errno != ENOTDIR) e = errno; } - stunalloc(cmdname); + stunalloc(cmdpath); } } -- 2.9.3 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 1/3] libbb: GETOPT_RESET macro
Signed-off-by: Kaarle Ritvanen <kaarle.ritva...@datakunkku.fi> --- include/libbb.h| 19 +++ libbb/getopt32.c | 8 +--- libbb/vfork_daemon_rexec.c | 28 ++-- runit/sv.c | 7 +-- shell/shell_common.c | 8 +--- util-linux/getopt.c| 7 +-- 6 files changed, 25 insertions(+), 52 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 0407163..eb78619 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1178,6 +1178,25 @@ extern uint32_t option_mask32; extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; +/* BSD-derived getopt() functions require that optind be set to 1 in + * order to reset getopt() state. This used to be generally accepted + * way of resetting getopt(). However, glibc's getopt() + * has additional getopt() state beyond optind, and requires that + * optind be set to zero to reset its state. So the unfortunate state of + * affairs is that BSD-derived versions of getopt() misbehave if + * optind is set to 0 in order to reset getopt(), and glibc's getopt() + * will core dump if optind is set 1 in order to reset getopt(). + * + * More modern versions of BSD require that optreset be set to 1 in + * order to reset getopt(). Sigh. Standards, anyone? + */ +#ifdef __GLIBC__ +#define GETOPT_RESET optind = 0; +#else /* BSD style */ +#define GETOPT_RESET optind = 1; +#endif + + /* Having next pointer as a first member allows easy creation * of "llist-compatible" structs, and using llist_FOO functions * on them. diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 497fc01..38fac14 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -576,13 +576,7 @@ getopt32(char **argv, const char *applet_opts, ...) * run_nofork_applet() does this, but we might end up here * also via gunzip_main() -> gzip_main(). Play safe. */ -#ifdef __GLIBC__ - optind = 0; -#else /* BSD style */ - optind = 1; - /* optreset = 1; */ -#endif - /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ + GETOPT_RESET /* Note: just "getopt() <= 0" will not work well for * "fake" short options, like this one: diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 2e7dc2d..e2a6b39 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -121,28 +121,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) /* In case getopt() or getopt32() was already called: * reset the libc getopt() function, which keeps internal state. -* -* BSD-derived getopt() functions require that optind be set to 1 in -* order to reset getopt() state. This used to be generally accepted -* way of resetting getopt(). However, glibc's getopt() -* has additional getopt() state beyond optind, and requires that -* optind be set to zero to reset its state. So the unfortunate state of -* affairs is that BSD-derived versions of getopt() misbehave if -* optind is set to 0 in order to reset getopt(), and glibc's getopt() -* will core dump if optind is set 1 in order to reset getopt(). -* -* More modern versions of BSD require that optreset be set to 1 in -* order to reset getopt(). Sigh. Standards, anyone? */ -#ifdef __GLIBC__ - optind = 0; -#else /* BSD style */ - optind = 1; - /* optreset = 1; */ -#endif - /* optarg = NULL; opterr = 1; optopt = 63; - do we need this too? */ - /* (values above are what they initialized to in glibc and uclibc) */ - /* option_mask32 = 0; - not needed, no applet depends on it being 0 */ + GETOPT_RESET argc = 1; while (argv[argc]) @@ -167,11 +147,7 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) restore_nofork_data(); /* Other globals can be simply reset to defaults */ -#ifdef __GLIBC__ - optind = 0; -#else /* BSD style */ - optind = 1; -#endif + GETOPT_RESET return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ } diff --git a/runit/sv.c b/runit/sv.c index 9e21322..4ba5df7 100644 --- a/runit/sv.c +++ b/runit/sv.c @@ -688,12 +688,7 @@ int svc_main(int argc UNUSED_PARAM, char **argv) /* getopt32() was already called: * reset the libc getopt() function, which keeps internal state. */ -#ifdef __GLIBC__ - optind = 0; -#else /* BSD style */ - optind = 1; - /* optreset = 1; */ -#endif + GETOPT_RESET do { if (opts & 1) { diff --git a/shell/shell_common.c b/shell/shell_common.c index 549b17c..cc9ac15 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -401,13 +401,7 @@ shell_builtin_ulimit(char **argv) /* In case getopt was already called:
[PATCH 0/3] ash: exec: -a option for setting zeroth arg
function old new delta execcmd 81 171 +90 shellexec251 258 +7 evalcommand 13641366 +2 -- (add/remove: 0/0 grow/shrink: 3/0 up/down: 99/0) Total: 99 bytes Kaarle Ritvanen (3): libbb: GETOPT_RESET macro ash: shellexec: rename variable ash: exec: -a option for setting zeroth arg include/libbb.h| 19 ++ libbb/getopt32.c | 8 +--- libbb/vfork_daemon_rexec.c | 28 ++- runit/sv.c | 7 +-- shell/ash.c| 48 +- shell/shell_common.c | 8 +--- util-linux/getopt.c| 7 +-- 7 files changed, 60 insertions(+), 65 deletions(-) -- 2.9.3 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 3/3] ash: exec: -a option for setting zeroth arg
Signed-off-by: Kaarle Ritvanen <kaarle.ritva...@datakunkku.fi> --- shell/ash.c | 42 -- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 58ae950..b799b85 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7744,9 +7744,9 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char ** * have to change the find_command routine as well. * argv[-1] must exist and be writable! See tryexec() for why. */ -static void shellexec(char **, const char *, int) NORETURN; +static void shellexec(const char *, char **, const char *, int) NORETURN; static void -shellexec(char **argv, const char *path, int idx) +shellexec(const char *cmdname, char **argv, const char *path, int idx) { char *cmdpath; int e; @@ -7755,12 +7755,15 @@ shellexec(char **argv, const char *path, int idx) int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL); - if (strchr(argv[0], '/') != NULL + if (!cmdname) + cmdname = argv[0]; + + if (strchr(cmdname, '/') != NULL #if ENABLE_FEATURE_SH_STANDALONE -|| (applet_no = find_applet_by_name(argv[0])) >= 0 +|| (applet_no = find_applet_by_name(cmdname)) >= 0 #endif ) { - tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp); + tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) cmdname, argv, envp); if (applet_no >= 0) { /* We tried execing ourself, but it didn't work. * Maybe /proc/self/exe doesn't exist? @@ -7772,7 +7775,7 @@ shellexec(char **argv, const char *path, int idx) } else { try_PATH: e = ENOENT; - while ((cmdpath = path_advance(, argv[0])) != NULL) { + while ((cmdpath = path_advance(, cmdname)) != NULL) { if (--idx < 0 && pathopt == NULL) { tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdpath, argv, envp); if (errno != ENOENT && errno != ENOTDIR) @@ -9353,9 +9356,28 @@ truecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) } static int FAST_FUNC -execcmd(int argc UNUSED_PARAM, char **argv) +execcmd(int argc, char **argv) { - if (argv[1]) { + int opt; + char *argv0 = NULL; + char *cmdname = NULL; + + GETOPT_RESET + while ((opt = getopt(argc, argv, "a:")) != -1) + switch (opt) { + case 'a': + argv0 = optarg; + break; + default: + return 1; + } + + if (argv[optind]) { + if (argv0) { + cmdname = argv[optind]; + argv[optind] = argv0; + } + iflag = 0; /* exit on error */ mflag = 0; optschanged(); @@ -9371,7 +9393,7 @@ execcmd(int argc UNUSED_PARAM, char **argv) /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */ /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */ - shellexec(argv + 1, pathval(), 0); + shellexec(cmdname, argv + optind, pathval(), 0); /* NOTREACHED */ } return 0; @@ -9773,7 +9795,7 @@ evalcommand(union node *cmd, int flags) /* fall through to exec'ing external program */ } listsetvar(varlist.list, VEXPORT|VSTACK); - shellexec(argv, path, cmdentry.u.index); + shellexec(NULL, argv, path, cmdentry.u.index); /* NOTREACHED */ } /* default */ case CMDBUILTIN: -- 2.9.3 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH] ntpd: postpone hostname resolution if fails on startup
Signed-off-by: Kaarle Ritvanen <kaarle.ritva...@datakunkku.fi> --- function old new delta resolve_peer_hostname - 85 +85 static.set_next- 23 +23 step_time385 377 -8 add_peers224 215 -9 recv_and_process_peer_pkt 22062194 -12 .rodata 156130 156114 -16 ntpd_main 11501086 -64 -- (add/remove: 2/0 grow/shrink: 0/5 up/down: 108/-109) Total: -1 bytes networking/ntpd.c | 116 +- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 4103189..7f7d69e 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -765,34 +765,48 @@ reset_peer_stats(peer_t *p, double offset) } static void +resolve_peer_hostname(peer_t *p) { + len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123); + if (lsa) { + if (p->p_lsa) { + free(p->p_lsa); + free(p->p_dotted); + } + p->p_lsa = lsa; + p->p_dotted = xmalloc_sockaddr2dotted_noport(>u.sa); + } + set_next(p, lsa ? 0 : RETRY_INTERVAL); +} + +static void add_peers(const char *s) { llist_t *item; peer_t *p; p = xzalloc(sizeof(*p)); - p->p_lsa = xhost2sockaddr(s, 123); - p->p_dotted = xmalloc_sockaddr2dotted_noport(>p_lsa->u.sa); + p->p_hostname = xstrdup(s); + resolve_peer_hostname(p); /* Names like N..pool.ntp.org are randomly resolved * to a pool of machines. Sometimes different N's resolve to the same IP. * It is not useful to have two peers with same IP. We skip duplicates. */ - for (item = G.ntp_peers; item != NULL; item = item->link) { - peer_t *pp = (peer_t *) item->data; - if (strcmp(p->p_dotted, pp->p_dotted) == 0) { - bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); - free(p->p_lsa); - free(p->p_dotted); - free(p); - return; + if (p->p_lsa) + for (item = G.ntp_peers; item != NULL; item = item->link) { + peer_t *pp = (peer_t *) item->data; + if (pp->p_lsa && strcmp(p->p_dotted, pp->p_dotted) == 0) { + bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); + free(p->p_hostname); + free(p->p_lsa); + free(p->p_dotted); + free(p); + return; + } } - } - p->p_hostname = xstrdup(s); p->p_fd = -1; p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); - p->next_action_time = G.cur_time; /* = set_next(p, 0); */ reset_peer_stats(p, STEP_THRESHOLD); llist_add_to(_peers, p); @@ -2317,54 +2331,50 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) for (item = G.ntp_peers; item != NULL; item = item->link) { peer_t *p = (peer_t *) item->data; - if (p->next_action_time <= G.cur_time) { - if (p->p_fd == -1) { - /* Time to send new req */ - if (--cnt == 0) { - VERB4 bb_error_msg("disabling burst mode"); - G.polladj_count = 0; - G.poll_exp = MINPOLL; - } - send_query_to_peer(p); - } else { - /* Timed out waiting for reply */ - close(p->p_fd); - p->p_fd = -1; - /* If poll interval is small, increase it */ - if (G.poll_exp < BIGPOLL) - adjust_poll(MINPOLL); - timeout = poll_interval(NOREPLY_INTERVAL); - bb_error_msg("timed out waiting for %s, reac
[PATCH 0/3] su: FEATURE_SU_NULLOK_SECURE
This patch set implements a new feature which, when enabled, makes su reject blank passwords unless the user is on a secure TTY defined in /etc/securetty. This resembles the default PAM configuration of some Linux distros which specify the nullok_secure option for pam_unix.so. function old new delta check_securetty- 117+117 su_main 547 564 +17 sulogin_main 362 367 +5 ask_and_check_password12 17 +5 ask_and_check_password_extended 99 102 +3 login_main 13111182-129 -- (add/remove: 2/0 grow/shrink: 4/1 up/down: 147/-129) Total: 18 bytes Kaarle Ritvanen (3): login: move check_securetty to libbb libbb: allow_blank argument for ask_and_check_password_extended() su: FEATURE_SU_NULLOK_SECURE include/libbb.h | 3 ++- libbb/Kbuild.src | 1 + libbb/correct_password.c | 6 +++--- libbb/securetty.c| 27 +++ loginutils/login.c | 19 --- loginutils/su.c | 18 +- loginutils/sulogin.c | 2 +- 7 files changed 47 insertions(+), 29 deletions(-) create mode 100644 libbb/securetty.c -- 2.5.0 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 1/3] login: move check_securetty to libbb
Signed-off-by: Kaarle Ritvanen <kaarle.ritva...@datakunkku.fi> --- include/libbb.h| 1 + libbb/Kbuild.src | 1 + libbb/securetty.c | 27 +++ loginutils/login.c | 19 --- 4 files changed, 29 insertions(+), 19 deletions(-) create mode 100644 libbb/securetty.c diff --git a/include/libbb.h b/include/libbb.h index 82484f9..e607b8f 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1354,6 +1354,7 @@ extern void selinux_or_die(void) FAST_FUNC; #define SETUP_ENV_NO_CHDIR (1 << 4) void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; void nuke_str(char *str) FAST_FUNC; +int check_securetty(const char *short_tty); int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC; int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; int ask_and_check_password(const struct passwd *pw) FAST_FUNC; diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 7fb6872..0f09de7 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -84,6 +84,7 @@ lib-y += safe_gethostname.o lib-y += safe_poll.o lib-y += safe_strncpy.o lib-y += safe_write.o +lib-y += securetty.o lib-y += setup_environment.o lib-y += signals.o lib-y += simplify_path.o diff --git a/libbb/securetty.c b/libbb/securetty.c new file mode 100644 index 000..95edbc9 --- /dev/null +++ b/libbb/securetty.c @@ -0,0 +1,27 @@ +/* vi: set sw=4 ts=4: */ +/* + * /etc/securetty checking. + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ + +#include "libbb.h" + +#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM +int check_securetty(const char *short_tty) +{ + char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ + parser_t *parser = config_open2("/etc/securetty", fopen_for_read); + while (config_read(parser, , 1, 1, "# \t", PARSE_NORMAL)) { + if (strcmp(buf, short_tty) == 0) + break; + buf = NULL; + } + config_close(parser); + /* buf != NULL here if config file was not found, empty +* or line was found which equals short_tty */ + return buf != NULL; +} +#else +ALWAYS_INLINE int check_securetty(const char *short_tty UNUSED_PARAM) { return 1; } +#endif diff --git a/loginutils/login.c b/loginutils/login.c index 67fe82e..8d765fb 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -129,25 +129,6 @@ static void die_if_nologin(void) # define die_if_nologin() ((void)0) #endif -#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM -static int check_securetty(const char *short_tty) -{ - char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ - parser_t *parser = config_open2("/etc/securetty", fopen_for_read); - while (config_read(parser, , 1, 1, "# \t", PARSE_NORMAL)) { - if (strcmp(buf, short_tty) == 0) - break; - buf = NULL; - } - config_close(parser); - /* buf != NULL here if config file was not found, empty -* or line was found which equals short_tty */ - return buf != NULL; -} -#else -static ALWAYS_INLINE int check_securetty(const char *short_tty UNUSED_PARAM) { return 1; } -#endif - #if ENABLE_SELINUX static void initselinux(char *username, char *full_tty, security_context_t *user_sid) -- 2.5.0 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 2/3] libbb: allow_blank argument for ask_and_check_password_extended()
Signed-off-by: Kaarle Ritvanen <kaarle.ritva...@datakunkku.fi> --- include/libbb.h | 2 +- libbb/correct_password.c | 6 +++--- loginutils/sulogin.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index e607b8f..4c43c72 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1356,7 +1356,7 @@ void setup_environment(const char *shell, int flags, const struct passwd *pw) FA void nuke_str(char *str) FAST_FUNC; int check_securetty(const char *short_tty); int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC; -int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; +int ask_and_check_password_extended(const struct passwd *pw, int timeout, int allow_blank, const char *prompt) FAST_FUNC; int ask_and_check_password(const struct passwd *pw) FAST_FUNC; /* Returns a malloced string */ #if !ENABLE_USE_BB_CRYPT diff --git a/libbb/correct_password.c b/libbb/correct_password.c index 513c930..57cd2b8 100644 --- a/libbb/correct_password.c +++ b/libbb/correct_password.c @@ -96,7 +96,7 @@ int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext) * NULL pw means "just fake it for login with bad username" */ int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, - int timeout, const char *prompt) + int timeout, int allow_blank, const char *prompt) { IF_FEATURE_SHADOWPASSWDS(char buffer[SHADOW_BUFSIZE];) char *plaintext; @@ -105,7 +105,7 @@ int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, pw_pass = get_passwd(pw, buffer); if (!pw_pass[0]) /* empty password field? */ - return 1; + return allow_blank; plaintext = bb_ask(STDIN_FILENO, timeout, prompt); if (!plaintext) { @@ -120,5 +120,5 @@ int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, int FAST_FUNC ask_and_check_password(const struct passwd *pw) { - return ask_and_check_password_extended(pw, 0, "Password: "); + return ask_and_check_password_extended(pw, 0, 1, "Password: "); } diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 19b1e30..16a83f4 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -65,7 +65,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) while (1) { int r; - r = ask_and_check_password_extended(pwd, timeout, + r = ask_and_check_password_extended(pwd, timeout, 1, "Give root password for system maintenance\n" "(or type Control-D for normal startup):" ); -- 2.5.0 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 3/3] su: FEATURE_SU_NULLOK_SECURE
When this feature is enabled, blank passwords are not accepted by su unless the user is on a secure TTY defined in /etc/securetty. This resembles the default PAM configuration of some Linux distros which specify the nullok_secure option for pam_unix.so. Signed-off-by: Kaarle Ritvanen <kaarle.ritva...@datakunkku.fi> --- loginutils/su.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/loginutils/su.c b/loginutils/su.c index 3c0e8c1..85d8e11 100644 --- a/loginutils/su.c +++ b/loginutils/su.c @@ -24,6 +24,11 @@ //config: bool "Enable su to check user's shell to be listed in /etc/shells" //config: depends on SU //config: default y +//config: +//config:config FEATURE_SU_NULLOK_SECURE +//config: bool "Disallow blank passwords from TTYs other than specified in /etc/securetty" +//config: depends on SU +//config: default n //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ //applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) @@ -76,6 +81,7 @@ int su_main(int argc UNUSED_PARAM, char **argv) struct passwd *pw; uid_t cur_uid = getuid(); const char *tty; + int allow_blank = 1; #if ENABLE_FEATURE_UTMP char user_buf[64]; #endif @@ -96,6 +102,12 @@ int su_main(int argc UNUSED_PARAM, char **argv) argv++; } + tty = xmalloc_ttyname(STDIN_FILENO); + if (!tty) tty = "none"; + tty = skip_dev_pfx(tty); + + if (ENABLE_FEATURE_SU_NULLOK_SECURE) allow_blank = check_securetty(tty); + if (ENABLE_FEATURE_SU_SYSLOG) { /* The utmp entry (via getlogin) is probably the best way to * identify the user, especially if someone su's from a su-shell. @@ -109,16 +121,12 @@ int su_main(int argc UNUSED_PARAM, char **argv) pw = getpwuid(cur_uid); old_user = pw ? xstrdup(pw->pw_name) : ""; } - tty = xmalloc_ttyname(2); - if (!tty) { - tty = "none"; - } openlog(applet_name, 0, LOG_AUTH); } pw = xgetpwnam(opt_username); - if (cur_uid == 0 || ask_and_check_password(pw) > 0) { + if (cur_uid == 0 || ask_and_check_password_extended(pw, 0, allow_blank, "Password: ") > 0) { if (ENABLE_FEATURE_SU_SYSLOG) syslog(LOG_NOTICE, "%c %s %s:%s", '+', tty, old_user, opt_username); -- 2.5.0 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 2/3] libbb: allow_blank argument for ask_and_check_password_extended()
--- include/libbb.h | 2 +- libbb/correct_password.c | 6 +++--- loginutils/sulogin.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index e607b8f..4c43c72 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1356,7 +1356,7 @@ void setup_environment(const char *shell, int flags, const struct passwd *pw) FA void nuke_str(char *str) FAST_FUNC; int check_securetty(const char *short_tty); int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC; -int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; +int ask_and_check_password_extended(const struct passwd *pw, int timeout, int allow_blank, const char *prompt) FAST_FUNC; int ask_and_check_password(const struct passwd *pw) FAST_FUNC; /* Returns a malloced string */ #if !ENABLE_USE_BB_CRYPT diff --git a/libbb/correct_password.c b/libbb/correct_password.c index 513c930..57cd2b8 100644 --- a/libbb/correct_password.c +++ b/libbb/correct_password.c @@ -96,7 +96,7 @@ int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext) * NULL pw means "just fake it for login with bad username" */ int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, - int timeout, const char *prompt) + int timeout, int allow_blank, const char *prompt) { IF_FEATURE_SHADOWPASSWDS(char buffer[SHADOW_BUFSIZE];) char *plaintext; @@ -105,7 +105,7 @@ int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, pw_pass = get_passwd(pw, buffer); if (!pw_pass[0]) /* empty password field? */ - return 1; + return allow_blank; plaintext = bb_ask(STDIN_FILENO, timeout, prompt); if (!plaintext) { @@ -120,5 +120,5 @@ int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, int FAST_FUNC ask_and_check_password(const struct passwd *pw) { - return ask_and_check_password_extended(pw, 0, "Password: "); + return ask_and_check_password_extended(pw, 0, 1, "Password: "); } diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 19b1e30..16a83f4 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -65,7 +65,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) while (1) { int r; - r = ask_and_check_password_extended(pwd, timeout, + r = ask_and_check_password_extended(pwd, timeout, 1, "Give root password for system maintenance\n" "(or type Control-D for normal startup):" ); -- 2.1.0 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 1/3] login: move check_securetty to libbb
--- include/libbb.h| 1 + libbb/Kbuild.src | 1 + libbb/securetty.c | 27 +++ loginutils/login.c | 19 --- 4 files changed, 29 insertions(+), 19 deletions(-) create mode 100644 libbb/securetty.c diff --git a/include/libbb.h b/include/libbb.h index 82484f9..e607b8f 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1354,6 +1354,7 @@ extern void selinux_or_die(void) FAST_FUNC; #define SETUP_ENV_NO_CHDIR (1 << 4) void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; void nuke_str(char *str) FAST_FUNC; +int check_securetty(const char *short_tty); int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC; int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; int ask_and_check_password(const struct passwd *pw) FAST_FUNC; diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 7fb6872..0f09de7 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -84,6 +84,7 @@ lib-y += safe_gethostname.o lib-y += safe_poll.o lib-y += safe_strncpy.o lib-y += safe_write.o +lib-y += securetty.o lib-y += setup_environment.o lib-y += signals.o lib-y += simplify_path.o diff --git a/libbb/securetty.c b/libbb/securetty.c new file mode 100644 index 000..95edbc9 --- /dev/null +++ b/libbb/securetty.c @@ -0,0 +1,27 @@ +/* vi: set sw=4 ts=4: */ +/* + * /etc/securetty checking. + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ + +#include "libbb.h" + +#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM +int check_securetty(const char *short_tty) +{ + char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ + parser_t *parser = config_open2("/etc/securetty", fopen_for_read); + while (config_read(parser, , 1, 1, "# \t", PARSE_NORMAL)) { + if (strcmp(buf, short_tty) == 0) + break; + buf = NULL; + } + config_close(parser); + /* buf != NULL here if config file was not found, empty +* or line was found which equals short_tty */ + return buf != NULL; +} +#else +ALWAYS_INLINE int check_securetty(const char *short_tty UNUSED_PARAM) { return 1; } +#endif diff --git a/loginutils/login.c b/loginutils/login.c index 67fe82e..8d765fb 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -129,25 +129,6 @@ static void die_if_nologin(void) # define die_if_nologin() ((void)0) #endif -#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM -static int check_securetty(const char *short_tty) -{ - char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ - parser_t *parser = config_open2("/etc/securetty", fopen_for_read); - while (config_read(parser, , 1, 1, "# \t", PARSE_NORMAL)) { - if (strcmp(buf, short_tty) == 0) - break; - buf = NULL; - } - config_close(parser); - /* buf != NULL here if config file was not found, empty -* or line was found which equals short_tty */ - return buf != NULL; -} -#else -static ALWAYS_INLINE int check_securetty(const char *short_tty UNUSED_PARAM) { return 1; } -#endif - #if ENABLE_SELINUX static void initselinux(char *username, char *full_tty, security_context_t *user_sid) -- 2.1.0 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH 3/3] su: FEATURE_SU_NULLOK_SECURE
When this feature is enabled, blank passwords are not accepted by su unless the user is on a secure TTY defined in /etc/securetty. This resembles the default PAM configuration of some Linux distros which specify the nullok_secure option for pam_unix.so. --- loginutils/su.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/loginutils/su.c b/loginutils/su.c index 3c0e8c1..85d8e11 100644 --- a/loginutils/su.c +++ b/loginutils/su.c @@ -24,6 +24,11 @@ //config: bool "Enable su to check user's shell to be listed in /etc/shells" //config: depends on SU //config: default y +//config: +//config:config FEATURE_SU_NULLOK_SECURE +//config: bool "Disallow blank passwords from TTYs other than specified in /etc/securetty" +//config: depends on SU +//config: default n //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ //applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) @@ -76,6 +81,7 @@ int su_main(int argc UNUSED_PARAM, char **argv) struct passwd *pw; uid_t cur_uid = getuid(); const char *tty; + int allow_blank = 1; #if ENABLE_FEATURE_UTMP char user_buf[64]; #endif @@ -96,6 +102,12 @@ int su_main(int argc UNUSED_PARAM, char **argv) argv++; } + tty = xmalloc_ttyname(STDIN_FILENO); + if (!tty) tty = "none"; + tty = skip_dev_pfx(tty); + + if (ENABLE_FEATURE_SU_NULLOK_SECURE) allow_blank = check_securetty(tty); + if (ENABLE_FEATURE_SU_SYSLOG) { /* The utmp entry (via getlogin) is probably the best way to * identify the user, especially if someone su's from a su-shell. @@ -109,16 +121,12 @@ int su_main(int argc UNUSED_PARAM, char **argv) pw = getpwuid(cur_uid); old_user = pw ? xstrdup(pw->pw_name) : ""; } - tty = xmalloc_ttyname(2); - if (!tty) { - tty = "none"; - } openlog(applet_name, 0, LOG_AUTH); } pw = xgetpwnam(opt_username); - if (cur_uid == 0 || ask_and_check_password(pw) > 0) { + if (cur_uid == 0 || ask_and_check_password_extended(pw, 0, allow_blank, "Password: ") > 0) { if (ENABLE_FEATURE_SU_SYSLOG) syslog(LOG_NOTICE, "%c %s %s:%s", '+', tty, old_user, opt_username); -- 2.1.0 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] su: support denying accounts with blank password
On Wed, 10 Jun 2015, Timo Teras wrote: > On Tue, 09 Jun 2015 22:20:30 +0200 > Laurent Bercotwrote: > > > IOW, if a computer gets hacked because its root password was > > blank or default, it's not a problem you can solve by choosing > > the other solution. :) > > The only situation that would benefit from this is that you have box > running network only services (no local logins for users). And admin > is done with ssh key authentication. > > The problem then becomes: services run as non-root users, and to > maintain security isolation, you don't want those service accounts to > be able to sudo or su. > > Having no password for root would allow console login if necessary > without need to consult password lists. But at the same time disable all > other root access. Yes, applying this patch would allow for greater security than setting the root password. Passwords are always subject to dictionary and brute force attacks, recording by keyloggers, discovery of the Post-it note where they are written on etc. This patch, on the other hand, would remove these attack vectors completely while allowing root access via a trusted console. In mainstream Linux distributions, the same effect can be achieved by adjusting the PAM configuration for su. Having this patch included would increase busybox's usefulness without increasing its footprint at all. BR, Kaarle ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH v2] sendmail: automatically determine sender if not specified
On Wed, 5 Feb 2014, Denys Vlasenko wrote: I just committed the following change: http://git.busybox.net/busybox/commit/?id=07f417b6ab92e0429f302ff6783bb9681b60120e but I'm unsure it is good enough for your use case. This is probably good enough for the use case I have now at hand because I'm in control of the SMTP server's configuration. I can configure it to fill in the correct domain part when the client provides a plain username, but normally mail servers seem to reject such submissions. RFC 5321 specifies envelope addresses to always include the domain name part. To emulate the setup where a sendmail daemon is running locally with the default configuration, the sendmail applet should use the host's FQDN as the domain part of the sender address as in my patch. BR, Kaarle ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH] sendmail: use FQDN in default envelope sender
RFC 5321 requires the return path to be supplied with a proper domain name. Signed-off-by: Kaarle Ritvanen kaarle.ritva...@datakunkku.fi --- mailutils/sendmail.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 824109d..9455b4e 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -326,7 +326,6 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // we should start with modern EHLO if (250 != smtp_checkp(EHLO %s, host, -1)) smtp_checkp(HELO %s, host, 250); - free(host); // perform authentication if (opts OPT_a) { @@ -353,8 +352,11 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // got no sender address? use auth name, then UID username as a last resort if (!opt_from) { - opt_from = G.user ? G.user : xuid2uname(getuid()); + opt_from = xasprintf(%s@%s, +G.user ? G.user : xuid2uname(getuid()), +xgethostbyname(host)-h_name); } + free(host); smtp_checkp(MAIL FROM:%s, opt_from, 250); -- 1.8.3.1 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: Interworking of cron and sendmail applets
On Tue, 4 Feb 2014, Denys Vlasenko wrote: I am looking at Fedora's man sendmail and it says that -fSENDER is optional. When it's absent, sender is derived from From: header. Verbatim quote from the man page: Sets the name of the 'from' person (i.e., the envelope sender of the mail). This address may also be used in the From: header if that header is missing during initial submission. So it says that the argument of -f is used as the default value for the From header, not vice versa. Looking at the code, sendmail seems to behave pretty much like the patch I sent earlier, i.e. derive the envelope sender address from the current user's login name and the host's FQDN. BR, Kaarle ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH] sendmail: automatically determine sender if not specified
Make the -f option optional. If not given, construct the sender address from the username and fully qualified hostname. This is required to interoperate with the cron applet. --- mailutils/sendmail.c | 16 +++- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index b5aa1d1..b99c42f 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -199,8 +199,8 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) G.fp0 = xfdopen_for_read(3); // parse options - // -v is a counter, -f is required. -H and -S are mutually exclusive, -a is a list - opt_complementary = vv:f:w+:H--S:S--H:a::; + // -v is a counter, -H and -S are mutually exclusive, -a is a list + opt_complementary = vv:w+:H--S:S--H:a::; // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility, // it is still under development. @@ -279,7 +279,6 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // we should start with modern EHLO if (250 != smtp_checkp(EHLO %s, host, -1)) smtp_checkp(HELO %s, host, 250); - free(host); // perform authentication if (opts OPT_a) { @@ -305,12 +304,11 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // file descriptor (e.g. 4), or again from a secured file. // got no sender address? - use system username as a resort - // N.B. we marked -f as required option! - //if (!G.user) { - // // N.B. IMHO getenv(USER) can be way easily spoofed! - // G.user = xuid2uname(getuid()); - // opt_from = xasprintf(%s@%s, G.user, domain); - //} + if (!G.user) G.user = xuid2uname(getuid()); + if (!opt_from) + opt_from = xasprintf(%s@%s, G.user, xgethostbyname(host)-h_name); + free(host); + smtp_checkp(MAIL FROM:%s, opt_from, 250); // process message -- 1.8.3.1 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: Interworking of cron and sendmail applets
On Tue, 21 Jan 2014, Harald Becker wrote: Beside modifying the Busybox binary, you can create a script file for sendmail: #!/bin/sh exec /bin/busybox sendmail -f ... $@ install this script as your sendmail and make it executable (chmod +x). Then cron shall pickup this script for sendmail and the script will add the missing information. Of course, there are ways to hack around the problem, but I prefer a solution that's easy to replicate in multiple environments with minimum hassle. I would like to understand why the sendmail applet requires the use of the -f option. It used to be optional, but it was made mandatory in commit 88b8f0a, which has an informative commit log message: sendmail: update by Vladimir. I suggest the -f option be made optional again unless there are good reasons not to do so. BR, Kaarle ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
Re: [PATCH] ifupdown: support 'link' address family
On Sun, 29 Dec 2013, Kaarle Ritvanen wrote: Does not configure anything. L2 configuration hook scripts should do their job on receiving ADDRFAM=link. Configuration will be done only once, irrespective of L3 protocols used. Using the 'link' family in the interfaces file conforms to the Debian implementation: http://sources.debian.net/src/ifupdown/0.7.47.1/link.defn There were no comments so far on this patch. My intention was to allow separating the link layer configuration from the IPv4 (inet) and IPv6 (inet6) configuration blocks in the interfaces file in a way that is compatible with the Debian implementation. Do you think this makes sense? Ideally, the ifupdown applet would have built-in support for configuring bonding, bridges, VLANs etc., but for the time being, I plan to use hook scripts for these purposes. BR, Kaarle ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox
[PATCH] ifupdown: support 'link' address family
Does not configure anything. L2 configuration hook scripts should do their job on receiving ADDRFAM=link. Configuration will be done only once, irrespective of L3 protocols used. Using the 'link' family in the interfaces file conforms to the Debian implementation: http://sources.debian.net/src/ifupdown/0.7.47.1/link.defn Signed-off-by: Kaarle Ritvanen kaarle.ritva...@datakunkku.fi --- networking/ifupdown.c | 13 + 1 file changed, 13 insertions(+) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 0f0857c..91a786d 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -685,6 +685,18 @@ static const struct address_family_t addr_inet = { #endif /* FEATURE_IFUPDOWN_IPV4 */ +static int FAST_FUNC link_up_down(struct interface_defn_t *ifd UNUSED_PARAM, execfn *exec UNUSED_PARAM) +{ + return 1; +} + +static const struct method_t link_methods[] = { + {none, link_up_down, link_up_down} +}; + +static const struct address_family_t addr_link = { + link, ARRAY_SIZE(link_methods), link_methods +}; /* Returns pointer to the next word, or NULL. * In 1st case, advances *buf to the word after this one. @@ -831,6 +843,7 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in #if ENABLE_FEATURE_IFUPDOWN_IPV6 addr_inet6, #endif + addr_link, NULL }; char *iface_name; -- 1.8.1.4 ___ busybox mailing list busybox@busybox.net http://lists.busybox.net/mailman/listinfo/busybox