676 lines
20 KiB
Diff
676 lines
20 KiB
Diff
diff -upb shadow-4.1.0/libmisc/system.c.selinux shadow-4.1.0/libmisc/system.c
|
|
--- shadow-4.1.0/libmisc/system.c.selinux 2008-03-03 14:18:17.000000000 +0100
|
|
+++ shadow-4.1.0/libmisc/system.c 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -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);
|
|
+}
|
|
+
|
|
diff -upb shadow-4.1.0/libmisc/Makefile.am.selinux shadow-4.1.0/libmisc/Makefile.am
|
|
--- shadow-4.1.0/libmisc/Makefile.am.selinux 2007-11-23 10:15:48.000000000 +0100
|
|
+++ shadow-4.1.0/libmisc/Makefile.am 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -42,6 +42,7 @@ libmisc_a_SOURCES = \
|
|
setugid.c \
|
|
setupenv.c \
|
|
shell.c \
|
|
+ system.c \
|
|
strtoday.c \
|
|
sub.c \
|
|
sulog.c \
|
|
diff -upb shadow-4.1.0/libmisc/copydir.c.selinux shadow-4.1.0/libmisc/copydir.c
|
|
--- shadow-4.1.0/libmisc/copydir.c.selinux 2007-11-11 00:45:59.000000000 +0100
|
|
+++ shadow-4.1.0/libmisc/copydir.c 2008-03-03 14:19:01.000000000 +0100
|
|
@@ -54,7 +54,7 @@ struct link_name {
|
|
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;
|
|
|
|
@@ -199,7 +199,7 @@ int copy_tree (const char *src_root, con
|
|
if (strlen (src_root) + strlen (ent->d_name) + 2 >
|
|
sizeof src_name) {
|
|
err++;
|
|
- break;
|
|
+ break;
|
|
}
|
|
snprintf (src_name, sizeof src_name, "%s/%s", src_root,
|
|
ent->d_name);
|
|
@@ -207,7 +207,7 @@ int copy_tree (const char *src_root, con
|
|
if (strlen (dst_root) + strlen (ent->d_name) + 2 >
|
|
sizeof dst_name) {
|
|
err++;
|
|
- break;
|
|
+ break;
|
|
}
|
|
snprintf (dst_name, sizeof dst_name, "%s/%s", dst_root,
|
|
ent->d_name);
|
|
@@ -313,7 +313,7 @@ int copy_tree (const char *src_root, con
|
|
if (mknod (dst_name, sb.st_mode & ~07777, sb.st_rdev)
|
|
|| chown (dst_name,
|
|
uid == (uid_t) - 1 ? sb.st_uid : uid,
|
|
- gid == (gid_t) - 1 ? sb.st_gid : gid)
|
|
+ gid == (gid_t) - 1 ? sb.st_gid : gid)
|
|
|| chmod (dst_name, sb.st_mode & 07777)) {
|
|
err++;
|
|
break;
|
|
@@ -363,6 +363,10 @@ int copy_tree (const char *src_root, con
|
|
src_orig = 0;
|
|
dst_orig = 0;
|
|
}
|
|
+#ifdef WITH_SELINUX
|
|
+ /* Reset SELinux to create files with default contexts */
|
|
+ setfscreatecon (NULL);
|
|
+#endif
|
|
return err ? -1 : 0;
|
|
}
|
|
|
|
diff -upb shadow-4.1.0/man/usermod.8.xml.selinux shadow-4.1.0/man/usermod.8.xml
|
|
--- shadow-4.1.0/man/usermod.8.xml.selinux 2007-12-09 00:24:36.000000000 +0100
|
|
+++ shadow-4.1.0/man/usermod.8.xml 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -245,6 +245,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>
|
|
|
|
diff -upb shadow-4.1.0/man/useradd.8.selinux shadow-4.1.0/man/useradd.8
|
|
--- shadow-4.1.0/man/useradd.8.selinux 2008-03-03 14:14:45.000000000 +0100
|
|
+++ shadow-4.1.0/man/useradd.8 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -163,6 +163,11 @@ doesn\'t work yet\.
|
|
Allow the creation of a user account with a duplicate (non\-unique) UID\.
|
|
.RE
|
|
.PP
|
|
+\fB\-Z\fR, \fB\-\-selinux-user\fR \fISEUSER\fR
|
|
+.RS 4
|
|
+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\.
|
|
+.RE
|
|
+.PP
|
|
\fB\-p\fR, \fB\-\-password\fR \fIPASSWORD\fR
|
|
.RS 4
|
|
The encrypted password, as returned by
|
|
diff -upb shadow-4.1.0/man/usermod.8.selinux shadow-4.1.0/man/usermod.8
|
|
--- shadow-4.1.0/man/usermod.8.selinux 2007-12-10 00:07:16.000000000 +0100
|
|
+++ shadow-4.1.0/man/usermod.8 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -133,6 +133,11 @@ Note: if you wish to unlock the account
|
|
value from
|
|
\fI/etc/default/useradd\fR)\.
|
|
.RE
|
|
+.PP
|
|
+\fB\-Z\fR, \fB\-\-selinux-user\fR \fISEUSER\fR
|
|
+.RS 4
|
|
+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.
|
|
+.RE
|
|
.SH "CAVEATS"
|
|
.PP
|
|
|
|
diff -upb shadow-4.1.0/man/useradd.8.xml.selinux shadow-4.1.0/man/useradd.8.xml
|
|
--- shadow-4.1.0/man/useradd.8.xml.selinux 2007-12-09 00:24:36.000000000 +0100
|
|
+++ shadow-4.1.0/man/useradd.8.xml 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -273,6 +273,19 @@
|
|
between 0 and 999 are typically reserved for system accounts.
|
|
</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>
|
|
|
|
@@ -346,7 +359,7 @@
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
- </variablelist>
|
|
+ </variablelist>
|
|
|
|
</refsect2>
|
|
</refsect1>
|
|
@@ -399,7 +412,7 @@
|
|
|
|
<refsect1 id='files'>
|
|
<title>FILES</title>
|
|
- <variablelist>
|
|
+ <variablelist>
|
|
<varlistentry>
|
|
<term><filename>/etc/passwd</filename></term>
|
|
<listitem>
|
|
diff -upb shadow-4.1.0/lib/prototypes.h.selinux shadow-4.1.0/lib/prototypes.h
|
|
--- shadow-4.1.0/lib/prototypes.h.selinux 2007-11-23 21:10:52.000000000 +0100
|
|
+++ shadow-4.1.0/lib/prototypes.h 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -53,6 +53,9 @@ extern int is_listed (const char *, cons
|
|
/* 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 *);
|
|
@@ -151,6 +154,9 @@ extern void setup_env (struct passwd *);
|
|
/* 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 *);
|
|
|
|
diff -upb shadow-4.1.0/lib/defines.h.selinux shadow-4.1.0/lib/defines.h
|
|
--- shadow-4.1.0/lib/defines.h.selinux 2007-11-24 12:18:35.000000000 +0100
|
|
+++ shadow-4.1.0/lib/defines.h 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -342,4 +342,7 @@ extern char *strerror ();
|
|
#include <libaudit.h>
|
|
#endif
|
|
|
|
+#ifdef WITH_SELINUX
|
|
+#include <selinux/selinux.h>
|
|
+#endif
|
|
#endif /* _DEFINES_H_ */
|
|
diff -upb shadow-4.1.0/src/userdel.c.selinux shadow-4.1.0/src/userdel.c
|
|
--- shadow-4.1.0/src/userdel.c.selinux 2007-11-24 23:41:19.000000000 +0100
|
|
+++ shadow-4.1.0/src/userdel.c 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -809,6 +809,17 @@ int main (int argc, char **argv)
|
|
#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.
|
|
diff -upb shadow-4.1.0/src/usermod.c.selinux shadow-4.1.0/src/usermod.c
|
|
--- shadow-4.1.0/src/usermod.c.selinux 2007-11-24 23:41:19.000000000 +0100
|
|
+++ shadow-4.1.0/src/usermod.c 2008-03-03 14:18:17.000000000 +0100
|
|
@@ -90,6 +90,7 @@ static char *user_comment;
|
|
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;
|
|
@@ -139,6 +140,7 @@ static int sgr_locked = 0;
|
|
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);
|
|
@@ -250,12 +252,12 @@ static int get_groups (char *list)
|
|
#endif
|
|
|
|
if (ngroups == sys_ngroups) {
|
|
- fprintf (stderr,
|
|
+ fprintf (stderr,
|
|
_
|
|
("%s: too many groups specified (max %d).\n"),
|
|
Prog, ngroups);
|
|
break;
|
|
- }
|
|
+ }
|
|
|
|
/*
|
|
* Add the group name to the user's list of groups.
|
|
@@ -302,6 +304,9 @@ static void usage (void)
|
|
" -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
|
|
"\n"));
|
|
exit (E_USAGE);
|
|
}
|
|
@@ -332,7 +337,7 @@ static char *new_pw_passwd (char *pw_pas
|
|
"You should set a password with usermod -p to unlock this user account.\n"),
|
|
Prog);
|
|
return pw_pass;
|
|
- }
|
|
+ }
|
|
|
|
#ifdef WITH_AUDIT
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "updating password",
|
|
@@ -405,7 +410,7 @@ static void new_pwent (struct passwd *pw
|
|
#else
|
|
pwent->pw_gecos = user_comment;
|
|
#endif
|
|
- }
|
|
+ }
|
|
|
|
if (dflg) {
|
|
#ifdef WITH_AUDIT
|
|
@@ -826,7 +831,7 @@ static void process_flags (int argc, cha
|
|
user_comment = xstrdup (pwd->pw_gecos);
|
|
user_home = xstrdup (pwd->pw_dir);
|
|
user_shell = xstrdup (pwd->pw_shell);
|
|
- }
|
|
+ }
|
|
#ifdef WITH_AUDIT
|
|
user_newname = user_name;
|
|
user_newid = user_id;
|
|
@@ -888,13 +893,20 @@ static void process_flags (int argc, cha
|
|
{"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':
|
|
@@ -966,7 +978,7 @@ static void process_flags (int argc, cha
|
|
fprintf (stderr,
|
|
_("%s: unknown group %s\n"),
|
|
Prog, optarg);
|
|
- exit (E_NOTFOUND);
|
|
+ exit (E_NOTFOUND);
|
|
}
|
|
user_newgid = grp->gr_gid;
|
|
gflg++;
|
|
@@ -1028,6 +1040,16 @@ static void process_flags (int argc, cha
|
|
case 'U':
|
|
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 ();
|
|
}
|
|
@@ -1040,7 +1062,7 @@ static void process_flags (int argc, cha
|
|
exit (E_USAGE);
|
|
}
|
|
if (!is_shadow_pwd && (eflg || fflg)) {
|
|
- fprintf (stderr,
|
|
+ fprintf (stderr,
|
|
_
|
|
("%s: shadow passwords required for -e and -f\n"),
|
|
Prog);
|
|
@@ -1575,6 +1597,8 @@ int main (int argc, char **argv)
|
|
nscd_flush_cache ("passwd");
|
|
nscd_flush_cache ("group");
|
|
|
|
+ selinux_update_mapping();
|
|
+
|
|
if (mflg)
|
|
move_home ();
|
|
|
|
@@ -1603,3 +1627,62 @@ int main (int argc, char **argv)
|
|
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;
|
|
+ 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
|
|
+ }
|
|
+
|
|
+ argv[0] = "/sbin/restorecon";
|
|
+ argv[1] = "-F";
|
|
+ argv[2] = "-R";
|
|
+ argv[3] = user_home;
|
|
+ argv[4] = 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
|
|
+}
|
|
diff -upb shadow-4.1.0/src/useradd.c.selinux shadow-4.1.0/src/useradd.c
|
|
--- shadow-4.1.0/src/useradd.c.selinux 2008-03-03 14:14:45.000000000 +0100
|
|
+++ shadow-4.1.0/src/useradd.c 2008-03-03 14:19:01.000000000 +0100
|
|
@@ -100,6 +100,7 @@ static const char *user_comment = "";
|
|
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 set_defaults (void);
|
|
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 *);
|
|
@@ -356,6 +358,7 @@ static void get_defaults (void)
|
|
def_create_mail_spool = xstrdup (cp);
|
|
}
|
|
}
|
|
+ fclose(fp);
|
|
}
|
|
|
|
/*
|
|
@@ -586,7 +589,7 @@ static int get_groups (char *list)
|
|
#endif
|
|
|
|
if (ngroups == sys_ngroups) {
|
|
- fprintf (stderr,
|
|
+ fprintf (stderr,
|
|
_
|
|
("%s: too many groups specified (max %d).\n"),
|
|
Prog, ngroups);
|
|
@@ -644,6 +647,10 @@ static void usage (void)
|
|
" 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"
|
|
+#ifdef WITH_SELINUX
|
|
+ " -Z, --selinux-user SEUSER use a specific SEUSER for the SELinux user mapping\n"
|
|
+#endif
|
|
+
|
|
"\n"));
|
|
exit (E_USAGE);
|
|
}
|
|
@@ -696,7 +703,7 @@ static void new_spent (struct spwd *spen
|
|
spent->sp_warn = scale_age (getdef_num ("PASS_WARN_AGE", -1));
|
|
spent->sp_inact = scale_age (def_inactive);
|
|
spent->sp_expire = scale_age (user_expire);
|
|
- }
|
|
+ }
|
|
else {
|
|
spent->sp_min = scale_age(-1);
|
|
spent->sp_max = scale_age(-1);
|
|
@@ -1030,32 +1037,39 @@ static void process_flags (int argc, cha
|
|
{"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 =
|
|
+#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':
|
|
if (!VALID (optarg)
|
|
|| optarg[0] != '/') {
|
|
- fprintf (stderr,
|
|
+ fprintf (stderr,
|
|
_
|
|
("%s: invalid base directory '%s'\n"),
|
|
Prog, optarg);
|
|
- exit (E_BAD_ARG);
|
|
+ exit (E_BAD_ARG);
|
|
}
|
|
def_home = optarg;
|
|
bflg++;
|
|
break;
|
|
case 'c':
|
|
if (!VALID (optarg)) {
|
|
- fprintf (stderr,
|
|
+ fprintf (stderr,
|
|
_
|
|
("%s: invalid comment '%s'\n"),
|
|
Prog, optarg);
|
|
- exit (E_BAD_ARG);
|
|
+ exit (E_BAD_ARG);
|
|
}
|
|
user_comment = optarg;
|
|
cflg++;
|
|
@@ -1063,11 +1077,11 @@ static void process_flags (int argc, cha
|
|
case 'd':
|
|
if (!VALID (optarg)
|
|
|| optarg[0] != '/') {
|
|
- fprintf (stderr,
|
|
+ fprintf (stderr,
|
|
_
|
|
("%s: invalid home directory '%s'\n"),
|
|
Prog, optarg);
|
|
- exit (E_BAD_ARG);
|
|
+ exit (E_BAD_ARG);
|
|
}
|
|
user_home = optarg;
|
|
dflg++;
|
|
@@ -1161,7 +1175,7 @@ static void process_flags (int argc, cha
|
|
_
|
|
("%s: -K requires KEY=VALUE\n"),
|
|
Prog);
|
|
- exit (E_BAD_ARG);
|
|
+ exit (E_BAD_ARG);
|
|
}
|
|
/* terminate name, point to value */
|
|
*cp++ = '\0';
|
|
@@ -1215,6 +1229,17 @@ static void process_flags (int argc, cha
|
|
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 ();
|
|
}
|
|
@@ -1238,7 +1263,7 @@ static void process_flags (int argc, cha
|
|
*/
|
|
if (Dflg) {
|
|
if (optind != argc)
|
|
- usage ();
|
|
+ usage ();
|
|
|
|
if (uflg || oflg || Gflg || dflg || cflg || mflg)
|
|
usage ();
|
|
@@ -1253,7 +1278,7 @@ static void process_flags (int argc, cha
|
|
("%s: invalid user name '%s'\n"),
|
|
Prog, user_name);
|
|
#ifdef WITH_AUDIT
|
|
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
|
|
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
|
|
user_name, -1, 0);
|
|
#endif
|
|
exit (E_BAD_ARG);
|
|
@@ -1583,6 +1608,33 @@ static void usr_update (void)
|
|
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
|
|
*
|
|
@@ -1592,7 +1644,11 @@ static void usr_update (void)
|
|
*/
|
|
static void create_home (void)
|
|
{
|
|
+
|
|
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)) {
|
|
fprintf (stderr,
|
|
@@ -1614,6 +1670,10 @@ static void create_home (void)
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
"adding home directory", user_name, user_id, 1);
|
|
#endif
|
|
+#ifdef WITH_SELINUX
|
|
+ /* Reset SELinux to create files with default contexts */
|
|
+ setfscreatecon (NULL);
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
@@ -1847,6 +1907,8 @@ int main (int argc, char **argv)
|
|
|
|
close_files ();
|
|
|
|
+ selinux_update_mapping();
|
|
+
|
|
nscd_flush_cache ("passwd");
|
|
nscd_flush_cache ("group");
|
|
|