[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH]: pam support for coreutils 5.0
From: |
Arkadiusz Miskiewicz |
Subject: |
[PATCH]: pam support for coreutils 5.0 |
Date: |
Mon, 7 Apr 2003 21:28:45 +0200 |
User-agent: |
Mutt/1.4.1i |
Patch adds pam support to coreutils 5.0 (same as for sh-utils).
diff -Nur sh-utils-2.0.12.orig/configure.ac sh-utils-2.0.12/configure.ac
--- sh-utils-2.0.12.orig/configure.ac Sun Apr 28 11:29:18 2002
+++ sh-utils-2.0.12/configure.ac Mon May 27 23:10:36 2002
@@ -8,6 +8,13 @@
AM_INIT_AUTOMAKE([1.6b gnits dist-bzip2])
+dnl Give the chance to enable PAM
+AC_ARG_ENABLE(pam, dnl
+[ --enable-pam Enable use of the PAM libraries],
+AC_DEFINE(USE_PAM,,[Use PAM?])
+LIB_PAM="-ldl -lpam -lpam_misc"
+)
+
AC_GNU_SOURCE
jm_PERL
AC_PROG_CC
@@ -238,6 +245,13 @@
AM_GNU_GETTEXT([external])
+# just in case we want PAM
+AC_SUBST(LIB_PAM)
+# with PAM su doesn't need libcrypt
+if test -n "$LIB_PAM" ; then
+ LIB_CRYPT=
+fi
+
AC_CONFIG_FILES(
Makefile
doc/Makefile
diff -Nur sh-utils-2.0.12.orig/doc/coreutils.texi
sh-utils-2.0.12/doc/coreutils.texi
--- sh-utils-2.0.12.orig/doc/coreutils.texi Sun Apr 28 23:55:31 2002
+++ sh-utils-2.0.12/doc/coreutils.texi Mon May 27 23:11:49 2002
@@ -10898,32 +10898,6 @@
@end table
address@hidden wheel group, not supported
address@hidden group wheel, not supported
address@hidden fascism
address@hidden Why GNU @command{su} does not support the @samp{wheel} group
-
-(This section is by Richard Stallman.)
-
address@hidden Twenex
address@hidden MIT AI lab
-Sometimes a few of the users try to hold total power over all the
-rest. For example, in 1984, a few users at the MIT AI lab decided to
-seize power by changing the operator password on the Twenex system and
-keeping it secret from everyone else. (I was able to thwart this coup
-and give power back to the users by patching the kernel, but I
-wouldn't know how to do that in Unix.)
-
-However, occasionally the rulers do tell someone. Under the usual
address@hidden mechanism, once someone learns the root password who
-sympathizes with the ordinary users, he or she can tell the rest. The
-``wheel group'' feature would make this impossible, and thus cement the
-power of the rulers.
-
-I'm on the side of the masses, not that of the rulers. If you are
-used to supporting the bosses and sysadmins in whatever they do, you
-might find this idea strange at first.
-
@node Process control
@chapter Process control
diff -Nur sh-utils-2.0.12.orig/src/Makefile.am sh-utils-2.0.12/src/Makefile.am
--- sh-utils-2.0.12.orig/src/Makefile.am Mon May 27 23:06:24 2002
+++ sh-utils-2.0.12/src/Makefile.am Mon May 27 23:09:22 2002
@@ -47,7 +47,7 @@
uptime_LDADD = $(LDADD) @GETLOADAVG_LIBS@
-su_LDADD = $(LDADD) @LIB_CRYPT@
+su_LDADD = $(LDADD) @LIB_CRYPT@ @LIB_PAM@
$(PROGRAMS): ../lib/libfetish.a
diff -Nur sh-utils-2.0.12.orig/src/su.c sh-utils-2.0.12/src/su.c
--- sh-utils-2.0.12.orig/src/su.c Mon May 27 23:06:24 2002
+++ sh-utils-2.0.12/src/su.c Mon May 27 23:08:28 2002
@@ -38,6 +38,16 @@
restricts who can su to UID 0 accounts. RMS considers that to
be fascist.
+#ifdef USE_PAM
+
+ Actually, with PAM, su has nothing to do with whether or not a
+ wheel group is enforced by su. RMS tries to restrict your access
+ to a su which implements the wheel group, but PAM considers that
+ to be fascist, and gives the user/sysadmin the opportunity to
+ enforce a wheel group by proper editing of /etc/pam.conf
+
+#endif
+
Options:
-, -l, --login Make the subshell a login shell.
Unset all environment variables except
@@ -81,6 +91,14 @@
prototype (returning `int') in <unistd.h>. */
#define getusershell _getusershell_sys_proto_
+#ifdef USE_PAM
+# include <security/pam_appl.h>
+# include <security/pam_misc.h>
+# include <signal.h>
+# include <sys/wait.h>
+# include <sys/fsuid.h>
+#endif /* USE_PAM */
+
#include "system.h"
#include "closeout.h"
#include "dirname.h"
@@ -151,7 +169,9 @@
/* The user to become if none is specified. */
#define DEFAULT_USER "root"
+#ifndef USE_PAM
char *crypt ();
+#endif
char *getpass ();
char *getusershell ();
void endusershell ();
@@ -159,7 +179,7 @@
extern char **environ;
-static void run_shell (const char *, const char *, char **)
+static void run_shell (const char *, const char *, char **, const struct
passwd *)
ATTRIBUTE_NORETURN;
/* The name this program was run with. */
@@ -272,7 +292,22 @@
}
#endif
+#ifdef USE_PAM
+static pam_handle_t *pamh = NULL;
+static int retval;
+static struct pam_conv conv = {
+ misc_conv,
+ NULL
+};
+
+#define PAM_BAIL_P if (retval) { \
+ pam_end(pamh, PAM_SUCCESS); \
+ return 0; \
+}
+#endif
+
/* Ask the user for a password.
+ If PAM is in use, let PAM ask for the password if necessary.
Return 1 if the user gives the correct password for entry PW,
0 if not. Return 1 without asking for a password if run by UID 0
or if PW has an empty password. */
@@ -280,6 +315,29 @@
static int
correct_password (const struct passwd *pw)
{
+#ifdef USE_PAM
+ /* root always succeeds; this isn't an authentication question (no
+ * extra privs are being granted) so it shouldn't authenticate with PAM.
+ * However, we want to create the pam_handle so that proper credentials
+ * are created later with pam_setcred(). */
+ retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh);
+ PAM_BAIL_P;
+
+ retval = pam_authenticate(pamh, 0);
+ PAM_BAIL_P;
+
+ retval = pam_acct_mgmt(pamh, 0);
+ if (retval == PAM_NEW_AUTHTOK_REQD) {
+ /* password has expired. Offer option to change it. */
+ if (getuid()) {
+ retval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+ PAM_BAIL_P;
+ } else retval = PAM_SUCCESS;
+ }
+ PAM_BAIL_P;
+ /* must be authenticated if this point was reached */
+ return 1;
+#else /* !USE_PAM */
char *unencrypted, *encrypted, *correct;
#if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP
/* Shadow passwd stuff for SVR3 and maybe other systems. */
@@ -304,6 +362,7 @@
encrypted = crypt (unencrypted, correct);
memset (unencrypted, 0, strlen (unencrypted));
return strcmp (encrypted, correct) == 0;
+#endif /* !USE_PAM */
}
/* Update `environ' for the new shell based on PW, with SHELL being
@@ -313,16 +372,20 @@
modify_environment (const struct passwd *pw, const char *shell)
{
char *term;
+ char *display;
if (simulate_login)
{
- /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
+ /* Leave TERM, DISPLAY unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
Unset all other environment variables. */
term = getenv ("TERM");
+ display = getenv ("DISPLAY");
environ = (char **) xmalloc (2 * sizeof (char *));
environ[0] = 0;
if (term)
xputenv (concat ("TERM", "=", term));
+ if (display)
+ xputenv (concat ("DISPLAY", "=", display));
xputenv (concat ("HOME", "=", pw->pw_dir));
xputenv (concat ("SHELL", "=", shell));
xputenv (concat ("USER", "=", pw->pw_name));
@@ -359,23 +422,73 @@
error (EXIT_FAILURE, errno, _("cannot set groups"));
endgrent ();
#endif
+#ifdef USE_PAM
+ retval = pam_setcred(pamh, PAM_ESTABLISH_CRED);
+ if (retval != PAM_SUCCESS)
+ error (1, 0, pam_strerror(pamh, retval));
+#endif /* USE_PAM */
if (setgid (pw->pw_gid))
error (EXIT_FAILURE, errno, _("cannot set group id"));
if (setuid (pw->pw_uid))
error (EXIT_FAILURE, errno, _("cannot set user id"));
}
+#ifdef USE_PAM
+static int caught=0;
+/* Signal handler for parent process later */
+static void su_catch_sig(int sig)
+{
+ ++caught;
+}
+
+int
+pam_copyenv (pam_handle_t *pamh)
+{
+ char **env;
+
+ env = pam_getenvlist(pamh);
+ if(env) {
+ while(*env) {
+ xputenv(*env);
+ env++;
+ }
+ }
+ return(0);
+}
+#endif
+
/* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
If COMMAND is nonzero, pass it to the shell with the -c option.
If ADDITIONAL_ARGS is nonzero, pass it to the shell as more
arguments. */
static void
-run_shell (const char *shell, const char *command, char **additional_args)
+run_shell (const char *shell, const char *command, char **additional_args,
const struct passwd *pw)
{
const char **args;
int argno = 1;
+#ifdef USE_PAM
+ int child;
+ sigset_t ourset;
+ int status;
+
+ retval = pam_open_session(pamh,0);
+ if (retval != PAM_SUCCESS) {
+ fprintf (stderr, _("could not open session\n"));
+ exit (1);
+ }
+
+/* do this at the last possible moment, because environment variables may
+ be passed even in the session phase
+*/
+ if(pam_copyenv(pamh) != PAM_SUCCESS)
+ fprintf (stderr, _("error copying PAM environment\n"));
+ child = fork();
+ if (child == 0) { /* child shell */
+ change_identity (pw);
+ pam_end(pamh, 0);
+#endif
if (additional_args)
args = (const char **) xmalloc (sizeof (char *)
* (10 + elements (additional_args)));
@@ -408,6 +521,61 @@
error (0, errno, "%s", shell);
exit (exit_status);
}
+#ifdef USE_PAM
+ } else if (child == -1) {
+ fprintf(stderr, _("cannot fork user shell: %s"), strerror(errno));
+ exit(1);
+ }
+ /* parent only */
+ sigfillset(&ourset);
+ if (sigprocmask(SIG_BLOCK, &ourset, NULL)) {
+ fprintf(stderr, _("%s: signal malfunction\n"), PROGRAM_NAME);
+ caught = 1;
+ }
+ if (!caught) {
+ struct sigaction action;
+ action.sa_handler = su_catch_sig;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ sigemptyset(&ourset);
+ if (sigaddset(&ourset, SIGTERM)
+ || sigaddset(&ourset, SIGALRM)
+ || sigaction(SIGTERM, &action, NULL)
+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) {
+ fprintf(stderr, _("%s: signal masking malfunction\n"), PROGRAM_NAME);
+ caught = 1;
+ }
+ }
+ if (!caught) {
+ do {
+ int pid;
+
+ pid = waitpid(-1, &status, WUNTRACED);
+
+ if (WIFSTOPPED(status)) {
+ kill(getpid(), SIGSTOP);
+ /* once we get here, we must have resumed */
+ kill(pid, SIGCONT);
+ }
+ } while (WIFSTOPPED(status));
+ }
+
+ if (caught) {
+ fprintf(stderr, _("\nSession terminated, killing shell..."));
+ kill (child, SIGTERM);
+ }
+ retval = pam_close_session(pamh, 0);
+ PAM_BAIL_P;
+ retval = pam_end(pamh, PAM_SUCCESS);
+ PAM_BAIL_P;
+ if (caught) {
+ sleep(2);
+ kill(child, SIGKILL);
+ fprintf(stderr, _(" killed.\n"));
+ exit(-1);
+ }
+ exit (WEXITSTATUS(status));
+#endif /* USE_PAM */
}
/* Return 1 if SHELL is a restricted shell (one not returned by
@@ -580,9 +748,14 @@
}
modify_environment (pw, shell);
+
+#ifdef USE_PAM
+ setfsuid(pw->pw_uid);
+#else
change_identity (pw);
+#endif
if (simulate_login && chdir (pw->pw_dir))
error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir);
- run_shell (shell, command, additional_args);
+ run_shell (shell, command, additional_args, pw);
}
--- coreutils-4.5.3.orig/po/pl.po Fri Nov 1 01:55:42 2002
+++ coreutils-4.5.3/po/pl.po Fri Nov 1 02:11:20 2002
@@ -6491,6 +6491,41 @@
msgid "cannot set user id"
msgstr "nie można ustawić identyfikatora użytkownika"
+#: src/su.c:468
+msgid "could not open session\n"
+msgstr "nie można otworzyć sesji\n"
+
+#: src/su.c:476
+msgid "error copying PAM environment\n"
+msgstr "błąd podczas kopiowania środowiska PAM\n"
+
+#: src/su.c:521
+#, c-format
+msgid "cannot fork user shell: %s"
+msgstr "nie można utworzyć procesu powłoki użytkownika: %s"
+
+#: src/su.c:527
+#, c-format
+msgid "%s: signal malfunction\n"
+msgstr "%s: błędne działanie sygnałów\n"
+
+#: src/su.c:540
+#, c-format
+msgid "%s: signal masking malfunction\n"
+msgstr "%s: błędne działanie maskowania sygnałów\n"
+
+#: src/su.c:559
+msgid ""
+"\n"
+"Session terminated, killing shell..."
+msgstr ""
+"\n"
+"Sesja zakończona, zabijanie powłoki..."
+
+#: src/su.c:569
+msgid " killed.\n"
+msgstr " zabito.\n"
+
#: src/su.c:437
#, c-format
msgid "Usage: %s [OPTION]... [-] [USER [ARG]...]\n"
--
Arkadiusz Miśkiewicz CS at FoE, Wroclaw University of Technology
address@hidden AM2-6BONE, 1024/3DB19BBD, arekm(at)ircnet, PLD/Linux
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH]: pam support for coreutils 5.0,
Arkadiusz Miskiewicz <=