- Fix execution and creation of Home Directories under SELinux
- Resolves: rhbz#217441
This commit is contained in:
parent
8abc852df0
commit
eba9b69bbf
@ -1,46 +1,466 @@
|
||||
diff -rup shadow-4.0.17-orig/src/useradd.c shadow-4.0.17/src/useradd.c
|
||||
--- shadow-4.0.17-orig/src/useradd.c 2006-11-29 18:31:43.000000000 -0500
|
||||
+++ shadow-4.0.17/src/useradd.c 2006-11-29 21:38:22.000000000 -0500
|
||||
@@ -45,6 +45,9 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
--- shadow-4.0.17/src/useradd.c.useradd 2006-12-21 09:14:45.000000000 -0500
|
||||
+++ shadow-4.0.17/src/useradd.c 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -100,6 +100,7 @@
|
||||
static const char *user_home = "";
|
||||
static const char *user_shell = "";
|
||||
static const char *create_mail_spool = "";
|
||||
+static const char *user_selinux = "";
|
||||
|
||||
static long user_expire = -1;
|
||||
static int is_shadow_pwd;
|
||||
@@ -170,6 +171,7 @@
|
||||
static int get_groups (char *);
|
||||
static void usage (void);
|
||||
static void new_pwent (struct passwd *);
|
||||
+static void selinux_update_mapping (void);
|
||||
|
||||
static long scale_age (long);
|
||||
static void new_spent (struct spwd *);
|
||||
@@ -361,6 +363,7 @@
|
||||
def_create_mail_spool = xstrdup (cp);
|
||||
}
|
||||
}
|
||||
+ fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -648,7 +651,10 @@
|
||||
" -p, --password PASSWORD use encrypted password for the new user\n"
|
||||
" account\n"
|
||||
" -s, --shell SHELL the login shell for the new user account\n"
|
||||
- " -u, --uid UID force use the UID for the new user account\n"
|
||||
+ " -u, --uid UID force use the UID for the new user account\n"
|
||||
+#ifdef WITH_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+ " -Z, --selinux-user SEUSER use a specific SEUSER for the SELinux user mapping\n"
|
||||
+#endif
|
||||
#include "chkname.h"
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
@@ -1612,6 +1615,9 @@ static void usr_update (void)
|
||||
"\n"));
|
||||
exit (E_USAGE);
|
||||
}
|
||||
@@ -1048,11 +1054,18 @@
|
||||
{"non-unique", no_argument, NULL, 'o'},
|
||||
{"password", required_argument, NULL, 'p'},
|
||||
{"shell", required_argument, NULL, 's'},
|
||||
+#ifdef WITH_SELINUX
|
||||
+ {"selinux-user", required_argument, NULL, 'Z'},
|
||||
+#endif
|
||||
{"uid", required_argument, NULL, 'u'},
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
while ((c =
|
||||
- getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:mlMnrop:s:u:",
|
||||
+#ifdef WITH_SELINUX
|
||||
+ getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:mlMnrop:s:u:Z:",
|
||||
+#else
|
||||
+ getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:mlMnrop:s:u",
|
||||
+#endif
|
||||
long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
@@ -1236,6 +1249,17 @@
|
||||
case 'M':
|
||||
Mflg++;
|
||||
break;
|
||||
+#ifdef WITH_SELINUX
|
||||
+ case 'Z':
|
||||
+ if (is_selinux_enabled() > 0)
|
||||
+ user_selinux = optarg;
|
||||
+ else {
|
||||
+ fprintf (stderr,_("%s: -Z requires SELinux enabled kernel\n"), Prog);
|
||||
+
|
||||
+ exit (E_BAD_ARG);
|
||||
+ }
|
||||
+ break;
|
||||
+#endif
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
@@ -1603,6 +1628,33 @@
|
||||
grp_update ();
|
||||
}
|
||||
|
||||
+static void selinux_update_mapping () {
|
||||
+
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (is_selinux_enabled() <= 0) return;
|
||||
+
|
||||
+ if (*user_selinux) { /* must be done after passwd write() */
|
||||
+ const char *argv[7];
|
||||
+ argv[0] = "/usr/sbin/semanage";
|
||||
+ argv[1] = "login";
|
||||
+ argv[2] = "-a";
|
||||
+ argv[3] = "-s";
|
||||
+ argv[4] = user_selinux;
|
||||
+ argv[5] = user_name;
|
||||
+ argv[6] = NULL;
|
||||
+ if (safe_system(argv[0], argv, NULL, 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"),
|
||||
+ Prog, user_name, user_selinux);
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
+ "adding SELinux user mapping", user_name, user_id, 0);
|
||||
+#endif
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+}
|
||||
/*
|
||||
* create_home - create the user's home directory
|
||||
*
|
||||
@@ -1612,7 +1664,11 @@
|
||||
*/
|
||||
static void create_home (void)
|
||||
{
|
||||
+ mode_t mode = 0;
|
||||
+
|
||||
+ mode = 0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK);
|
||||
if (access (user_home, F_OK)) {
|
||||
+#ifdef WITH_SELINUX
|
||||
+ selinux_file_context (user_home);
|
||||
+#endif
|
||||
/* XXX - create missing parent directories. --marekm */
|
||||
if (mkdir (user_home, 0)) {
|
||||
@@ -1625,9 +1631,19 @@ static void create_home (void)
|
||||
#endif
|
||||
fail_exit (E_HOMEDIR);
|
||||
}
|
||||
+#ifdef WITH_SELINUX
|
||||
+ {
|
||||
+ security_context_t con = NULL;
|
||||
fprintf (stderr,
|
||||
@@ -1840,6 +1896,15 @@
|
||||
|
||||
usr_update ();
|
||||
|
||||
+ create_mail ();
|
||||
+
|
||||
+ if (!matchpathcon(user_home, mode, &con))
|
||||
+ {
|
||||
+ setfilecon(user_home, con);
|
||||
+ freecon(con);
|
||||
+ }
|
||||
+ }
|
||||
+ nscd_flush_cache ("passwd");
|
||||
+ nscd_flush_cache ("group");
|
||||
+
|
||||
+ close_files ();
|
||||
+
|
||||
+ selinux_update_mapping();
|
||||
+
|
||||
if (mflg) {
|
||||
create_home ();
|
||||
if (home_added)
|
||||
@@ -1863,13 +1928,6 @@
|
||||
* with --gafton
|
||||
*/
|
||||
|
||||
- create_mail ();
|
||||
-
|
||||
- nscd_flush_cache ("passwd");
|
||||
- nscd_flush_cache ("group");
|
||||
-
|
||||
- close_files ();
|
||||
-
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
--- shadow-4.0.17/src/userdel.c.useradd 2006-12-21 09:14:45.000000000 -0500
|
||||
+++ shadow-4.0.17/src/userdel.c 2006-12-21 09:20:56.000000000 -0500
|
||||
@@ -792,6 +792,17 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ if (is_selinux_enabled() > 0) {
|
||||
+ const char *argv[5];
|
||||
+ argv[0] = "/usr/sbin/semanage";
|
||||
+ argv[1] = "login";
|
||||
+ argv[2] = "-d";
|
||||
+ argv[3] = user_name;
|
||||
+ argv[4] = NULL;
|
||||
+ safe_system(argv[0], argv, NULL, 1);
|
||||
+ }
|
||||
+#endif
|
||||
/*
|
||||
* Cancel any crontabs or at jobs. Have to do this before we remove
|
||||
* the entry from /etc/passwd.
|
||||
--- shadow-4.0.17/src/usermod.c.useradd 2006-12-21 09:14:45.000000000 -0500
|
||||
+++ shadow-4.0.17/src/usermod.c 2006-12-21 09:20:28.000000000 -0500
|
||||
@@ -90,6 +90,7 @@
|
||||
static char *user_home;
|
||||
static char *user_newhome;
|
||||
static char *user_shell;
|
||||
+static const char *user_selinux = "";
|
||||
static long user_expire;
|
||||
static long user_inactive;
|
||||
static long sys_ngroups;
|
||||
@@ -132,6 +133,7 @@
|
||||
static int get_groups (char *);
|
||||
static void usage (void);
|
||||
static void new_pwent (struct passwd *);
|
||||
+static void selinux_update_mapping (void);
|
||||
|
||||
static void new_spent (struct spwd *);
|
||||
static void fail_exit (int);
|
||||
@@ -301,6 +303,9 @@
|
||||
" -s, --shell SHELL new login shell for the user account\n"
|
||||
" -u, --uid UID new UID for the user account\n"
|
||||
" -U, --unlock unlock the user account\n"
|
||||
+#ifdef WITH_SELINUX
|
||||
+ " -Z, --selinux-user new selinux user mapping for the user account\n"
|
||||
+#endif
|
||||
chown (user_home, user_id, user_gid);
|
||||
- chmod (user_home,
|
||||
- 0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK));
|
||||
+ chmod (user_home, mode);
|
||||
home_added++;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
Only in shadow-4.0.17/src: useradd.c.useradd
|
||||
"\n"));
|
||||
exit (E_USAGE);
|
||||
}
|
||||
@@ -925,13 +930,20 @@
|
||||
{"move-home", no_argument, NULL, 'm'},
|
||||
{"non-unique", no_argument, NULL, 'o'},
|
||||
{"password", required_argument, NULL, 'p'},
|
||||
+#ifdef WITH_SELINUX
|
||||
+ {"selinux-user", required_argument, NULL, 'Z'},
|
||||
+#endif
|
||||
{"shell", required_argument, NULL, 's'},
|
||||
{"uid", required_argument, NULL, 'u'},
|
||||
{"unlock", no_argument, NULL, 'U'},
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
while ((c =
|
||||
+#ifdef WITH_SELINUX
|
||||
+ getopt_long (argc, argv, "ac:d:e:f:g:G:hl:Lmop:s:u:UZ:",
|
||||
+#else
|
||||
getopt_long (argc, argv, "ac:d:e:f:g:G:hl:Lmop:s:u:U",
|
||||
+#endif
|
||||
long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
@@ -1080,6 +1092,16 @@
|
||||
|
||||
Uflg++;
|
||||
break;
|
||||
+#ifdef WITH_SELINUX
|
||||
+ case 'Z':
|
||||
+ if (is_selinux_enabled() > 0)
|
||||
+ user_selinux = optarg;
|
||||
+ else {
|
||||
+ fprintf (stderr, _("%s: -Z requires SELinux enabled kernel\n"), Prog);
|
||||
+ exit (E_BAD_ARG);
|
||||
+ }
|
||||
+ break;
|
||||
+#endif
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
@@ -1549,6 +1571,8 @@
|
||||
if (Gflg || lflg)
|
||||
grp_err = grp_update ();
|
||||
|
||||
+ selinux_update_mapping();
|
||||
+
|
||||
if (mflg)
|
||||
move_home ();
|
||||
|
||||
@@ -1580,3 +1604,56 @@
|
||||
exit (E_SUCCESS);
|
||||
/* NOT REACHED */
|
||||
}
|
||||
+
|
||||
+static void selinux_update_mapping () {
|
||||
+#ifdef WITH_SELINUX
|
||||
+ const char *argv[7];
|
||||
+
|
||||
+ if (is_selinux_enabled() <= 0) return;
|
||||
+
|
||||
+ if (*user_selinux) {
|
||||
+ argv[0] = "/usr/sbin/semanage";
|
||||
+ argv[1] = "login";
|
||||
+ argv[2] = "-m";
|
||||
+ argv[3] = "-s";
|
||||
+ argv[4] = user_selinux;
|
||||
+ argv[5] = user_name;
|
||||
+ argv[6] = NULL;
|
||||
+ if (safe_system(argv[0], argv, NULL, 1)) {
|
||||
+ argv[2] = "-a";
|
||||
+ if (safe_system(argv[0], argv, NULL, 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"),
|
||||
+ Prog, user_name, user_selinux);
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
+ "modifying User mapping ", user_name, user_id, 0);
|
||||
+#endif
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (dflg && !user_selinux) {
|
||||
+ argv[0] = "/usr/sbin/genhomedircon";
|
||||
+ argv[1] = NULL;
|
||||
+ safe_system(argv[0], argv, NULL,0);
|
||||
+ }
|
||||
+
|
||||
+ if (!mflg) {
|
||||
+ argv[0] = "/sbin/restorecon";
|
||||
+ argv[1] = "-R";
|
||||
+ argv[2] = user_home;
|
||||
+ argv[3] = NULL;
|
||||
+ if (safe_system(argv[0], argv, NULL, 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: warning: unable to relabel the homedir %s for %s.\n"),
|
||||
+ Prog, user_home, user_name);
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
+ "relabeling home directory", user_name, user_id, 0);
|
||||
+#endif
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
--- shadow-4.0.17/man/usermod.8.xml.useradd 2006-06-16 12:11:04.000000000 -0400
|
||||
+++ shadow-4.0.17/man/usermod.8.xml 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -226,6 +226,19 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ <option>-Z</option>, <option>--selinux-user</option>
|
||||
+ <replaceable>SEUSER</replaceable>
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The SELinux user for the user's login. The default is to leave this
|
||||
+ field the blank, which causes the system to select the default
|
||||
+ SELinux user.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
--- shadow-4.0.17/man/useradd.8.xml.useradd 2006-06-16 12:11:04.000000000 -0400
|
||||
+++ shadow-4.0.17/man/useradd.8.xml 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -251,6 +251,19 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ <option>-Z</option>, <option>--selinux-user</option>
|
||||
+ <replaceable>SEUSER</replaceable>
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The SELinux user for the user's login. The default is to leave this
|
||||
+ field blank, which causes the system to select the default SELinux
|
||||
+ user.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<refsect2 id='changing_the_default_values'>
|
||||
--- shadow-4.0.17/man/useradd.8.useradd 2006-12-21 09:14:45.000000000 -0500
|
||||
+++ shadow-4.0.17/man/useradd.8 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -137,6 +137,9 @@
|
||||
The numerical value of the user's ID. This value must be unique, unless the
|
||||
\fB\-o\fR
|
||||
option is used. The value must be non\-negative. The default is to use the smallest ID value greater than 999 and greater than every other user. Values between 0 and 999 are typically reserved for system accounts.
|
||||
+.TP 3n
|
||||
+\fB\-Z\fR, \fB\-\-selinux-user\fR \fISEUSER\fR
|
||||
+The SELinux user for the user's login. The default is to leave this field blank, which causes the system to select the default SELinux user.
|
||||
.SS "Changing the default values"
|
||||
.PP
|
||||
When invoked with the
|
||||
--- shadow-4.0.17/man/usermod.8.useradd 2006-12-21 09:14:45.000000000 -0500
|
||||
+++ shadow-4.0.17/man/usermod.8 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -90,6 +90,10 @@
|
||||
\fB\-p\fR
|
||||
or
|
||||
\fB\-L\fR.
|
||||
+.TP 3n
|
||||
+\fB\-Z\fR, \fB\-\-selinux-user\fR \fISEUSER\fR
|
||||
+The SELinux user for the user's login. The default is to leave this field blank, which causes the system to select the default SELinux user.
|
||||
+
|
||||
.SH "CAVEATS"
|
||||
.PP
|
||||
|
||||
--- /dev/null 2006-12-21 08:27:04.805433018 -0500
|
||||
+++ shadow-4.0.17/libmisc/system.c 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -0,0 +1,37 @@
|
||||
+#include <config.h>
|
||||
+
|
||||
+#ident "$Id: shell.c,v 1.13 2006/01/18 19:38:27 kloczek Exp $"
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <sys/wait.h>
|
||||
+#include <fcntl.h>
|
||||
+#include "prototypes.h"
|
||||
+#include "defines.h"
|
||||
+
|
||||
+int safe_system(const char *command, const char *argv[], const char *env[], int ignore_stderr)
|
||||
+{
|
||||
+ int status = -1;
|
||||
+ int fd;
|
||||
+ pid_t pid;
|
||||
+
|
||||
+ pid = fork();
|
||||
+ if (pid < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (pid) { /* Parent */
|
||||
+ waitpid(pid, &status, 0);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ fd = open("/dev/null", O_RDWR);
|
||||
+ /* Child */
|
||||
+ dup2(fd,0); // Close Stdin
|
||||
+ if (ignore_stderr)
|
||||
+ dup2(fd,2); // Close Stderr
|
||||
+
|
||||
+ execve(command, (char *const *) argv, (char *const *) env);
|
||||
+ fprintf (stderr,
|
||||
+ _("Failed to exec '%s'\n"), argv[0]);
|
||||
+ exit (-1);
|
||||
+}
|
||||
+
|
||||
--- shadow-4.0.17/libmisc/Makefile.am.useradd 2005-09-05 12:21:37.000000000 -0400
|
||||
+++ shadow-4.0.17/libmisc/Makefile.am 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -41,6 +41,7 @@
|
||||
setugid.c \
|
||||
setupenv.c \
|
||||
shell.c \
|
||||
+ system.c \
|
||||
strtoday.c \
|
||||
sub.c \
|
||||
sulog.c \
|
||||
--- shadow-4.0.17/libmisc/copydir.c.useradd 2006-07-10 00:35:56.000000000 -0400
|
||||
+++ shadow-4.0.17/libmisc/copydir.c 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -54,7 +54,7 @@
|
||||
static struct link_name *links;
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
-static int selinux_file_context (const char *dst_name)
|
||||
+int selinux_file_context (const char *dst_name)
|
||||
{
|
||||
security_context_t scontext = NULL;
|
||||
|
||||
--- shadow-4.0.17/lib/prototypes.h.useradd 2006-02-07 11:36:30.000000000 -0500
|
||||
+++ shadow-4.0.17/lib/prototypes.h 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -52,6 +52,9 @@
|
||||
/* copydir.c */
|
||||
extern int copy_tree (const char *, const char *, uid_t, gid_t);
|
||||
extern int remove_tree (const char *);
|
||||
+#ifdef WITH_SELINUX
|
||||
+extern int selinux_file_context (const char *dst_name);
|
||||
+#endif
|
||||
|
||||
/* encrypt.c */
|
||||
extern char *pw_encrypt (const char *, const char *);
|
||||
@@ -147,6 +150,9 @@
|
||||
/* shell.c */
|
||||
extern int shell (const char *, const char *, char *const *);
|
||||
|
||||
+/* system.c */
|
||||
+extern int safe_system(const char *command, const char *argv[], const char *env[], int ignore_stderr);
|
||||
+
|
||||
/* strtoday.c */
|
||||
extern long strtoday (const char *);
|
||||
|
||||
--- shadow-4.0.17/lib/defines.h.useradd 2005-09-05 12:22:03.000000000 -0400
|
||||
+++ shadow-4.0.17/lib/defines.h 2006-12-21 09:14:45.000000000 -0500
|
||||
@@ -342,4 +342,7 @@
|
||||
#include <libaudit.h>
|
||||
#endif
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#endif
|
||||
#endif /* _DEFINES_H_ */
|
||||
|
@ -5,7 +5,7 @@
|
||||
Summary: Utilities for managing accounts and shadow password files
|
||||
Name: shadow-utils
|
||||
Version: 4.0.18.1
|
||||
Release: 7%{?dist}
|
||||
Release: 8%{?dist}
|
||||
Epoch: 2
|
||||
URL: http://shadow.pld.org.pl/
|
||||
Source0: ftp://ftp.pld.org.pl/software/shadow/shadow-%{version}.tar.bz2
|
||||
|
Loading…
Reference in New Issue
Block a user