2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-01 14:55:12 +00:00

Add support for BSD authentication.

This commit is contained in:
Todd C. Miller
2000-10-26 16:42:40 +00:00
parent e7ee4f9885
commit 0208b22686
8 changed files with 685 additions and 438 deletions

View File

@@ -115,8 +115,8 @@ SRCS = alloc.c alloca.c check.c defaults.c fileops.c find_path.c fnmatch.c \
strerror.c sudo.c sudo.tab.c sudo_setenv.c testsudoers.c tgetpass.c \ strerror.c sudo.c sudo.tab.c sudo_setenv.c testsudoers.c tgetpass.c \
utime.c visudo.c $(AUTH_SRCS) utime.c visudo.c $(AUTH_SRCS)
AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/dce.c auth/fwtk.c auth/kerb4.c \ AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \ auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \
auth/secureware.c auth/securid.c auth/sia.c auth/sudo_auth.c auth/secureware.c auth/securid.c auth/sia.c auth/sudo_auth.c
HDRS = compat.h defaults.h ins_2001.h ins_classic.h ins_csops.h ins_goons.h \ HDRS = compat.h defaults.h ins_2001.h ins_classic.h ins_csops.h ins_goons.h \
@@ -230,6 +230,8 @@ afs.o: $(authdir)/afs.c $(AUTHDEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/afs.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/afs.c
aix_auth.o: $(authdir)/aix_auth.c $(AUTHDEP) aix_auth.o: $(authdir)/aix_auth.c $(AUTHDEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/aix_auth.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/aix_auth.c
bsdauth.o: $(authdir)/bsdauth.c $(AUTHDEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/bsdauth.c
dce.o: $(authdir)/dce.c $(AUTHDEP) dce.o: $(authdir)/dce.c $(AUTHDEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/dce.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(authdir)/dce.c
fwtk.o: $(authdir)/fwtk.c $(AUTHDEP) fwtk.o: $(authdir)/fwtk.c $(AUTHDEP)

132
auth/bsdauth.c Normal file
View File

@@ -0,0 +1,132 @@
/*
* Copyright (c) 2000 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. Products derived from this software may not be called "Sudo" nor
* may "Sudo" appear in their names without specific prior written
* permission from the author.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <stdio.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif /* STDC_HEADERS */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_STRING_H
#include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <sys/param.h>
#include <sys/types.h>
#include <pwd.h>
#include <login_cap.h>
#include <bsd_auth.h>
#include "sudo.h"
#include "sudo_auth.h"
#ifndef lint
static const char rcsid[] = "$Sudo$";
#endif /* lint */
extern char *login_style; /* from sudo.c */
int
bsdauth_init(pw, promptp, auth)
struct passwd *pw;
char **promptp;
sudo_auth *auth;
{
static auth_session_t *as;
extern login_cap_t *lc; /* from sudo.c */
if ((as = auth_open()) == NULL) {
log_error(USE_ERRNO|NO_EXIT|NO_MAIL,
"unable to begin bsd authentication");
return(AUTH_FATAL);
}
/* XXX - maybe sanity check the auth style earlier? */
login_style = login_getstyle(lc, login_style, "auth-sudo");
if (login_style == NULL) {
log_error(NO_EXIT|NO_MAIL, "invalid authentication type");
auth_close(as);
return(AUTH_FATAL);
}
auth->data = (VOID *) as;
return(AUTH_SUCCESS);
}
/* XXX - doesn't deal with custom prompts yet (have to use lower-level funcs) */
int
bsdauth_verify(pw, prompt, auth)
struct passwd *pw;
char *prompt;
sudo_auth *auth;
{
char *s;
int authok;
sig_t childkiller;
auth_session_t *as = (auth_session_t *) auth->data;
/* save old signal handler */
childkiller = signal(SIGCHLD, SIG_DFL);
auth_verify(as, login_style, pw->pw_name, login_class, NULL);
/* restore old signal handler */
(void)signal(SIGCHLD, childkiller);
authok = auth_getstate(as);
if ((authok & AUTH_ALLOW))
return(AUTH_SUCCESS);
if ((s = auth_getvalue(as, "errormsg")) != NULL)
log_error(NO_EXIT|NO_MAIL, "%s\n", s);
return(AUTH_FAILURE);
}
int
bsdauth_cleanup(pw, auth)
struct passwd *pw;
sudo_auth *auth;
{
auth_session_t *as = (auth_session_t *) auth->data;
auth_close(as);
return(AUTH_SUCCESS);
}

View File

@@ -55,7 +55,7 @@ typedef struct sudo_auth {
/* Values for sudo_auth.flags. */ /* Values for sudo_auth.flags. */
/* XXX - these names are too long for my liking */ /* XXX - these names are too long for my liking */
#define FLAG_USER 0x01 /* functions must run as root */ #define FLAG_USER 0x01 /* functions must run as the user, not root */
#define FLAG_CONFIGURED 0x02 /* method configured ok */ #define FLAG_CONFIGURED 0x02 /* method configured ok */
#define FLAG_ONEANDONLY 0x04 /* one and only auth method */ #define FLAG_ONEANDONLY 0x04 /* one and only auth method */
@@ -75,6 +75,9 @@ int sia_setup __P((struct passwd *pw, char **prompt, sudo_auth *auth));
int sia_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth)); int sia_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
int sia_cleanup __P((struct passwd *pw, sudo_auth *auth)); int sia_cleanup __P((struct passwd *pw, sudo_auth *auth));
int aixauth_verify __P((struct passwd *pw, char *pass, sudo_auth *auth)); int aixauth_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
int bsdauth_init __P((struct passwd *pw, char **prompt, sudo_auth *auth));
int bsdauth_verify __P((struct passwd *pw, char *prompt, sudo_auth *auth));
int bsdauth_cleanup __P((struct passwd *pw, sudo_auth *auth));
/* Prototypes for normal methods */ /* Prototypes for normal methods */
int passwd_verify __P((struct passwd *pw, char *pass, sudo_auth *auth)); int passwd_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
@@ -118,6 +121,10 @@ int securid_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
# define AUTH_STANDALONE \ # define AUTH_STANDALONE \
AUTH_ENTRY(0, "fwtk", fwtk_init, \ AUTH_ENTRY(0, "fwtk", fwtk_init, \
NULL, fwtk_verify, fwtk_cleanup) NULL, fwtk_verify, fwtk_cleanup)
#elif defined(HAVE_BSD_AUTH_H)
# define AUTH_STANDALONE \
AUTH_ENTRY(0, "bsdauth", bsdauth_init, \
NULL, bsdauth_verify, bsdauth_cleanup)
#endif #endif
#endif /* SUDO_AUTH_H */ #endif /* SUDO_AUTH_H */

View File

@@ -495,7 +495,10 @@
#undef HAVE_DCE #undef HAVE_DCE
/* Define if you use the BSD login capabilities database. */ /* Define if you use the BSD login capabilities database. */
#undef HAVE_LOGINCAP #undef HAVE_LOGIN_CAP_H
/* Define if you use BSD authentication. */
#undef HAVE_BSD_AUTH_H
/* Define if you use the FWTK authsrv daemon. */ /* Define if you use the FWTK authsrv daemon. */
#undef HAVE_FWTK #undef HAVE_FWTK

861
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -374,17 +374,20 @@ AC_ARG_WITH(DCE, [ --with-DCE enable DCE support],
;; ;;
esac]) esac])
AC_ARG_WITH(logincap, [ --with-logincap enable login class support], AC_ARG_WITH(logincap, [ --with-logincap enable BSD login class support],
[case $with_logincap in [case $with_logincap in
yes) AC_DEFINE(HAVE_LOGINCAP) yes|no) ;;
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."]) *) AC_MSG_ERROR(["--with-logincap does not take an argument."])
;; ;;
esac]) esac])
AC_ARG_WITH(bsdauth, [ --with-bsdauth enable BSD authentication support],
[case $with_bsdauth in
yes|no) ;;
*) AC_MSG_ERROR(["--with-bsdauth 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
@@ -1428,6 +1431,9 @@ case "$host" in
fi fi
;; ;;
*-*-freebsd*) *-*-freebsd*)
if test "$with_logincap" = "yes"; then
SUDO_LIBS="${SUDO_LIBS} -lutil"
fi
if test "$with_skey" = "yes"; then if test "$with_skey" = "yes"; then
SUDO_LIBS="${SUDO_LIBS} -lmd" SUDO_LIBS="${SUDO_LIBS} -lmd"
fi fi
@@ -1491,6 +1497,12 @@ if test "$OS" != "ultrix"; then
AC_CHECK_HEADERS(termio.h) AC_CHECK_HEADERS(termio.h)
AC_CHECK_HEADERS(termios.h, AC_CHECK_FUNCS(tcgetattr)) AC_CHECK_HEADERS(termios.h, AC_CHECK_FUNCS(tcgetattr))
fi fi
if test "$with_logincap" = "yes"; then
AC_CHECK_HEADERS(login_cap.h)
fi
if test "$with_bsdauth" = "yes"; then
AC_CHECK_HEADER(bsd_auth.h, AC_DEFINE(HAVE_BSD_AUTH_H) [with_passwd=no; AUTH_OBJS=bsdauth.o])
fi
dnl dnl
dnl typedef checks dnl typedef checks
dnl dnl
@@ -1702,18 +1714,6 @@ 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

View File

@@ -207,6 +207,10 @@ sudo_pwdup(pw)
(void) memcpy(local_pw, pw, sizeof(struct passwd)); (void) memcpy(local_pw, pw, sizeof(struct passwd));
local_pw->pw_name = estrdup(pw->pw_name); local_pw->pw_name = estrdup(pw->pw_name);
local_pw->pw_dir = estrdup(pw->pw_dir); local_pw->pw_dir = estrdup(pw->pw_dir);
local_pw->pw_gecos = estrdup(pw->pw_gecos);
#ifdef HAVE_LOGIN_CAP_H
local_pw->pw_class = estrdup(pw->pw_class);
#endif
/* pw_shell is a special case since we overide with $SHELL */ /* pw_shell is a special case since we overide with $SHELL */
local_pw->pw_shell = estrdup(sudo_getshell(pw)); local_pw->pw_shell = estrdup(sudo_getshell(pw));

70
sudo.c
View File

@@ -77,7 +77,7 @@
# 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 #ifdef HAVE_LOGIN_CAP_H
# include <login_cap.h> # include <login_cap.h>
# ifndef LOGIN_DEFROOTCLASS # ifndef LOGIN_DEFROOTCLASS
# define LOGIN_DEFROOTCLASS "daemon" # define LOGIN_DEFROOTCLASS "daemon"
@@ -112,7 +112,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 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));
@@ -139,6 +139,12 @@ static char *runas_homedir = NULL; /* XXX */
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
static struct rlimit corelimit; static struct rlimit corelimit;
#endif /* RLIMIT_CORE */ #endif /* RLIMIT_CORE */
#ifdef HAVE_LOGIN_CAP_H
login_cap_t *lc;
#endif /* HAVE_LOGIN_CAP_H */
#ifdef HAVE_BSD_AUTH_H
char *login_style;
#endif /* HAVE_BSD_AUTH_H */
/* /*
* Table of "bad" envariables to remove and len for strncmp() * Table of "bad" envariables to remove and len for strncmp()
@@ -545,6 +551,9 @@ init_vars(sudo_mode)
; ;
} }
/* Set login class if applicable. */
set_loginclass(sudo_user.pw);
/* Resolve the path and return. */ /* Resolve the path and return. */
if ((sudo_mode & MODE_RUN)) if ((sudo_mode & MODE_RUN))
return(find_path(NewArgv[0], &user_cmnd)); return(find_path(NewArgv[0], &user_cmnd));
@@ -599,7 +608,20 @@ parse_args()
NewArgc--; NewArgc--;
NewArgv++; NewArgv++;
break; break;
#ifdef HAVE_LOGINCAP #ifdef HAVE_BSD_AUTH_H
case 'a':
/* Must have an associated authentication style. */
if (NewArgv[1] == NULL)
usage(1);
login_style = NewArgv[1];
/* Shift Argv over and adjust Argc. */
NewArgc--;
NewArgv++;
break;
#endif
#ifdef HAVE_LOGIN_CAP_H
case 'c': case 'c':
/* Must have an associated login class. */ /* Must have an associated login class. */
if (NewArgv[1] == NULL) if (NewArgv[1] == NULL)
@@ -930,14 +952,22 @@ set_perms(perm, sudo_mode)
sudo_setenv("LOGNAME", pw->pw_name); sudo_setenv("LOGNAME", pw->pw_name);
} }
#ifdef HAVE_LOGIN_CAP_H
if (def_flag(I_LOGINCLASS)) { if (def_flag(I_LOGINCLASS)) {
/* /*
* setusercontext() will set uid/gid/etc * setusercontext() will set uid/gid/etc
* for us so no need to do it below. * for us so no need to do it below.
*/ */
if (set_loginclass(pw) > 0) if (setusercontext(lc, pw, pw->pw_uid,
LOGIN_SETUSER|LOGIN_SETGROUP|LOGIN_SETRESOURCES|LOGIN_SETPRIORITY))
log_error(
NO_MAIL|USE_ERRNO|MSG_ONLY,
"setusercontext() failed for login class %s",
login_class);
else
break; break;
} }
#endif /* HAVE_LOGIN_CAP_H */
if (setgid(pw->pw_gid)) { if (setgid(pw->pw_gid)) {
(void) fprintf(stderr, (void) fprintf(stderr,
@@ -1051,12 +1081,11 @@ initial_setup()
#endif /* POSIX_SIGNALS */ #endif /* POSIX_SIGNALS */
} }
#ifdef HAVE_LOGINCAP #ifdef HAVE_LOGIN_CAP_H
static int static void
set_loginclass(pw) set_loginclass(pw)
struct passwd *pw; struct passwd *pw;
{ {
login_cap_t *lc;
int errflags; int errflags;
/* /*
@@ -1083,28 +1112,16 @@ set_loginclass(pw)
} }
lc = login_getclass(login_class); lc = login_getclass(login_class);
if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) { if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0)
log_error(errflags, "unknown login class: %s", login_class); log_error(errflags, "unknown login class: %s", login_class);
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", login_class);
login_close(lc);
return(1);
} }
#else #else
static int static int
set_loginclass(pw) set_loginclass(pw)
struct passwd *pw; struct passwd *pw;
{ {
return(0);
} }
#endif /* HAVE_LOGINCAP */ #endif /* HAVE_LOGIN_CAP_H */
/* /*
* 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.
@@ -1189,10 +1206,13 @@ 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] ");
(void) fprintf(stderr, "[-p prompt] [-u username/#uid] [-c class] -s | <command>\n"); #ifdef HAVE_LOGIN_CAP_H
#else (void) fprintf(stderr, "[-c class] ");
(void) fprintf(stderr, "[-p prompt] [-u username/#uid] -s | <command>\n");
#endif #endif
#ifdef HAVE_BSD_AUTH_H
(void) fprintf(stderr, "[-a auth_type] ");
#endif
(void) fprintf(stderr, "-s | <command>\n");
exit(exit_val); exit(exit_val);
} }