FreeBSD login class (login.conf) support.
This commit is contained in:
@@ -491,6 +491,9 @@
|
|||||||
/* Define if you use OSF DCE. */
|
/* Define if you use OSF DCE. */
|
||||||
#undef HAVE_DCE
|
#undef HAVE_DCE
|
||||||
|
|
||||||
|
/* Define if you use the BSD login capabilities database. */
|
||||||
|
#undef HAVE_LOGINCAP
|
||||||
|
|
||||||
/* Define if you use the FWTK authsrv daemon. */
|
/* Define if you use the FWTK authsrv daemon. */
|
||||||
#undef HAVE_FWTK
|
#undef HAVE_FWTK
|
||||||
|
|
||||||
|
28
configure.in
28
configure.in
@@ -315,6 +315,17 @@ AC_ARG_WITH(DCE, [ --with-DCE enable DCE support],
|
|||||||
;;
|
;;
|
||||||
esac])
|
esac])
|
||||||
|
|
||||||
|
AC_ARG_WITH(logincap, [ --with-logincap enable login class support],
|
||||||
|
[case $with_logincap in
|
||||||
|
yes) AC_DEFINE(HAVE_LOGINCAP)
|
||||||
|
AC_MSG_CHECKING(whether to try BSD login capabilities database)
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
;;
|
||||||
|
no) ;;
|
||||||
|
*) AC_MSG_ERROR(["--with-logincap does not take an argument."])
|
||||||
|
;;
|
||||||
|
esac])
|
||||||
|
|
||||||
AC_MSG_CHECKING(whether to lecture users the first time they run sudo)
|
AC_MSG_CHECKING(whether to lecture users the first time they run sudo)
|
||||||
AC_ARG_WITH(lecture, [ --without-lecture don't print lecture for first-time sudoer],
|
AC_ARG_WITH(lecture, [ --without-lecture don't print lecture for first-time sudoer],
|
||||||
[case $with_lecture in
|
[case $with_lecture in
|
||||||
@@ -1273,6 +1284,11 @@ case "$host" in
|
|||||||
CC="$ac_cv_prog_CC"
|
CC="$ac_cv_prog_CC"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
*-*-freebsd*)
|
||||||
|
if test "$with_skey" = "yes"; then
|
||||||
|
SUDO_LIBS="${SUDO_LIBS} -lmd"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
*-*-*bsd*)
|
*-*-*bsd*)
|
||||||
if test "$CHECKSHADOW" = "true"; then
|
if test "$CHECKSHADOW" = "true"; then
|
||||||
CHECKSHADOW="false"
|
CHECKSHADOW="false"
|
||||||
@@ -1521,6 +1537,18 @@ if test "$with_DCE" = "yes"; then
|
|||||||
SUDO_LIBS="${SUDO_LIBS} -ldce"
|
SUDO_LIBS="${SUDO_LIBS} -ldce"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl extra login capabilities libs and includes
|
||||||
|
dnl
|
||||||
|
if test "$with_logincap" = "yes"; then
|
||||||
|
SUDO_LIBS="${SUDO_LIBS} -lutil"
|
||||||
|
if test -f /usr/include/login_cap.h -a -f /usr/include/sys/types.h -a -f /usr/lib/libutil.a; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo 'Unable to locate libutil.a and/or login_cap.h, you will have to edit the Makefile and add -L/path/to/libutil to SUDO_LDFLAGS and/or -I/path/to/login_cap.h to CPPFLAGS'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl extra S/Key lib and includes
|
dnl extra S/Key lib and includes
|
||||||
dnl
|
dnl
|
||||||
|
@@ -193,6 +193,9 @@ struct sudo_defs_types sudo_defs_table[] = {
|
|||||||
}, {
|
}, {
|
||||||
"targetpw", T_FLAG,
|
"targetpw", T_FLAG,
|
||||||
"Prompt for the target user's password, not the users's"
|
"Prompt for the target user's password, not the users's"
|
||||||
|
}, {
|
||||||
|
"use_loginclass", T_FLAG,
|
||||||
|
"Apply defaults in the target user's login class if there is one"
|
||||||
}, {
|
}, {
|
||||||
"loglinelen", T_INT|T_BOOL,
|
"loglinelen", T_INT|T_BOOL,
|
||||||
"Length at which to wrap log file lines (0 for no wrap): %d"
|
"Length at which to wrap log file lines (0 for no wrap): %d"
|
||||||
|
43
defaults.h
43
defaults.h
@@ -115,35 +115,36 @@ struct sudo_defs_types {
|
|||||||
#define I_ROOTPW 25
|
#define I_ROOTPW 25
|
||||||
#define I_RUNASPW 26
|
#define I_RUNASPW 26
|
||||||
#define I_TARGETPW 27
|
#define I_TARGETPW 27
|
||||||
|
#define I_LOGINCLASS 28
|
||||||
|
|
||||||
/* Integer values */
|
/* Integer values */
|
||||||
#define I_LOGLEN 28 /* wrap log file line after N chars */
|
#define I_LOGLEN 29 /* wrap log file line after N chars */
|
||||||
#define I_TS_TIMEOUT 29 /* timestamp stale after N minutes */
|
#define I_TS_TIMEOUT 30 /* timestamp stale after N minutes */
|
||||||
#define I_PW_TIMEOUT 30 /* exit if pass not entered in N minutes */
|
#define I_PW_TIMEOUT 31 /* exit if pass not entered in N minutes */
|
||||||
#define I_PW_TRIES 31 /* exit after N bad password tries */
|
#define I_PW_TRIES 32 /* exit after N bad password tries */
|
||||||
#define I_UMASK 32 /* umask to use or 0777 to use user's */
|
#define I_UMASK 33 /* umask to use or 0777 to use user's */
|
||||||
|
|
||||||
/* Strings */
|
/* Strings */
|
||||||
#define I_LOGFILE 33 /* path to logfile (or NULL for none) */
|
#define I_LOGFILE 34 /* path to logfile (or NULL for none) */
|
||||||
#define I_MAILERPATH 34 /* path to sendmail or other mailer */
|
#define I_MAILERPATH 35 /* path to sendmail or other mailer */
|
||||||
#define I_MAILERFLAGS 35 /* flags to pass to the mailer */
|
#define I_MAILERFLAGS 36 /* flags to pass to the mailer */
|
||||||
#define I_MAILTO 36 /* who to send bitch mail to */
|
#define I_MAILTO 37 /* who to send bitch mail to */
|
||||||
#define I_MAILSUB 37 /* subject line of mail msg */
|
#define I_MAILSUB 38 /* subject line of mail msg */
|
||||||
#define I_BADPASS_MSG 38 /* what to say when passwd is wrong */
|
#define I_BADPASS_MSG 39 /* what to say when passwd is wrong */
|
||||||
#define I_TIMESTAMPDIR 39 /* path to timestamp dir */
|
#define I_TIMESTAMPDIR 40 /* path to timestamp dir */
|
||||||
#define I_EXEMPT_GRP 40 /* no password or PATH override for these */
|
#define I_EXEMPT_GRP 41 /* no password or PATH override for these */
|
||||||
#define I_PASSPROMPT 41 /* password prompt */
|
#define I_PASSPROMPT 42 /* password prompt */
|
||||||
#define I_RUNAS_DEF 42 /* default user to run commands as */
|
#define I_RUNAS_DEF 43 /* default user to run commands as */
|
||||||
#define I_SECURE_PATH 43 /* set $PATH to this if not NULL */
|
#define I_SECURE_PATH 44 /* set $PATH to this if not NULL */
|
||||||
#define I_EDITOR 44 /* path to editor used by visudo */
|
#define I_EDITOR 45 /* path to editor used by visudo */
|
||||||
|
|
||||||
/* Integer versions of list/verify options */
|
/* Integer versions of list/verify options */
|
||||||
#define I_LISTPW 45
|
#define I_LISTPW 46
|
||||||
#define I_VERIFYPW 46
|
#define I_VERIFYPW 47
|
||||||
|
|
||||||
/* String versions of list/verify options */
|
/* String versions of list/verify options */
|
||||||
#define I_LISTPWSTR 47
|
#define I_LISTPWSTR 48
|
||||||
#define I_VERIFYPWSTR 48
|
#define I_VERIFYPWSTR 49
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macros for accessing sudo_defs_table.
|
* Macros for accessing sudo_defs_table.
|
||||||
|
76
sudo.c
76
sudo.c
@@ -76,6 +76,9 @@
|
|||||||
# endif /* __hpux */
|
# endif /* __hpux */
|
||||||
# include <prot.h>
|
# include <prot.h>
|
||||||
#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
|
#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
|
||||||
|
#ifdef HAVE_LOGINCAP
|
||||||
|
# include <login_cap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
@@ -105,6 +108,7 @@ static void usage __P((int));
|
|||||||
static void usage_excl __P((int));
|
static void usage_excl __P((int));
|
||||||
static void check_sudoers __P((void));
|
static void check_sudoers __P((void));
|
||||||
static int init_vars __P((int));
|
static int init_vars __P((int));
|
||||||
|
static int set_loginclass __P((struct passwd *));
|
||||||
static void add_env __P((int));
|
static void add_env __P((int));
|
||||||
static void clean_env __P((char **, struct env_table *));
|
static void clean_env __P((char **, struct env_table *));
|
||||||
static void initial_setup __P((void));
|
static void initial_setup __P((void));
|
||||||
@@ -594,6 +598,20 @@ parse_args()
|
|||||||
NewArgc--;
|
NewArgc--;
|
||||||
NewArgv++;
|
NewArgv++;
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_LOGINCAP
|
||||||
|
case 'c':
|
||||||
|
/* Must have an associated login class. */
|
||||||
|
if (NewArgv[1] == NULL)
|
||||||
|
usage(1);
|
||||||
|
|
||||||
|
login_class = NewArgv[1];
|
||||||
|
def_flag(I_LOGINCLASS) = TRUE;
|
||||||
|
|
||||||
|
/* Shift Argv over and adjust Argc. */
|
||||||
|
NewArgc--;
|
||||||
|
NewArgv++;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 'b':
|
case 'b':
|
||||||
rval |= MODE_BACKGROUND;
|
rval |= MODE_BACKGROUND;
|
||||||
break;
|
break;
|
||||||
@@ -938,6 +956,15 @@ set_perms(perm, sudo_mode)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (def_flag(I_LOGINCLASS)) {
|
||||||
|
/*
|
||||||
|
* setusercontext() will set uid/gid/etc
|
||||||
|
* for us so no need to do it below.
|
||||||
|
*/
|
||||||
|
if (set_loginclass(pw) > 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (setgid(pw->pw_gid)) {
|
if (setgid(pw->pw_gid)) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"%s: cannot set gid to %ld: %s\n",
|
"%s: cannot set gid to %ld: %s\n",
|
||||||
@@ -1050,6 +1077,51 @@ initial_setup()
|
|||||||
#endif /* POSIX_SIGNALS */
|
#endif /* POSIX_SIGNALS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LOGINCAP
|
||||||
|
int
|
||||||
|
set_loginclass(pw)
|
||||||
|
struct passwd *pw;
|
||||||
|
{
|
||||||
|
login_cap_t *lc;
|
||||||
|
|
||||||
|
if (login_class && strcmp(login_class, "-") != 0) {
|
||||||
|
if (strcmp(*user_runas, "root") != 0) {
|
||||||
|
(void) fprintf(stderr, "%s: only root can use -c %s\n",
|
||||||
|
Argv[0], login_class);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lc = login_getclass(login_class);
|
||||||
|
if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0)
|
||||||
|
log_error(NO_MAIL|MSG_ONLY, "unknown login class: %s", login_class);
|
||||||
|
} else if (!(lc = login_getpwclass(pw))) {
|
||||||
|
/*
|
||||||
|
* This is not a fatal error if the user didn't specify the login
|
||||||
|
* class themselves. We do this because if login.conf gets
|
||||||
|
* corrupted we want the admin to be able to use sudo to fix it.
|
||||||
|
*/
|
||||||
|
log_error(login_class ? NO_MAIL|MSG_ONLY : NO_MAIL|NO_EXIT|MSG_ONLY,
|
||||||
|
"can't get class for user: %s", user_runas);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set everything except the environment and umask. */
|
||||||
|
if (setusercontext(lc, pw, pw->pw_uid,
|
||||||
|
LOGIN_SETUSER|LOGIN_SETGROUP|LOGIN_SETRESOURCES|LOGIN_SETPRIORITY) < 0)
|
||||||
|
log_error(NO_MAIL|USE_ERRNO|MSG_ONLY,
|
||||||
|
"setusercontext() failed for login class %s", lc);
|
||||||
|
|
||||||
|
login_close(lc);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int set_loginclass(pw)
|
||||||
|
struct passwd *pw;
|
||||||
|
{
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up the fully qualified domain name and set user_host and user_shost.
|
* Look up the fully qualified domain name and set user_host and user_shost.
|
||||||
*/
|
*/
|
||||||
@@ -1137,6 +1209,10 @@ usage(exit_val)
|
|||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"usage: %s -V | -h | -L | -l | -v | -k | -K | [-H] [-S] [-b]\n%*s",
|
"usage: %s -V | -h | -L | -l | -v | -k | -K | [-H] [-S] [-b]\n%*s",
|
||||||
Argv[0], (int) strlen(Argv[0]) + 8, " ");
|
Argv[0], (int) strlen(Argv[0]) + 8, " ");
|
||||||
|
#ifdef HAVE_LOGINCAP
|
||||||
|
(void) fprintf(stderr, "[-p prompt] [-u username/#uid] [-c class] -s | <command>\n");
|
||||||
|
#else
|
||||||
(void) fprintf(stderr, "[-p prompt] [-u username/#uid] -s | <command>\n");
|
(void) fprintf(stderr, "[-p prompt] [-u username/#uid] -s | <command>\n");
|
||||||
|
#endif
|
||||||
exit(exit_val);
|
exit(exit_val);
|
||||||
}
|
}
|
||||||
|
2
sudo.h
2
sudo.h
@@ -56,6 +56,7 @@ struct sudo_user {
|
|||||||
char *cmnd_safe;
|
char *cmnd_safe;
|
||||||
char *cmnd;
|
char *cmnd;
|
||||||
char *cmnd_args;
|
char *cmnd_args;
|
||||||
|
char *class_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -129,6 +130,7 @@ struct sudo_user {
|
|||||||
#define user_host (sudo_user.host)
|
#define user_host (sudo_user.host)
|
||||||
#define user_shost (sudo_user.shost)
|
#define user_shost (sudo_user.shost)
|
||||||
#define safe_cmnd (sudo_user.cmnd_safe)
|
#define safe_cmnd (sudo_user.cmnd_safe)
|
||||||
|
#define login_class (sudo_user.class_name)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We used to use the system definition of PASS_MAX or _PASSWD_LEN,
|
* We used to use the system definition of PASS_MAX or _PASSWD_LEN,
|
||||||
|
Reference in New Issue
Block a user