[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] PAM additions for vtysh
From: |
Bjoern A. Zeeb |
Subject: |
[PATCH] PAM additions for vtysh |
Date: |
Thu, 17 Jan 2002 23:17:57 +0100 (CET) |
Hi,
this is mostly an updated and corrected patch to [zebra 10305] which
was never commented or applied.
If you do not like it please drop me a note.
diff is against cvs from today 2002-01-17, 18:09 UTC.
changes to previous version:
* corrected some errors for compiling and that made vtysh -b unusable
* added configure option to enable setuid installation (means user can
now decide; default should be no)
* beautified some configure --help output
Please call your autotools-chain after applying.
Perhaps applying after a 0.93 release might be considerable.
Saw that cvs version already is marked as 0.93.
Please carefully review because this is partly security related. Well
actually vtysh has to be run by root when using PAM in most cases so
it is not really worse ...
It compiles on FreeBSD 4-STABLE and Debian GNU/Linux. Still could not
get readline working on the sol8 box to test vtysh.
As always patch might also be found on
http://patch.zabbadoz.net/?zebra=1
Comments welcome !
--
Bjoern A. Zeeb bzeeb at Zabbadoz dot NeT
56 69 73 69 74 http://www.zabbadoz.net/
--
--- zebra-cvs-20020117-000.vanilla/./vtysh/Makefile.am Fri Feb 9 07:17:55 2001
+++ zebra-cvs-20020117-000/./vtysh/Makefile.am Thu Jan 17 19:23:27 2002
@@ -24,6 +24,12 @@
depend:
@$(CPP) -MM $(INCLUDES) $(LDFLAGS) *.c
+## hook for setuid installation if with use pam
+install-exec-hook:
+ for i in @vtysh_suidbins@; do \
+ chmod 4755 $(DESTDIR)$(bindir)/$$i; \
+ done
+
## File dependency.
vtysh.o: vtysh.c ../lib/command.h ../lib/vector.h ../lib/vty.h \
../vtysh/vtysh.h
--- zebra-cvs-20020117-000.vanilla/./vtysh/vtysh.c Mon Aug 20 08:35:35 2001
+++ zebra-cvs-20020117-000/./vtysh/vtysh.c Thu Jan 17 19:36:52 2002
@@ -34,6 +34,10 @@
#include "memory.h"
#include "vtysh/vtysh.h"
+#ifdef USE_PAM
+#include "vtysh_privs.h"
+#endif /* USE_PAM */
+
/* Struct VTY. */
struct vty *vty;
@@ -1239,7 +1243,15 @@
unlink (integrate_sav);
rename (integrate_default, integrate_sav);
+#ifdef USE_PAM
+ /* we need su privs to open fd to write config file */
+ SET_ROOT_PRIVS;
+#endif /* USE_PAM */
fp = fopen (integrate_default, "w");
+#ifdef USE_PAM
+ /* restore old privs again */
+ RESTORE_USER_PRIVS;
+#endif /* USE_PAM */
if (fp == NULL)
{
printf ("%% Can't open configuration file %s.\n", integrate_default);
@@ -1305,6 +1317,11 @@
}
else if (pid == 0)
{
+#ifdef USE_PAM
+ /* make some clean (e)uid user only that
+ * we will not get a root shell */
+ DROP_ANY_ROOT_PRIVS;
+#endif /* USE_PAM */
/* This is child process. */
switch (argc)
{
@@ -1318,6 +1335,10 @@
ret = execlp (command, command, arg1, arg2, NULL);
break;
}
+#ifdef USE_PAM
+ /* we are unable to gain superuser privs again at this point.
+ * uid==euid > 0 and therfore we are on save side of force */
+#endif /* USE_PAM */
/* When execlp suceed, this part is not executed. */
fprintf (stderr, "Can't execute %s: %s\n", command, strerror (errno));
--- zebra-cvs-20020117-000.vanilla/./vtysh/vtysh_main.c Sun Feb 11 04:37:34 2001
+++ zebra-cvs-20020117-000/./vtysh/vtysh_main.c Thu Jan 17 20:01:10 2002
@@ -35,6 +35,11 @@
#include "vtysh/vtysh.h"
#include "vtysh/vtysh_user.h"
+
+#ifdef USE_PAM
+#include "vtysh_privs.h"
+#endif /* USE_PAM */
+
/* VTY shell program name. */
char *progname;
@@ -68,6 +73,12 @@
/* Master of threads. */
struct thread_master *master;
+
+#ifdef USE_PAM
+ uid_privs_t uid_privs;
+ uid_privs_t *uid_privs_p = &uid_privs;
+#endif /* USE_PAM */
+
/* SIGTSTP handler. This function care user's ^Z input. */
void
@@ -197,6 +208,33 @@
char *eval_line = NULL;
char *integrated_file = NULL;
+#ifdef USE_PAM
+#ifdef HAVE_SETEUID
+ /* on default we assume to be setuid root and not started as root;
+ * this somehow is a worst case regarding security.
+ */
+ uid_privs_p->enabled_id_switching = 1;
+
+ /* first save inital state: uid=logged_in_user, euid=root */
+ uid_privs_p->inital_uid = uid_privs_p->saved_uid = getuid();
+ uid_privs_p->inital_euid = uid_privs_p->saved_euid = geteuid();
+
+ /* only if neither installed setuid root nor started as root
+ * do no (e)uid switching
+ */
+ if (uid_privs_p->inital_euid != 0)
+ {
+ uid_privs_p->enabled_id_switching = 0;
+ }
+#else /* HAVE_SETEUID */
+ /* disable id switching if we do not have seteuid() */
+ uid_privs_p->enabled_id_switching = 0;
+#endif /* HAVE_SETEUID */
+
+ /* for real safety */
+ DROP_ROOT_PRIVS;
+#endif /* USE_PAM */
+
/* Preserve name of myself. */
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
@@ -246,22 +284,41 @@
sort_node ();
+#ifdef USE_PAM
+ /* re-get su privs to succeed */
+ RESTORE_USER_PRIVS;
+#endif /* USE_PAM */
vtysh_connect_all ();
/* Read vtysh configuration file. */
vtysh_read_config (config_file, config_current, config_default);
- /* If eval mode */
- if (eval_flag)
+ /* Boot startup configuration file. */
+ if (boot_flag)
{
- vtysh_execute_no_pager (eval_line);
+ vtysh_read_config (integrate_file, integrate_current, integrate_default);
exit (0);
}
+
+#ifdef USE_PAM
+ /* immediately swap superuser privs now
+ * before any user commands will be excuted. */
+ DROP_ROOT_PRIVS;
+
+ if (uid_privs_p->inital_uid == 0)
+ {
+ /* we are started as root ?! :(
+ * we do NOT want this !
+ */
+ fprintf (stderr, "User root is not allowed to start vtysh !\n");
+ exit(2);
+ }
+#endif /* USE_PAM */
- /* Boot startup configuration file. */
- if (boot_flag)
+ /* If eval mode */
+ if (eval_flag)
{
- vtysh_read_config (integrate_file, integrate_current, integrate_default);
+ vtysh_execute_no_pager (eval_line);
exit (0);
}
--- zebra-cvs-20020117-000.vanilla/./vtysh/vtysh_privs.h Thu Jan 17
20:14:54 2002
+++ zebra-cvs-20020117-000/./vtysh/vtysh_privs.h Thu Jan 17 20:06:15 2002
@@ -0,0 +1,122 @@
+/*
+ *
+ * vtysh privileges macros and variables
+ *
+ * 2000-11-03, 2001-09-01, 2002-01-17,
+ * "Bjoern A. Zeeb" <address@hidden>
+ *
+ * when configured with PAM Support turned on vtysh might be
+ * installed setuid root (on systems where seteuid is available)
+ * to enable normal users to use pam authentication and
+ * therefore needing access to p.ex. /etc/shadow or /etc/master.passwd
+ * which always only su should have.
+ *
+ * these macros in here will manage to "swapping" and dropping
+ * of uid and euid what will take us to the save side of force and
+ * preventing root-shells when running start-shell (|bash|zsh) and/or
+ * exploiting the shells by "swapping" uid/euid in there again.
+ *
+ * I personally did this as learning-by-doing C-language and PAM
+ * so do not blame me.
+ *
+ * This piece of code is GPL v2 or any later version if you want.
+ *
+ * Note: I have first seen this concept in proftpd so send thanks
+ * for the idea to them.
+ *
+ */
+
+#ifndef VTYSH_PRIVS_H
+#define VTYSH_PRIVS_H
+
+#ifdef USE_PAM
+
+#ifndef HAVE_SETEUID
+/* seteuid switching (enabled_id_switching) should always be disabled so
+ * we should never be called. simply need this function to compile cleanly.
+ */
+void
+seteuid(int id)
+{
+ fprintf(stderr, "seteuid() call on system without support for this.\n");
+ exit(2);
+}
+#endif /* HAVE_SETEUID */
+
+/*
+ * variable to manage (e)uids with PAM and setuid root installation
+ */
+
+/* manage (e)uids with PAM and setuid root installation */
+typedef struct {
+ char enabled_id_switching; /* switch (e)uids or not */
+ int inital_uid; /* uid of logged in user */
+ int inital_euid; /* euid of vtysh (root) at startup */
+ int saved_uid; /* save uid before swapping */
+ int saved_euid; /* save euid before swapping */
+} uid_privs_t;
+
+extern uid_privs_t uid_privs;
+extern uid_privs_t *uid_privs_p;
+
+
+/*
+ * macros to "swap" / drop /set (e)uids
+ */
+
+
+/* At startup euid should be su (setuid root) and uid >0.
+ * If we are started as root it shouldn't matter anyway
+ */
+#define DROP_ROOT_PRIVS if ((geteuid() == 0) && (getuid > 0) &&
\
+ uid_privs_p->enabled_id_switching) { \
+ uid_privs_p->saved_uid = getuid(); \
+ uid_privs_p->saved_euid = geteuid(); \
+ setuid(0); \
+ seteuid(uid_privs_p->saved_uid); \
+ }
+
+/* if euid == 0 we already have enough privs.
+ * if uid != 0 we cannot get su privs again.
+ * this will give us euid==uid==0 :-( and save previous (e)uid to restore
later.
+ */
+#define SET_ROOT_PRIVS if ((getuid() == 0) && (geteuid() > 0) && \
+ uid_privs_p->enabled_id_switching) { \
+ uid_privs_p->saved_uid = getuid(); \
+ uid_privs_p->saved_euid = geteuid(); \
+ seteuid(0); \
+ }
+
+/* simply restore saved (e)uids.
+ * we first have to set uid and then euid.
+ */
+#define RESTORE_USER_PRIVS if ((geteuid() == 0) && (getuid() >= 0) && \
+ uid_privs_p->enabled_id_switching) { \
+ setuid(uid_privs_p->saved_uid); \
+ /* above should always be 0 */ \
+ seteuid(uid_privs_p->saved_euid); \
+ /* above should always be uid > 0 */ \
+ }
+
+/* if we call external programm we will drop any su that no one can only
+ * think about doing a seteuid(0); again and getting a root-shell that way
+ */
+#define DROP_ANY_ROOT_PRIVS if ((geteuid() == 0) && (getuid() > 0) && \
+ uid_privs_p->enabled_id_switching) { \
+ int tmp_saved_uid = getuid(); \
+ seteuid(0); \
+ setuid(tmp_saved_uid); \
+ seteuid(tmp_saved_uid); \
+ } else if ((getuid() == 0) && (geteuid() > 0) \
+ && uid_privs_p->enabled_id_switching) { \
+ int tmp_saved_euid = geteuid(); \
+ seteuid(0); \
+ setuid(tmp_saved_euid); \
+ seteuid(tmp_saved_euid); \
+ }
+
+#endif /* USE_PAM */
+
+#endif /* VTYSH_PRIVS_H */
+
+/* End vtysh_privs.h */
--- zebra-cvs-20020117-000.vanilla/./vtysh/vtysh_user.c Tue Nov 21 00:25:05 2000
+++ zebra-cvs-20020117-000/./vtysh/vtysh_user.c Thu Jan 17 20:13:42 2002
@@ -23,71 +23,184 @@
#include <pwd.h>
-#ifdef USE_PAM
-#include <security/pam_appl.h>
-#include <security/pam_misc.h>
-#endif /* USE_PAM */
-
#include "memory.h"
#include "linklist.h"
#include "command.h"
#ifdef USE_PAM
+#include <time.h>
+
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+
+#include "vtysh_privs.h"
+
+#define VTYSH_LOGIN_MAXTIRES 3
+
+#define VTYSH_AUTH_PAM_FAIL_DELAY 3000000
+
+#define VTYSH_LOGIN_DIE_TIMEOUT 30
+#define VTYSH_LOGIN_DIE_USER_MSG "% Username: timeout expired!\n"
+#define VTYSH_LOGIN_DIE_PASS_MSG "% Password: timeout expired!\n"
+
+#define VTYSH_LOGIN_FAILED_MSG "% Authentication failed.\n\n"
+
+static const char *login_prompt = "\nUser Access Verification\n\nUsername: ";
+
+typedef enum {
+ USER_MSG,
+ PASS_MSG
+} pam_msg_e;
+
static struct pam_conv conv =
{
misc_conv,
NULL
};
+void set_pam_login_timeouts(int flag, pam_msg_e state)
+{
+ time_t now;
+
+ if (flag) {
+ (void) time(&now);
+ pam_misc_conv_die_time = now + VTYSH_LOGIN_DIE_TIMEOUT;
+
+ /* Username */
+ if (state == USER_MSG)
+ pam_misc_conv_die_line = VTYSH_LOGIN_DIE_USER_MSG;
+ /* Password */
+ else if (state == PASS_MSG)
+ pam_misc_conv_die_line = VTYSH_LOGIN_DIE_PASS_MSG;
+ } else {
+ pam_misc_conv_die_time = 0;
+ }
+}
+
+
+int get_pam_user(pam_handle_t *pamh, int *timeoutp, const char *user)
+{
+ int ret;
+
+ /* enable timeouts for user(login) authentication */
+ set_pam_login_timeouts(1, USER_MSG);
+
+ ret = pam_get_user(pamh, &user, NULL);
+
+ /* stop timeout */
+ set_pam_login_timeouts(0, USER_MSG);
+
+ if (pam_misc_conv_died) {
+ pam_misc_conv_died = 0;
+ *timeoutp = 1;
+ return (PAM_PERM_DENIED);
+ } else
+ return (ret);
+}
+
+int do_pam_auth_user(pam_handle_t *pamh, int *timeoutp)
+{
+ int ret;
+
+ /* enable timeouts for user(login) authentication */
+ set_pam_login_timeouts(1, PASS_MSG);
+
+ ret = pam_authenticate(pamh, PAM_SILENT);
+
+ /* stop timeout */
+ set_pam_login_timeouts(0, PASS_MSG);
+
+ if (pam_misc_conv_died) {
+ pam_misc_conv_died = 0;
+ *timeoutp = 1;
+ return (PAM_PERM_DENIED);
+ } else
+ return (ret);
+}
+
int
-vtysh_pam (char *user)
+get_login_n_authenticate_user(pam_handle_t *pamh, int *timeoutp,
+ const char *user)
+{
+ int ret;
+ int fail = 0;
+
+ ret = get_pam_user(pamh, timeoutp, user);
+ if (!*timeoutp) {
+ if (ret != PAM_SUCCESS)
+ fail = 1;
+
+ ret = do_pam_auth_user(pamh, timeoutp);
+
+ if (((ret != PAM_SUCCESS) || fail) && !*timeoutp)
+ printf ("%s", VTYSH_LOGIN_FAILED_MSG);
+ }
+
+ if (fail)
+ return (PAM_PERM_DENIED);
+ else
+ return (ret);
+}
+
+int
+vtysh_pam(char *userp)
{
int ret;
pam_handle_t *pamh = NULL;
+ int authtries = 0;
+ int timeout;
+ char *tmp_userp = userp;
- /* Start PAM. */
- ret = pam_start("zebra", user, &conv, &pamh);
- /* printf ("ret %d\n", ret); */
-
- /* Is user really user? */
- if (ret == PAM_SUCCESS)
- ret = pam_authenticate (pamh, 0);
- /* printf ("ret %d\n", ret); */
-
-#if 0
- /* Permitted access? */
- if (ret == PAM_SUCCESS)
- ret = pam_acct_mgmt (pamh, 0);
- printf ("ret %d\n", ret);
-
- if (ret == PAM_AUTHINFO_UNAVAIL)
- ret = PAM_SUCCESS;
-#endif /* 0 */
-
- /* This is where we have been authorized or not. */
-#ifdef DEBUG
- if (ret == PAM_SUCCESS)
- printf("Authenticated\n");
- else
- printf("Not Authenticated\n");
-#endif /* DEBUG */
+ tmp_userp = NULL;
- /* close Linux-PAM */
- if (pam_end (pamh, ret) != PAM_SUCCESS)
- {
- pamh = NULL;
- fprintf(stderr, "vtysh_pam: failed to release authenticator\n");
- exit(1);
- }
+ ret = pam_start("zebra", tmp_userp, &conv, &pamh);
+ if (ret != PAM_SUCCESS)
+ goto out;
+
+ ret = pam_set_item(pamh, PAM_USER_PROMPT, (const void *)login_prompt);
+ if (ret != PAM_SUCCESS)
+ goto out;
+
+#ifdef HAVE_PAM_FAIL_DELAY
+ ret = pam_fail_delay(pamh, VTYSH_AUTH_PAM_FAIL_DELAY);
+ if (ret != PAM_SUCCESS)
+ goto out;
+#endif /* HAVE_PAM_FAIL_DELAY */
+
+ do {
+
+ authtries++;
+ timeout = 0;
+
+ /* always ask for username */
+ tmp_userp = NULL;
+
+ if (pam_set_item(pamh, PAM_USER, tmp_userp) != PAM_SUCCESS)
+ goto out;
+
+ ret = get_login_n_authenticate_user(pamh, &timeout, tmp_userp);
+
+ } while ((ret != PAM_SUCCESS) && (authtries < VTYSH_LOGIN_MAXTIRES));
+
+ if (timeout)
+ printf ("%s", VTYSH_LOGIN_FAILED_MSG);
+
+out:
+ if (pam_end(pamh, ret) != PAM_SUCCESS)
+ pamh = NULL;
return ret == PAM_SUCCESS ? 0 : 1;
}
#endif /* USE_PAM */
+
struct user
{
char *name;
u_char nopassword;
+#ifdef USE_PAM
+ u_char pamauthentication;
+#endif /* USE_PAM */
};
struct list *userlist;
@@ -131,6 +244,10 @@
{
if (user->nopassword)
printf (" username %s nopassword\n", user->name);
+#ifdef USE_PAM
+ else if (user->pamauthentication)
+ printf (" username %s pamauthentication\n", user->name);
+#endif /* USE_PAM */
}
}
@@ -152,7 +267,7 @@
DEFUN (username_nopassword,
username_nopassword_cmd,
"username WORD nopassword",
- "\n"
+ "Establish passwordless user name authentication\n"
"\n"
"\n")
{
@@ -162,6 +277,21 @@
return CMD_SUCCESS;
}
+#ifdef USE_PAM
+DEFUN (username_pamauthentication,
+ username_pamauthentication_cmd,
+ "username WORD pamauthentication",
+ "Validate user using PAM auhtentication\n"
+ "\n"
+ "\n")
+{
+ struct user *user;
+ user = user_get (argv[0]);
+ user->pamauthentication = 1;
+ return CMD_SUCCESS;
+}
+#endif /* USE_PAM */
+
int
vtysh_auth ()
{
@@ -173,13 +303,27 @@
user = user_lookup (passwd->pw_name);
if (user && user->nopassword)
/* Pass through */;
- else
- {
#ifdef USE_PAM
- if (vtysh_pam (passwd->pw_name))
+ else if (user && user->pamauthentication) {
+ /* this enables one to not give access to all shell users or
+ * have one user that gets access and user/password is authenticated
+ * through some other system (p.ex. pam_radius, pam_tacacs
+ */
+ /* re-get su privs for pam to succeed everywhere */
+ SET_ROOT_PRIVS;
+ if (vtysh_pam(passwd->pw_name))
exit (0);
+ else {
+ /* login succeeded. we no longer need su privs. */
+ RESTORE_USER_PRIVS;
+ }
+ }
#endif /* USE_PAM */
- }
+ else {
+ printf("%% Login invalid.\nYou (%s, %s) are not allowed to login.\n\n",
+ passwd->pw_name, passwd->pw_gecos);
+ exit (0);
+ }
return 0;
}
@@ -188,4 +332,7 @@
{
userlist = list_new ();
install_element (CONFIG_NODE, &username_nopassword_cmd);
+#ifdef USE_PAM
+ install_element (CONFIG_NODE, &username_pamauthentication_cmd);
+#endif /* USE_PAM */
}
--- zebra-cvs-20020117-000.vanilla/./acconfig.h Thu Aug 30 09:04:12 2001
+++ zebra-cvs-20020117-000/./acconfig.h Thu Jan 17 19:23:27 2002
@@ -109,6 +109,9 @@
/* PAM support */
#undef USE_PAM
+/* Define if you have the seteuid function. */
+#undef HAVE_SETEUID
+
/* TCP/IP communication between zebra and protocol daemon. */
#undef HAVE_TCP_ZEBRA
--- zebra-cvs-20020117-000.vanilla/./configure.in Tue Oct 23 10:43:55 2001
+++ zebra-cvs-20020117-000/./configure.in Thu Jan 17 20:28:05 2002
@@ -60,7 +60,7 @@
dnl Packages configuration
dnl ----------------------
AC_ARG_ENABLE(vtysh,
-[ --enable-vtysh, Make integrated VTY version of zebra])
+[ --enable-vtysh Make integrated VTY version of zebra])
AC_ARG_ENABLE(ipv6,
[ --disable-ipv6 turn off IPv6 related features and daemons])
AC_ARG_ENABLE(zebra,
@@ -76,7 +76,7 @@
AC_ARG_ENABLE(ospf6d,
[ --disable-ospf6d do not build ospf6d])
AC_ARG_ENABLE(bgp-announce,
-[ --disable-bgp-announce, turn off BGP route announcement])
+[ --disable-bgp-announce turn off BGP route announcement])
AC_ARG_ENABLE(netlink,
[ --enable-netlink force to use Linux netlink interface])
AC_ARG_ENABLE(broken-aliases,
@@ -85,6 +85,8 @@
[ --enable-snmp enable SNMP support])
AC_ARG_WITH(libpam,
[ --with-libpam use libpam for PAM support in vtysh])
+AC_ARG_ENABLE(vtysh-setuid,
+[ --enable-vtysh-setuid enable setuid root installation of vtysh if
compiled with pam])
AC_ARG_ENABLE(tcpsock,
[ --enable-tcp-zebra enable TCP/IP socket connection between zebra and
protocol daemon])
dnl Temporary option until OSPF NSSA implementation complete
@@ -221,11 +223,14 @@
dnl of the PAM library. Prior to 0.72 release, the Linux PAM shared library
dnl omitted requiring libdl linking information. PAM-0.72 or better ships
dnl with RedHat 6.2 and Debian 2.2 or better.
+PAM=no
AC_CHECK_LIB(pam, pam_start,
[AC_CHECK_LIB(pam, misc_conv,
[AC_DEFINE(USE_PAM)
+ PAM=yes
LIBPAM="-lpam"],
[AC_DEFINE(USE_PAM)
+ PAM=yes
LIBPAM="-lpam -lpam_misc"]
)
],
@@ -233,8 +238,10 @@
[AC_CHECK_LIB(pam, pam_end,
[AC_CHECK_LIB(pam, misc_conv,
[AC_DEFINE(USE_PAM)
+ PAM=yes
LIBPAM="-lpam -ldl"],
[AC_DEFINE(USE_PAM)
+ PAM=yes
LIBPAM="-lpam -ldl -lpam_misc"]
)
],AC_MSG_WARN([*** pam support will not be built ***]),
@@ -243,6 +250,24 @@
)
fi
AC_SUBST(LIBPAM)
+
+dnl --------------------------------------------
+dnl seteuid for PAM in setuid root installations
+dnl --------------------------------------------
+if test "$PAM" = "yes"; then
+SETEUID=no
+vtysh_suidbins=""
+AC_CHECK_FUNCS(seteuid, SETEUID=yes)
+ if test "${enable_vtysh_setuid}" = "yes"; then
+ if test "${SETEUID}" = "yes"; then
+ vtysh_suidbins="vtysh"
+ AC_MSG_RESULT([*** !!! vtysh will be installed setuid root !!!
***])
+ else
+ AC_MSG_RESULT([seteuid not found on your system. vtysh will not
be installed setuid root.]);
+ fi
+ fi
+fi
+AC_SUBST(vtysh_suidbins)
dnl -------------------------------
dnl Endian-ness check
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] PAM additions for vtysh,
Bjoern A. Zeeb <=