Group :: Sistema/Base
RPM: SimplePAMApps
Main Changelog Spec Patches Sources Download Gear Bugs e FR Repocop
Patch: SimplePAMApps-0.60-owl-alt-su.patch
Download
Download
diff -urp SimplePAMApps-0.60.orig/common/include/su_indep.h SimplePAMApps-0.60/common/include/su_indep.h
--- SimplePAMApps-0.60.orig/common/include/su_indep.h Thu Dec 10 08:46:24 1998
+++ SimplePAMApps-0.60/common/include/su_indep.h Sun Jan 12 19:24:44 2003
@@ -1,5 +1,11 @@
#include <unistd.h>
+typedef struct
+{
+ const char *user, *command, *shell;
+ int login, fast;
+} su_context;
+
extern int is_terminal;
void store_terminal_modes();
@@ -12,7 +18,5 @@ void restore_terminal_owner();
int make_process_unkillable(const char **callname
, const char **err_descr);
void make_process_killable();
-void usage();
-void parse_command_line(int argc, char *argv[]
- , int *is_login, const char **user, const char **command);
+void parse_command_line(int argc, char *argv[], su_context *ctx);
diff -urp SimplePAMApps-0.60.orig/common/lib/shell_args.c SimplePAMApps-0.60/common/lib/shell_args.c
--- SimplePAMApps-0.60.orig/common/lib/shell_args.c Tue Dec 8 17:02:48 1998
+++ SimplePAMApps-0.60/common/lib/shell_args.c Sun Jan 12 19:24:44 2003
@@ -13,7 +13,7 @@
* The assumptions used by this code are that a an argument list is
* returned in the following cases:
*
- * 1. login is true [command is always ignored]
+ * 1. login is true
*
* - the user has a shell entry which is used
* - if the user does not have a shell entry NULL is returned
@@ -56,9 +56,6 @@ char * const *build_shell_args(const cha
const char **args=NULL; /* array of PATH+ARGS+NULL pointers */
D(("called."));
- if (login) {
- command = NULL; /* command always ignored for login */
- }
if (pw_shell && *pw_shell != '\0') {
char *line;
diff -urp SimplePAMApps-0.60.orig/common/lib/su_indep.c SimplePAMApps-0.60/common/lib/su_indep.c
--- SimplePAMApps-0.60.orig/common/lib/su_indep.c Mon Feb 1 08:25:05 1999
+++ SimplePAMApps-0.60/common/lib/su_indep.c Tue Apr 15 09:37:55 2003
@@ -15,6 +15,8 @@
#include <stdarg.h>
#include <syslog.h>
#include <errno.h>
+#include <getopt.h>
+#include "../include/su_indep.h"
/* -------------------------------------------- */
/* ------ declarations ------------------------ */
@@ -184,71 +186,98 @@ void make_process_killable()
/* ------ command line parser ----------------- */
-void usage()
+__attribute__ ((__noreturn__))
+static void usage (int status)
{
- (void) fprintf(stderr,"usage: su [-] [-c \"command\"] [username]\n");
- exit(1);
+ fprintf (stderr, "usage: su [-|-l] [-c \"command\"] [-s \"shell\"] [username]\n");
+ exit (status);
}
-void parse_command_line(int argc, char *argv[]
- , int *is_login, const char **user, const char **command)
+void parse_command_line(int argc, char *argv[], su_context *ctx)
{
- int username_present, command_present;
-
- *is_login = 0;
- *user = NULL;
- *command = NULL;
- username_present = command_present = 0;
-
- while ( --argc > 0 ) {
- const char *token;
-
- token = *++argv;
- if (*token == '-') {
- switch (*++token) {
- case '\0': /* su as a login shell for the user */
- if (*is_login)
- usage();
- *is_login = 1;
- break;
- case 'c':
- if (command_present) {
- usage();
- } else { /* indicate we are running commands */
- if (*++token != '\0') {
- command_present = 1;
- *command = token;
- } else if (--argc > 0) {
- command_present = 1;
- *command = *++argv;
- } else
- usage();
+ int optc;
+ struct option const longopts[] =
+ {
+ { "command", required_argument, 0, 'c' },
+ { "login", no_argument, 0, 'l' },
+ { "shell", required_argument, 0, 's' },
+ { "help", no_argument, 0, 'h' },
+ { 0, 0, 0, 0 }
+ };
+
+ if (argc < 1)
+ usage (EXIT_FAILURE);
+
+ memset (ctx, 0, sizeof(*ctx));
+
+ while ((optc = getopt_long (argc, argv, "c:ls:", longopts, 0)) != -1)
+ {
+ switch (optc)
+ {
+ case 'c':
+ if (ctx->command)
+ usage (EXIT_FAILURE);
+ ctx->command = optarg;
+ break;
+
+ case 'l':
+ if (ctx->login)
+ usage (EXIT_FAILURE);
+ ctx->login = 1;
+ break;
+
+ case 's':
+ if (ctx->shell)
+ usage (EXIT_FAILURE);
+ ctx->shell = optarg;
+ break;
+
+ case 'h':
+ usage (EXIT_SUCCESS);
+
+ default:
+ usage (EXIT_FAILURE);
}
- break;
- default:
- usage();
- }
- } else { /* must be username */
- if (username_present)
- usage();
- username_present = 1;
- *user = *argv;
}
- }
- if (!username_present) { /* default user is superuser */
- const struct passwd *pw;
+ if (optind < argc && !strcmp (argv[optind], "-"))
+ {
+ if (ctx->login)
+ usage (EXIT_FAILURE);
+ ctx->login = 1;
+ ++optind;
+ }
+
+ if (optind < argc)
+ ctx->user = argv[optind++];
+
+ if (optind < argc)
+ usage (EXIT_FAILURE);
+
+ if (!ctx->user)
+ { /* default user is superuser */
+ const struct passwd *pw = getpwuid (ROOT_UID);
+ if (!(pw && pw->pw_name)) /* No ROOT_UID!? */
+ {
+ fprintf (stderr, "su: no access to superuser identity (%d)!\n", ROOT_UID);
+ exit (EXIT_FAILURE);
+ }
+
+ ctx->user = strdup (pw->pw_name);
+ endpwent();
+ }
- pw = getpwuid(ROOT_UID);
- if (pw == NULL) /* No ROOT_UID!? */
+ if (ctx->shell)
{
- printf ("\nsu:no access to superuser identity!? (%d)\n",
- ROOT_UID);
- exit (1);
- }
-
- *user = NULL;
- if (pw->pw_name != NULL)
- *user = strdup(pw->pw_name);
- }
+ if (getuid())
+ {
+ fprintf (stderr, "su: setting shell: permission denied\n");
+ exit (EXIT_FAILURE);
+ }
+ if (access (ctx->shell, X_OK) < 0)
+ {
+ fprintf (stderr, "su: setting shell: %s\n", strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+ }
}
diff -urp SimplePAMApps-0.60.orig/pamapps/lib/wtmp-gate.c SimplePAMApps-0.60/pamapps/lib/wtmp-gate.c
--- SimplePAMApps-0.60.orig/pamapps/lib/wtmp-gate.c Wed Nov 25 12:33:32 1998
+++ SimplePAMApps-0.60/pamapps/lib/wtmp-gate.c Mon Nov 19 04:47:15 2001
@@ -35,6 +35,7 @@ int utmp_open_session(pam_handle_t *pamh
*err_descr = pam_strerror(pamh, retval);
return -1;
}
+ if (!terminal) terminal = "???";
retval = pam_get_item(pamh, PAM_RHOST, (const void **)&rhost);
if (retval != PAM_SUCCESS)
rhost = NULL;
@@ -55,6 +56,7 @@ int utmp_close_session(pam_handle_t *pam
*err_descr = pam_strerror(pamh, retval);
return -1;
}
+ if (!terminal) terminal = "???";
return
utmp_do_close_session(terminal, callname, err_descr);
diff -urp SimplePAMApps-0.60.orig/pamapps/su/su.1 SimplePAMApps-0.60/pamapps/su/su.1
--- SimplePAMApps-0.60.orig/pamapps/su/su.1 Fri Jun 12 17:11:04 1998
+++ SimplePAMApps-0.60/pamapps/su/su.1 Tue Apr 15 12:44:09 2003
@@ -8,7 +8,8 @@
su \- assume a user's identity
.SH SYNOPSIS
-.B su [-] [-c "command"] [username]
+.B su
+[\fB-\fR|\fB-l\fR] [\fB-c \fIcommand\fR] [\fB-s \fIshell\fR] [\fIusername\fR]
.sp 2
.SH DESCRIPTION
.B Su
@@ -85,49 +86,28 @@ encountering an accounting failure, a wa
.BR su
will proceed to invoke the sought user's shell.
-.sp
-A simple entry in the
-.I Linux-PAM
-configuration file for this service would be:
-.br
-
-.br
- #
-.br
- # su service, authentication not required for root.
-.br
- # For other users authentication is provided via
-.br
- # pwdb. Some account management done with time module
-.br
- #
-.br
- su auth sufficient pam_rootok.so
-.br
- su auth required pam_pwdb.so
-.br
- su account required pam_pwdb.so
- su account required pam_time.so
-.br
- su session required pam_pwdb.so
-.br
- #
-
-.sp
-(For the equivalent
-.B /etc/pam.d/su
-file, you should delete the first field ("su") from the above
-example). Note, the
-.BR password
-module-type is not required for this application to function
-correctly.
-
-.sp
-For continuity of service, the administrator might wish to make the
-.BR login "(1)"
-and
-.BR su
-configurations similar.
+.SH OPTIONS
+.TP
+.BI "\-c " command ", \-\-command=" command
+Pass
+.IR command,
+a single command line to run, to the shell with a
+.B \-c
+option instead of starting an interactive shell.
+.TP
+.B "\-, \-l, \-\-login"
+Invoke the shell as a login shell.
+.TP
+.BI "\-s, \-\-shell " shell
+.RI "Superuser may run " shell " instead of " user 's
+command-shell, unless the user running
+.B su
+is not the superuser and
+.IR user 's
+shell is restricted.
+.TP
+.B "\-\-help"
+Print a usage message on standard output and exit successfully.
.SH "EXIT CODE"
diff -urp SimplePAMApps-0.60.orig/pamapps/su/su.c SimplePAMApps-0.60/pamapps/su/su.c
--- SimplePAMApps-0.60.orig/pamapps/su/su.c Thu Feb 18 12:29:50 1999
+++ SimplePAMApps-0.60/pamapps/su/su.c Tue Apr 15 09:40:54 2003
@@ -18,9 +18,10 @@
#define DEFAULT_SHELL "/bin/sh"
#define SLEEP_TO_KILL_CHILDREN 3 /* seconds to wait after SIGTERM before
SIGKILL */
-#define SU_FAIL_DELAY 2000000 /* usec on authentication failure */
+#define SU_FAIL_DELAY 0 /* usec on authentication failure */
#include <stdlib.h>
+#include <stdarg.h>
#include <signal.h>
#include <stdio.h>
#include <sys/stat.h>
@@ -65,8 +66,8 @@ static int state;
#define SU_STATE_TERMINAL_REOWNED 7
#define SU_STATE_UTMP_WRITTEN 8
-static void exit_now(int exit_code, const char *format, ...);
-static void exit_child_now(int exit_code, const char *format, ...);
+static void exit_now(int exit_code, const char *format, ...) __attribute__ ((__noreturn__));
+static void exit_child_now(int exit_code, const char *format, ...) __attribute__ ((__noreturn__));
static void do_pam_init(const char *user, int is_login);
static void su_exec_shell(const char *shell, uid_t uid, int is_login
, const char *command, const char *user);
@@ -75,12 +76,11 @@ static void su_exec_shell(const char *sh
/* ------ the application itself -------------- */
/* -------------------------------------------- */
-void main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
- int retcode, is_login, status;
+ int retcode, status;
int retval, final_retval; /* PAM_xxx return values */
- const char *command, *user;
- const char *shell;
+ su_context ctx;
pid_t child;
uid_t uid;
const char *place, *err_descr;
@@ -102,7 +102,7 @@ void main(int argc, char *argv[])
/* ------------ parse the argument list ----------- */
- parse_command_line(argc, argv, &is_login, &user, &command);
+ parse_command_line(argc, argv, &ctx);
/* ------ initialize the Linux-PAM interface ------ */
@@ -112,8 +112,8 @@ void main(int argc, char *argv[])
exit_now(1, "su: failed\n");
#endif
- do_pam_init(user, is_login); /* call pam_start and set PAM items */
- user = NULL; /* get this info later (it may change) */
+ do_pam_init(ctx.user, ctx.login); /* call pam_start and set PAM items */
+ ctx.user = NULL; /* get this info later (it may change) */
/*
* Note. We have forgotten everything about the user. We will get
@@ -166,10 +166,14 @@ void main(int argc, char *argv[])
* Obtain all of the new credentials of the user
*/
place = "set_user_credentials";
- retval = set_user_credentials(pamh, is_login, &user, &uid, &shell);
- if (retval != PAM_SUCCESS) {
- (void) pam_close_session(pamh,retval);
- break;
+ {
+ const char *shell;
+ retval = set_user_credentials(pamh, ctx.login, &ctx.user, &uid, &shell);
+ if (retval != PAM_SUCCESS) {
+ (void) pam_close_session(pamh, retval);
+ break;
+ }
+ if (!ctx.shell) ctx.shell = shell;
}
state = SU_STATE_CREDENTIALS_GOTTEN;
@@ -183,8 +187,7 @@ void main(int argc, char *argv[])
/*
* ... setup terminal, ...
*/
- retcode = change_terminal_owner(uid, is_login
- , &place, &err_descr);
+ retcode = change_terminal_owner(uid, ctx.login, &place, &err_descr);
if (retcode > 0) {
(void) fprintf(stderr, "su: %s: %s\n", place, err_descr);
err_descr = NULL; /* forget about the problem */
@@ -195,7 +198,7 @@ void main(int argc, char *argv[])
/*
* ... make [uw]tmp entries.
*/
- if (is_login) {
+ if (ctx.login) {
/*
* Note: we use the parent pid as a session identifier for
* the logging.
@@ -218,14 +221,14 @@ void main(int argc, char *argv[])
}
if (child == 0) { /* child exec's shell */
- su_exec_shell(shell, uid, is_login, command, user);
+ su_exec_shell(ctx.shell, uid, ctx.login, ctx.command, ctx.user);
/* never reached */
}
/* wait for child to terminate */
/* job control is off for login sessions */
- prepare_for_job_control(!is_login && command != NULL);
+ prepare_for_job_control(!ctx.login && ctx.command);
status = wait_for_child(child);
if (status != 0)
D(("shell returned %d", status));
@@ -293,7 +296,7 @@ void main(int argc, char *argv[])
if (reset_terminal_modes() != 0 && !status)
status = 1;
- exit(status); /* transparent exit */
+ return status;
}
/* -------------------------------------------- */
@@ -380,7 +383,7 @@ static void do_pam_init(const char *user
if (terminal) {
retval = pam_set_item(pamh, PAM_TTY, (const void *)terminal);
} else {
- retval = PAM_PERM_DENIED; /* how did we get here? */
+ if (getuid() != 0) retval = PAM_PERM_DENIED;
}
terminal = NULL;
}
@@ -389,8 +392,6 @@ static void do_pam_init(const char *user
const char *ruser = getlogin(); /* Who is running this program? */
if (ruser) {
retval = pam_set_item(pamh, PAM_RUSER, (const void *)ruser);
- } else {
- retval = PAM_PERM_DENIED; /* must be known to system */
}
ruser = NULL;
}
@@ -403,7 +404,7 @@ static void do_pam_init(const char *user
exit_now(1, "su: problem establishing environment\n");
}
-#ifdef HAVE_PAM_FAIL_DELAY
+#if defined(HAVE_PAM_FAIL_DELAY) && SU_FAIL_DELAY
/* have to pause on failure. At least this long (doubles..) */
retval = pam_fail_delay(pamh, SU_FAIL_DELAY);
if (retval != PAM_SUCCESS) {
@@ -472,6 +473,9 @@ static void su_exec_shell(const char *sh
if (shell_args == NULL) {
exit_child_now(1, "su: could not identify appropriate shell\n");
}
+
+ retval = pam_misc_setenv(pamh, "SHELL", shell_args[0], 0);
+ D(("pam_misc_setenv: SHELL=%s: retval=%d", shell_args[0], retval));
/*
* and now copy the environment for non-PAM use