This commit is contained in:
Peter Vrabec 2009-04-14 10:19:14 +00:00
parent eab8b43860
commit ea53f7cab2
16 changed files with 141 additions and 2150 deletions

View file

@ -1,4 +1,3 @@
shadow-4.0.17-login.defs shadow-4.0.17-login.defs
shadow-4.0.18.1-useradd shadow-4.0.18.1-useradd
shadow-4.1.1.tar.bz2 shadow-4.1.3.tar.bz2
shadow-4.1.2.tar.bz2

View file

@ -1,58 +0,0 @@
# *REQUIRED*
# Directory where mailboxes reside, _or_ name of file, relative to the
# home directory. If you _do_ define both, MAIL_DIR takes precedence.
# QMAIL_DIR is for Qmail
#
#QMAIL_DIR Maildir
MAIL_DIR /var/spool/mail
#MAIL_FILE .mail
# Password aging controls:
#
# PASS_MAX_DAYS Maximum number of days a password may be used.
# PASS_MIN_DAYS Minimum number of days allowed between password changes.
# PASS_MIN_LEN Minimum acceptable password length.
# PASS_WARN_AGE Number of days warning given before a password expires.
#
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
PASS_WARN_AGE 7
#
# Min/max values for automatic uid selection in useradd
#
UID_MIN 500
UID_MAX 60000
#
# Min/max values for automatic gid selection in groupadd
#
GID_MIN 500
GID_MAX 60000
#
# If defined, this command is run when removing a user.
# It should remove any at/cron/print jobs etc. owned by
# the user to be removed (passed as the first argument).
#
#USERDEL_CMD /usr/sbin/userdel_local
#
# If useradd should create home directories for users by default
# On RH systems, we do. This option is overridden with the -m flag on
# useradd command line.
#
CREATE_HOME yes
# The permission mask is initialized to this value. If not specified,
# the permission mask will be initialized to 022.
UMASK 077
# This enables userdel to remove user groups if no members exist.
#
USERGROUPS_ENAB yes
# Use MD5 or DES to encrypt password? Red Hat use MD5 by default.
MD5_CRYPT_ENAB yes

View file

@ -1,33 +0,0 @@
diff -up shadow-4.1.1/src/usermod.c.selinux-user shadow-4.1.1/src/usermod.c
--- shadow-4.1.1/src/usermod.c.selinux-user 2008-09-09 17:28:45.673915250 +0200
+++ shadow-4.1.1/src/usermod.c 2008-09-09 17:35:39.000000000 +0200
@@ -116,6 +116,7 @@ static int
oflg = 0, /* permit non-unique user ID to be specified with -u */
pflg = 0, /* new encrypted password */
sflg = 0, /* new shell program */
+ Sflg = 0, /* new selinux user */
uflg = 0, /* specify new user ID */
Uflg = 0; /* unlock the password */
@@ -967,8 +968,10 @@ static void process_flags (int argc, cha
break;
#ifdef WITH_SELINUX
case 'Z':
- if (is_selinux_enabled() > 0)
- user_selinux = optarg;
+ if (is_selinux_enabled() > 0) {
+ user_selinux = optarg;
+ Sflg++;
+ }
else {
fprintf (stderr, _("%s: -Z requires SELinux enabled kernel\n"), Prog);
exit (E_BAD_ARG);
@@ -1015,7 +1018,7 @@ static void process_flags (int argc, cha
}
if (Uflg + uflg + sflg + pflg + oflg + mflg + Lflg + lflg + Gflg +
- gflg + fflg + eflg + dflg + cflg == 0) {
+ gflg + fflg + eflg + dflg + cflg + Sflg == 0) {
fprintf (stderr, _("%s: no changes\n"), Prog);
exit (E_SUCCESS);
}

View file

@ -1,447 +0,0 @@
diff -urp shadow-4.1.2.orig/src/groupadd.c shadow-4.1.2/src/groupadd.c
--- shadow-4.1.2.orig/src/groupadd.c 2008-09-02 08:31:11.000000000 -0400
+++ shadow-4.1.2/src/groupadd.c 2008-09-02 09:05:14.000000000 -0400
@@ -205,7 +205,7 @@ static void grp_update (void)
}
#endif /* SHADOWGRP */
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding group", group_name,
+ audit_logger (AUDIT_ADD_GROUP, Prog, "adding group", group_name,
group_id, 1);
#endif
SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u",
@@ -269,7 +269,7 @@ static void open_files (void)
if (!gr_lock ()) {
fprintf (stderr, _("%s: unable to lock group file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "locking group file",
+ audit_logger (AUDIT_ADD_GROUP, Prog, "locking group file",
group_name, -1, 0);
#endif
exit (E_GRP_UPDATE);
@@ -277,7 +277,7 @@ static void open_files (void)
if (!gr_open (O_RDWR)) {
fprintf (stderr, _("%s: unable to open group file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "opening group file",
+ audit_logger (AUDIT_ADD_GROUP, Prog, "opening group file",
group_name, -1, 0);
#endif
fail_exit (E_GRP_UPDATE);
@@ -310,7 +310,7 @@ static void fail_exit (int code)
#ifdef WITH_AUDIT
if (code != E_SUCCESS) {
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding group",
+ audit_logger (AUDIT_ADD_GROUP, Prog, "adding group",
group_name, -1, 0);
}
#endif
diff -urp shadow-4.1.2.orig/src/groupdel.c shadow-4.1.2/src/groupdel.c
--- shadow-4.1.2.orig/src/groupdel.c 2008-09-02 08:31:11.000000000 -0400
+++ shadow-4.1.2/src/groupdel.c 2008-09-02 09:04:18.000000000 -0400
@@ -100,7 +100,7 @@ static void fail_exit (int code)
#endif
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group",
+ audit_logger (AUDIT_DEL_GROUP, Prog, "deleting group",
group_name, -1, 0);
#endif
@@ -143,7 +143,7 @@ static void grp_update (void)
static void close_files (void)
{
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group", group_name,
+ audit_logger (AUDIT_DEL_GROUP, Prog, "deleting group", group_name,
group_id, 1);
#endif
SYSLOG ((LOG_INFO, "remove group `%s'\n", group_name));
@@ -316,7 +316,7 @@ int main (int argc, char **argv)
fprintf (stderr, _("%s: group %s does not exist\n"),
Prog, group_name);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_GROUP, Prog,
"deleting group",
group_name, -1, 0);
#endif
@@ -338,7 +338,7 @@ int main (int argc, char **argv)
Prog, group_name);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group",
+ audit_logger (AUDIT_DEL_GROUP, Prog, "deleting group",
group_name, -1, 0);
#endif
if (!yp_get_default_domain (&nis_domain) &&
diff -urp shadow-4.1.2.orig/src/useradd.c shadow-4.1.2/src/useradd.c
--- shadow-4.1.2.orig/src/useradd.c 2008-09-02 08:31:11.000000000 -0400
+++ shadow-4.1.2/src/useradd.c 2008-09-02 08:47:31.000000000 -0400
@@ -216,7 +216,7 @@ static void fail_exit (int code)
#endif
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user", user_name, -1,
+ audit_logger (AUDIT_ADD_USER, Prog, "adding user", user_name, -1,
0);
#endif
SYSLOG ((LOG_INFO, "failed adding user `%s', data deleted", user_name));
@@ -793,7 +793,7 @@ static void grp_update (void)
fail_exit (E_GRP_UPDATE);
}
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"adding user to group", user_name, -1, 1);
#endif
SYSLOG ((LOG_INFO, "add `%s' to group `%s'",
@@ -844,7 +844,7 @@ static void grp_update (void)
fail_exit (E_GRP_UPDATE);
}
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"adding user to shadow group", user_name, -1, 1);
#endif
SYSLOG ((LOG_INFO, "add `%s' to shadow group `%s'",
@@ -1162,7 +1162,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_ADD_USER, Prog, "adding user",
user_name, -1, 0);
#endif
exit (E_BAD_ARG);
@@ -1251,7 +1251,7 @@ static void open_files (void)
if (!pw_lock ()) {
fprintf (stderr, _("%s: unable to lock password file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"locking password file", user_name, user_id, 0);
#endif
exit (E_PW_UPDATE);
@@ -1260,7 +1260,7 @@ static void open_files (void)
if (!pw_open (O_RDWR)) {
fprintf (stderr, _("%s: unable to open password file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"opening password file", user_name, user_id, 0);
#endif
fail_exit (E_PW_UPDATE);
@@ -1271,7 +1271,7 @@ static void open_files (void)
_("%s: cannot lock shadow password file\n"),
Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"locking shadow password file", user_name,
user_id, 0);
#endif
@@ -1283,7 +1283,7 @@ static void open_files (void)
_("%s: cannot open shadow password file\n"),
Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"opening shadow password file", user_name,
user_id, 0);
#endif
@@ -1385,6 +1385,10 @@ static void grp_add (void)
* Write out the new group file entry.
*/
if (!gr_update (&grp)) {
+#ifdef WITH_AUDIT
+ audit_logger (AUDIT_ADD_GROUP, Prog,
+ "adding group", grp.gr_name, -1, 0);
+#endif
fprintf (stderr, _("%s: error adding new group entry\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
@@ -1393,11 +1397,19 @@ static void grp_add (void)
* Write out the new shadow group entries as well.
*/
if (is_shadow_grp && !sgr_update (&sgrp)) {
+#ifdef WITH_AUDIT
+ audit_logger (AUDIT_ADD_GROUP, Prog,
+ "adding group", grp.gr_name, -1, 0);
+#endif
fprintf (stderr, _("%s: error adding new group entry\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
#endif /* SHADOWGRP */
SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid));
+#ifdef WITH_AUDIT
+ audit_logger (AUDIT_ADD_GROUP, Prog, "adding group",
+ grp.gr_name, -1, 1);
+#endif
do_grp_update++;
}
@@ -1486,13 +1498,13 @@ static void usr_update (void)
("%s: error adding new shadow password entry\n"),
Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"adding shadow password", user_name, user_id, 0);
#endif
fail_exit (E_PW_UPDATE);
}
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user", user_name,
+ audit_logger (AUDIT_ADD_USER, Prog, "adding user", user_name,
user_id, 1);
#endif
@@ -1522,7 +1534,7 @@ static void selinux_update_mapping () {
_("%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,
+ audit_logger (AUDIT_ADD_USER, Prog,
"adding SELinux user mapping", user_name, user_id, 0);
#endif
}
@@ -1551,7 +1563,7 @@ static void create_home (void)
("%s: cannot create directory %s\n"),
Prog, user_home);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"adding home directory", user_name,
user_id, 0);
#endif
@@ -1562,7 +1574,7 @@ static void create_home (void)
0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK));
home_added++;
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_USER, Prog,
"adding home directory", user_name, user_id, 1);
#endif
#ifdef WITH_SELINUX
@@ -1722,7 +1734,7 @@ int main (int argc, char **argv)
if (getpwnam (user_name)) { /* local, no need for xgetpwnam */
fprintf (stderr, _("%s: user %s exists\n"), Prog, user_name);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
+ audit_logger (AUDIT_ADD_USER, Prog, "adding user",
user_name, -1, 0);
#endif
fail_exit (E_NAME_IN_USE);
@@ -1741,7 +1753,7 @@ int main (int argc, char **argv)
("%s: group %s exists - if you want to add this user to that group, use -g.\n"),
Prog, user_name);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_ADD_GROUP, Prog,
"adding group", user_name, -1, 0);
#endif
fail_exit (E_NAME_IN_USE);
@@ -1772,7 +1784,7 @@ int main (int argc, char **argv)
if (getpwuid (user_id) != NULL) {
fprintf (stderr, _("%s: UID %u is not unique\n"), Prog, (unsigned int) user_id);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user", user_name, user_id, 0);
+ audit_logger (AUDIT_ADD_USER, Prog, "adding user", user_name, user_id, 0);
#endif
fail_exit (E_UID_IN_USE);
}
diff -urp shadow-4.1.2.orig/src/userdel.c shadow-4.1.2/src/userdel.c
--- shadow-4.1.2.orig/src/userdel.c 2008-09-02 08:31:11.000000000 -0400
+++ shadow-4.1.2/src/userdel.c 2008-09-02 09:03:20.000000000 -0400
@@ -170,7 +170,7 @@ static void update_groups (void)
* Update the DBM group file with the new entry as well.
*/
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"deleting user from group", user_name, user_id,
0);
#endif
@@ -220,8 +220,8 @@ static void update_groups (void)
#endif
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "deleting group", user_name, user_id, 0);
+ audit_logger (AUDIT_DEL_GROUP, Prog, "deleting group",
+ grp->gr_name, -1, 1);
#endif
SYSLOG ((LOG_INFO,
"removed group `%s' owned by `%s'\n",
@@ -270,7 +270,7 @@ static void update_groups (void)
exit (E_GRP_UPDATE);
}
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"deleting user from shadow group", user_name,
user_id, 0);
#endif
@@ -327,7 +327,7 @@ static void fail_exit (int code)
sgr_unlock ();
#endif
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting user", user_name,
+ audit_logger (AUDIT_DEL_USER, Prog, "deleting user", user_name,
user_id, 0);
#endif
exit (code);
@@ -344,7 +344,7 @@ static void open_files (void)
if (!pw_lock ()) {
fprintf (stderr, _("%s: unable to lock password file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"locking password file", user_name, user_id, 0);
#endif
exit (E_PW_UPDATE);
@@ -352,7 +352,7 @@ static void open_files (void)
if (!pw_open (O_RDWR)) {
fprintf (stderr, _("%s: unable to open password file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"opening password file", user_name, user_id, 0);
#endif
fail_exit (E_PW_UPDATE);
@@ -361,7 +361,7 @@ static void open_files (void)
fprintf (stderr,
_("%s: cannot lock shadow password file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"locking shadow password file", user_name,
user_id, 0);
#endif
@@ -371,7 +371,7 @@ static void open_files (void)
fprintf (stderr,
_("%s: cannot open shadow password file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"opening shadow password file", user_name,
user_id, 0);
#endif
@@ -380,7 +380,7 @@ static void open_files (void)
if (!gr_lock ()) {
fprintf (stderr, _("%s: unable to lock group file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "locking group file",
+ audit_logger (AUDIT_DEL_USER, Prog, "locking group file",
user_name, user_id, 0);
#endif
fail_exit (E_GRP_UPDATE);
@@ -388,7 +388,7 @@ static void open_files (void)
if (!gr_open (O_RDWR)) {
fprintf (stderr, _("%s: cannot open group file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "opening group file",
+ audit_logger (AUDIT_DEL_USER, Prog, "opening group file",
user_name, user_id, 0);
#endif
fail_exit (E_GRP_UPDATE);
@@ -398,7 +398,7 @@ static void open_files (void)
fprintf (stderr,
_("%s: unable to lock shadow group file\n"), Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"locking shadow group file", user_name, user_id,
0);
#endif
@@ -408,7 +408,7 @@ static void open_files (void)
fprintf (stderr, _("%s: cannot open shadow group file\n"),
Prog);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"opening shadow group file", user_name, user_id,
0);
#endif
@@ -436,7 +436,7 @@ static void update_user (void)
fail_exit (E_PW_UPDATE);
}
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting user entries",
+ audit_logger (AUDIT_DEL_USER, Prog, "deleting user entries",
user_name, user_id, 1);
#endif
SYSLOG ((LOG_INFO, "delete user `%s'\n", user_name));
@@ -476,7 +476,7 @@ static void user_busy (const char *name,
_("%s: user %s is currently logged in\n"), Prog, name);
if (!fflg) {
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"deleting user logged in", name, -1, 0);
#endif
exit (E_USER_BUSY);
@@ -577,7 +577,7 @@ static void remove_mailbox (void)
if (fflg) {
unlink (mailfile); /* always remove, ignore errors */
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting mail file",
+ audit_logger (AUDIT_DEL_USER, Prog, "deleting mail file",
user_name, user_id, 1);
#endif
return;
@@ -589,7 +589,7 @@ static void remove_mailbox (void)
("%s: %s not owned by %s, not removing\n"),
Prog, mailfile, user_name);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting mail file",
+ audit_logger (AUDIT_DEL_USER, Prog, "deleting mail file",
user_name, user_id, 0);
#endif
return;
@@ -601,7 +601,7 @@ static void remove_mailbox (void)
}
#ifdef WITH_AUDIT
else {
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting mail file",
+ audit_logger (AUDIT_DEL_USER, Prog, "deleting mail file",
user_name, user_id, 1);
}
#endif
@@ -713,7 +713,7 @@ int main (int argc, char **argv)
fprintf (stderr, _("%s: user %s does not exist\n"),
Prog, user_name);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"deleting user not found", user_name, -1, 0);
#endif
exit (E_NOTFOUND);
@@ -799,14 +799,14 @@ int main (int argc, char **argv)
_("%s: error removing directory %s\n"),
Prog, user_home);
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"deleting home directory", user_name,
user_id, 1);
#endif
errors++;
}
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"deleting home directory", user_name, user_id, 1);
#endif
}
@@ -838,7 +838,7 @@ int main (int argc, char **argv)
#endif /* USE_PAM */
#ifdef WITH_AUDIT
if (errors)
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ audit_logger (AUDIT_DEL_USER, Prog,
"deleting home directory", user_name, -1, 0);
#endif
exit (errors ? E_HOMEDIR : E_SUCCESS);

View file

@ -1,32 +0,0 @@
diff -up shadow-4.1.2/src/groupmems.c.checkName shadow-4.1.2/src/groupmems.c
--- shadow-4.1.2/src/groupmems.c.checkName 2008-09-24 11:17:02.000000000 +0200
+++ shadow-4.1.2/src/groupmems.c 2008-09-24 14:03:01.000000000 +0200
@@ -43,6 +43,7 @@
#include <pwd.h>
#include "defines.h"
#include "groupio.h"
+#include "chkname.h"
/* Exit Status Values */
@@ -54,6 +55,7 @@
#define EXIT_NOT_PRIMARY 5 /* not primary owner of group */
#define EXIT_NOT_MEMBER 6 /* member of group does not exist */
#define EXIT_MEMBER_EXISTS 7 /* member of group already exists */
+#define E_BAD_ARG 8 /* invalid argument to option */
#define TRUE 1
#define FALSE 0
@@ -225,6 +227,12 @@ int main (int argc, char **argv)
usage ();
}
+ /* check if user names is valid */
+ if ( adduser && !check_user_name (adduser)) {
+ fprintf (stderr, _("%s is not a valid user name\n"), adduser);
+ exit (E_BAD_ARG);
+ }
+
if (!isroot () && NULL != thisgroup) {
fputs (_("Only root can add members to different groups\n"),
stderr);

View file

@ -1,22 +0,0 @@
diff -up shadow-4.1.2/src/groupmems.c.gmNoGroup shadow-4.1.2/src/groupmems.c
--- shadow-4.1.2/src/groupmems.c.gmNoGroup 2008-09-24 15:00:30.000000000 +0200
+++ shadow-4.1.2/src/groupmems.c 2008-09-24 15:07:20.000000000 +0200
@@ -56,6 +56,7 @@
#define EXIT_NOT_MEMBER 6 /* member of group does not exist */
#define EXIT_MEMBER_EXISTS 7 /* member of group already exists */
#define E_BAD_ARG 8 /* invalid argument to option */
+#define EXIT_NOT_GROUP 8 /* group does not exist */
#define TRUE 1
#define FALSE 0
@@ -293,6 +294,10 @@ int main (int argc, char **argv)
}
grp = (struct group *) gr_locate (name);
+ if (NULL == grp) {
+ fputs (_("Specified group does not exist\n"), stderr);
+ exit (EXIT_NOT_GROUP);
+ }
if (NULL != adduser) {
grp->gr_mem = addtogroup (adduser, grp->gr_mem);

View file

@ -1,30 +0,0 @@
diff -up shadow-4.1.2/src/groupmems.c.gmSEGV shadow-4.1.2/src/groupmems.c
--- shadow-4.1.2/src/groupmems.c.gmSEGV 2008-04-22 22:05:11.000000000 +0200
+++ shadow-4.1.2/src/groupmems.c 2008-09-02 08:30:52.000000000 +0200
@@ -95,7 +95,7 @@ static char *whoami (void)
}
}
-static void addtogroup (char *user, char **members)
+static char **addtogroup (char *user, char **members)
{
int i;
@@ -109,6 +109,8 @@ static void addtogroup (char *user, char
members = (char **) realloc (members, sizeof (char *) * (i+2));
members[i] = user;
members[i + 1] = NULL;
+
+ return members;
}
static void rmfromgroup (char *user, char **members)
@@ -285,7 +287,7 @@ int main (int argc, char **argv)
grp = (struct group *) gr_locate (name);
if (NULL != adduser) {
- addtogroup (adduser, grp->gr_mem);
+ grp->gr_mem = addtogroup (adduser, grp->gr_mem);
gr_update (grp);
} else if (NULL != deluser) {
rmfromgroup (deluser, grp->gr_mem);

View file

@ -1,93 +0,0 @@
diff -up shadow-4.1.2/libmisc/chkname.c.goodname shadow-4.1.2/libmisc/chkname.c
--- shadow-4.1.2/libmisc/chkname.c.goodname 2008-04-27 02:40:13.000000000 +0200
+++ shadow-4.1.2/libmisc/chkname.c 2008-05-26 14:37:09.000000000 +0200
@@ -50,16 +50,24 @@
static int good_name (const char *name)
{
/*
- * User/group names must match [a-z_][a-z0-9_-]*[$]
- */
- if (!*name || !((*name >= 'a' && *name <= 'z') || *name == '_'))
+ * User/group names must match gnu e-regex:
+ * [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]?
+ *
+ * as a non-POSIX, extension, allow "$" as the last char for
+ * sake of Samba 3.x "add machine script"
+ */
+ if (!*name || !((*name >= 'a' && *name <= 'z')
+ || (*name >= 'A' && *name <= 'Z')
+ || (*name >= '0' && *name <= '9')
+ || *name == '_' || *name == '.'))
return 0;
while (*++name) {
- if (!((*name >= 'a' && *name <= 'z') ||
- (*name >= '0' && *name <= '9') ||
- *name == '_' || *name == '-' ||
- (*name == '$' && *(name + 1) == '\0')))
+ if (!( (*name >= 'a' && *name <= 'z')
+ || (*name >= 'A' && *name <= 'Z')
+ || (*name >= '0' && *name <= '9')
+ || *name == '_' || *name == '.' || *name == '-'
+ || (*name == '$' && *(name + 1) == '\0')))
return 0;
}
@@ -75,10 +83,9 @@ int check_user_name (const char *name)
#endif
/*
- * User names are limited by whatever utmp can
- * handle (usually max 8 characters).
+ * User names are limited by whatever utmp can handle.
*/
- if (strlen (name) > sizeof (ut.ut_user))
+ if (strlen(name) + 1 > sizeof(ut.ut_user))
return 0;
return good_name (name);
@@ -86,11 +93,13 @@ int check_user_name (const char *name)
int check_group_name (const char *name)
{
- /*
- * Arbitrary limit for group names - max 16
- * characters (same as on HP-UX 10).
- */
- if (strlen (name) > 16)
+#if HAVE_UTMPX_H
+ struct utmpx ut;
+#else
+ struct utmp ut;
+#endif
+
+ if (strlen(name) + 1 > sizeof(ut.ut_user))
return 0;
return good_name (name);
diff -up shadow-4.1.2/man/groupadd.8.goodname shadow-4.1.2/man/groupadd.8
--- shadow-4.1.2/man/groupadd.8.goodname 2008-05-26 14:37:09.000000000 +0200
+++ shadow-4.1.2/man/groupadd.8 2008-05-26 14:40:51.000000000 +0200
@@ -150,9 +150,7 @@ Shadow password suite configuration\&.
.RE
.SH "CAVEATS"
.PP
-Groupnames must begin with a lower case letter or an underscore, and only lower case letters, underscores, dashes, and dollar signs may follow\&. In regular expression terms: [a\-z_][a\-z0\-9_\-]*[$]
-.PP
-Groupnames may only be up to 16 characters long\&.
+Groupnames may only be up to 32 characters long\&.
.PP
You may not add a NIS or LDAP group\&. This must be performed on the corresponding server\&.
.PP
diff -up shadow-4.1.2/man/useradd.8.goodname shadow-4.1.2/man/useradd.8
--- shadow-4.1.2/man/useradd.8.goodname 2008-05-26 14:37:09.000000000 +0200
+++ shadow-4.1.2/man/useradd.8 2008-05-26 14:41:48.000000000 +0200
@@ -293,8 +293,6 @@ You may not add a user to a NIS or LDAP
Similarly, if the username already exists in an external user database such as NIS or LDAP,
\fBuseradd\fR
will deny the user account creation request\&.
-.PP
-Usernames must begin with a lower case letter or an underscore, and only lower case letters, underscores, dashes, and dollar signs may follow\&. In regular expression terms: [a\-z_][a\-z0\-9_\-]*[$]
.SH "CONFIGURATION"
.PP
The following configuration variables in

View file

@ -1,269 +0,0 @@
diff -up shadow-4.1.2/libmisc/find_new_ids.c.redhat shadow-4.1.2/libmisc/find_new_ids.c
--- shadow-4.1.2/libmisc/find_new_ids.c.redhat 2008-04-22 00:00:19.000000000 +0200
+++ shadow-4.1.2/libmisc/find_new_ids.c 2008-05-26 14:18:43.000000000 +0200
@@ -56,11 +56,11 @@ int find_new_uid (int sys_user, uid_t *u
assert (uid != NULL);
if (sys_user == 0) {
- uid_min = getdef_unum ("UID_MIN", 1000);
+ uid_min = getdef_unum ("UID_MIN", 500);
uid_max = getdef_unum ("UID_MAX", 60000);
} else {
uid_min = getdef_unum ("SYS_UID_MIN", 1);
- uid_max = getdef_unum ("UID_MIN", 1000) - 1;
+ uid_max = getdef_unum ("UID_MIN", 500) - 1;
uid_max = getdef_unum ("SYS_UID_MAX", uid_max);
}
@@ -139,11 +139,11 @@ int find_new_gid (int sys_group, gid_t *
assert (gid != NULL);
if (sys_group == 0) {
- gid_min = getdef_unum ("GID_MIN", 1000);
+ gid_min = getdef_unum ("GID_MIN", 500);
gid_max = getdef_unum ("GID_MAX", 60000);
} else {
gid_min = getdef_unum ("SYS_GID_MIN", 1);
- gid_max = getdef_unum ("GID_MIN", 1000) - 1;
+ gid_max = getdef_unum ("GID_MIN", 500) - 1;
gid_max = getdef_unum ("SYS_GID_MAX", gid_max);
}
diff -up shadow-4.1.2/src/useradd.c.redhat shadow-4.1.2/src/useradd.c
--- shadow-4.1.2/src/useradd.c.redhat 2008-05-19 22:31:52.000000000 +0200
+++ shadow-4.1.2/src/useradd.c 2008-05-26 14:18:43.000000000 +0200
@@ -85,7 +85,7 @@
static gid_t def_group = 100;
static const char *def_gname = "other";
static const char *def_home = "/home";
-static const char *def_shell = "";
+static const char *def_shell = "/sbin/nologin";
static const char *def_template = SKEL_DIR;
static const char *def_create_mail_spool = "no";
@@ -97,7 +97,7 @@ static char def_file[] = USER_DEFAULTS_F
#define VALID(s) (strcspn (s, ":\n") == strlen (s))
static const char *user_name = "";
-static const char *user_pass = "!";
+static const char *user_pass = "!!";
static uid_t user_id;
static gid_t user_gid;
static const char *user_comment = "";
@@ -133,6 +133,7 @@ static int
kflg = 0, /* specify a directory to fill new user directory */
lflg = 0, /* do not add user to lastlog database file */
mflg = 0, /* create user's home directory if it doesn't exist */
+ Mflg = 0, /* do NOT create user's home directory no matter what */
Nflg = 0, /* do not create a group having the same name as the user, but add the user to def_group (or the group specified with -g) */
oflg = 0, /* permit non-unique user ID to be specified with -u */
rflg = 0, /* create a system account */
@@ -656,6 +657,7 @@ static void usage (void)
" faillog databases\n"
" -m, --create-home create home directory for the new user\n"
" account\n"
+ " -M, do not create user's home directory(overrides /etc/login.defs)\n"
" -N, --no-user-group do not create a group with the same name as\n"
" the user\n"
" -o, --non-unique allow create user with duplicate\n"
@@ -886,7 +888,7 @@ static void process_flags (int argc, cha
{NULL, 0, NULL, '\0'}
};
while ((c =
- getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:lmMNop:rs:u:U",
+ getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:lmMnNop:rs:u:U",
long_options, NULL)) != -1) {
switch (c) {
case 'b':
@@ -1026,6 +1028,10 @@ static void process_flags (int argc, cha
case 'm':
mflg++;
break;
+ case 'M':
+ Mflg++;
+ break;
+ case 'n':
case 'N':
Nflg++;
break;
@@ -1079,6 +1085,9 @@ static void process_flags (int argc, cha
Uflg = getdef_bool ("USERGROUPS_ENAB");
}
+ if (mflg && Mflg) /* the admin is not decided .. create or not ? */
+ usage();
+
/*
* Certain options are only valid in combination with others.
* Check it here so that they can be specified in any order.
@@ -1628,6 +1637,14 @@ int main (int argc, char **argv)
}
#endif /* USE_PAM */
+ if (!rflg) /* for system accounts defaults are ignored and we
+ * do not create a home dir -- gafton */
+ if (getdef_bool("CREATE_HOME"))
+ mflg = 1;
+
+ if (Mflg) /* absolutely sure that we do not create home dirs */
+ mflg = 0;
+
/*
* See if we are messing with the defaults file, or creating
* a new user.
@@ -1727,27 +1744,22 @@ int main (int argc, char **argv)
("%s: warning: the home directory already exists.\n"
"Not copying any file from skel directory into it.\n"),
Prog);
-
- } else if (getdef_str ("CREATE_HOME")) {
- /*
- * RedHat added the CREATE_HOME option in login.defs in their
- * version of shadow-utils (which makes -m the default, with
- * new -M option to turn it off). Unfortunately, this
- * changes the way useradd works (it can be run by scripts
- * expecting some standard behaviour), compared to other
- * Unices and other Linux distributions, and also adds a lot
- * of confusion :-(.
- * So we now recognize CREATE_HOME and give a warning here
- * (better than "configuration error ... notify administrator"
- * errors in every program that reads /etc/login.defs). -MM
- */
- fprintf (stderr,
- _
- ("%s: warning: CREATE_HOME not supported, please use -m instead.\n"),
- Prog);
}
-
- create_mail ();
+ /* Warning removed to protect the innocent. */
+ /*
+ * The whole idea about breaking some stupid scripts by creating a new
+ * variable is crap - I could care less about the scripts. Historically
+ * adduser type programs have always created the home directories and
+ * I don't like the idea of providing a script when we can fix the
+ * binary itself. And if the scripts are using the right options to the
+ * useradd then they will not break. If not, they depend on unspecified
+ * behavior and they will break, but they were broken anyway to begin
+ * with --gafton
+ */
+
+ /* Do not create mail directory for system accounts */
+ if( !rflg )
+ create_mail ();
close_files ();
diff -up shadow-4.1.2/man/useradd.8.redhat shadow-4.1.2/man/useradd.8
--- shadow-4.1.2/man/useradd.8.redhat 2008-05-25 01:20:26.000000000 +0200
+++ shadow-4.1.2/man/useradd.8 2008-05-26 14:26:14.000000000 +0200
@@ -27,7 +27,7 @@ option, the
\fBuseradd\fR
command creates a new user account using the values specified on the command line plus the default values from the system\&. Depending on command line options, the
\fBuseradd\fR
-command will update system files and may also create the new user\'s home directory and copy initial files\&.
+command will update system files and may also create the new user\'s home directory and copy initial files\&. The version provided with Red Hat Linux will create a group for each user added to the system by default\&.
.SH "OPTIONS"
.PP
The options which apply to the
@@ -84,8 +84,7 @@ The number of days after a password expi
.PP
\fB\-g\fR, \fB\-\-gid\fR \fIGROUP\fR
.RS 4
-The group name or number of the user\'s initial login group\&. The group name must exist\&. A group number must refer to an already existing group\&. The default group number is 1 or whatever is specified in
-\fI/etc/default/useradd\fR\&.
+The group name or number of the user\'s initial login group\&. The group name must exist\&. A group number must refer to an already existing group\&.
.RE
.PP
\fB\-G\fR, \fB\-\-groups\fR \fIGROUP1\fR[\fI,GROUP2,\&.\&.\&.\fR[\fI,GROUPN\fR]]]
@@ -143,6 +142,13 @@ Do not add the user to the lastlog and f
By default, the user\'s entries in the lastlog and faillog databases are resetted to avoid reusing the entry from a previously deleted user\&.
.RE
.PP
+\fB-M\fR
+.RS 4
+The user\'s home directory will not be created, even if the system wide settings from
+\fI/etc/login.defs\fR
+is to create home dirs\.
+.RE
+.PP
\fB\-m\fR, \fB\-\-create\-home\fR
.RS 4
Create the user\'s home directory if it does not exist\&. The files and directories contained in the skeleton directory (which can be defined with the
@@ -195,6 +201,19 @@ range, defined in
counterparts for the creation of groups)\&.
.RE
.PP
+\fB-r\fR
+.RS 4
+This flag is used to create a system account\. That is, a user with a UID lower than the value of UID_MIN defined in
+\fI/etc/login.defs\fR
+and whose password does not expire\. Note that
+\fBuseradd\fR
+will not create a home directory for such an user, regardless of the default setting in
+\fI/etc/login.defs\fR\.
+You have to specify
+\fB-m\fR
+option if you want a home directory for a system account to be created\. This is an option added by Red Hat\.
+.RE
+.PP
\fB\-s\fR, \fB\-\-shell\fR \fISHELL\fR
.RS 4
The name of the user\'s login shell\&. The default is to leave this field blank, which causes the system to select the default login shell\&.
@@ -265,6 +284,8 @@ The name of a new user\'s login shell\&.
The system administrator is responsible for placing the default user files in the
\fI/etc/skel/\fR
directory\&.
+.br
+This version of useradd was modified by Red Hat to suit Red Hat user/group conventions\&.
.SH "CAVEATS"
.PP
You may not add a user to a NIS or LDAP group\&. This must be performed on the corresponding server\&.
@@ -407,6 +428,11 @@ Group account information\&.
Secure group account information\&.
.RE
.PP
+\fI/etc/gshadow\fR
+.RS 4
+Secure group account information\.
+.RE
+.PP
\fI/etc/default/useradd\fR
.RS 4
Default values for account creation\&.
diff -up shadow-4.1.2/man/groupadd.8.redhat shadow-4.1.2/man/groupadd.8
--- shadow-4.1.2/man/groupadd.8.redhat 2008-05-25 01:20:05.000000000 +0200
+++ shadow-4.1.2/man/groupadd.8 2008-05-26 14:35:49.000000000 +0200
@@ -14,7 +14,7 @@
groupadd \- create a new group
.SH "SYNOPSIS"
.HP 9
-\fBgroupadd\fR [\-g\ \fIGID\fR\ [\-o]] [\-f] [\-K\ \fIKEY\fR=\fIVALUE\fR] \fIgroup\fR
+\fBgroupadd\fR [\-g\ \fIgid\fR\ [\-o]] [\-r] [\-f] [\-K\ \fIKEY\fR=\fIVALUE\fR] \fIgroup\fR
.SH "DESCRIPTION"
.PP
The
@@ -34,11 +34,22 @@ This option causes the command to simply
is turned off)\&.
.RE
.PP
+\fB-r\fR
+.RS 4
+This flag instructs
+\fBgroupadd\fR
+to add a system account\. The first available
+\fIgid\fR
+lower than 500 will be automatically selected unless the
+\fB-g\fR
+option is also given on the command line\. This is an option added by Red Hat\.
+.RE
+.PP
\fB\-g\fR, \fB\-\-gid\fR \fIGID\fR
.RS 4
The numerical value of the group\'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 group\&. Values between 0 and 999 are typically reserved for system accounts\&.
+option is used\&. The value must be non\-negative\&. The default is to use the smallest ID value greater than 499 and greater than every other group\&. Values between 0 and 500 are typically reserved for system accounts\&.
.RE
.PP
\fB\-h\fR, \fB\-\-help\fR

View file

@ -1,490 +0,0 @@
diff -up /dev/null shadow-4.1.2/libmisc/system.c
--- /dev/null 2008-07-15 12:00:55.602698860 +0200
+++ shadow-4.1.2/libmisc/system.c 2008-07-24 10:14:24.000000000 +0200
@@ -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 -up shadow-4.1.2/libmisc/copydir.c.selinux shadow-4.1.2/libmisc/copydir.c
--- shadow-4.1.2/libmisc/copydir.c.selinux 2008-05-24 17:35:17.000000000 +0200
+++ shadow-4.1.2/libmisc/copydir.c 2008-07-24 10:14:24.000000000 +0200
@@ -85,7 +85,7 @@ static int copy_file (const char *src, c
* symlink, directory, ...
*
*/
-static int selinux_file_context (const char *dst_name)
+int selinux_file_context (const char *dst_name)
{
security_context_t scontext = NULL;
@@ -256,6 +256,12 @@ 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;
}
diff -up shadow-4.1.2/libmisc/Makefile.am.selinux shadow-4.1.2/libmisc/Makefile.am
--- shadow-4.1.2/libmisc/Makefile.am.selinux 2008-01-27 15:21:48.000000000 +0100
+++ shadow-4.1.2/libmisc/Makefile.am 2008-07-24 10:14:24.000000000 +0200
@@ -43,6 +43,7 @@ libmisc_a_SOURCES = \
setugid.c \
setupenv.c \
shell.c \
+ system.c \
strtoday.c \
sub.c \
sulog.c \
diff -up shadow-4.1.2/src/useradd.c.selinux shadow-4.1.2/src/useradd.c
--- shadow-4.1.2/src/useradd.c.selinux 2008-07-24 10:13:23.000000000 +0200
+++ shadow-4.1.2/src/useradd.c 2008-07-24 10:14:24.000000000 +0200
@@ -104,6 +104,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;
@@ -176,6 +177,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 *);
@@ -376,6 +378,7 @@ static void get_defaults (void)
def_create_mail_spool = xstrdup (cp);
}
}
+ fclose(fp);
}
/*
@@ -668,6 +671,9 @@ static void usage (void)
" -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, --user-group create a group with the same name as the user\n"
+#ifdef WITH_SELINUX
+ " -Z, --selinux-user SEUSER use a specific SEUSER for the SELinux user mapping\n"
+#endif
"\n"), stderr);
exit (E_USAGE);
}
@@ -883,12 +889,19 @@ static void process_flags (int argc, cha
{"password", required_argument, NULL, 'p'},
{"system", no_argument, NULL, 'r'},
{"shell", required_argument, NULL, 's'},
+#ifdef WITH_SELINUX
+ {"selinux-user", required_argument, NULL, 'Z'},
+#endif
{"uid", required_argument, NULL, 'u'},
{"user-group", no_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:lmMnNop:rs:u:UZ:",
+#else
getopt_long (argc, argv, "b:c:d:De:f:g:G:k:K:lmMnNop:rs:u:U",
+#endif
long_options, NULL)) != -1) {
switch (c) {
case 'b':
@@ -1073,6 +1086,17 @@ 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 ();
}
@@ -1479,6 +1503,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
*
@@ -1488,7 +1539,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,
@@ -1510,6 +1565,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
}
}
@@ -1763,6 +1822,8 @@ int main (int argc, char **argv)
close_files ();
+ selinux_update_mapping();
+
nscd_flush_cache ("passwd");
nscd_flush_cache ("group");
diff -up shadow-4.1.2/src/usermod.c.selinux shadow-4.1.2/src/usermod.c
--- shadow-4.1.2/src/usermod.c.selinux 2008-05-24 17:35:17.000000000 +0200
+++ shadow-4.1.2/src/usermod.c 2008-07-24 10:14:24.000000000 +0200
@@ -94,6 +94,7 @@ static char *user_newcomment;
static char *user_home;
static char *user_newhome;
static char *user_shell;
+static const char *user_selinux = "";
static char *user_newshell;
static long user_expire;
static long user_newexpire;
@@ -141,6 +142,7 @@ static void date_to_str (char *buf, size
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);
@@ -323,6 +325,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"), stderr);
exit (E_USAGE);
}
@@ -849,13 +854,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 =
- getopt_long (argc, argv, "ac:d:e:f:g:G:hl:Lmop:s:u:U",
+#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':
@@ -956,6 +968,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 ();
}
@@ -1534,6 +1556,8 @@ int main (int argc, char **argv)
nscd_flush_cache ("passwd");
nscd_flush_cache ("group");
+ selinux_update_mapping();
+
if (mflg)
move_home ();
@@ -1562,3 +1586,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 -up shadow-4.1.2/src/userdel.c.selinux shadow-4.1.2/src/userdel.c
--- shadow-4.1.2/src/userdel.c.selinux 2008-05-24 17:35:17.000000000 +0200
+++ shadow-4.1.2/src/userdel.c 2008-07-24 10:14:24.000000000 +0200
@@ -811,6 +811,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 -up shadow-4.1.2/man/useradd.8.selinux shadow-4.1.2/man/useradd.8
--- shadow-4.1.2/man/useradd.8.selinux 2008-07-24 10:13:23.000000000 +0200
+++ shadow-4.1.2/man/useradd.8 2008-07-24 10:20:27.000000000 +0200
@@ -239,6 +239,11 @@ options are not specified) is defined by
variable in
\fIlogin\&.defs\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
.SS "Changing the default values"
.PP
When invoked with only the
diff -up shadow-4.1.2/man/usermod.8.xml.selinux shadow-4.1.2/man/usermod.8.xml
--- shadow-4.1.2/man/usermod.8.xml.selinux 2007-12-31 17:48:34.000000000 +0100
+++ shadow-4.1.2/man/usermod.8.xml 2008-07-24 10:14:24.000000000 +0200
@@ -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 -up shadow-4.1.2/man/usermod.8.selinux shadow-4.1.2/man/usermod.8
--- shadow-4.1.2/man/usermod.8.selinux 2008-05-25 01:20:28.000000000 +0200
+++ shadow-4.1.2/man/usermod.8 2008-07-24 10:21:39.000000000 +0200
@@ -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 -up shadow-4.1.2/man/useradd.8.xml.selinux shadow-4.1.2/man/useradd.8.xml
--- shadow-4.1.2/man/useradd.8.xml.selinux 2008-05-20 00:18:17.000000000 +0200
+++ shadow-4.1.2/man/useradd.8.xml 2008-07-24 10:14:24.000000000 +0200
@@ -363,6 +363,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'>
diff -up shadow-4.1.2/lib/defines.h.selinux shadow-4.1.2/lib/defines.h
--- shadow-4.1.2/lib/defines.h.selinux 2008-05-24 19:35:54.000000000 +0200
+++ shadow-4.1.2/lib/defines.h 2008-07-24 10:14:24.000000000 +0200
@@ -321,4 +321,7 @@ extern char *strerror ();
# define unused
#endif
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif
#endif /* _DEFINES_H_ */
diff -up shadow-4.1.2/lib/prototypes.h.selinux shadow-4.1.2/lib/prototypes.h
--- shadow-4.1.2/lib/prototypes.h.selinux 2008-04-27 02:40:13.000000000 +0200
+++ shadow-4.1.2/lib/prototypes.h 2008-07-24 10:14:24.000000000 +0200
@@ -83,6 +83,10 @@ extern int copy_tree (const char *src_ro
long int uid, long int gid);
extern int remove_tree (const char *root);
+#ifdef WITH_SELINUX
+extern int selinux_file_context (const char *dst_name);
+#endif
+
/* encrypt.c */
extern char *pw_encrypt (const char *, const char *);
@@ -226,6 +230,9 @@ extern struct spwd *__spw_dup (const str
/* 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 *);

View file

@ -1,99 +0,0 @@
diff -up shadow-4.1.2/libmisc/find_new_ids.c.sysAccountDownhill shadow-4.1.2/libmisc/find_new_ids.c
--- shadow-4.1.2/libmisc/find_new_ids.c.sysAccountDownhill 2008-05-26 14:52:49.000000000 +0200
+++ shadow-4.1.2/libmisc/find_new_ids.c 2008-05-26 14:58:55.000000000 +0200
@@ -52,6 +52,7 @@ int find_new_uid (int sys_user, uid_t *u
{
const struct passwd *pwd;
uid_t uid_min, uid_max, user_id;
+ char * index;
assert (uid != NULL);
@@ -62,6 +63,8 @@ int find_new_uid (int sys_user, uid_t *u
uid_min = getdef_unum ("SYS_UID_MIN", 1);
uid_max = getdef_unum ("UID_MIN", 500) - 1;
uid_max = getdef_unum ("SYS_UID_MAX", uid_max);
+ index = alloca (sizeof (char) * uid_max +1);
+ memset (index, 0, sizeof (char) * uid_max + 1);
}
if ( (NULL != preferred_uid)
@@ -91,12 +94,28 @@ int find_new_uid (int sys_user, uid_t *u
pw_rewind ();
while ( ((pwd = getpwent ()) != NULL)
|| ((pwd = pw_next ()) != NULL)) {
- if ((pwd->pw_uid >= user_id) && (pwd->pw_uid <= uid_max)) {
- user_id = pwd->pw_uid + 1;
+ if (sys_user == 0) {
+ if ((pwd->pw_uid >= user_id) && (pwd->pw_uid <= uid_max)) {
+ user_id = pwd->pw_uid + 1;
+ }
+ }
+ else {
+ /* create index of occupied system accounts UIDs */
+ if (pwd->pw_uid <= uid_max)
+ index[pwd->pw_uid] = 1;
}
}
endpwent ();
+ /* find free system account */
+ if(sys_user) {
+ for( user_id = uid_max; (user_id >= uid_min) && index[user_id]; user_id--);
+ if ( user_id < uid_min ) {
+ fputs (_("Can't get unique UID (no more available UIDs)\n"), stderr);
+ return -1;
+ }
+ }
+
/*
* If a user with UID equal to UID_MAX exists, the above algorithm
* will give us UID_MAX+1 even if not unique. Search for the first
@@ -135,6 +154,7 @@ int find_new_gid (int sys_group, gid_t *
{
const struct group *grp;
gid_t gid_min, gid_max, group_id;
+ char * index;
assert (gid != NULL);
@@ -145,6 +165,8 @@ int find_new_gid (int sys_group, gid_t *
gid_min = getdef_unum ("SYS_GID_MIN", 1);
gid_max = getdef_unum ("GID_MIN", 500) - 1;
gid_max = getdef_unum ("SYS_GID_MAX", gid_max);
+ index = alloca (sizeof (char) * gid_max +1);
+ memset (index, 0, sizeof (char) * gid_max + 1);
}
if ( (NULL != preferred_gid)
@@ -173,12 +195,28 @@ int find_new_gid (int sys_group, gid_t *
gr_rewind ();
while ( ((grp = getgrent ()) != NULL)
|| ((grp = gr_next ()) != NULL)) {
- if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) {
- group_id = grp->gr_gid + 1;
+ if (sys_group == 0) {
+ if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) {
+ group_id = grp->gr_gid + 1;
+ }
+ }
+ else {
+ /* create index of occupied system accounts GIDs */
+ if (grp->gr_gid <= gid_max)
+ index[grp->gr_gid] = 1;
}
}
endgrent ();
+ /* find free system account */
+ if(sys_group) {
+ for( group_id = gid_max; (group_id >= gid_min) && index[group_id]; group_id--);
+ if ( group_id < gid_min ) {
+ fputs (_("Can't get unique GID (no more available GIDs)\n"), stderr);
+ return -1;
+ }
+ }
+
/*
* If a group with GID equal to GID_MAX exists, the above algorithm
* will give us GID_MAX+1 even if not unique. Search for the first

View file

@ -1,532 +0,0 @@
diff -up /dev/null shadow-4.1.2/lib/get_gid.c
--- /dev/null 2009-03-16 11:03:38.574001227 +0100
+++ shadow-4.1.2/lib/get_gid.c 2009-03-23 18:45:59.000000000 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009 , Nicolas François
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the copyright holders or contributors may not be used to
+ * endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ident "$Id$"
+
+#include "prototypes.h"
+#include "defines.h"
+
+int get_gid (const char *gidstr, gid_t *gid)
+{
+ long long int val;
+ char *endptr;
+
+ errno = 0;
+ val = strtoll (gidstr, &endptr, 10);
+ if ( ('\0' == gidstr)
+ || ('\0' != *endptr)
+ || (ERANGE == errno)
+ || (val != (gid_t)val)) {
+ return 0;
+ }
+
+ *gid = (gid_t)val;
+ return 1;
+}
+
diff -up /dev/null shadow-4.1.2/lib/get_uid.c
--- /dev/null 2009-03-16 11:03:38.574001227 +0100
+++ shadow-4.1.2/lib/get_uid.c 2009-03-23 18:45:59.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009 , Nicolas François
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the copyright holders or contributors may not be used to
+ * endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ident "$Id$"
+
+#include "prototypes.h"
+#include "defines.h"
+
+int get_uid (const char *uidstr, uid_t *uid)
+{
+ long long int val;
+ char *endptr;
+
+ errno = 0;
+ val = strtoll (uidstr, &endptr, 10);
+ if ( ('\0' == uidstr)
+ || ('\0' != *endptr)
+ || (ERANGE == errno)
+ || (val != (uid_t)val)) {
+ return 0;
+ }
+
+ *uid = (uid_t)val;
+ return 1;
+}
+
+
diff -up shadow-4.1.2/lib/Makefile.am.uid shadow-4.1.2/lib/Makefile.am
--- shadow-4.1.2/lib/Makefile.am.uid 2008-01-06 14:57:28.000000000 +0100
+++ shadow-4.1.2/lib/Makefile.am 2009-03-23 18:45:59.000000000 +0100
@@ -17,6 +17,8 @@ libshadow_la_SOURCES = \
fputsx.c \
getdef.c \
getdef.h \
+ get_gid.c \
+ get_uid.c \
groupio.c \
groupmem.c \
groupio.h \
diff -up shadow-4.1.2/lib/prototypes.h.uid shadow-4.1.2/lib/prototypes.h
--- shadow-4.1.2/lib/prototypes.h.uid 2009-03-23 18:45:59.000000000 +0100
+++ shadow-4.1.2/lib/prototypes.h 2009-03-23 18:45:59.000000000 +0100
@@ -110,6 +110,12 @@ extern int find_new_gid (int sys_group,
/* getlong.c */
extern int getlong(const char *numstr, long int *result);
+/* get_gid.c */
+extern int get_gid (const char *gidstr, gid_t *gid);
+
+/* get_uid.c */
+extern int get_uid (const char *uidstr, uid_t *uid);
+
/* fputsx.c */
extern char *fgetsx (char *, int, FILE *);
extern int fputsx (const char *, FILE *);
diff -up shadow-4.1.2/src/groupadd.c.uid shadow-4.1.2/src/groupadd.c
--- shadow-4.1.2/src/groupadd.c.uid 2009-03-23 18:45:59.000000000 +0100
+++ shadow-4.1.2/src/groupadd.c 2009-03-23 18:45:59.000000000 +0100
@@ -98,7 +98,6 @@ static void check_new_name (void);
static void close_files (void);
static void open_files (void);
static void fail_exit (int code);
-static gid_t get_gid (const char *gidstr);
static void process_flags (int argc, char **argv);
static void check_flags (void);
static void check_perms (void);
@@ -326,22 +325,6 @@ static void fail_exit (int code)
exit (code);
}
-/*
- * get_id - validate and get group ID
- */
-static gid_t get_gid (const char *gidstr)
-{
- long val;
- char *errptr;
-
- val = strtol (gidstr, &errptr, 10);
- if (('\0' != *errptr) || (errno == ERANGE) || (val < 0)) {
- fprintf (stderr, _("%s: invalid numeric argument '%s'\n"),
- Prog, gidstr);
- exit (E_BAD_ARG);
- }
- return val;
-}
/*
* process_flags - parse the command line options
@@ -383,7 +366,13 @@ static void process_flags (int argc, cha
break;
case 'g':
gflg++;
- group_id = get_gid (optarg);
+ if ( (get_gid (optarg, &group_id) == 0)
+ || (group_id == (gid_t)-1)) {
+ fprintf (stderr,
+ _("%s: invalid group ID '%s'\n"),
+ Prog, optarg);
+ exit (E_BAD_ARG);
+ }
break;
case 'h':
usage ();
diff -up shadow-4.1.2/src/groupmod.c.uid shadow-4.1.2/src/groupmod.c
--- shadow-4.1.2/src/groupmod.c.uid 2008-04-27 02:40:13.000000000 +0200
+++ shadow-4.1.2/src/groupmod.c 2009-03-23 18:45:59.000000000 +0100
@@ -100,7 +100,6 @@ static void check_new_name (void);
static void process_flags (int, char **);
static void close_files (void);
static void open_files (void);
-static gid_t get_gid (const char *gidstr);
static void update_primary_groups (gid_t ogid, gid_t ngid);
/*
@@ -361,23 +360,6 @@ static void check_new_name (void)
}
/*
- * get_id - validate and get group ID
- */
-static gid_t get_gid (const char *gidstr)
-{
- long val;
- char *errptr;
-
- val = strtol (gidstr, &errptr, 10);
- if (*errptr || errno == ERANGE || val < 0) {
- fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
- gidstr);
- fail_exit (E_BAD_ARG);
- }
- return val;
-}
-
-/*
* process_flags - perform command line argument setting
*
* process_flags() interprets the command line arguments and sets the
@@ -404,7 +386,13 @@ static void process_flags (int argc, cha
switch (c) {
case 'g':
gflg++;
- group_newid = get_gid (optarg);
+ if ( (get_gid (optarg, &group_newid) == 0)
+ || (group_newid == (gid_t)-1)) {
+ fprintf (stderr,
+ _("%s: invalid group ID '%s'\n"),
+ Prog, optarg);
+ exit (E_BAD_ARG);
+ }
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK,
Prog, "modifying group",
diff -up shadow-4.1.2/src/newusers.c.uid shadow-4.1.2/src/newusers.c
--- shadow-4.1.2/src/newusers.c.uid 2008-04-27 02:40:13.000000000 +0200
+++ shadow-4.1.2/src/newusers.c 2009-03-23 18:45:59.000000000 +0100
@@ -90,7 +90,7 @@ static pam_handle_t *pamh = NULL;
static void usage (void);
static void fail_exit (int);
static int add_group (const char *, const char *, gid_t *, gid_t);
-static int get_uid (const char *, uid_t *);
+static int get_user_id (const char *, uid_t *);
static int add_user (const char *, uid_t, gid_t);
static void update_passwd (struct passwd *, const char *);
static int add_passwd (struct passwd *, const char *);
@@ -178,22 +178,26 @@ static int add_group (const char *name,
* The GID is a number, which means either this is a brand
* new group, or an existing group.
*/
- char *endptr;
- long int i = strtoul (gid, &endptr, 10);
- if ((*endptr != '\0') && (errno != ERANGE)) {
+ if (get_gid (gid, &grent.gr_gid) == 0) {
fprintf (stderr,
- _("%s: group ID `%s' is not valid\n"),
+ _("%s: invalid group ID '%s'\n"),
Prog, gid);
return -1;
}
- if ( (getgrgid (i) != NULL)
- || (gr_locate_gid (i) != NULL)) {
+ if ( (getgrgid ((gid_t) grent.gr_gid) != NULL)
+ || (gr_locate_gid ((gid_t) grent.gr_gid) != NULL)) {
/* The user will use this ID for her
* primary group */
- *ngid = i;
+ *ngid = (gid_t) grent.gr_gid;
return 0;
}
- grent.gr_gid = i;
+ /* Do not create groups with GID == (gid_t)-1 */
+ if (grent.gr_gid == (gid_t)-1) {
+ fprintf (stderr,
+ _("%s: invalid group ID '%s'\n"),
+ Prog, gid);
+ return -1;
+ }
} else {
/* The gid parameter can be "" or a name which is not
* already the name of an existing group.
@@ -267,7 +271,7 @@ static int add_group (const char *name,
return 0;
}
-static int get_uid (const char *uid, uid_t *nuid) {
+static int get_user_id (const char *uid, uid_t *nuid) {
const struct passwd *pwd = NULL;
/*
@@ -275,15 +279,11 @@ static int get_uid (const char *uid, uid
* caller provided, or the next available UID.
*/
if (isdigit (uid[0])) {
- char *endptr;
- long int i = strtoul (uid, &endptr, 10);
- if ((*endptr != '\0') && (errno != ERANGE)) {
- fprintf (stderr,
- _("%s: user ID `%s' is not valid\n"),
+ if ((get_uid (uid, nuid) == 0) || (*nuid == (uid_t)-1)) {
+ fprintf (stderr, _("%s: invalid user ID '%s'\n"),
Prog, uid);
return -1;
}
- *nuid = i;
} else {
if ('\0' != uid[0]) {
/* local, no need for xgetpwnam */
@@ -740,7 +740,7 @@ int main (int argc, char **argv)
}
if ( (NULL == pw)
- && (get_uid (fields[2], &uid) != 0)) {
+ && (get_user_id (fields[2], &uid) != 0)) {
fprintf (stderr,
_("%s: line %d: can't create user\n"),
Prog, line);
diff -up shadow-4.1.2/src/useradd.c.uid shadow-4.1.2/src/useradd.c
--- shadow-4.1.2/src/useradd.c.uid 2009-03-23 18:45:59.000000000 +0100
+++ shadow-4.1.2/src/useradd.c 2009-03-23 18:45:59.000000000 +0100
@@ -170,7 +170,6 @@ static int home_added;
static void fail_exit (int);
static struct group *getgr_nam_gid (const char *);
static long get_number (const char *);
-static uid_t get_uid (const char *);
static void get_defaults (void);
static void show_defaults (void);
static int set_defaults (void);
@@ -225,39 +224,30 @@ static void fail_exit (int code)
static struct group *getgr_nam_gid (const char *grname)
{
- long gid;
- char *errptr;
-
- gid = strtol (grname, &errptr, 10);
- if (*grname != '\0' && *errptr == '\0' && errno != ERANGE && gid >= 0)
+ long long int gid;
+ char *endptr;
+
+ errno = 0;
+ gid = strtoll (grname, &endptr, 10);
+ if ( ('\0' != *grname)
+ && ('\0' == *endptr)
+ && (ERANGE != errno)
+ && (gid == (gid_t)gid)) {
return xgetgrgid (gid);
+ }
return xgetgrnam (grname);
}
static long get_number (const char *numstr)
{
long val;
- char *errptr;
+ char *endptr;
- val = strtol (numstr, &errptr, 10);
- if (*errptr || errno == ERANGE) {
- fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
- numstr);
- exit (E_BAD_ARG);
- }
- return val;
-}
-
-static uid_t get_uid (const char *uidstr)
-{
- long val;
- char *errptr;
-
- val = strtol (uidstr, &errptr, 10);
- if (*errptr || errno == ERANGE || val < 0) {
- fprintf (stderr,
- _("%s: invalid numeric argument '%s'\n"), Prog,
- uidstr);
+ errno = 0;
+ val = strtol (numstr, &endptr, 10);
+ if (('\0' == *numstr) || ('\0' != *endptr) || (ERANGE == errno)) {
+ fprintf (stderr, _("%s: invalid numeric argument '%s'\n"),
+ Prog, numstr);
exit (E_BAD_ARG);
}
return val;
@@ -302,26 +292,13 @@ static void get_defaults (void)
* Primary GROUP identifier
*/
if (MATCH (buf, DGROUP)) {
- unsigned int val = (unsigned int) strtoul (cp, &ep, 10);
- const struct group *grp;
-
- if (*cp != '\0' && *ep == '\0') { /* valid number */
- def_group = val;
- /* local, no need for xgetgrgid */
- if ((grp = getgrgid (def_group))) {
- def_gname = xstrdup (grp->gr_name);
- } else {
- fprintf (stderr,
- _("%s: unknown GID %s\n"),
- Prog, cp);
- }
- /* local, no need for xgetgrnam */
- } else if ((grp = getgrnam (cp))) {
- def_group = grp->gr_gid;
- def_gname = xstrdup (cp);
+ const struct group *grp = getgr_nam_gid (cp);
+ if (NULL == grp) {
+ fprintf (stderr, _("%s: unknown GID %s\n"),
+ Prog, cp);
} else {
- fprintf (stderr,
- _("%s: unknown group %s\n"), Prog, cp);
+ def_group = grp->gr_gid;
+ def_gname = xstrdup (grp->gr_name);
}
}
@@ -343,12 +320,17 @@ static void get_defaults (void)
* Default Password Inactive value
*/
else if (MATCH (buf, INACT)) {
+ errno = 0;
long val = strtol (cp, &ep, 10);
- if (*cp || errno == ERANGE)
+ if ( ('\0' != *cp)
+ && ('\0' == *ep)
+ && (ERANGE != errno)
+ && (val >= 0)) {
def_inactive = val;
- else
+ } else {
def_inactive = -1;
+ }
}
/*
@@ -1080,7 +1062,13 @@ static void process_flags (int argc, cha
sflg++;
break;
case 'u':
- user_id = get_uid (optarg);
+ if ( (get_uid (optarg, &user_id) == 0)
+ || (user_id == (gid_t)-1)) {
+ fprintf (stderr,
+ _("%s: invalid user ID '%s'\n"),
+ Prog, optarg);
+ exit (E_BAD_ARG);
+ }
uflg++;
break;
case 'U':
diff -up shadow-4.1.2/src/usermod.c.uid shadow-4.1.2/src/usermod.c
--- shadow-4.1.2/src/usermod.c.uid 2009-03-23 18:45:59.000000000 +0100
+++ shadow-4.1.2/src/usermod.c 2009-03-23 18:48:36.000000000 +0100
@@ -155,7 +155,6 @@ static void update_gshadow (void);
static void grp_update (void);
static long get_number (const char *);
-static uid_t get_id (const char *);
static void process_flags (int, char **);
static void close_files (void);
static void open_files (void);
@@ -193,12 +192,17 @@ static void date_to_str (char *buf, size
*/
static struct group *getgr_nam_gid (const char *grname)
{
- long val;
- char *errptr;
-
- val = strtol (grname, &errptr, 10);
- if (*grname != '\0' && *errptr == '\0' && errno != ERANGE && val >= 0)
+ long long int val;
+ char *endptr;
+
+ errno = 0;
+ val = strtoll (grname, &endptr, 10);
+ if ( ('\0' != *grname)
+ && ('\0' == *endptr)
+ && (ERANGE != errno)
+ && (val == (gid_t)val)) {
return xgetgrgid (val);
+ }
return xgetgrnam (grname);
}
@@ -752,20 +756,6 @@ static long get_number (const char *nums
return val;
}
-static uid_t get_id (const char *uidstr)
-{
- long val;
- char *errptr;
-
- val = strtol (uidstr, &errptr, 10);
- if (*errptr || errno == ERANGE || val < 0) {
- fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
- uidstr);
- exit (E_BAD_ARG);
- }
- return val;
-}
-
/*
* process_flags - perform command line argument setting
*
@@ -963,7 +953,13 @@ static void process_flags (int argc, cha
sflg++;
break;
case 'u':
- user_newid = get_id (optarg);
+ if ( (get_uid (optarg, &user_newid) ==0)
+ || (user_newid == (uid_t)-1)) {
+ fprintf (stderr,
+ _("%s: invalid user ID '%s'\n"),
+ Prog, optarg);
+ exit (E_BAD_ARG);
+ }
uflg++;
break;
case 'U':

View file

@ -0,0 +1,68 @@
diff -up shadow-4.1.3/libmisc/chkname.c.goodname shadow-4.1.3/libmisc/chkname.c
--- shadow-4.1.3/libmisc/chkname.c.goodname 2008-12-23 23:42:21.000000000 +0100
+++ shadow-4.1.3/libmisc/chkname.c 2009-04-14 11:46:21.000000000 +0200
@@ -54,20 +54,28 @@
static bool is_valid_name (const char *name)
{
/*
- * User/group names must match [a-z_][a-z0-9_-]*[$]
- */
- if (('\0' == *name) ||
- !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
+ * User/group names must match gnu e-regex:
+ * [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]?
+ *
+ * as a non-POSIX, extension, allow "$" as the last char for
+ * sake of Samba 3.x "add machine script"
+ */
+ if ( ('\0' == *name) ||
+ !((*name >= 'a' && *name <= 'z') ||
+ (*name >= 'A' && *name <= 'Z') ||
+ (*name >= '0' && *name <= '9') ||
+ (*name == '_') || (*name == '.')
+ )) {
return false;
}
while ('\0' != *++name) {
- if (!(( ('a' <= *name) && ('z' >= *name) ) ||
- ( ('0' <= *name) && ('9' >= *name) ) ||
- ('_' == *name) ||
- ('-' == *name) ||
- ( ('$' == *name) && ('\0' == *(name + 1)) )
- )) {
+ if (!( (*name >= 'a' && *name <= 'z') ||
+ (*name >= 'A' && *name <= 'Z') ||
+ (*name >= '0' && *name <= '9') ||
+ (*name == '_') || (*name == '.') || (*name == '-') ||
+ (*name == '$' && *(name + 1) == '\0')
+ )) {
return false;
}
}
diff -up shadow-4.1.3/man/groupadd.8.goodname shadow-4.1.3/man/groupadd.8
--- shadow-4.1.3/man/groupadd.8.goodname 2009-04-12 04:46:15.000000000 +0200
+++ shadow-4.1.3/man/groupadd.8 2009-04-14 11:45:13.000000000 +0200
@@ -139,9 +139,7 @@ Shadow password suite configuration\&.
.RE
.SH "CAVEATS"
.PP
-Groupnames must begin with a lower case letter or an underscore, and only lower case letters, underscores, dashes, and dollar signs may follow\&. In regular expression terms: [a\-z_][a\-z0\-9_\-]*[$]?
-.PP
-Groupnames may only be up to 16 characters long\&.
+Groupnames may only be up to 32 characters long\&.
.PP
You may not add a NIS or LDAP group\&. This must be performed on the corresponding server\&.
.PP
diff -up shadow-4.1.3/man/useradd.8.goodname shadow-4.1.3/man/useradd.8
--- shadow-4.1.3/man/useradd.8.goodname 2009-04-12 04:46:35.000000000 +0200
+++ shadow-4.1.3/man/useradd.8 2009-04-14 11:45:13.000000000 +0200
@@ -385,8 +385,6 @@ Similarly, if the username already exist
\fBuseradd\fR
will deny the user account creation request\&.
.PP
-Usernames must begin with a lower case letter or an underscore, and only lower case letters, underscores, dashes, and dollar signs may follow\&. In regular expression terms: [a\-z_][a\-z0\-9_\-]*[$]?
-.PP
Usernames may only be up to 32 characters long\&.
.SH "CONFIGURATION"
.PP

55
shadow-4.1.3-redhat.patch Normal file
View file

@ -0,0 +1,55 @@
diff -up shadow-4.1.3-rc1/libmisc/find_new_gid.c.redhat shadow-4.1.3-rc1/libmisc/find_new_gid.c
--- shadow-4.1.3-rc1/libmisc/find_new_gid.c.redhat 2009-04-06 15:46:43.000000000 +0200
+++ shadow-4.1.3-rc1/libmisc/find_new_gid.c 2009-04-06 15:48:29.000000000 +0200
@@ -56,11 +56,11 @@ int find_new_gid (bool sys_group, gid_t
assert (gid != NULL);
if (!sys_group) {
- gid_min = getdef_ulong ("GID_MIN", 1000L);
+ gid_min = getdef_ulong ("GID_MIN", 500L);
gid_max = getdef_ulong ("GID_MAX", 60000L);
} else {
gid_min = getdef_ulong ("SYS_GID_MIN", 1L);
- gid_max = getdef_ulong ("GID_MIN", 1000L) - 1;
+ gid_max = getdef_ulong ("GID_MIN", 500L) - 1;
gid_max = getdef_ulong ("SYS_GID_MAX", (unsigned long) gid_max);
}
used_gids = alloca (sizeof (char) * gid_max +1);
diff -up shadow-4.1.3-rc1/libmisc/find_new_uid.c.redhat shadow-4.1.3-rc1/libmisc/find_new_uid.c
--- shadow-4.1.3-rc1/libmisc/find_new_uid.c.redhat 2009-04-06 15:46:49.000000000 +0200
+++ shadow-4.1.3-rc1/libmisc/find_new_uid.c 2009-04-06 15:48:46.000000000 +0200
@@ -56,11 +56,11 @@ int find_new_uid (bool sys_user, uid_t *
assert (uid != NULL);
if (!sys_user) {
- uid_min = getdef_ulong ("UID_MIN", 1000L);
+ uid_min = getdef_ulong ("UID_MIN", 500L);
uid_max = getdef_ulong ("UID_MAX", 60000L);
} else {
uid_min = getdef_ulong ("SYS_UID_MIN", 1L);
- uid_max = getdef_ulong ("UID_MIN", 1000L) - 1;
+ uid_max = getdef_ulong ("UID_MIN", 500L) - 1;
uid_max = getdef_ulong ("SYS_UID_MAX", (unsigned long) uid_max);
}
used_uids = alloca (sizeof (char) * uid_max +1);
diff -up shadow-4.1.3-rc1/src/useradd.c.redhat shadow-4.1.3-rc1/src/useradd.c
--- shadow-4.1.3-rc1/src/useradd.c.redhat 2009-04-06 15:49:02.000000000 +0200
+++ shadow-4.1.3-rc1/src/useradd.c 2009-04-06 15:55:22.000000000 +0200
@@ -89,7 +89,7 @@ char *Prog;
static gid_t def_group = 100;
static const char *def_gname = "other";
static const char *def_home = "/home";
-static const char *def_shell = "";
+static const char *def_shell = "/sbin/nologin";
static const char *def_template = SKEL_DIR;
static const char *def_create_mail_spool = "no";
@@ -101,7 +101,7 @@ static char def_file[] = USER_DEFAULTS_F
#define VALID(s) (strcspn (s, ":\n") == strlen (s))
static const char *user_name = "";
-static const char *user_pass = "!";
+static const char *user_pass = "!!";
static uid_t user_id;
static gid_t user_gid;
static const char *user_comment = "";

View file

@ -1,36 +1,22 @@
%if %{?WITH_SELINUX:0}%{!?WITH_SELINUX:1}
%define WITH_SELINUX 1
%endif
Summary: Utilities for managing accounts and shadow password files Summary: Utilities for managing accounts and shadow password files
Name: shadow-utils Name: shadow-utils
Version: 4.1.2 Version: 4.1.3
Release: 13%{?dist} Release: 1%{?dist}
Epoch: 2 Epoch: 2
URL: http://pkg-shadow.alioth.debian.org/ URL: http://pkg-shadow.alioth.debian.org/
Source0: ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/shadow-%{version}.tar.bz2 Source0: ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/shadow-%{version}.tar.bz2
Source1: shadow-4.0.17-login.defs Source1: shadow-4.0.17-login.defs
Source2: shadow-4.0.18.1-useradd Source2: shadow-4.0.18.1-useradd
Patch0: shadow-4.1.3-redhat.patch
Patch0: shadow-4.1.2-redhat.patch Patch1: shadow-4.1.3-goodname.patch
Patch1: shadow-4.1.2-goodname.patch
Patch2: shadow-4.1.2-selinux.patch
Patch3: shadow-4.1.2-sysAccountDownhill.patch
Patch4: shadow-4.1.2-gmSEGV.patch
Patch5: shadow-4.1.2-audit.patch
Patch6: shadow-4.1.1-selinuxUserMappings.patch
Patch7: shadow-4.1.2-checkName.patch
Patch8: shadow-4.1.2-gmNoGroup.patch
Patch9: shadow-4.1.2-uid.patch
License: BSD and GPLv2+ License: BSD and GPLv2+
Group: System Environment/Base Group: System Environment/Base
BuildRequires: autoconf, automake, libtool, gettext-devel
BuildRequires: libselinux-devel >= 1.25.2-1 BuildRequires: libselinux-devel >= 1.25.2-1
BuildRequires: audit-libs-devel >= 1.6.5 BuildRequires: audit-libs-devel >= 1.6.5
#BuildRequires: autoconf, automake, libtool, gettext-devel
Requires: libselinux >= 1.25.2-1 Requires: libselinux >= 1.25.2-1
Requires: audit-libs >= 1.6.5 Requires: audit-libs >= 1.6.5
Requires: setup policycoreutils Requires: setup
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description %description
@ -49,34 +35,23 @@ are used for managing group accounts.
%setup -q -n shadow-%{version} %setup -q -n shadow-%{version}
%patch0 -p1 -b .redhat %patch0 -p1 -b .redhat
%patch1 -p1 -b .goodname %patch1 -p1 -b .goodname
%patch2 -p1 -b .selinux
%patch3 -p1 -b .sysAccountDownhill
%patch4 -p1 -b .gmSEGV
%patch5 -p1 -b .audit
%patch6 -p1 -b .selinuxUserMappings
%patch7 -p1 -b .checkName
%patch8 -p1 -b .gmNoGroup
%patch9 -p1 -b .uid
iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8
cp -f doc/HOWTO.utf8 doc/HOWTO cp -f doc/HOWTO.utf8 doc/HOWTO
rm po/*.gmo #rm po/*.gmo
rm po/stamp-po #rm po/stamp-po
#aclocal
aclocal #libtoolize --force
libtoolize --force #automake -a
automake -a #autoconf
autoconf
%build %build
%configure \ %configure \
--enable-shadowgrp \ --enable-shadowgrp \
--with-audit \ --with-audit \
--with-sha-crypt \ --with-sha-crypt \
%if %{WITH_SELINUX}
--with-selinux \ --with-selinux \
%endif
--without-libcrack \ --without-libcrack \
--without-libpam \ --without-libpam \
--disable-shared --disable-shared
@ -199,11 +174,11 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man8/vigr.8* %{_mandir}/man8/vigr.8*
%changelog %changelog
* Tue Mar 24 2009 Peter Vrabec <pvrabec@redhat.com> 2:4.1.2-13 * Tue Apr 14 2009 Peter Vrabec <pvrabec@redhat.com> 2:4.1.3-1
- do not allow UID/GID = 4294967295 (#484040,#133664) - upgrade
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2:4.1.2-12 * Tue Mar 24 2009 Peter Vrabec <pvrabec@redhat.com> 2:4.1.2-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild - don not allow UID/GID = 4294967295 (#484040)
* Mon Jan 19 2009 Peter Vrabec <pvrabec@redhat.com> 2:4.1.2-11 * Mon Jan 19 2009 Peter Vrabec <pvrabec@redhat.com> 2:4.1.2-11
- fix license tag (#226416) - fix license tag (#226416)

View file

@ -1,4 +1,3 @@
e91727c55dbafc9915250e31535f13bb shadow-4.0.17-login.defs e91727c55dbafc9915250e31535f13bb shadow-4.0.17-login.defs
ebdf46b79f9b414353c9ae8aba4d55cc shadow-4.0.18.1-useradd ebdf46b79f9b414353c9ae8aba4d55cc shadow-4.0.18.1-useradd
b1aa30abb3cce16a37b53e45e1ec70a4 shadow-4.1.1.tar.bz2 d222bd50f64d52a32882c82ab1e85f28 shadow-4.1.3.tar.bz2
ce90cbe9cba7f6673cb10cad49083c1c shadow-4.1.2.tar.bz2