From: Arkadiusz Miśkiewicz Date: Tue, 18 Jun 2013 18:38:26 +0000 (+0200) Subject: - up to 2.23.1; initrd build broken, rest builds fine X-Git-Tag: auto/th/util-linux-2.23.1-1~1 X-Git-Url: http://git.pld-linux.org/?a=commitdiff_plain;h=232bdb1aa2ccb366530735e18678f22ef68813fa;p=packages%2Futil-linux.git - up to 2.23.1; initrd build broken, rest builds fine --- diff --git a/util-linux-diet.patch b/util-linux-diet.patch index b0085b0..24404a5 100644 --- a/util-linux-diet.patch +++ b/util-linux-diet.patch @@ -72,16 +72,16 @@ --- util-linux-2.19/misc-utils/findmnt.c~ 2011-01-31 16:43:47.000000000 +0100 +++ util-linux-2.19/misc-utils/findmnt.c 2011-02-10 20:54:23.100130391 +0100 -@@ -30,6 +30,9 @@ - #include - #include - #include +@@ -36,6 +36,9 @@ + # include + #endif + #include +#ifdef __dietlibc__ +#include /* for major and minor macros */ +#endif - #include - + #include "pathnames.h" + #include "nls.h" --- util-linux-2.19/disk-utils/fsck.c~ 2011-02-07 16:19:29.000000000 +0100 +++ util-linux-2.19/disk-utils/fsck.c 2011-02-10 21:09:27.024658725 +0100 @@ -270,7 +270,13 @@ @@ -101,10 +101,10 @@ --- util-linux-2.21/configure.ac~ 2012-02-24 12:53:35.000000000 +0200 +++ util-linux-2.21/configure.ac 2012-03-05 21:03:25.833675080 +0200 -@@ -311,6 +311,7 @@ - lchown \ +@@ -323,6 +323,7 @@ AC_CHECK_FUNCS([ \ llseek \ lseek64 \ + mempcpy \ + mkostemp \ nanosleep \ personality \ @@ -144,37 +144,6 @@ if (n <= 0) return 0; ---- util-linux-2.22.1/lib/Makemodule.am.orig 2012-09-20 15:16:51.344635140 +0200 -+++ util-linux-2.22.1/lib/Makemodule.am 2012-10-13 16:15:53.662070426 +0200 -@@ -5,7 +5,6 @@ - lib/at.c \ - lib/blkdev.c \ - lib/canonicalize.c \ -- lib/cpuset.c \ - lib/crc32.c \ - lib/env.c \ - lib/fileutils.c \ -@@ -15,7 +14,6 @@ - lib/mbsalign.c \ - lib/md5.c \ - lib/pager.c \ -- lib/path.c \ - lib/procutils.c \ - lib/randutils.c \ - lib/setproctitle.c \ -@@ -25,6 +23,12 @@ - lib/wholedisk.c \ - lib/xgetpass.c - -+if HAVE_CPU_SET_T -+libcommon_la_SOURCES += \ -+ lib/cpuset.c \ -+ lib/path.c -+endif -+ - if LINUX - libcommon_la_SOURCES += \ - lib/linux_version.c \ --- util-linux-2.22.1/lib/tt.c.orig 2012-09-20 15:16:51.349635172 +0200 +++ util-linux-2.22.1/lib/tt.c 2012-10-13 16:58:37.331962836 +0200 @@ -59,11 +59,13 @@ diff --git a/util-linux-runuser.patch b/util-linux-runuser.patch deleted file mode 100644 index 7b885d0..0000000 --- a/util-linux-runuser.patch +++ /dev/null @@ -1,1957 +0,0 @@ -diff --git a/configure.ac b/configure.ac -index 87e85fa..ead559c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1149,6 +1154,15 @@ UL_REQUIRES_HAVE([su], [security_pam_misc_h], [PAM header file]) - AM_CONDITIONAL(BUILD_SU, test "x$build_su" = xyes) - - -+AC_ARG_ENABLE([runuser], -+ AS_HELP_STRING([--disable-runuser], [do not build runuser]), -+ [], enable_runuser=yes -+) -+UL_BUILD_INIT([runuser]) -+UL_REQUIRES_HAVE([runuser], [security_pam_misc_h], [PAM header file]) -+AM_CONDITIONAL(BUILD_RUNUSER, test "x$build_runuser" = xyes) -+ -+ - AC_ARG_ENABLE([schedutils], - AS_HELP_STRING([--disable-schedutils], [do not build chrt, ionice, teskset]), - [], enable_schedutils=yes -diff --git a/login-utils/Makemodule.am b/login-utils/Makemodule.am -index e10da46..755a361 100644 ---- a/login-utils/Makemodule.am -+++ b/login-utils/Makemodule.am -@@ -83,6 +83,8 @@ - dist_man_MANS += login-utils/su.1 - su_SOURCES = \ - login-utils/su.c \ -+ login-utils/su-common.c \ -+ login-utils/su-common.h \ - login-utils/logindefs.c \ - login-utils/logindefs.h - su_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS) -@@ -91,6 +93,19 @@ - endif - - -+if BUILD_RUNUSER -+bin_PROGRAMS += runuser -+dist_man_MANS += login-utils/runuser.1 -+runuser_SOURCES = \ -+ login-utils/runuser.c \ -+ login-utils/su-common.c \ -+ login-utils/su-common.h \ -+ login-utils/logindefs.c \ -+ login-utils/logindefs.h -+runuser_LDADD = $(LDADD) -lpam -lpam_misc -+endif -+ -+ - if BUILD_NEWGRP - usrbin_exec_PROGRAMS += newgrp - dist_man_MANS += login-utils/newgrp.1 -diff --git a/login-utils/runuser.1 b/login-utils/runuser.1 -new file mode 100644 -index 0000000..66ad1c4 ---- /dev/null -+++ b/login-utils/runuser.1 -@@ -0,0 +1,230 @@ -+.TH RUNUSER "1" "August 2012" "util-linux" "User Commands" -+.SH NAME -+runuser \- run a command with substitute user and group ID -+.SH SYNOPSIS -+.B runuser -+[options...] [\-] [user [args...]] -+.SH DESCRIPTION -+.B runuser -+allows to run commands with substitute user and group ID. -+The difference between the commands -+.B runuser -+and -+.B su -+is that -+.B runuser -+does not ask for password, because it may be executed by root user only. -+The command -+.B runuser -+does not have to be installed with suid permissions. -+.PP -+When called without arguments -+.B runuser -+defaults to running an interactive shell as -+.IR root . -+.PP -+For backward compatibility -+.B runuser -+defaults to not change the current directory and to only set the -+environment variables -+.B HOME -+and -+.B SHELL -+(plus -+.B USER -+and -+.B LOGNAME -+if the target -+.I user -+is not root). It is recommended to always use the -+.B \-\-login -+option (instead it's shortcut -+.BR \- ) -+to avoid side effects caused by mixing environments. -+.PP -+This version of -+.B runuser -+uses PAM for session management. -+.SH OPTIONS -+.TP -+\fB\-c\fR \fIcommand\fR, \fB\-\-command\fR=\fIcommand\fR -+Pass -+.I command -+to the shell with the -+.B \-c -+option. -+.TP -+\fB\-\-session\-command\fR=\fIcommand\fR -+Same as -+.B \-c -+but do not create a new session (discouraged). -+.TP -+\fB\-f\fR, \fB\-\-fast\fR -+Pass -+.B \-f -+to the shell which may or may not be useful depending on the -+shell. -+.TP -+\fB\-g\fR, \fB\-\-group\fR=\fIgroup\fR\fR -+specify the primary group, this option is allowed for root user only -+.TP -+\fB\-G\fR, \fB\-\-supp-group\fR=\fIgroup\fR\fR -+specify a supplemental group, this option is allowed for root user only -+.TP -+\fB\-\fR, \fB\-l\fR, \fB\-\-login\fR -+Starts the shell as login shell with an environment similar to a real -+login: -+.RS 10 -+.TP -+o -+clears all environment variables except for -+.B TERM -+.TP -+o -+initializes the environment variables -+.BR HOME , -+.BR SHELL , -+.BR USER , -+.BR LOGNAME , -+.B PATH -+.TP -+o -+changes to the target user's home directory -+.TP -+o -+sets argv[0] of the shell to -+.RB ' \- ' -+in order to make the shell a login shell -+.RE -+.TP -+\fB\-m\fR, \fB\-p\fR, \fB\-\-preserve-environment\fR -+Preserves the whole environment, ie does not set -+.BR HOME , -+.BR SHELL , -+.B USER -+nor -+.BR LOGNAME . -+.TP -+\fB\-s\fR \fISHELL\fR, \fB\-\-shell\fR=\fISHELL\fR -+Runs the specified shell instead of the default. The shell to run is -+selected according to the following rules in order: -+.RS 10 -+.TP -+o -+the shell specified with -+.B \-\-shell -+.TP -+o -+The shell specified in the environment variable -+.B SHELL -+if the -+.B \-\-preserve-environment -+option is used. -+.TP -+o -+the shell listed in the passwd entry of the target user -+.TP -+o -+/bin/sh -+.RE -+.IP -+If the target user has a restricted shell (i.e. not listed in -+/etc/shells) the -+.B \-\-shell -+option and the -+.B SHELL -+environment variables are ignored unless the calling user is root. -+.TP -+\fB\-\-help\fR -+Display help text and exit. -+.TP -+\fB\-\-version\fR -+Display version information and exit. -+.SH CONFIG FILES -+.B runuser -+reads the -+.I /etc/default/runuser -+and -+.I /etc/login.defs -+configuration files. The following configuration items are relevant -+for -+.BR runuser : -+.PP -+.B ENV_PATH -+(string) -+.RS 4 -+Defines the PATH environment variable for a regular user. The -+default value is -+.IR /usr/local/bin:\:/bin:\:/usr/bin . -+.RE -+.PP -+.B ENV_ROOTPATH -+(string) -+.br -+.B ENV_SUPATH -+(string) -+.RS 4 -+Defines the PATH environment variable for root. The default value is -+.IR /usr/local/sbin:\:/usr/local/bin:\:/sbin:\:/bin:\:/usr/sbin:\:/usr/bin . -+.RE -+.PP -+.B ALWAYS_SET_PATH -+(boolean) -+.RS 4 -+If set to -+.I yes -+and \-\-login and \-\-preserve\-environment were not specified -+.B runuser -+initializes -+.BR PATH . -+.RE -+.SH EXIT STATUS -+.B runuser -+normally returns the exit status of the command it executed. If the -+command was killed by a signal, -+.B runuser -+returns the number of the signal plus 128. -+.PP -+Exit status generated by -+.B runuser -+itself: -+.RS 10 -+.TP -+1 -+Generic error before executing the requested command -+.TP -+126 -+The requested command could not be executed -+.TP -+127 -+The requested command could was not found -+.RE -+.SH FILES -+.PD 0 -+.TP 17 -+/etc/pam.d/runuser -+default PAM configuration file -+.TP -+/etc/pam.d/runuser-l -+PAM configuration file if \-\-login is specified -+.TP -+/etc/default/runuser -+runuser specific logindef config file -+.TP -+/etc/login.defs -+global logindef config file -+.PD 1 -+.SH "SEE ALSO" -+.BR pam (8), -+.BR shells (5), -+.BR login.defs (5), -+.BR su (1) -+.SH AUTHOR -+Derived from coreutils' su which was based on an implemenation from -+David MacKenzie and Fedora runuser command from Dan Walsh. -+.SH AVAILABILITY -+The runuser command is part of the util-linux package and is -+available from -+.UR ftp://\:ftp.kernel.org\:/pub\:/linux\:/utils\:/util-linux/ -+Linux Kernel Archive -+.UE . -diff --git a/login-utils/runuser.c b/login-utils/runuser.c -new file mode 100644 -index 0000000..d761a14 ---- /dev/null -+++ b/login-utils/runuser.c -@@ -0,0 +1,7 @@ -+ -+#include "su-common.h" -+ -+int main(int argv, char **argc) -+{ -+ return su_main(argv, argc, RUNUSER_MODE); -+} -diff --git a/login-utils/su-common.c b/login-utils/su-common.c -new file mode 100644 -index 0000000..d1fecd7 ---- /dev/null -+++ b/login-utils/su-common.c -@@ -0,0 +1,918 @@ -+/* su for Linux. Run a shell with substitute user and group IDs. -+ Copyright (C) 1992-2006 Free Software Foundation, Inc. -+ Copyright (C) 2012 SUSE Linux Products GmbH, Nuernberg -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2, or (at your option) -+ any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software Foundation, -+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -+ -+/* Run a shell with the real and effective UID and GID and groups -+ of USER, default `root'. -+ -+ The shell run is taken from USER's password entry, /bin/sh if -+ none is specified there. If the account has a password, su -+ prompts for a password unless run by a user with real UID 0. -+ -+ Does not change the current directory. -+ Sets `HOME' and `SHELL' from the password entry for USER, and if -+ USER is not root, sets `USER' and `LOGNAME' to USER. -+ The subshell is not a login shell. -+ -+ If one or more ARGs are given, they are passed as additional -+ arguments to the subshell. -+ -+ Does not handle /bin/sh or other shells specially -+ (setting argv[0] to "-su", passing -c only to certain shells, etc.). -+ I don't see the point in doing that, and it's ugly. -+ -+ Based on an implemenation by David MacKenzie . */ -+ -+enum -+{ -+ EXIT_CANNOT_INVOKE = 126, -+ EXIT_ENOENT = 127 -+}; -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "err.h" -+ -+#include -+#include "c.h" -+#include "xalloc.h" -+#include "nls.h" -+#include "pathnames.h" -+#include "env.h" -+ -+/* name of the pam configuration files. separate configs for su and su - */ -+#define PAM_SRVNAME_SU "su" -+#define PAM_SRVNAME_SU_L "su-l" -+ -+#define PAM_SRVNAME_RUNUSER "runuser" -+#define PAM_SRVNAME_RUNUSER_L "runuser-l" -+ -+#define _PATH_LOGINDEFS_SU "/etc/defaults/su" -+#define _PATH_LOGINDEFS_RUNUSER "/etc/defaults/runuser" -+ -+#define is_pam_failure(_rc) ((_rc) != PAM_SUCCESS) -+ -+#include "logindefs.h" -+#include "su-common.h" -+ -+/* The shell to run if none is given in the user's passwd entry. */ -+#define DEFAULT_SHELL "/bin/sh" -+ -+/* The user to become if none is specified. */ -+#define DEFAULT_USER "root" -+ -+#ifndef HAVE_ENVIRON_DECL -+extern char **environ; -+#endif -+ -+static void run_shell (char const *, char const *, char **, size_t) -+ __attribute__ ((__noreturn__)); -+ -+/* If true, pass the `-f' option to the subshell. */ -+static bool fast_startup; -+ -+/* If true, simulate a login instead of just starting a shell. */ -+static bool simulate_login; -+ -+/* If true, change some environment vars to indicate the user su'd to. */ -+static bool change_environment; -+ -+/* If true, then don't call setsid() with a command. */ -+static int same_session = 0; -+ -+/* SU_MODE_{RUNUSER,SU} */ -+static int su_mode; -+ -+static bool _pam_session_opened; -+static bool _pam_cred_established; -+static sig_atomic_t volatile caught_signal = false; -+static pam_handle_t *pamh = NULL; -+ -+static int restricted = 1; /* zero for root user */ -+ -+static struct option const longopts[] = -+{ -+ {"command", required_argument, NULL, 'c'}, -+ {"session-command", required_argument, NULL, 'C'}, -+ {"fast", no_argument, NULL, 'f'}, -+ {"login", no_argument, NULL, 'l'}, -+ {"preserve-environment", no_argument, NULL, 'p'}, -+ {"shell", required_argument, NULL, 's'}, -+ {"group", required_argument, NULL, 'g'}, -+ {"supp-group", required_argument, NULL, 'G'}, -+ {"help", no_argument, 0, 'h'}, -+ {"version", no_argument, 0, 'V'}, -+ {NULL, 0, NULL, 0} -+}; -+ -+/* Log the fact that someone has run su to the user given by PW; -+ if SUCCESSFUL is true, they gave the correct password, etc. */ -+ -+static void -+log_su (struct passwd const *pw, bool successful) -+{ -+ const char *new_user, *old_user, *tty; -+ -+ new_user = pw->pw_name; -+ /* The utmp entry (via getlogin) is probably the best way to identify -+ the user, especially if someone su's from a su-shell. */ -+ old_user = getlogin (); -+ if (!old_user) -+ { -+ /* getlogin can fail -- usually due to lack of utmp entry. -+ Resort to getpwuid. */ -+ struct passwd *pwd = getpwuid (getuid ()); -+ old_user = (pwd ? pwd->pw_name : ""); -+ } -+ tty = ttyname (STDERR_FILENO); -+ if (!tty) -+ tty = "none"; -+ -+ openlog (program_invocation_short_name, 0 , LOG_AUTH); -+ syslog (LOG_NOTICE, "%s(to %s) %s on %s", -+ successful ? "" : -+ su_mode == RUNUSER_MODE ? "FAILED RUNUSER " : "FAILED SU ", -+ new_user, old_user, tty); -+ closelog (); -+} -+ -+static struct pam_conv conv = -+{ -+ misc_conv, -+ NULL -+}; -+ -+static void -+cleanup_pam (int retcode) -+{ -+ int saved_errno = errno; -+ -+ if (_pam_session_opened) -+ pam_close_session (pamh, 0); -+ -+ if (_pam_cred_established) -+ pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT); -+ -+ pam_end(pamh, retcode); -+ -+ errno = saved_errno; -+} -+ -+/* Signal handler for parent process. */ -+static void -+su_catch_sig (int sig __attribute__((__unused__))) -+{ -+ caught_signal = true; -+} -+ -+/* Export env variables declared by PAM modules. */ -+static void -+export_pamenv (void) -+{ -+ char **env; -+ -+ /* This is a copy but don't care to free as we exec later anyways. */ -+ env = pam_getenvlist (pamh); -+ while (env && *env) -+ { -+ if (putenv (*env) != 0) -+ err (EXIT_FAILURE, NULL); -+ env++; -+ } -+} -+ -+static void -+create_watching_parent (void) -+{ -+ pid_t child; -+ sigset_t ourset; -+ int status = 0; -+ int retval; -+ -+ retval = pam_open_session (pamh, 0); -+ if (is_pam_failure(retval)) -+ { -+ cleanup_pam (retval); -+ errx (EXIT_FAILURE, _("cannot not open session: %s"), -+ pam_strerror (pamh, retval)); -+ } -+ else -+ _pam_session_opened = 1; -+ -+ child = fork (); -+ if (child == (pid_t) -1) -+ { -+ cleanup_pam (PAM_ABORT); -+ err (EXIT_FAILURE, _("cannot create child process")); -+ } -+ -+ /* the child proceeds to run the shell */ -+ if (child == 0) -+ return; -+ -+ /* In the parent watch the child. */ -+ -+ /* su without pam support does not have a helper that keeps -+ sitting on any directory so let's go to /. */ -+ if (chdir ("/") != 0) -+ warn (_("cannot change directory to %s"), "/"); -+ -+ sigfillset (&ourset); -+ if (sigprocmask (SIG_BLOCK, &ourset, NULL)) -+ { -+ warn (_("cannot block signals")); -+ caught_signal = true; -+ } -+ if (!caught_signal) -+ { -+ struct sigaction action; -+ action.sa_handler = su_catch_sig; -+ sigemptyset (&action.sa_mask); -+ action.sa_flags = 0; -+ sigemptyset (&ourset); -+ if (!same_session) -+ { -+ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) -+ { -+ warn (_("cannot set signal handler")); -+ caught_signal = true; -+ } -+ } -+ if (!caught_signal && (sigaddset(&ourset, SIGTERM) -+ || sigaddset(&ourset, SIGALRM) -+ || sigaction(SIGTERM, &action, NULL) -+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) { -+ warn (_("cannot set signal handler")); -+ caught_signal = true; -+ } -+ if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL) -+ || sigaction(SIGQUIT, &action, NULL))) -+ { -+ warn (_("cannot set signal handler")); -+ caught_signal = true; -+ } -+ } -+ if (!caught_signal) -+ { -+ pid_t pid; -+ for (;;) -+ { -+ pid = waitpid (child, &status, WUNTRACED); -+ -+ if (pid != (pid_t)-1 && WIFSTOPPED (status)) -+ { -+ kill (getpid (), SIGSTOP); -+ /* once we get here, we must have resumed */ -+ kill (pid, SIGCONT); -+ } -+ else -+ break; -+ } -+ if (pid != (pid_t)-1) -+ if (WIFSIGNALED (status)) -+ status = WTERMSIG (status) + 128; -+ else -+ status = WEXITSTATUS (status); -+ else -+ status = 1; -+ } -+ else -+ status = 1; -+ -+ if (caught_signal) -+ { -+ fprintf (stderr, _("\nSession terminated, killing shell...")); -+ kill (child, SIGTERM); -+ } -+ -+ cleanup_pam (PAM_SUCCESS); -+ -+ if (caught_signal) -+ { -+ sleep (2); -+ kill (child, SIGKILL); -+ fprintf (stderr, _(" ...killed.\n")); -+ } -+ exit (status); -+} -+ -+static void -+authenticate (const struct passwd *pw) -+{ -+ const struct passwd *lpw; -+ const char *cp, *srvname = NULL; -+ int retval; -+ -+ switch (su_mode) { -+ case SU_MODE: -+ srvname = simulate_login ? PAM_SRVNAME_SU_L : PAM_SRVNAME_SU; -+ break; -+ case RUNUSER_MODE: -+ srvname = simulate_login ? PAM_SRVNAME_RUNUSER_L : PAM_SRVNAME_RUNUSER; -+ break; -+ } -+ -+ retval = pam_start (srvname, pw->pw_name, &conv, &pamh); -+ if (is_pam_failure(retval)) -+ goto done; -+ -+ if (isatty (0) && (cp = ttyname (0)) != NULL) -+ { -+ const char *tty; -+ -+ if (strncmp (cp, "/dev/", 5) == 0) -+ tty = cp + 5; -+ else -+ tty = cp; -+ retval = pam_set_item (pamh, PAM_TTY, tty); -+ if (is_pam_failure(retval)) -+ goto done; -+ } -+ -+ lpw = getpwuid (getuid ()); -+ if (lpw && lpw->pw_name) -+ { -+ retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); -+ if (is_pam_failure(retval)) -+ goto done; -+ } -+ -+ if (su_mode == RUNUSER_MODE) -+ { -+ /* -+ * This is the only difference between runuser(1) and su(1). The command -+ * runuser(1) does not required authentication, because user is root. -+ */ -+ if (restricted) -+ errx(EXIT_FAILURE, _("may not be used by non-root users")); -+ return; -+ } -+ -+ retval = pam_authenticate (pamh, 0); -+ if (is_pam_failure(retval)) -+ goto done; -+ -+ retval = pam_acct_mgmt (pamh, 0); -+ if (retval == PAM_NEW_AUTHTOK_REQD) -+ { -+ /* Password has expired. Offer option to change it. */ -+ retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); -+ } -+ -+done: -+ -+ log_su (pw, !is_pam_failure(retval)); -+ -+ if (is_pam_failure(retval)) -+ { -+ const char *msg = pam_strerror(pamh, retval); -+ pam_end(pamh, retval); -+ sleep (getlogindefs_num ("FAIL_DELAY", 1)); -+ errx (EXIT_FAILURE, "%s", msg?msg:_("incorrect password")); -+ } -+} -+ -+/* Add or clear /sbin and /usr/sbin for the su command -+ used without `-'. */ -+ -+/* Set if /sbin is found in path. */ -+#define SBIN_MASK 0x01 -+/* Set if /usr/sbin is found in path. */ -+#define USBIN_MASK 0x02 -+ -+static char * -+addsbin (const char *const path) -+{ -+ unsigned char smask = 0; -+ char *ptr, *tmp, *cur, *ret = NULL; -+ size_t len; -+ -+ if (!path || *path == 0) -+ return NULL; -+ -+ tmp = xstrdup (path); -+ cur = tmp; -+ for (ptr = strsep (&cur, ":"); ptr != NULL; ptr = strsep (&cur, ":")) -+ { -+ if (!strcmp (ptr, "/sbin")) -+ smask |= SBIN_MASK; -+ if (!strcmp (ptr, "/usr/sbin")) -+ smask |= USBIN_MASK; -+ } -+ -+ if ((smask & (USBIN_MASK|SBIN_MASK)) == (USBIN_MASK|SBIN_MASK)) -+ { -+ free (tmp); -+ return NULL; -+ } -+ -+ len = strlen (path); -+ if (!(smask & USBIN_MASK)) -+ len += strlen ("/usr/sbin:"); -+ -+ if (!(smask & SBIN_MASK)) -+ len += strlen (":/sbin"); -+ -+ ret = xmalloc (len + 1); -+ strcpy (tmp, path); -+ -+ *ret = 0; -+ cur = tmp; -+ for (ptr = strsep (&cur, ":"); ptr; ptr = strsep (&cur, ":")) -+ { -+ if (!strcmp (ptr, ".")) -+ continue; -+ if (*ret) -+ strcat (ret, ":"); -+ if (!(smask & USBIN_MASK) && !strcmp (ptr, "/bin")) -+ { -+ strcat (ret, "/usr/sbin:"); -+ strcat (ret, ptr); -+ smask |= USBIN_MASK; -+ continue; -+ } -+ if (!(smask & SBIN_MASK) && !strcmp (ptr, "/usr/bin")) -+ { -+ strcat (ret, ptr); -+ strcat (ret, ":/sbin"); -+ smask |= SBIN_MASK; -+ continue; -+ } -+ strcat (ret, ptr); -+ } -+ free (tmp); -+ -+ if (!(smask & USBIN_MASK)) -+ strcat (ret, ":/usr/sbin"); -+ -+ if (!(smask & SBIN_MASK)) -+ strcat (ret, ":/sbin"); -+ -+ return ret; -+} -+ -+static char * -+clearsbin (const char *const path) -+{ -+ char *ptr, *tmp, *cur, *ret = NULL; -+ -+ if (!path || *path == 0) -+ return NULL; -+ -+ tmp = xstrdup (path); -+ -+ ret = xmalloc (strlen (path) + 1); -+ *ret = 0; -+ cur = tmp; -+ for (ptr = strsep (&cur, ":"); ptr; ptr = strsep (&cur, ":")) -+ { -+ if (!strcmp (ptr, "/sbin")) -+ continue; -+ if (!strcmp (ptr, "/usr/sbin")) -+ continue; -+ if (!strcmp (ptr, "/usr/local/sbin")) -+ continue; -+ if (*ret) -+ strcat (ret, ":"); -+ strcat (ret, ptr); -+ } -+ free (tmp); -+ -+ return ret; -+} -+ -+static void -+set_path(const struct passwd* pw) -+{ -+ int r; -+ if (pw->pw_uid) -+ r = logindefs_setenv("PATH", "ENV_PATH", _PATH_DEFPATH); -+ -+ else if ((r = logindefs_setenv("PATH", "ENV_ROOTPATH", NULL)) != 0) -+ r = logindefs_setenv("PATH", "ENV_SUPATH", _PATH_DEFPATH_ROOT); -+ -+ if (r != 0) -+ err (EXIT_FAILURE, _("failed to set PATH")); -+} -+ -+/* Update `environ' for the new shell based on PW, with SHELL being -+ the value for the SHELL environment variable. */ -+ -+static void -+modify_environment (const struct passwd *pw, const char *shell) -+{ -+ if (simulate_login) -+ { -+ /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. -+ Unset all other environment variables. */ -+ char const *term = getenv ("TERM"); -+ if (term) -+ term = xstrdup (term); -+ environ = xmalloc ((6 + !!term) * sizeof (char *)); -+ environ[0] = NULL; -+ if (term) -+ xsetenv ("TERM", term, 1); -+ xsetenv ("HOME", pw->pw_dir, 1); -+ xsetenv ("SHELL", shell, 1); -+ xsetenv ("USER", pw->pw_name, 1); -+ xsetenv ("LOGNAME", pw->pw_name, 1); -+ set_path(pw); -+ } -+ else -+ { -+ /* Set HOME, SHELL, and if not becoming a super-user, -+ USER and LOGNAME. */ -+ if (change_environment) -+ { -+ xsetenv ("HOME", pw->pw_dir, 1); -+ xsetenv ("SHELL", shell, 1); -+ if (getlogindefs_bool ("ALWAYS_SET_PATH", 0)) -+ set_path(pw); -+ else -+ { -+ char const *path = getenv ("PATH"); -+ char *new = NULL; -+ -+ if (pw->pw_uid) -+ new = clearsbin (path); -+ else -+ new = addsbin (path); -+ -+ if (new) -+ { -+ xsetenv ("PATH", new, 1); -+ free (new); -+ } -+ } -+ if (pw->pw_uid) -+ { -+ xsetenv ("USER", pw->pw_name, 1); -+ xsetenv ("LOGNAME", pw->pw_name, 1); -+ } -+ } -+ } -+ -+ export_pamenv (); -+} -+ -+/* Become the user and group(s) specified by PW. */ -+ -+static void -+init_groups (const struct passwd *pw, gid_t *groups, int num_groups) -+{ -+ int retval; -+ -+ errno = 0; -+ -+ if (num_groups) -+ retval = setgroups (num_groups, groups); -+ else -+ retval = initgroups (pw->pw_name, pw->pw_gid); -+ -+ if (retval == -1) -+ { -+ cleanup_pam (PAM_ABORT); -+ err (EXIT_FAILURE, _("cannot set groups")); -+ } -+ endgrent (); -+ -+ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED); -+ if (is_pam_failure(retval)) -+ errx (EXIT_FAILURE, "%s", pam_strerror (pamh, retval)); -+ else -+ _pam_cred_established = 1; -+} -+ -+static void -+change_identity (const struct passwd *pw) -+{ -+ if (setgid (pw->pw_gid)) -+ err (EXIT_FAILURE, _("cannot set group id")); -+ if (setuid (pw->pw_uid)) -+ err (EXIT_FAILURE, _("cannot set user id")); -+} -+ -+/* Run SHELL, or DEFAULT_SHELL if SHELL is empty. -+ If COMMAND is nonzero, pass it to the shell with the -c option. -+ Pass ADDITIONAL_ARGS to the shell as more arguments; there -+ are N_ADDITIONAL_ARGS extra arguments. */ -+ -+static void -+run_shell (char const *shell, char const *command, char **additional_args, -+ size_t n_additional_args) -+{ -+ size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; -+ char const **args = xcalloc (n_args, sizeof *args); -+ size_t argno = 1; -+ -+ if (simulate_login) -+ { -+ char *arg0; -+ char *shell_basename; -+ -+ shell_basename = basename (shell); -+ arg0 = xmalloc (strlen (shell_basename) + 2); -+ arg0[0] = '-'; -+ strcpy (arg0 + 1, shell_basename); -+ args[0] = arg0; -+ } -+ else -+ args[0] = basename (shell); -+ if (fast_startup) -+ args[argno++] = "-f"; -+ if (command) -+ { -+ args[argno++] = "-c"; -+ args[argno++] = command; -+ } -+ memcpy (args + argno, additional_args, n_additional_args * sizeof *args); -+ args[argno + n_additional_args] = NULL; -+ execv (shell, (char **) args); -+ -+ { -+ int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); -+ warn ("%s", shell); -+ exit (exit_status); -+ } -+} -+ -+/* Return true if SHELL is a restricted shell (one not returned by -+ getusershell), else false, meaning it is a standard shell. */ -+ -+static bool -+restricted_shell (const char *shell) -+{ -+ char *line; -+ -+ setusershell (); -+ while ((line = getusershell ()) != NULL) -+ { -+ if (*line != '#' && !strcmp (line, shell)) -+ { -+ endusershell (); -+ return false; -+ } -+ } -+ endusershell (); -+ return true; -+} -+ -+static void __attribute__((__noreturn__)) -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_invocation_short_name); -+ else -+ { -+ fputs(USAGE_HEADER, stdout); -+ printf (_(" %s [options] [-] [USER [arg]...]\n"), program_invocation_short_name); -+ fputs (_("\n\ -+ Change the effective user id and group id to that of USER.\n\ -+ A mere - implies -l. If USER not given, assume root.\n"), stdout); -+ fputs(USAGE_OPTIONS, stdout); -+ fputs (_("\ -+ -, -l, --login make the shell a login shell\n\ -+ -c, --command pass a single command to the shell with -c\n\ -+ --session-command pass a single command to the shell with -c\n\ -+ and do not create a new session\n\ -+ -g --group=group specify the primary group\n\ -+ -G --supp-group=group specify a supplemental group\n\ -+ -f, --fast pass -f to the shell (for csh or tcsh)\n\ -+ -m, --preserve-environment do not reset environment variables\n\ -+ -p same as -m\n\ -+ -s, --shell run shell if /etc/shells allows it\n\ -+"), stdout); -+ -+ fputs(USAGE_SEPARATOR, stdout); -+ fputs(USAGE_HELP, stdout); -+ fputs(USAGE_VERSION, stdout); -+ printf(USAGE_MAN_TAIL("su(1)")); -+ } -+ exit (status); -+} -+ -+static -+void load_config(void) -+{ -+ switch (su_mode) { -+ case SU_MODE: -+ logindefs_load_file(_PATH_LOGINDEFS_SU); -+ break; -+ case RUNUSER_MODE: -+ logindefs_load_file(_PATH_LOGINDEFS_RUNUSER); -+ break; -+ } -+ -+ logindefs_load_file(_PATH_LOGINDEFS); -+} -+ -+/* -+ * Returns 1 if the current user is not root -+ */ -+static int -+evaluate_uid(void) -+{ -+ uid_t ruid = getuid(); -+ uid_t euid = geteuid(); -+ -+ /* if we're really root and aren't running setuid */ -+ return (uid_t) 0 == ruid && ruid == euid ? 0 : 1; -+} -+ -+int -+su_main (int argc, char **argv, int mode) -+{ -+ int optc; -+ const char *new_user = DEFAULT_USER; -+ char *command = NULL; -+ int request_same_session = 0; -+ char *shell = NULL; -+ struct passwd *pw; -+ struct passwd pw_copy; -+ struct group *gr; -+ gid_t groups[NGROUPS_MAX]; -+ int num_supp_groups = 0; -+ int use_gid = 0; -+ -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ su_mode = mode; -+ fast_startup = false; -+ simulate_login = false; -+ change_environment = true; -+ -+ while ((optc = getopt_long (argc, argv, "c:fg:G:lmps:hV", longopts, NULL)) != -1) -+ { -+ switch (optc) -+ { -+ case 'c': -+ command = optarg; -+ break; -+ -+ case 'C': -+ command = optarg; -+ request_same_session = 1; -+ break; -+ -+ case 'f': -+ fast_startup = true; -+ break; -+ -+ case 'g': -+ gr = getgrnam(optarg); -+ if (!gr) -+ errx(EXIT_FAILURE, _("group %s does not exist"), optarg); -+ use_gid = 1; -+ groups[0] = gr->gr_gid; -+ break; -+ -+ case 'G': -+ num_supp_groups++; -+ if (num_supp_groups >= NGROUPS_MAX) -+ errx(EXIT_FAILURE, -+ _("can't specify more than %d supplemental groups"), -+ NGROUPS_MAX - 1); -+ gr = getgrnam(optarg); -+ if (!gr) -+ errx(EXIT_FAILURE, _("group %s does not exist"), optarg); -+ groups[num_supp_groups] = gr->gr_gid; -+ break; -+ -+ case 'l': -+ simulate_login = true; -+ break; -+ -+ case 'm': -+ case 'p': -+ change_environment = false; -+ break; -+ -+ case 's': -+ shell = optarg; -+ break; -+ -+ case 'h': -+ usage(0); -+ -+ case 'V': -+ printf(UTIL_LINUX_VERSION); -+ exit(EXIT_SUCCESS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ restricted = evaluate_uid (); -+ -+ if (optind < argc && !strcmp (argv[optind], "-")) -+ { -+ simulate_login = true; -+ ++optind; -+ } -+ if (optind < argc) -+ new_user = argv[optind++]; -+ -+ if ((num_supp_groups || use_gid) && restricted) -+ errx(EXIT_FAILURE, _("only root can specify alternative groups")); -+ -+ logindefs_load_defaults = load_config; -+ -+ pw = getpwnam (new_user); -+ if (! (pw && pw->pw_name && pw->pw_name[0] && pw->pw_dir && pw->pw_dir[0] -+ && pw->pw_passwd)) -+ errx (EXIT_FAILURE, _("user %s does not exist"), new_user); -+ -+ /* Make a copy of the password information and point pw at the local -+ copy instead. Otherwise, some systems (e.g. Linux) would clobber -+ the static data through the getlogin call from log_su. -+ Also, make sure pw->pw_shell is a nonempty string. -+ It may be NULL when NEW_USER is a username that is retrieved via NIS (YP), -+ but that doesn't have a default shell listed. */ -+ pw_copy = *pw; -+ pw = &pw_copy; -+ pw->pw_name = xstrdup (pw->pw_name); -+ pw->pw_passwd = xstrdup (pw->pw_passwd); -+ pw->pw_dir = xstrdup (pw->pw_dir); -+ pw->pw_shell = xstrdup (pw->pw_shell && pw->pw_shell[0] -+ ? pw->pw_shell -+ : DEFAULT_SHELL); -+ endpwent (); -+ -+ if (num_supp_groups && !use_gid) -+ { -+ pw->pw_gid = groups[1]; -+ memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups); -+ } -+ else if (use_gid) -+ { -+ pw->pw_gid = groups[0]; -+ num_supp_groups++; -+ } -+ -+ authenticate (pw); -+ -+ if (request_same_session || !command || !pw->pw_uid) -+ same_session = 1; -+ -+ if (!shell && !change_environment) -+ shell = getenv ("SHELL"); -+ if (shell && getuid () != 0 && restricted_shell (pw->pw_shell)) -+ { -+ /* The user being su'd to has a nonstandard shell, and so is -+ probably a uucp account or has restricted access. Don't -+ compromise the account by allowing access with a standard -+ shell. */ -+ warnx (_("using restricted shell %s"), pw->pw_shell); -+ shell = NULL; -+ } -+ shell = xstrdup (shell ? shell : pw->pw_shell); -+ -+ init_groups (pw, groups, num_supp_groups); -+ -+ create_watching_parent (); -+ /* Now we're in the child. */ -+ -+ change_identity (pw); -+ if (!same_session) -+ setsid (); -+ -+ /* Set environment after pam_open_session, which may put KRB5CCNAME -+ into the pam_env, etc. */ -+ -+ modify_environment (pw, shell); -+ -+ if (simulate_login && chdir (pw->pw_dir) != 0) -+ warn (_("warning: cannot change directory to %s"), pw->pw_dir); -+ -+ run_shell (shell, command, argv + optind, max (0, argc - optind)); -+} -+ -+// vim: sw=2 cinoptions=>4,n-2,{2,^-2,\:2,=2,g0,h2,p5,t0,+2,(0,u0,w1,m1 -diff --git a/login-utils/su-common.h b/login-utils/su-common.h -new file mode 100644 -index 0000000..7cf3769 ---- /dev/null -+++ b/login-utils/su-common.h -@@ -0,0 +1,11 @@ -+#ifndef UTIL_LINUX_SU_COMMON_H -+#define UTIL_LINUX_SU_COMMON_H -+ -+enum { -+ SU_MODE, -+ RUNUSER_MODE -+}; -+ -+extern int su_main(int argc, char **argv, int mode); -+ -+#endif /* UTIL_LINUX_SU_COMMON */ -diff --git a/login-utils/su.1 b/login-utils/su.1 -index 598cebd..59e1731 100644 ---- a/login-utils/su.1 -+++ b/login-utils/su.1 -@@ -59,6 +59,12 @@ Pass - to the shell which may or may not be useful depending on the - shell. - .TP -+\fB\-g\fR, \fB\-\-group\fR=\fIgroup\fR\fR -+specify the primary group, this option is allowed for root user only -+.TP -+\fB\-G\fR, \fB\-\-supp-group\fR=\fIgroup\fR\fR -+specify a supplemental group, this option is allowed for root user only -+.TP - \fB\-\fR, \fB\-l\fR, \fB\-\-login\fR - Starts the shell as login shell with an environment similar to a real - login: -diff --git a/login-utils/su.c b/login-utils/su.c -index c6b8bce..29c10f0 100644 ---- a/login-utils/su.c -+++ b/login-utils/su.c -@@ -1,689 +1,8 @@ --/* su for Linux. Run a shell with substitute user and group IDs. -- Copyright (C) 1992-2006 Free Software Foundation, Inc. -- Copyright (C) 2012 SUSE Linux Products GmbH, Nuernberg - -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2, or (at your option) -- any later version. -+#include "su-common.h" - -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software Foundation, -- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -- --/* Run a shell with the real and effective UID and GID and groups -- of USER, default `root'. -- -- The shell run is taken from USER's password entry, /bin/sh if -- none is specified there. If the account has a password, su -- prompts for a password unless run by a user with real UID 0. -- -- Does not change the current directory. -- Sets `HOME' and `SHELL' from the password entry for USER, and if -- USER is not root, sets `USER' and `LOGNAME' to USER. -- The subshell is not a login shell. -- -- If one or more ARGs are given, they are passed as additional -- arguments to the subshell. -- -- Does not handle /bin/sh or other shells specially -- (setting argv[0] to "-su", passing -c only to certain shells, etc.). -- I don't see the point in doing that, and it's ugly. -- -- Based on an implemenation by David MacKenzie . */ -- --enum --{ -- EXIT_CANNOT_INVOKE = 126, -- EXIT_ENOENT = 127 --}; -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "err.h" -- --#include --#include "c.h" --#include "xalloc.h" --#include "nls.h" --#include "pathnames.h" --#include "env.h" -- --/* name of the pam configuration files. separate configs for su and su - */ --#define PAM_SERVICE_NAME "su" --#define PAM_SERVICE_NAME_L "su-l" -- --#define is_pam_failure(_rc) ((_rc) != PAM_SUCCESS) -- --#include "logindefs.h" -- --/* The shell to run if none is given in the user's passwd entry. */ --#define DEFAULT_SHELL "/bin/sh" -- --/* The user to become if none is specified. */ --#define DEFAULT_USER "root" -- --#ifndef HAVE_ENVIRON_DECL --extern char **environ; --#endif -- --static void run_shell (char const *, char const *, char **, size_t) -- __attribute__ ((__noreturn__)); -- --/* If true, pass the `-f' option to the subshell. */ --static bool fast_startup; -- --/* If true, simulate a login instead of just starting a shell. */ --static bool simulate_login; -- --/* If true, change some environment vars to indicate the user su'd to. */ --static bool change_environment; -- --/* If true, then don't call setsid() with a command. */ --int same_session = 0; -- --static bool _pam_session_opened; --static bool _pam_cred_established; --static sig_atomic_t volatile caught_signal = false; --static pam_handle_t *pamh = NULL; -- --static struct option const longopts[] = --{ -- {"command", required_argument, NULL, 'c'}, -- {"session-command", required_argument, NULL, 'C'}, -- {"fast", no_argument, NULL, 'f'}, -- {"login", no_argument, NULL, 'l'}, -- {"preserve-environment", no_argument, NULL, 'p'}, -- {"shell", required_argument, NULL, 's'}, -- {"help", no_argument, 0, 'h'}, -- {"version", no_argument, 0, 'V'}, -- {NULL, 0, NULL, 0} --}; -- --/* Log the fact that someone has run su to the user given by PW; -- if SUCCESSFUL is true, they gave the correct password, etc. */ -- --static void --log_su (struct passwd const *pw, bool successful) --{ -- const char *new_user, *old_user, *tty; -- -- new_user = pw->pw_name; -- /* The utmp entry (via getlogin) is probably the best way to identify -- the user, especially if someone su's from a su-shell. */ -- old_user = getlogin (); -- if (!old_user) -- { -- /* getlogin can fail -- usually due to lack of utmp entry. -- Resort to getpwuid. */ -- struct passwd *pwd = getpwuid (getuid ()); -- old_user = (pwd ? pwd->pw_name : ""); -- } -- tty = ttyname (STDERR_FILENO); -- if (!tty) -- tty = "none"; -- -- openlog (program_invocation_short_name, 0 , LOG_AUTH); -- syslog (LOG_NOTICE, "%s(to %s) %s on %s", -- successful ? "" : "FAILED SU ", -- new_user, old_user, tty); -- closelog (); --} -- --static struct pam_conv conv = --{ -- misc_conv, -- NULL --}; -- --static void --cleanup_pam (int retcode) -+int main(int argv, char **argc) - { -- int saved_errno = errno; -- -- if (_pam_session_opened) -- pam_close_session (pamh, 0); -- -- if (_pam_cred_established) -- pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT); -- -- pam_end(pamh, retcode); -- -- errno = saved_errno; --} -- --/* Signal handler for parent process. */ --static void --su_catch_sig (int sig __attribute__((__unused__))) --{ -- caught_signal = true; --} -- --/* Export env variables declared by PAM modules. */ --static void --export_pamenv (void) --{ -- char **env; -- -- /* This is a copy but don't care to free as we exec later anyways. */ -- env = pam_getenvlist (pamh); -- while (env && *env) -- { -- if (putenv (*env) != 0) -- err (EXIT_FAILURE, NULL); -- env++; -- } --} -- --static void --create_watching_parent (void) --{ -- pid_t child; -- sigset_t ourset; -- int status = 0; -- int retval; -- -- retval = pam_open_session (pamh, 0); -- if (is_pam_failure(retval)) -- { -- cleanup_pam (retval); -- errx (EXIT_FAILURE, _("cannot not open session: %s"), -- pam_strerror (pamh, retval)); -- } -- else -- _pam_session_opened = 1; -- -- child = fork (); -- if (child == (pid_t) -1) -- { -- cleanup_pam (PAM_ABORT); -- err (EXIT_FAILURE, _("cannot create child process")); -- } -- -- /* the child proceeds to run the shell */ -- if (child == 0) -- return; -- -- /* In the parent watch the child. */ -- -- /* su without pam support does not have a helper that keeps -- sitting on any directory so let's go to /. */ -- if (chdir ("/") != 0) -- warn (_("cannot change directory to %s"), "/"); -- -- sigfillset (&ourset); -- if (sigprocmask (SIG_BLOCK, &ourset, NULL)) -- { -- warn (_("cannot block signals")); -- caught_signal = true; -- } -- if (!caught_signal) -- { -- struct sigaction action; -- action.sa_handler = su_catch_sig; -- sigemptyset (&action.sa_mask); -- action.sa_flags = 0; -- sigemptyset (&ourset); -- if (!same_session) -- { -- if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) -- { -- warn (_("cannot set signal handler")); -- caught_signal = true; -- } -- } -- if (!caught_signal && (sigaddset(&ourset, SIGTERM) -- || sigaddset(&ourset, SIGALRM) -- || sigaction(SIGTERM, &action, NULL) -- || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) { -- warn (_("cannot set signal handler")); -- caught_signal = true; -- } -- if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL) -- || sigaction(SIGQUIT, &action, NULL))) -- { -- warn (_("cannot set signal handler")); -- caught_signal = true; -- } -- } -- if (!caught_signal) -- { -- pid_t pid; -- for (;;) -- { -- pid = waitpid (child, &status, WUNTRACED); -- -- if (pid != (pid_t)-1 && WIFSTOPPED (status)) -- { -- kill (getpid (), SIGSTOP); -- /* once we get here, we must have resumed */ -- kill (pid, SIGCONT); -- } -- else -- break; -- } -- if (pid != (pid_t)-1) -- if (WIFSIGNALED (status)) -- status = WTERMSIG (status) + 128; -- else -- status = WEXITSTATUS (status); -- else -- status = 1; -- } -- else -- status = 1; -- -- if (caught_signal) -- { -- fprintf (stderr, _("\nSession terminated, killing shell...")); -- kill (child, SIGTERM); -- } -- -- cleanup_pam (PAM_SUCCESS); -- -- if (caught_signal) -- { -- sleep (2); -- kill (child, SIGKILL); -- fprintf (stderr, _(" ...killed.\n")); -- } -- exit (status); --} -- --static void --authenticate (const struct passwd *pw) --{ -- const struct passwd *lpw; -- const char *cp; -- int retval; -- -- retval = pam_start (simulate_login ? PAM_SERVICE_NAME_L : PAM_SERVICE_NAME, -- pw->pw_name, &conv, &pamh); -- if (is_pam_failure(retval)) -- goto done; -- -- if (isatty (0) && (cp = ttyname (0)) != NULL) -- { -- const char *tty; -- -- if (strncmp (cp, "/dev/", 5) == 0) -- tty = cp + 5; -- else -- tty = cp; -- retval = pam_set_item (pamh, PAM_TTY, tty); -- if (is_pam_failure(retval)) -- goto done; -- } -- -- lpw = getpwuid (getuid ()); -- if (lpw && lpw->pw_name) -- { -- retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); -- if (is_pam_failure(retval)) -- goto done; -- } -- -- retval = pam_authenticate (pamh, 0); -- if (is_pam_failure(retval)) -- goto done; -- -- retval = pam_acct_mgmt (pamh, 0); -- if (retval == PAM_NEW_AUTHTOK_REQD) -- { -- /* Password has expired. Offer option to change it. */ -- retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); -- } -- --done: -- -- log_su (pw, !is_pam_failure(retval)); -- -- if (is_pam_failure(retval)) -- { -- const char *msg = pam_strerror(pamh, retval); -- pam_end(pamh, retval); -- sleep (getlogindefs_num ("FAIL_DELAY", 1)); -- errx (EXIT_FAILURE, "%s", msg?msg:_("incorrect password")); -- } --} -- --static void --set_path(const struct passwd* pw) --{ -- int r; -- if (pw->pw_uid) -- r = logindefs_setenv("PATH", "ENV_PATH", _PATH_DEFPATH); -- -- else if ((r = logindefs_setenv("PATH", "ENV_ROOTPATH", NULL)) != 0) -- r = logindefs_setenv("PATH", "ENV_SUPATH", _PATH_DEFPATH_ROOT); -- -- if (r != 0) -- err (EXIT_FAILURE, _("failed to set PATH")); --} -- --/* Update `environ' for the new shell based on PW, with SHELL being -- the value for the SHELL environment variable. */ -- --static void --modify_environment (const struct passwd *pw, const char *shell) --{ -- if (simulate_login) -- { -- /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. -- Unset all other environment variables. */ -- char const *term = getenv ("TERM"); -- if (term) -- term = xstrdup (term); -- environ = xmalloc ((6 + !!term) * sizeof (char *)); -- environ[0] = NULL; -- if (term) -- xsetenv ("TERM", term, 1); -- xsetenv ("HOME", pw->pw_dir, 1); -- xsetenv ("SHELL", shell, 1); -- xsetenv ("USER", pw->pw_name, 1); -- xsetenv ("LOGNAME", pw->pw_name, 1); -- set_path(pw); -- } -- else -- { -- /* Set HOME, SHELL, and if not becoming a super-user, -- USER and LOGNAME. */ -- if (change_environment) -- { -- xsetenv ("HOME", pw->pw_dir, 1); -- xsetenv ("SHELL", shell, 1); -- if (getlogindefs_bool ("ALWAYS_SET_PATH", 0)) -- set_path(pw); -- -- if (pw->pw_uid) -- { -- xsetenv ("USER", pw->pw_name, 1); -- xsetenv ("LOGNAME", pw->pw_name, 1); -- } -- } -- } -- -- export_pamenv (); --} -- --/* Become the user and group(s) specified by PW. */ -- --static void --init_groups (const struct passwd *pw) --{ -- int retval; -- errno = 0; -- if (initgroups (pw->pw_name, pw->pw_gid) == -1) -- { -- cleanup_pam (PAM_ABORT); -- err (EXIT_FAILURE, _("cannot set groups")); -- } -- endgrent (); -- -- retval = pam_setcred (pamh, PAM_ESTABLISH_CRED); -- if (is_pam_failure(retval)) -- errx (EXIT_FAILURE, "%s", pam_strerror (pamh, retval)); -- else -- _pam_cred_established = 1; --} -- --static void --change_identity (const struct passwd *pw) --{ -- if (setgid (pw->pw_gid)) -- err (EXIT_FAILURE, _("cannot set group id")); -- if (setuid (pw->pw_uid)) -- err (EXIT_FAILURE, _("cannot set user id")); --} -- --/* Run SHELL, or DEFAULT_SHELL if SHELL is empty. -- If COMMAND is nonzero, pass it to the shell with the -c option. -- Pass ADDITIONAL_ARGS to the shell as more arguments; there -- are N_ADDITIONAL_ARGS extra arguments. */ -- --static void --run_shell (char const *shell, char const *command, char **additional_args, -- size_t n_additional_args) --{ -- size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; -- char const **args = xcalloc (n_args, sizeof *args); -- size_t argno = 1; -- -- if (simulate_login) -- { -- char *arg0; -- char *shell_basename; -- -- shell_basename = basename (shell); -- arg0 = xmalloc (strlen (shell_basename) + 2); -- arg0[0] = '-'; -- strcpy (arg0 + 1, shell_basename); -- args[0] = arg0; -- } -- else -- args[0] = basename (shell); -- if (fast_startup) -- args[argno++] = "-f"; -- if (command) -- { -- args[argno++] = "-c"; -- args[argno++] = command; -- } -- memcpy (args + argno, additional_args, n_additional_args * sizeof *args); -- args[argno + n_additional_args] = NULL; -- execv (shell, (char **) args); -- -- { -- int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); -- warn ("%s", shell); -- exit (exit_status); -- } --} -- --/* Return true if SHELL is a restricted shell (one not returned by -- getusershell), else false, meaning it is a standard shell. */ -- --static bool --restricted_shell (const char *shell) --{ -- char *line; -- -- setusershell (); -- while ((line = getusershell ()) != NULL) -- { -- if (*line != '#' && !strcmp (line, shell)) -- { -- endusershell (); -- return false; -- } -- } -- endusershell (); -- return true; --} -- --static void __attribute__((__noreturn__)) --usage (int status) --{ -- if (status != EXIT_SUCCESS) -- fprintf (stderr, _("Try `%s --help' for more information.\n"), -- program_invocation_short_name); -- else -- { -- fputs(USAGE_HEADER, stdout); -- printf (_(" %s [options] [-] [USER [arg]...]\n"), program_invocation_short_name); -- fputs (_("\n\ -- Change the effective user id and group id to that of USER.\n\ -- A mere - implies -l. If USER not given, assume root.\n"), stdout); -- fputs(USAGE_OPTIONS, stdout); -- fputs (_("\ -- -, -l, --login make the shell a login shell\n\ -- -c, --command pass a single command to the shell with -c\n\ -- --session-command pass a single command to the shell with -c\n\ -- and do not create a new session\n\ -- -f, --fast pass -f to the shell (for csh or tcsh)\n\ -- -m, --preserve-environment do not reset environment variables\n\ -- -p same as -m\n\ -- -s, --shell run shell if /etc/shells allows it\n\ --"), stdout); -- -- fputs(USAGE_SEPARATOR, stdout); -- fputs(USAGE_HELP, stdout); -- fputs(USAGE_VERSION, stdout); -- printf(USAGE_MAN_TAIL("su(1)")); -- } -- exit (status); --} -- --static --void load_config(void) --{ -- logindefs_load_file("/etc/default/su"); -- logindefs_load_file(_PATH_LOGINDEFS); --} -- --int --main (int argc, char **argv) --{ -- int optc; -- const char *new_user = DEFAULT_USER; -- char *command = NULL; -- int request_same_session = 0; -- char *shell = NULL; -- struct passwd *pw; -- struct passwd pw_copy; -- -- setlocale (LC_ALL, ""); -- bindtextdomain (PACKAGE, LOCALEDIR); -- textdomain (PACKAGE); -- -- fast_startup = false; -- simulate_login = false; -- change_environment = true; -- -- while ((optc = getopt_long (argc, argv, "c:flmps:hV", longopts, NULL)) != -1) -- { -- switch (optc) -- { -- case 'c': -- command = optarg; -- break; -- -- case 'C': -- command = optarg; -- request_same_session = 1; -- break; -- -- case 'f': -- fast_startup = true; -- break; -- -- case 'l': -- simulate_login = true; -- break; -- -- case 'm': -- case 'p': -- change_environment = false; -- break; -- -- case 's': -- shell = optarg; -- break; -- -- case 'h': -- usage(0); -- -- case 'V': -- printf(UTIL_LINUX_VERSION); -- exit(EXIT_SUCCESS); -- -- default: -- usage (EXIT_FAILURE); -- } -- } -- -- if (optind < argc && !strcmp (argv[optind], "-")) -- { -- simulate_login = true; -- ++optind; -- } -- if (optind < argc) -- new_user = argv[optind++]; -- -- logindefs_load_defaults = load_config; -- -- pw = getpwnam (new_user); -- if (! (pw && pw->pw_name && pw->pw_name[0] && pw->pw_dir && pw->pw_dir[0] -- && pw->pw_passwd)) -- errx (EXIT_FAILURE, _("user %s does not exist"), new_user); -- -- /* Make a copy of the password information and point pw at the local -- copy instead. Otherwise, some systems (e.g. Linux) would clobber -- the static data through the getlogin call from log_su. -- Also, make sure pw->pw_shell is a nonempty string. -- It may be NULL when NEW_USER is a username that is retrieved via NIS (YP), -- but that doesn't have a default shell listed. */ -- pw_copy = *pw; -- pw = &pw_copy; -- pw->pw_name = xstrdup (pw->pw_name); -- pw->pw_passwd = xstrdup (pw->pw_passwd); -- pw->pw_dir = xstrdup (pw->pw_dir); -- pw->pw_shell = xstrdup (pw->pw_shell && pw->pw_shell[0] -- ? pw->pw_shell -- : DEFAULT_SHELL); -- endpwent (); -- -- authenticate (pw); -- -- if (request_same_session || !command || !pw->pw_uid) -- same_session = 1; -- -- if (!shell && !change_environment) -- shell = getenv ("SHELL"); -- if (shell && getuid () != 0 && restricted_shell (pw->pw_shell)) -- { -- /* The user being su'd to has a nonstandard shell, and so is -- probably a uucp account or has restricted access. Don't -- compromise the account by allowing access with a standard -- shell. */ -- warnx (_("using restricted shell %s"), pw->pw_shell); -- shell = NULL; -- } -- shell = xstrdup (shell ? shell : pw->pw_shell); -- -- init_groups (pw); -- -- create_watching_parent (); -- /* Now we're in the child. */ -- -- change_identity (pw); -- if (!same_session) -- setsid (); -- -- /* Set environment after pam_open_session, which may put KRB5CCNAME -- into the pam_env, etc. */ -- -- modify_environment (pw, shell); -- -- if (simulate_login && chdir (pw->pw_dir) != 0) -- warn (_("warning: cannot change directory to %s"), pw->pw_dir); -- -- run_shell (shell, command, argv + optind, max (0, argc - optind)); -+ return su_main(argv, argc, SU_MODE); - } - --// vim: sw=2 cinoptions=>4,n-2,{2,^-2,\:2,=2,g0,h2,p5,t0,+2,(0,u0,w1,m1 diff --git a/util-linux.spec b/util-linux.spec index 2951ae7..3adc416 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -35,12 +35,12 @@ Summary(ru.UTF-8): Набор базовых системных утилит д Summary(tr.UTF-8): Temel sistem araçları Summary(uk.UTF-8): Набір базових системних утиліт для Linux Name: util-linux -Version: 2.22.2 -Release: 6 +Version: 2.23.1 +Release: 0.1 License: GPL Group: Applications/System -Source0: https://www.kernel.org/pub/linux/utils/util-linux/v2.22/%{name}-%{version}.tar.xz -# Source0-md5: eeacbfdd2556acd899a2d0ffdb446185 +Source0: https://www.kernel.org/pub/linux/utils/util-linux/v2.23/%{name}-%{version}.tar.xz +# Source0-md5: 33ba55ce82f8e3b8d7a38fac0f62779a Source1: http://www.mif.pg.gda.pl/homepages/ankry/man-PLD/%{name}-non-english-man-pages.tar.bz2 # Source1-md5: 3c940c7e7fe699eaa2ddb1bffb3de2fe Source2: login.pamd @@ -55,7 +55,7 @@ Source10: nologin.c Source11: nologin.8 Patch0: %{name}-pl.po-update.patch Patch1: %{name}-ng-union-mount.patch -Patch2: %{name}-runuser.patch + Patch3: %{name}-fdformat-ide.patch Patch4: %{name}-fhs.patch Patch5: %{name}-hotkeys.patch @@ -63,7 +63,6 @@ Patch7: %{name}-login-lastlog.patch Patch8: %{name}-procpartitions.patch Patch9: su-paths.patch Patch10: %{name}-diet.patch -Patch11: https://github.com/karelzak/util-linux/commit/38db00f17824f41679c99a6c711a11e4585a0484.patch # Patch11-md5: 2a37a871117466841edb3e8be692825b URL: http://userweb.kernel.org/~kzak/util-linux/ BuildRequires: audit-libs-devel >= 1.0.6 @@ -112,6 +111,7 @@ Obsoletes: rawdevices Obsoletes: schedutils Obsoletes: setarch Obsoletes: sparc32 +Obsoletes: util-linux-chkdupexe Obsoletes: util-linux-ng < 2.20-1 Obsoletes: util-linux-suids Conflicts: SysVinit < 2.86-26 @@ -343,22 +343,6 @@ sisteminizin işlevselliği açısından kritiktir. дерева. Swapon та swapoff, відповідно, дозволяє та заборонює свопінг у визначені файли або пристрої. -%package chkdupexe -Summary: chkdupexe - find duplicate executables -Summary(pl.UTF-8): chkdupexe odszukuje powtarzające się pliki uruchamialne -Group: Applications/System -Obsoletes: util-linux-ng-chkdupexe < 2.20-1 - -%description chkdupexe -chkdupexe will scan the union of $PATH and a hardcoded list of common -locations for binaries. It will report dangling symlinks and -duplicately-named binaries. - -%description chkdupexe -l pl.UTF-8 -chkdupexe przeszukuje katalogi z $PATH oraz inne powszechnie znane -katalogi z plikami uruchamialnymi i informuje o powtarzających się -plikach w różnych katalogach. - %package -n tunelp Summary: Configures kernel parallel port driver Summary(de.UTF-8): Konfiguriert den Kerneltreiber für den parallelen Port @@ -644,19 +628,31 @@ or UUID - staticaly linked for initrd. Pakiet ten zawiera narzędzie blkid do rozpoznawania partycji przez etykietę lub UUID - statycznie skonsolidowane na potrzeby initrd. +%package -n bash-completion-util-linux +Summary: bash completion for util-linux +Summary(pl.UTF-8): Dopełnienia basha dla util-linux +Group: Applications/Shells +Requires: %{name} = %{version}-%{release} +Requires: bash-completion + +%description -n bash-completion-util-linux +Bash completion for util-linux. + +%description -n bash-completion-util-linux -l pl.UTF-8 +Dopełnienia basha dla util-linux. + %prep %setup -q -a1 #%patch0 -p1 %patch1 -p1 -%patch2 -p1 + %patch3 -p1 %patch4 -p1 %patch5 -p1 %patch7 -p1 %patch8 -p1 %patch9 -p1 -%patch10 -p1 -%patch11 -p1 +%{?with_initrd:%patch10 -p1} install %{SOURCE10} nologin.c @@ -707,6 +703,7 @@ export CPPFLAGS="%{rpmcppflags} -I/usr/include/ncurses -DHAVE_LSEEK64_PROTOTYPE --disable-silent-rules \ --disable-su \ --disable-sulogin \ + --disable-tunelp \ --disable-use-tty-group \ --disable-utmpdump \ --disable-uuidd \ @@ -742,8 +739,6 @@ export CPPFLAGS="%{rpmcppflags} -I/usr/include/ncurses -DHAVE_LSEEK64_PROTOTYPE --disable-use-tty-group \ --disable-wall \ --enable-chfn-chsh \ - --enable-chkdupexe \ - --enable-ddate \ --enable-kill \ --enable-libblkid \ --enable-line \ @@ -754,10 +749,12 @@ export CPPFLAGS="%{rpmcppflags} -I/usr/include/ncurses -DHAVE_LSEEK64_PROTOTYPE --enable-runuser%{!?with_su:=no} \ --enable-su%{!?with_su:=no} \ --enable-sulogin \ + --enable-tunelp \ --enable-utmpdump \ --enable-vipw \ --enable-write \ --with-audit \ + --with-bashcompletiondir=/etc/bash_completion.d \ --with-selinux%{!?with_selinux:=no} %{__make} @@ -960,6 +957,7 @@ fi %attr(755,root,root) /sbin/chcpu %attr(755,root,root) /sbin/ctrlaltdel %attr(755,root,root) /sbin/addpart +%attr(755,root,root) /sbin/blkdiscard %attr(755,root,root) /sbin/delpart %attr(755,root,root) /sbin/partx %attr(755,root,root) /bin/lsblk @@ -980,7 +978,6 @@ fi %attr(755,root,root) %{_bindir}/colrm %attr(755,root,root) %{_bindir}/column %attr(755,root,root) %{_bindir}/cytune -%attr(755,root,root) %{_bindir}/ddate %attr(755,root,root) %{_bindir}/eject %attr(755,root,root) %{_bindir}/flock %{?with_fallocate:%attr(755,root,root) %{_bindir}/fallocate} @@ -998,6 +995,7 @@ fi %attr(755,root,root) %{_bindir}/lslocks %attr(755,root,root) %{_bindir}/mcookie %attr(755,root,root) %{_bindir}/namei +%attr(755,root,root) %{_bindir}/nsenter %attr(755,root,root) %{_bindir}/pg %attr(755,root,root) %{_bindir}/prlimit %attr(755,root,root) %{_bindir}/raw @@ -1006,6 +1004,7 @@ fi %attr(755,root,root) %{_bindir}/rev %attr(755,root,root) %{_bindir}/script %attr(755,root,root) %{_bindir}/scriptreplay +%attr(755,root,root) %{_bindir}/setpriv %attr(755,root,root) %{_bindir}/setsid %attr(755,root,root) %{_bindir}/setterm %attr(755,root,root) %{_bindir}/tailf @@ -1028,7 +1027,6 @@ fi %{_mandir}/man1/colcrt.1* %{_mandir}/man1/colrm.1* %{_mandir}/man1/column.1* -%{_mandir}/man1/ddate.1* %{_mandir}/man1/dmesg.1* %{_mandir}/man1/eject.1* %{?with_fallocate:%{_mandir}/man1/fallocate.1*} @@ -1047,11 +1045,13 @@ fi %{_mandir}/man1/mcookie.1* %{_mandir}/man1/more.1* %{_mandir}/man1/namei.1* +%{_mandir}/man1/nsenter.1* %{_mandir}/man1/prlimit.1* %{_mandir}/man1/pg.1* %{_mandir}/man1/renice.1* %{_mandir}/man1/rev.1* %{_mandir}/man1/rename.1* +%{_mandir}/man1/setpriv.1* %{_mandir}/man1/setsid.1* %{_mandir}/man1/script.1* %{_mandir}/man1/scriptreplay.1* @@ -1064,6 +1064,7 @@ fi %{_mandir}/man1/whereis.1* %{_mandir}/man1/write.1* %{_mandir}/man8/addpart.8* +%{_mandir}/man8/blkdiscard.8* %{_mandir}/man8/delpart.8* %{_mandir}/man8/partx.8* %{_mandir}/man8/lsblk.8* @@ -1096,7 +1097,6 @@ fi %lang(es) %{_mandir}/es/man1/colrm.1* %lang(es) %{_mandir}/es/man1/column.1* -%lang(es) %{_mandir}/es/man1/ddate.1* %lang(es) %{_mandir}/es/man1/getopt.1* %lang(es) %{_mandir}/es/man1/look.1* %lang(es) %{_mandir}/es/man1/more.1* @@ -1166,7 +1166,6 @@ fi %lang(ja) %{_mandir}/ja/man1/colcrt.1* %lang(ja) %{_mandir}/ja/man1/colrm.1* %lang(ja) %{_mandir}/ja/man1/column.1* -%lang(ja) %{_mandir}/ja/man1/ddate.1* %lang(ja) %{_mandir}/ja/man1/getopt.1* %lang(ja) %{_mandir}/ja/man1/hexdump.1* %lang(ja) %{_mandir}/ja/man1/kill.1* @@ -1200,7 +1199,6 @@ fi %lang(ko) %{_mandir}/ko/man1/colcrt.1* %lang(ko) %{_mandir}/ko/man1/colrm.1* %lang(ko) %{_mandir}/ko/man1/column.1* -%lang(ko) %{_mandir}/ko/man1/ddate.1* %lang(ko) %{_mandir}/ko/man1/getopt.1* %lang(ko) %{_mandir}/ko/man1/hexdump.1* %lang(ko) %{_mandir}/ko/man1/kill.1* @@ -1251,8 +1249,6 @@ fi %lang(pl) %{_mandir}/pl/man8/mkswap.8* %lang(pl) %{_mandir}/pl/man8/renice.8* -%lang(ru) %{_mandir}/ru/man1/ddate.1* - %attr(755,root,root) /sbin/fdisk %attr(755,root,root) /sbin/fsck.minix %attr(755,root,root) /sbin/mkfs.minix @@ -1314,9 +1310,11 @@ fi %attr(755,root,root) /sbin/fsck.cramfs %attr(755,root,root) /sbin/mkfs.cramfs %attr(755,root,root) /sbin/mkfs.bfs +%{_mandir}/man8/fsck.cramfs.8* +%{_mandir}/man8/mkfs.cramfs.8* %if %{with su} -%attr(755,root,root) /bin/runuser +%attr(755,root,root) /sbin/runuser %attr(4755,root,root) /bin/su %attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/pam.d/runuser %attr(640,root,root) %config(noreplace) %verify(not md5 mtime size) /etc/pam.d/runuser-l @@ -1407,14 +1405,6 @@ fi %lang(ko) %{_mandir}/ko/man8/losetup.8* %lang(pl) %{_mandir}/pl/man8/losetup.8* -%files chkdupexe -%defattr(644,root,root,755) -%attr(755,root,root) %{_bindir}/chkdupexe -%{_mandir}/man1/chkdupexe.1* -%lang(ja) %{_mandir}/ja/man1/chkdupexe.1* -%lang(ko) %{_mandir}/ko/man1/chkdupexe.1* -%lang(pl) %{_mandir}/pl/man1/chkdupexe.1* - %files -n tunelp %defattr(644,root,root,755) %attr(755,root,root) %{_sbindir}/tunelp @@ -1486,6 +1476,10 @@ fi %defattr(644,root,root,755) %{_libdir}/libuuid.a +%files -n bash-completion-util-linux +%defattr(644,root,root,755) +/etc/bash_completion.d/* + %if %{with initrd} && %{with dietlibc} %files -n libuuid-dietlibc %defattr(644,root,root,755)