Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81de782d1e | ||
|
|
d83eccdded | ||
|
|
681b66b13c | ||
|
|
2958bd050b | ||
|
|
38f493aff2 | ||
|
|
19bac44dde | ||
|
|
b49712ed32 | ||
|
|
cdbe1310cc | ||
|
|
b462f5335f | ||
|
|
115a4e89e2 | ||
|
|
9d935d9be1 | ||
|
|
7eca1112fb | ||
|
|
fe2a266c50 | ||
|
|
e97df9b1ec | ||
|
|
d048459d36 | ||
|
|
88fa0651bf | ||
|
|
4e038f3ae7 | ||
|
|
6c6c8d3a33 | ||
|
|
a8a921184f | ||
|
|
cbd2472b7c | ||
|
|
a0efca4581 | ||
|
|
4e1da34601 | ||
|
|
b03df41906 | ||
|
|
8ca6eea938 | ||
|
|
1c2ad5e6b9 | ||
|
|
991fee82df | ||
|
|
b52ce71c27 | ||
|
|
e78d22469f | ||
|
|
c4e8b411d4 | ||
|
|
3a51b90145 | ||
|
|
a2cd3e9ef0 | ||
|
|
1cbb562c23 | ||
|
|
558977bb2b | ||
|
|
332709da65 | ||
|
|
a74587a4ea | ||
|
|
1e13749483 | ||
|
|
1a1b8fcc36 | ||
|
|
23262b249c | ||
|
|
5687be5f31 | ||
|
|
e293aa9cfc | ||
|
|
edf7547ad5 | ||
|
|
2cac079ef4 | ||
|
|
5afc1c5b5f | ||
|
|
3025fefc41 | ||
|
|
00a5cff244 | ||
|
|
fc0ed79e5d | ||
|
|
13c618465d | ||
|
|
3c52a84ff8 |
21
ChangeLog
21
ChangeLog
@@ -1,3 +1,24 @@
|
|||||||
|
2019-12-01 Serge Hallyn <serge@hallyn.com>
|
||||||
|
|
||||||
|
* Release 4.8
|
||||||
|
* Initial optional bcrypt support.
|
||||||
|
* Make build/install of 'su' optional.
|
||||||
|
* Fix for vipw not resuming correctly when suspended
|
||||||
|
* Sync password field descriptions in manpages
|
||||||
|
* Check for valid shell argument in useradd
|
||||||
|
* Allow translation of new strings through POTFILES.in
|
||||||
|
* Migrate to itstool for translations
|
||||||
|
* Migrate to new SELinux api
|
||||||
|
* Support --enable-vendordir
|
||||||
|
* pwck: Only check homedir if set and not a system user
|
||||||
|
* Support nonstandard usernames
|
||||||
|
* sget{pw,gr}ent: check for data at EOL
|
||||||
|
* Add YYY-MM-DD support in chage
|
||||||
|
* Fix failing chmod calls for suidubins
|
||||||
|
* Fix --sbindir and --bindir for binary installations
|
||||||
|
* Fix LASTLOG_UID_MAX in login.defs
|
||||||
|
* Fix configure error with dash
|
||||||
|
|
||||||
2019-06-13 Serge Hallyn <serge@hallyn.com>
|
2019-06-13 Serge Hallyn <serge@hallyn.com>
|
||||||
|
|
||||||
* Release 4.7
|
* Release 4.7
|
||||||
|
|||||||
31
configure.ac
31
configure.ac
@@ -1,6 +1,6 @@
|
|||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
AC_PREREQ([2.64])
|
AC_PREREQ([2.64])
|
||||||
AC_INIT([shadow], [4.7], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
AC_INIT([shadow], [4.8], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
||||||
[https://github.com/shadow-maint/shadow])
|
[https://github.com/shadow-maint/shadow])
|
||||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz])
|
AM_INIT_AUTOMAKE([1.11 foreign dist-xz])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
@@ -277,6 +277,9 @@ AC_ARG_WITH(libcrack,
|
|||||||
AC_ARG_WITH(sha-crypt,
|
AC_ARG_WITH(sha-crypt,
|
||||||
[AC_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
|
[AC_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
|
||||||
[with_sha_crypt=$withval], [with_sha_crypt=yes])
|
[with_sha_crypt=$withval], [with_sha_crypt=yes])
|
||||||
|
AC_ARG_WITH(bcrypt,
|
||||||
|
[AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
|
||||||
|
[with_bcrypt=$withval], [with_bcrypt=no])
|
||||||
AC_ARG_WITH(nscd,
|
AC_ARG_WITH(nscd,
|
||||||
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
|
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
|
||||||
[with_nscd=$withval], [with_nscd=yes])
|
[with_nscd=$withval], [with_nscd=yes])
|
||||||
@@ -286,6 +289,9 @@ AC_ARG_WITH(sssd,
|
|||||||
AC_ARG_WITH(group-name-max-length,
|
AC_ARG_WITH(group-name-max-length,
|
||||||
[AC_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=16@:>@])],
|
[AC_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=16@:>@])],
|
||||||
[with_group_name_max_length=$withval], [with_group_name_max_length=yes])
|
[with_group_name_max_length=$withval], [with_group_name_max_length=yes])
|
||||||
|
AC_ARG_WITH(su,
|
||||||
|
[AC_HELP_STRING([--with-su], [build and install su program and man page @<:@default=yes@:>@])],
|
||||||
|
[with_su=$withval], [with_su=yes])
|
||||||
|
|
||||||
if test "$with_group_name_max_length" = "no" ; then
|
if test "$with_group_name_max_length" = "no" ; then
|
||||||
with_group_name_max_length=0
|
with_group_name_max_length=0
|
||||||
@@ -301,6 +307,11 @@ if test "$with_sha_crypt" = "yes"; then
|
|||||||
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
|
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL(USE_BCRYPT, test "x$with_bcrypt" = "xyes")
|
||||||
|
if test "$with_bcrypt" = "yes"; then
|
||||||
|
AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm])
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$with_nscd" = "yes"; then
|
if test "$with_nscd" = "yes"; then
|
||||||
AC_CHECK_FUNC(posix_spawn,
|
AC_CHECK_FUNC(posix_spawn,
|
||||||
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
|
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
|
||||||
@@ -313,6 +324,9 @@ if test "$with_sssd" = "yes"; then
|
|||||||
[AC_MSG_ERROR([posix_spawn is needed for sssd support])])
|
[AC_MSG_ERROR([posix_spawn is needed for sssd support])])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AS_IF([test "$with_su" != "no"], AC_DEFINE(WITH_SU, 1, [Build with su])])
|
||||||
|
AM_CONDITIONAL([WITH_SU], [test "x$with_su" != "xno"])
|
||||||
|
|
||||||
dnl Check for some functions in libc first, only if not found check for
|
dnl Check for some functions in libc first, only if not found check for
|
||||||
dnl other libraries. This should prevent linking libnsl if not really
|
dnl other libraries. This should prevent linking libnsl if not really
|
||||||
dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
|
dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
|
||||||
@@ -321,6 +335,17 @@ AC_SEARCH_LIBS(inet_ntoa, inet)
|
|||||||
AC_SEARCH_LIBS(socket, socket)
|
AC_SEARCH_LIBS(socket, socket)
|
||||||
AC_SEARCH_LIBS(gethostbyname, nsl)
|
AC_SEARCH_LIBS(gethostbyname, nsl)
|
||||||
|
|
||||||
|
AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
|
||||||
|
if test -n "$LIBECONF"; then
|
||||||
|
ECONF_CPPFLAGS="-DUSE_ECONF=1"
|
||||||
|
AC_ARG_ENABLE([vendordir],
|
||||||
|
AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files]),,[])
|
||||||
|
fi
|
||||||
|
AC_SUBST(ECONF_CPPFLAGS)
|
||||||
|
AC_SUBST(LIBECONF)
|
||||||
|
AC_SUBST([VENDORDIR], [$enable_vendordir])
|
||||||
|
AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
|
||||||
|
|
||||||
if test "$enable_shadowgrp" = "yes"; then
|
if test "$enable_shadowgrp" = "yes"; then
|
||||||
AC_DEFINE(SHADOWGRP, 1, [Define to support the shadow group file.])
|
AC_DEFINE(SHADOWGRP, 1, [Define to support the shadow group file.])
|
||||||
fi
|
fi
|
||||||
@@ -500,7 +525,7 @@ if test "$with_selinux" != "no"; then
|
|||||||
AC_MSG_ERROR([libsemanage not found])
|
AC_MSG_ERROR([libsemanage not found])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$selinux_lib$semanage_lib" == "yesyes" ; then
|
if test "$selinux_lib$semanage_lib" = "yesyes" ; then
|
||||||
AC_DEFINE(WITH_SELINUX, 1,
|
AC_DEFINE(WITH_SELINUX, 1,
|
||||||
[Build shadow with SELinux support])
|
[Build shadow with SELinux support])
|
||||||
LIBSELINUX="-lselinux"
|
LIBSELINUX="-lselinux"
|
||||||
@@ -715,8 +740,10 @@ echo " tcb support (incomplete): $with_tcb"
|
|||||||
echo " shadow group support: $enable_shadowgrp"
|
echo " shadow group support: $enable_shadowgrp"
|
||||||
echo " S/Key support: $with_skey"
|
echo " S/Key support: $with_skey"
|
||||||
echo " SHA passwords encryption: $with_sha_crypt"
|
echo " SHA passwords encryption: $with_sha_crypt"
|
||||||
|
echo " bcrypt passwords encryption: $with_bcrypt"
|
||||||
echo " nscd support: $with_nscd"
|
echo " nscd support: $with_nscd"
|
||||||
echo " sssd support: $with_sssd"
|
echo " sssd support: $with_sssd"
|
||||||
echo " subordinate IDs support: $enable_subids"
|
echo " subordinate IDs support: $enable_subids"
|
||||||
echo " use file caps: $with_fcaps"
|
echo " use file caps: $with_fcaps"
|
||||||
|
echo " install su: $with_su"
|
||||||
echo
|
echo
|
||||||
|
|||||||
@@ -31,6 +31,15 @@ LOG_OK_LOGINS no
|
|||||||
#
|
#
|
||||||
LASTLOG_ENAB yes
|
LASTLOG_ENAB yes
|
||||||
|
|
||||||
|
#
|
||||||
|
# Limit the highest user ID number for which the lastlog entries should
|
||||||
|
# be updated.
|
||||||
|
#
|
||||||
|
# No LASTLOG_UID_MAX means that there is no user ID limit for writing
|
||||||
|
# lastlog entries.
|
||||||
|
#
|
||||||
|
#LASTLOG_UID_MAX
|
||||||
|
|
||||||
#
|
#
|
||||||
# Enable checking and display of mailbox status upon login.
|
# Enable checking and display of mailbox status upon login.
|
||||||
#
|
#
|
||||||
@@ -311,6 +320,7 @@ CHFN_RESTRICT rwh
|
|||||||
# If set to MD5, MD5-based algorithm will be used for encrypting password
|
# If set to MD5, MD5-based algorithm will be used for encrypting password
|
||||||
# If set to SHA256, SHA256-based algorithm will be used for encrypting password
|
# If set to SHA256, SHA256-based algorithm will be used for encrypting password
|
||||||
# If set to SHA512, SHA512-based algorithm will be used for encrypting password
|
# If set to SHA512, SHA512-based algorithm will be used for encrypting password
|
||||||
|
# If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password
|
||||||
# If set to DES, DES-based algorithm will be used for encrypting password (default)
|
# If set to DES, DES-based algorithm will be used for encrypting password (default)
|
||||||
# Overrides the MD5_CRYPT_ENAB option
|
# Overrides the MD5_CRYPT_ENAB option
|
||||||
#
|
#
|
||||||
@@ -332,8 +342,23 @@ CHFN_RESTRICT rwh
|
|||||||
# If only one of the MIN or MAX values is set, then this value will be used.
|
# If only one of the MIN or MAX values is set, then this value will be used.
|
||||||
# If MIN > MAX, the highest value will be used.
|
# If MIN > MAX, the highest value will be used.
|
||||||
#
|
#
|
||||||
# SHA_CRYPT_MIN_ROUNDS 5000
|
#SHA_CRYPT_MIN_ROUNDS 5000
|
||||||
# SHA_CRYPT_MAX_ROUNDS 5000
|
#SHA_CRYPT_MAX_ROUNDS 5000
|
||||||
|
|
||||||
|
#
|
||||||
|
# Only works if ENCRYPT_METHOD is set to BCRYPT.
|
||||||
|
#
|
||||||
|
# Define the number of BCRYPT rounds.
|
||||||
|
# With a lot of rounds, it is more difficult to brute-force the password.
|
||||||
|
# However, more CPU resources will be needed to authenticate users if
|
||||||
|
# this value is increased.
|
||||||
|
#
|
||||||
|
# If not specified, 13 rounds will be attempted.
|
||||||
|
# If only one of the MIN or MAX values is set, then this value will be used.
|
||||||
|
# If MIN > MAX, the highest value will be used.
|
||||||
|
#
|
||||||
|
#BCRYPT_MIN_ROUNDS 13
|
||||||
|
#BCRYPT_MAX_ROUNDS 13
|
||||||
|
|
||||||
#
|
#
|
||||||
# List of groups to add to the user's supplementary group set
|
# List of groups to add to the user's supplementary group set
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ pamd_files = \
|
|||||||
chsh \
|
chsh \
|
||||||
groupmems \
|
groupmems \
|
||||||
login \
|
login \
|
||||||
passwd \
|
passwd
|
||||||
su
|
|
||||||
|
|
||||||
pamd_acct_tools_files = \
|
pamd_acct_tools_files = \
|
||||||
chage \
|
chage \
|
||||||
@@ -29,4 +28,8 @@ pamd_DATA += $(pamd_acct_tools_files)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if WITH_SU
|
||||||
|
pamd_files += su
|
||||||
|
endif
|
||||||
|
|
||||||
EXTRA_DIST = $(pamd_files) $(pamd_acct_tools_files)
|
EXTRA_DIST = $(pamd_files) $(pamd_acct_tools_files)
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ DEFS =
|
|||||||
noinst_LTLIBRARIES = libshadow.la
|
noinst_LTLIBRARIES = libshadow.la
|
||||||
|
|
||||||
libshadow_la_LDFLAGS = -version-info 0:0:0
|
libshadow_la_LDFLAGS = -version-info 0:0:0
|
||||||
|
libshadow_la_CPPFLAGS = $(ECONF_CPPFLAGS)
|
||||||
|
if HAVE_VENDORDIR
|
||||||
|
libshadow_la_CPPFLAGS += -DVENDORDIR=\"$(VENDORDIR)\"
|
||||||
|
endif
|
||||||
|
|
||||||
libshadow_la_SOURCES = \
|
libshadow_la_SOURCES = \
|
||||||
commonio.c \
|
commonio.c \
|
||||||
|
|||||||
@@ -65,6 +65,9 @@
|
|||||||
case '1':
|
case '1':
|
||||||
method = "MD5";
|
method = "MD5";
|
||||||
break;
|
break;
|
||||||
|
case '2':
|
||||||
|
method = "BCRYPT";
|
||||||
|
break;
|
||||||
case '5':
|
case '5':
|
||||||
method = "SHA256";
|
method = "SHA256";
|
||||||
break;
|
break;
|
||||||
|
|||||||
80
lib/getdef.c
80
lib/getdef.c
@@ -40,6 +40,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#ifdef USE_ECONF
|
||||||
|
#include <libeconf.h>
|
||||||
|
#endif
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
/*
|
/*
|
||||||
* A configuration item definition.
|
* A configuration item definition.
|
||||||
@@ -107,6 +110,10 @@ static struct itemdef def_table[] = {
|
|||||||
#ifdef USE_SHA_CRYPT
|
#ifdef USE_SHA_CRYPT
|
||||||
{"SHA_CRYPT_MAX_ROUNDS", NULL},
|
{"SHA_CRYPT_MAX_ROUNDS", NULL},
|
||||||
{"SHA_CRYPT_MIN_ROUNDS", NULL},
|
{"SHA_CRYPT_MIN_ROUNDS", NULL},
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
{"BCRYPT_MAX_ROUNDS", NULL},
|
||||||
|
{"BCRYPT_MIN_ROUNDS", NULL},
|
||||||
#endif
|
#endif
|
||||||
{"SUB_GID_COUNT", NULL},
|
{"SUB_GID_COUNT", NULL},
|
||||||
{"SUB_GID_MAX", NULL},
|
{"SUB_GID_MAX", NULL},
|
||||||
@@ -152,11 +159,20 @@ static struct itemdef knowndef_table[] = {
|
|||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef USE_ECONF
|
||||||
|
#ifdef VENDORDIR
|
||||||
|
static const char* vendordir = VENDORDIR;
|
||||||
|
#else
|
||||||
|
static const char* vendordir = NULL;
|
||||||
|
#endif
|
||||||
|
static const char* sysconfdir = "/etc";
|
||||||
|
#else
|
||||||
#ifndef LOGINDEFS
|
#ifndef LOGINDEFS
|
||||||
#define LOGINDEFS "/etc/login.defs"
|
#define LOGINDEFS "/etc/login.defs"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char* def_fname = LOGINDEFS; /* login config defs file */
|
static const char* def_fname = LOGINDEFS; /* login config defs file */
|
||||||
|
#endif
|
||||||
static bool def_loaded = false; /* are defs already loaded? */
|
static bool def_loaded = false; /* are defs already loaded? */
|
||||||
|
|
||||||
/* local function prototypes */
|
/* local function prototypes */
|
||||||
@@ -433,7 +449,27 @@ out:
|
|||||||
|
|
||||||
void setdef_config_file (const char* file)
|
void setdef_config_file (const char* file)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_ECONF
|
||||||
|
size_t len;
|
||||||
|
char* cp;
|
||||||
|
|
||||||
|
len = strlen(file) + strlen(sysconfdir) + 2;
|
||||||
|
cp = malloc(len);
|
||||||
|
if (cp == NULL)
|
||||||
|
exit (13);
|
||||||
|
snprintf(cp, len, "%s/%s", file, sysconfdir);
|
||||||
|
sysconfdir = cp;
|
||||||
|
#ifdef VENDORDIR
|
||||||
|
len = strlen(file) + strlen(vendordir) + 2;
|
||||||
|
cp = malloc(len);
|
||||||
|
if (cp == NULL)
|
||||||
|
exit (13);
|
||||||
|
snprintf(cp, len, "%s/%s", file, vendordir);
|
||||||
|
vendordir = cp;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
def_fname = file;
|
def_fname = file;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -444,9 +480,16 @@ void setdef_config_file (const char* file)
|
|||||||
|
|
||||||
static void def_load (void)
|
static void def_load (void)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_ECONF
|
||||||
|
econf_file *defs_file = NULL;
|
||||||
|
econf_err error;
|
||||||
|
char **keys;
|
||||||
|
size_t key_number;
|
||||||
|
#else
|
||||||
int i;
|
int i;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buf[1024], *name, *value, *s;
|
char buf[1024], *name, *value, *s;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the initialized flag.
|
* Set the initialized flag.
|
||||||
@@ -454,6 +497,42 @@ static void def_load (void)
|
|||||||
*/
|
*/
|
||||||
def_loaded = true;
|
def_loaded = true;
|
||||||
|
|
||||||
|
#ifdef USE_ECONF
|
||||||
|
|
||||||
|
error = econf_readDirs (&defs_file, vendordir, sysconfdir, "login", "defs", " \t", "#");
|
||||||
|
if (error) {
|
||||||
|
if (error == ECONF_NOFILE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SYSLOG ((LOG_CRIT, "cannot open login definitions [%s]",
|
||||||
|
econf_errString(error)));
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((error = econf_getKeys(defs_file, NULL, &key_number, &keys))) {
|
||||||
|
SYSLOG ((LOG_CRIT, "cannot read login definitions [%s]",
|
||||||
|
econf_errString(error)));
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < key_number; i++) {
|
||||||
|
char *value;
|
||||||
|
|
||||||
|
econf_getStringValue(defs_file, NULL, keys[i], &value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Store the value in def_table.
|
||||||
|
*
|
||||||
|
* Ignore failures to load the login.defs file.
|
||||||
|
* The error was already reported to the user and to
|
||||||
|
* syslog. The tools will just use their default values.
|
||||||
|
*/
|
||||||
|
(void)putdef_str (keys[i], value);
|
||||||
|
}
|
||||||
|
|
||||||
|
econf_free (keys);
|
||||||
|
econf_free (defs_file);
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* Open the configuration definitions file.
|
* Open the configuration definitions file.
|
||||||
*/
|
*/
|
||||||
@@ -517,6 +596,7 @@ static void def_load (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
(void) fclose (fp);
|
(void) fclose (fp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -336,6 +336,7 @@ extern /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const
|
|||||||
#ifdef WITH_SELINUX
|
#ifdef WITH_SELINUX
|
||||||
extern int set_selinux_file_context (const char *dst_name);
|
extern int set_selinux_file_context (const char *dst_name);
|
||||||
extern int reset_selinux_file_context (void);
|
extern int reset_selinux_file_context (void);
|
||||||
|
extern int check_selinux_permit (const char *perm_name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* semanage.c */
|
/* semanage.c */
|
||||||
|
|||||||
100
lib/selinux.c
100
lib/selinux.c
@@ -34,6 +34,7 @@
|
|||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
#include <selinux/selinux.h>
|
#include <selinux/selinux.h>
|
||||||
|
#include <selinux/context.h>
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -98,6 +99,105 @@ int reset_selinux_file_context (void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log callback for libselinux internal error reporting.
|
||||||
|
*/
|
||||||
|
__attribute__((__format__ (printf, 2, 3)))
|
||||||
|
static int selinux_log_cb (int type, const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
char *buf;
|
||||||
|
int r;
|
||||||
|
#ifdef WITH_AUDIT
|
||||||
|
static int selinux_audit_fd = -2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
va_start (ap, fmt);
|
||||||
|
r = vasprintf (&buf, fmt, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_AUDIT
|
||||||
|
if (-2 == selinux_audit_fd) {
|
||||||
|
selinux_audit_fd = audit_open ();
|
||||||
|
|
||||||
|
if (-1 == selinux_audit_fd) {
|
||||||
|
/* You get these only when the kernel doesn't have
|
||||||
|
* audit compiled in. */
|
||||||
|
if ( (errno != EINVAL)
|
||||||
|
&& (errno != EPROTONOSUPPORT)
|
||||||
|
&& (errno != EAFNOSUPPORT)) {
|
||||||
|
|
||||||
|
(void) fputs (_("Cannot open audit interface.\n"),
|
||||||
|
stderr);
|
||||||
|
SYSLOG ((LOG_WARN, "Cannot open audit interface."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 != selinux_audit_fd) {
|
||||||
|
if (SELINUX_AVC == type) {
|
||||||
|
if (audit_log_user_avc_message (selinux_audit_fd,
|
||||||
|
AUDIT_USER_AVC, buf, NULL, NULL,
|
||||||
|
NULL, 0) > 0) {
|
||||||
|
goto skip_syslog;
|
||||||
|
}
|
||||||
|
} else if (SELINUX_ERROR == type) {
|
||||||
|
if (audit_log_user_avc_message (selinux_audit_fd,
|
||||||
|
AUDIT_USER_SELINUX_ERR, buf, NULL, NULL,
|
||||||
|
NULL, 0) > 0) {
|
||||||
|
goto skip_syslog;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SYSLOG ((LOG_WARN, "libselinux: %s", buf));
|
||||||
|
|
||||||
|
skip_syslog:
|
||||||
|
free (buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check_selinux_permit - Check whether SELinux grants the given
|
||||||
|
* operation
|
||||||
|
*
|
||||||
|
* Parameter is the SELinux permission name, e.g. rootok
|
||||||
|
*
|
||||||
|
* Returns 0 when permission is granted
|
||||||
|
* or something failed but running in
|
||||||
|
* permissive mode
|
||||||
|
*/
|
||||||
|
int check_selinux_permit (const char *perm_name)
|
||||||
|
{
|
||||||
|
char *user_context_str;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (0 == is_selinux_enabled ()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) selinux_log_cb);
|
||||||
|
|
||||||
|
if (getprevcon (&user_context_str) != 0) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: can not get previous SELinux process context: %s\n"),
|
||||||
|
Prog, strerror (errno));
|
||||||
|
SYSLOG ((LOG_WARN,
|
||||||
|
"can not get previous SELinux process context: %s",
|
||||||
|
strerror (errno)));
|
||||||
|
return (security_getenforce () != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = selinux_check_access (user_context_str, user_context_str, "passwd", perm_name, NULL);
|
||||||
|
freecon (user_context_str);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#else /* !WITH_SELINUX */
|
#else /* !WITH_SELINUX */
|
||||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* !WITH_SELINUX */
|
#endif /* !WITH_SELINUX */
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ struct group *sgetgrent (const char *buf)
|
|||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < (NFIELDS - 1) || *grpfields[2] == '\0') {
|
if (i < (NFIELDS - 1) || *grpfields[2] == '\0' || cp != NULL) {
|
||||||
return (struct group *) 0;
|
return (struct group *) 0;
|
||||||
}
|
}
|
||||||
grent.gr_name = grpfields[0];
|
grent.gr_name = grpfields[0];
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ struct passwd *sgetpwent (const char *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* something at the end, columns over shot */
|
||||||
|
if( cp != NULL ) {
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There must be exactly NFIELDS colon separated fields or
|
* There must be exactly NFIELDS colon separated fields or
|
||||||
* the entry is invalid. Also, the UID and GID must be non-blank.
|
* the entry is invalid. Also, the UID and GID must be non-blank.
|
||||||
|
|||||||
@@ -152,11 +152,6 @@ static struct commonio_ops subordinate_ops = {
|
|||||||
NULL, /* close_hook */
|
NULL, /* close_hook */
|
||||||
};
|
};
|
||||||
|
|
||||||
static /*@observer@*/ /*@null*/const struct subordinate_range *subordinate_next(struct commonio_db *db)
|
|
||||||
{
|
|
||||||
return (const struct subordinate_range *)commonio_next (db);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* range_exists: Check whether @owner owns any ranges
|
* range_exists: Check whether @owner owns any ranges
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
EXTRA_DIST = .indent.pro xgetXXbyYY.c
|
EXTRA_DIST = .indent.pro xgetXXbyYY.c
|
||||||
|
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/lib
|
AM_CPPFLAGS = -I$(top_srcdir)/lib $(ECONF_CPPFLAGS)
|
||||||
|
|
||||||
noinst_LIBRARIES = libmisc.a
|
noinst_LIBRARIES = libmisc.a
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,18 @@
|
|||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "chkname.h"
|
#include "chkname.h"
|
||||||
|
|
||||||
|
int allow_bad_names = false;
|
||||||
|
|
||||||
static bool is_valid_name (const char *name)
|
static bool is_valid_name (const char *name)
|
||||||
{
|
{
|
||||||
|
if (allow_bad_names) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* User/group names must match [a-z_][a-z0-9_-]*[$]
|
* User/group names must match [a-z_][a-z0-9_-]*[$]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (('\0' == *name) ||
|
if (('\0' == *name) ||
|
||||||
!((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
|
!((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ int find_new_gid (bool sys_group,
|
|||||||
bool *used_gids;
|
bool *used_gids;
|
||||||
const struct group *grp;
|
const struct group *grp;
|
||||||
gid_t gid_min, gid_max, preferred_min;
|
gid_t gid_min, gid_max, preferred_min;
|
||||||
gid_t group_id, id;
|
gid_t id;
|
||||||
gid_t lowest_found, highest_found;
|
gid_t lowest_found, highest_found;
|
||||||
int result;
|
int result;
|
||||||
int nospam = 0;
|
int nospam = 0;
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ int find_new_uid(bool sys_user,
|
|||||||
bool *used_uids;
|
bool *used_uids;
|
||||||
const struct passwd *pwd;
|
const struct passwd *pwd;
|
||||||
uid_t uid_min, uid_max, preferred_min;
|
uid_t uid_min, uid_max, preferred_min;
|
||||||
uid_t user_id, id;
|
uid_t id;
|
||||||
uid_t lowest_found, highest_found;
|
uid_t lowest_found, highest_found;
|
||||||
int result;
|
int result;
|
||||||
int nospam = 0;
|
int nospam = 0;
|
||||||
|
|||||||
@@ -268,6 +268,9 @@ static /*@observer@*//*@null@*/const char *obscure_msg (
|
|||||||
#ifdef USE_SHA_CRYPT
|
#ifdef USE_SHA_CRYPT
|
||||||
|| (strcmp (result, "SHA256") == 0)
|
|| (strcmp (result, "SHA256") == 0)
|
||||||
|| (strcmp (result, "SHA512") == 0)
|
|| (strcmp (result, "SHA512") == 0)
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
|| (strcmp (result, "BCRYPT") == 0)
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -141,10 +141,14 @@ extern const char* process_prefix_flag (const char* short_opt, int argc, char **
|
|||||||
sub_gid_setdbname(sgid_db_file);
|
sub_gid_setdbname(sgid_db_file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_ECONF
|
||||||
|
setdef_config_file(prefix);
|
||||||
|
#else
|
||||||
len = strlen(prefix) + strlen("/etc/login.defs") + 2;
|
len = strlen(prefix) + strlen("/etc/login.defs") + 2;
|
||||||
def_conf_file = xmalloc(len);
|
def_conf_file = xmalloc(len);
|
||||||
snprintf(def_conf_file, len, "%s/%s", prefix, "/etc/login.defs");
|
snprintf(def_conf_file, len, "%s/%s", prefix, "/etc/login.defs");
|
||||||
setdef_config_file(def_conf_file);
|
setdef_config_file(def_conf_file);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefix == NULL)
|
if (prefix == NULL)
|
||||||
|
|||||||
123
libmisc/salt.c
123
libmisc/salt.c
@@ -22,10 +22,16 @@
|
|||||||
/* local function prototypes */
|
/* local function prototypes */
|
||||||
static void seedRNG (void);
|
static void seedRNG (void);
|
||||||
static /*@observer@*/const char *gensalt (size_t salt_size);
|
static /*@observer@*/const char *gensalt (size_t salt_size);
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
static long shadow_random (long min, long max);
|
static long shadow_random (long min, long max);
|
||||||
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
|
#ifdef USE_SHA_CRYPT
|
||||||
static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds);
|
static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds);
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT */
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
static /*@observer@*/const char *gensalt_bcrypt (void);
|
||||||
|
static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds);
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
|
|
||||||
#ifndef HAVE_L64A
|
#ifndef HAVE_L64A
|
||||||
static /*@observer@*/char *l64a(long value)
|
static /*@observer@*/char *l64a(long value)
|
||||||
@@ -79,8 +85,16 @@ static void seedRNG (void)
|
|||||||
* Add the salt prefix.
|
* Add the salt prefix.
|
||||||
*/
|
*/
|
||||||
#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0'
|
#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0'
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
/*
|
||||||
|
* Using the Prefix $2a$ to enable an anti-collision safety measure in musl libc.
|
||||||
|
* Negatively affects a subset of passwords containing the '\xff' character,
|
||||||
|
* which is not valid UTF-8 (so "unlikely to cause much annoyance").
|
||||||
|
*/
|
||||||
|
#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='a',(array)[4]='\0'
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
|
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
/* It is not clear what is the maximum value of random().
|
/* It is not clear what is the maximum value of random().
|
||||||
* We assume 2^31-1.*/
|
* We assume 2^31-1.*/
|
||||||
#define RANDOM_MAX 0x7FFFFFFF
|
#define RANDOM_MAX 0x7FFFFFFF
|
||||||
@@ -105,14 +119,15 @@ static long shadow_random (long min, long max)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
|
|
||||||
|
#ifdef USE_SHA_CRYPT
|
||||||
/* Default number of rounds if not explicitly specified. */
|
/* Default number of rounds if not explicitly specified. */
|
||||||
#define ROUNDS_DEFAULT 5000
|
#define ROUNDS_DEFAULT 5000
|
||||||
/* Minimum number of rounds. */
|
/* Minimum number of rounds. */
|
||||||
#define ROUNDS_MIN 1000
|
#define ROUNDS_MIN 1000
|
||||||
/* Maximum number of rounds. */
|
/* Maximum number of rounds. */
|
||||||
#define ROUNDS_MAX 999999999
|
#define ROUNDS_MAX 999999999
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return a salt prefix specifying the rounds number for the SHA crypt methods.
|
* Return a salt prefix specifying the rounds number for the SHA crypt methods.
|
||||||
*/
|
*/
|
||||||
@@ -165,6 +180,89 @@ static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds
|
|||||||
}
|
}
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT */
|
||||||
|
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
/* Default number of rounds if not explicitly specified. */
|
||||||
|
#define B_ROUNDS_DEFAULT 13
|
||||||
|
/* Minimum number of rounds. */
|
||||||
|
#define B_ROUNDS_MIN 4
|
||||||
|
/* Maximum number of rounds. */
|
||||||
|
#define B_ROUNDS_MAX 31
|
||||||
|
/*
|
||||||
|
* Return a salt prefix specifying the rounds number for the BCRYPT method.
|
||||||
|
*/
|
||||||
|
static /*@observer@*/const char *BCRYPT_salt_rounds (/*@null@*/int *prefered_rounds)
|
||||||
|
{
|
||||||
|
static char rounds_prefix[4]; /* Max size: 31$ */
|
||||||
|
long rounds;
|
||||||
|
|
||||||
|
if (NULL == prefered_rounds) {
|
||||||
|
long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1);
|
||||||
|
long max_rounds = getdef_long ("BCRYPT_MAX_ROUNDS", -1);
|
||||||
|
|
||||||
|
if (((-1 == min_rounds) && (-1 == max_rounds)) || (0 == *prefered_rounds)) {
|
||||||
|
rounds = B_ROUNDS_DEFAULT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (-1 == min_rounds) {
|
||||||
|
min_rounds = max_rounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 == max_rounds) {
|
||||||
|
max_rounds = min_rounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min_rounds > max_rounds) {
|
||||||
|
max_rounds = min_rounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
rounds = shadow_random (min_rounds, max_rounds);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rounds = *prefered_rounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sanity checks.
|
||||||
|
* Use 19 as an upper bound for now,
|
||||||
|
* because musl doesn't allow rounds >= 20.
|
||||||
|
*/
|
||||||
|
if (rounds < B_ROUNDS_MIN) {
|
||||||
|
rounds = B_ROUNDS_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rounds > 19) {
|
||||||
|
/* rounds = B_ROUNDS_MAX; */
|
||||||
|
rounds = 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) snprintf (rounds_prefix, sizeof rounds_prefix,
|
||||||
|
"%2.2ld$", rounds);
|
||||||
|
|
||||||
|
return rounds_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BCRYPT_SALT_SIZE 22
|
||||||
|
/*
|
||||||
|
* Generate a 22 character salt string for bcrypt.
|
||||||
|
*/
|
||||||
|
static /*@observer@*/const char *gensalt_bcrypt (void)
|
||||||
|
{
|
||||||
|
static char salt[32];
|
||||||
|
|
||||||
|
salt[0] = '\0';
|
||||||
|
|
||||||
|
seedRNG ();
|
||||||
|
strcat (salt, l64a (random()));
|
||||||
|
do {
|
||||||
|
strcat (salt, l64a (random()));
|
||||||
|
} while (strlen (salt) < BCRYPT_SALT_SIZE);
|
||||||
|
|
||||||
|
salt[BCRYPT_SALT_SIZE] = '\0';
|
||||||
|
|
||||||
|
return salt;
|
||||||
|
}
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate salt of size salt_size.
|
* Generate salt of size salt_size.
|
||||||
*/
|
*/
|
||||||
@@ -230,6 +328,11 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
|
|||||||
|
|
||||||
if (0 == strcmp (method, "MD5")) {
|
if (0 == strcmp (method, "MD5")) {
|
||||||
MAGNUM(result, '1');
|
MAGNUM(result, '1');
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
} else if (0 == strcmp (method, "BCRYPT")) {
|
||||||
|
BCRYPTMAGNUM(result);
|
||||||
|
strcat(result, BCRYPT_salt_rounds((int *)arg));
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
#ifdef USE_SHA_CRYPT
|
#ifdef USE_SHA_CRYPT
|
||||||
} else if (0 == strcmp (method, "SHA256")) {
|
} else if (0 == strcmp (method, "SHA256")) {
|
||||||
MAGNUM(result, '5');
|
MAGNUM(result, '5');
|
||||||
@@ -252,8 +355,18 @@ static /*@observer@*/const char *gensalt (size_t salt_size)
|
|||||||
* Concatenate a pseudo random salt.
|
* Concatenate a pseudo random salt.
|
||||||
*/
|
*/
|
||||||
assert (sizeof (result) > strlen (result) + salt_len);
|
assert (sizeof (result) > strlen (result) + salt_len);
|
||||||
strncat (result, gensalt (salt_len),
|
#ifdef USE_BCRYPT
|
||||||
sizeof (result) - strlen (result) - 1);
|
if (0 == strcmp (method, "BCRYPT")) {
|
||||||
|
strncat (result, gensalt_bcrypt (),
|
||||||
|
sizeof (result) - strlen (result) - 1);
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
|
strncat (result, gensalt (salt_len),
|
||||||
|
sizeof (result) - strlen (result) - 1);
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
}
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ man_MANS = \
|
|||||||
man1/sg.1 \
|
man1/sg.1 \
|
||||||
man3/shadow.3 \
|
man3/shadow.3 \
|
||||||
man5/shadow.5 \
|
man5/shadow.5 \
|
||||||
man1/su.1 \
|
|
||||||
man5/suauth.5 \
|
man5/suauth.5 \
|
||||||
man8/useradd.8 \
|
man8/useradd.8 \
|
||||||
man8/userdel.8 \
|
man8/userdel.8 \
|
||||||
@@ -54,6 +53,10 @@ man_nopam = \
|
|||||||
man5/login.access.5 \
|
man5/login.access.5 \
|
||||||
man5/porttime.5
|
man5/porttime.5
|
||||||
|
|
||||||
|
if WITH_SU
|
||||||
|
man_MANS += man1/su.1
|
||||||
|
endif
|
||||||
|
|
||||||
if !USE_PAM
|
if !USE_PAM
|
||||||
man_MANS += $(man_nopam)
|
man_MANS += $(man_nopam)
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ pre-built ones might not fit your version of shadow. To build them yourself use
|
|||||||
- xsltproc
|
- xsltproc
|
||||||
- docbook 4
|
- docbook 4
|
||||||
- docbook stylesheets
|
- docbook stylesheets
|
||||||
- xml2po
|
- itstool
|
||||||
|
|||||||
@@ -131,6 +131,12 @@
|
|||||||
<para>Display help message and exit.</para>
|
<para>Display help message and exit.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-i</option>, <option>--iso8601</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>When printing dates, use YYYY-MM-DD format.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>-I</option>, <option>--inactive</option> <replaceable>INACTIVE</replaceable>
|
<option>-I</option>, <option>--inactive</option> <replaceable>INACTIVE</replaceable>
|
||||||
|
|||||||
@@ -5,8 +5,19 @@ config.xml: ../config.xml.in
|
|||||||
$(MAKE) -C .. config.xml
|
$(MAKE) -C .. config.xml
|
||||||
cp ../config.xml $@
|
cp ../config.xml $@
|
||||||
|
|
||||||
%.xml: ../%.xml ../po/$(LANG).po
|
messages.mo: ../po/$(LANG).po
|
||||||
xml2po --expand-all-entities -l $(LANG) -p ../po/$(LANG).po -o $@ ../$@
|
msgfmt ../po/$(LANG).po -o messages.mo
|
||||||
|
|
||||||
|
login.defs.d:
|
||||||
|
ln -sf ../login.defs.d login.defs.d
|
||||||
|
|
||||||
|
%.xml: ../%.xml messages.mo login.defs.d
|
||||||
|
if grep -q SHADOW-CONFIG-HERE $< ; then \
|
||||||
|
sed -e 's/^<!-- SHADOW-CONFIG-HERE -->/<!ENTITY % config SYSTEM "config.xml">%config;/' $< > $@; \
|
||||||
|
else \
|
||||||
|
sed -e 's/^\(<!DOCTYPE .*docbookx.dtd"\)>/\1 [<!ENTITY % config SYSTEM "config.xml">%config;]>/' $< > $@; \
|
||||||
|
fi
|
||||||
|
itstool -d -l $(LANG) -m messages.mo -o . $@
|
||||||
sed -i 's:\(^<refentry .*\)>:\1 lang="$(LANG)">:' $@
|
sed -i 's:\(^<refentry .*\)>:\1 lang="$(LANG)">:' $@
|
||||||
|
|
||||||
include ../generate_mans.mak
|
include ../generate_mans.mak
|
||||||
@@ -16,4 +27,4 @@ $(man_MANS):
|
|||||||
@echo you need to run configure with --enable-man to generate man pages
|
@echo you need to run configure with --enable-man to generate man pages
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CLEANFILES = .xml2po.mo $(EXTRA_DIST) $(addsuffix .xml,$(EXTRA_DIST)) config.xml
|
CLEANFILES = messages.mo login.defs.d $(EXTRA_DIST) $(addsuffix .xml,$(EXTRA_DIST)) config.xml
|
||||||
|
|||||||
@@ -266,6 +266,18 @@
|
|||||||
<para>
|
<para>
|
||||||
The options which apply to the <command>newusers</command> command are:
|
The options which apply to the <command>newusers</command> command are:
|
||||||
</para>
|
</para>
|
||||||
|
<variablelist remap='IP'>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--badname</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allow names that do not conform to standards.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
<variablelist remap='IP' condition="no_pam">
|
<variablelist remap='IP' condition="no_pam">
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-c</option>, <option>--crypt-method</option></term>
|
<term><option>-c</option>, <option>--crypt-method</option></term>
|
||||||
|
|||||||
@@ -98,24 +98,43 @@
|
|||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The encrypted password field may be blank, in which case no password
|
If the <emphasis>password</emphasis> field is a lower-case
|
||||||
is required to authenticate as the specified login name. However,
|
<quote>x</quote>, then the encrypted password is actually stored in the
|
||||||
some applications which read the <filename>/etc/passwd</filename> file
|
|
||||||
may decide not to permit <emphasis>any</emphasis> access at all if the
|
|
||||||
<emphasis>password</emphasis> field is blank. If the
|
|
||||||
<emphasis>password</emphasis> field is a lower-case <quote>x</quote>,
|
|
||||||
then the encrypted password is actually stored in the
|
|
||||||
<citerefentry><refentrytitle>shadow</refentrytitle>
|
<citerefentry><refentrytitle>shadow</refentrytitle>
|
||||||
<manvolnum>5</manvolnum></citerefentry> file instead; there
|
<manvolnum>5</manvolnum></citerefentry> file instead; there
|
||||||
<emphasis>must</emphasis> be a corresponding line in the
|
<emphasis>must</emphasis> be a corresponding line in the
|
||||||
<filename>/etc/shadow</filename> file, or else the user account is invalid.
|
<filename>/etc/shadow</filename> file, or else the user account is invalid.
|
||||||
If the <emphasis>password</emphasis> field is any other string, then
|
|
||||||
it will be treated as an encrypted password, as specified by
|
|
||||||
<citerefentry><refentrytitle>crypt</refentrytitle>
|
|
||||||
<manvolnum>3</manvolnum></citerefentry>.
|
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The encrypted <emphasis>password</emphasis> field may be empty,
|
||||||
|
in which case no password is required to authenticate as the
|
||||||
|
specified login name. However, some applications which read the
|
||||||
|
<filename>/etc/passwd</filename> file may decide not to permit
|
||||||
|
<emphasis>any</emphasis> access at all if the
|
||||||
|
<emphasis>password</emphasis> field is blank.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
A <emphasis>password</emphasis> field which starts with an
|
||||||
|
exclamation mark means that the password is locked. The
|
||||||
|
remaining characters on the line represent the
|
||||||
|
<emphasis>password</emphasis> field before the password was
|
||||||
|
locked.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Refer to <citerefentry><refentrytitle>crypt</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum></citerefentry> for details on how
|
||||||
|
this string is interpreted.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If the password field contains some string that is not a valid
|
||||||
|
result of <citerefentry><refentrytitle>crypt</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum></citerefentry>, for instance ! or *,
|
||||||
|
the user will not be able to use a unix password to log in
|
||||||
|
(but the user may log in the system by other means).
|
||||||
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The comment field is used by various system utilities, such as
|
The comment field is used by various system utilities, such as
|
||||||
<citerefentry><refentrytitle>finger</refentrytitle>
|
<citerefentry><refentrytitle>finger</refentrytitle>
|
||||||
|
|||||||
@@ -182,6 +182,16 @@
|
|||||||
The options which apply to the <command>pwck</command> command are:
|
The options which apply to the <command>pwck</command> command are:
|
||||||
</para>
|
</para>
|
||||||
<variablelist remap='IP'>
|
<variablelist remap='IP'>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--badname</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allow names that do not conform to standards.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-h</option>, <option>--help</option></term>
|
<term><option>-h</option>, <option>--help</option></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|||||||
@@ -95,18 +95,6 @@
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><emphasis role="bold">encrypted password</emphasis></term>
|
<term><emphasis role="bold">encrypted password</emphasis></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
|
||||||
Refer to <citerefentry><refentrytitle>crypt</refentrytitle>
|
|
||||||
<manvolnum>3</manvolnum></citerefentry> for details on how
|
|
||||||
this string is interpreted.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If the password field contains some string that is not a valid
|
|
||||||
result of <citerefentry><refentrytitle>crypt</refentrytitle>
|
|
||||||
<manvolnum>3</manvolnum></citerefentry>, for instance ! or *,
|
|
||||||
the user will not be able to use a unix password to log in
|
|
||||||
(but the user may log in the system by other means).
|
|
||||||
</para>
|
|
||||||
<para>
|
<para>
|
||||||
This field may be empty, in which case no passwords are
|
This field may be empty, in which case no passwords are
|
||||||
required to authenticate as the specified login name.
|
required to authenticate as the specified login name.
|
||||||
@@ -120,6 +108,18 @@
|
|||||||
line represent the password field before the password was
|
line represent the password field before the password was
|
||||||
locked.
|
locked.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
Refer to <citerefentry><refentrytitle>crypt</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum></citerefentry> for details on how
|
||||||
|
this string is interpreted.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
If the password field contains some string that is not a valid
|
||||||
|
result of <citerefentry><refentrytitle>crypt</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum></citerefentry>, for instance ! or *,
|
||||||
|
the user will not be able to use a unix password to log in
|
||||||
|
(but the user may log in the system by other means).
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|||||||
@@ -126,6 +126,16 @@
|
|||||||
<para>The options which apply to the <command>useradd</command> command are:
|
<para>The options which apply to the <command>useradd</command> command are:
|
||||||
</para>
|
</para>
|
||||||
<variablelist remap='IP'>
|
<variablelist remap='IP'>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--badname</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allow names that do not conform to standards.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>-b</option>, <option>--base-dir</option> <replaceable>BASE_DIR</replaceable>
|
<option>-b</option>, <option>--base-dir</option> <replaceable>BASE_DIR</replaceable>
|
||||||
|
|||||||
@@ -108,6 +108,26 @@
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-b</option>, <option>--badnames</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allow names that do not conform to standards.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>-b</option>, <option>--badnames</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allow names that do not conform to standards.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>-c</option>, <option>--comment</option> <replaceable>COMMENT</replaceable>
|
<option>-c</option>, <option>--comment</option> <replaceable>COMMENT</replaceable>
|
||||||
|
|||||||
@@ -45,10 +45,13 @@ libmisc/entry.c
|
|||||||
libmisc/env.c
|
libmisc/env.c
|
||||||
libmisc/failure.c
|
libmisc/failure.c
|
||||||
libmisc/find_new_gid.c
|
libmisc/find_new_gid.c
|
||||||
|
libmisc/find_new_sub_gids.c
|
||||||
|
libmisc/find_new_sub_uids.c
|
||||||
libmisc/find_new_uid.c
|
libmisc/find_new_uid.c
|
||||||
libmisc/getgr_nam_gid.c
|
libmisc/getgr_nam_gid.c
|
||||||
libmisc/getrange.c
|
libmisc/getrange.c
|
||||||
libmisc/hushed.c
|
libmisc/hushed.c
|
||||||
|
libmisc/idmapping.c
|
||||||
libmisc/isexpired.c
|
libmisc/isexpired.c
|
||||||
libmisc/limits.c
|
libmisc/limits.c
|
||||||
libmisc/list.c
|
libmisc/list.c
|
||||||
@@ -59,6 +62,7 @@ libmisc/motd.c
|
|||||||
libmisc/myname.c
|
libmisc/myname.c
|
||||||
libmisc/obscure.c
|
libmisc/obscure.c
|
||||||
libmisc/pam_pass.c
|
libmisc/pam_pass.c
|
||||||
|
libmisc/pam_pass_non_interactive.c
|
||||||
libmisc/pwd2spwd.c
|
libmisc/pwd2spwd.c
|
||||||
libmisc/pwdcheck.c
|
libmisc/pwdcheck.c
|
||||||
libmisc/pwd_init.c
|
libmisc/pwd_init.c
|
||||||
@@ -75,6 +79,7 @@ libmisc/sulog.c
|
|||||||
libmisc/ttytype.c
|
libmisc/ttytype.c
|
||||||
libmisc/tz.c
|
libmisc/tz.c
|
||||||
libmisc/ulimit.c
|
libmisc/ulimit.c
|
||||||
|
libmisc/user_busy.c
|
||||||
libmisc/utmp.c
|
libmisc/utmp.c
|
||||||
libmisc/valid.c
|
libmisc/valid.c
|
||||||
libmisc/xgetXXbyYY.c
|
libmisc/xgetXXbyYY.c
|
||||||
@@ -101,7 +106,9 @@ src/lastlog.c
|
|||||||
src/login.c
|
src/login.c
|
||||||
src/login_nopam.c
|
src/login_nopam.c
|
||||||
src/logoutd.c
|
src/logoutd.c
|
||||||
|
src/newgidmap.c
|
||||||
src/newgrp.c
|
src/newgrp.c
|
||||||
|
src/newuidmap.c
|
||||||
src/newusers.c
|
src/newusers.c
|
||||||
src/passwd.c
|
src/passwd.c
|
||||||
src/pwck.c
|
src/pwck.c
|
||||||
|
|||||||
1566
po/zh_TW.po
1566
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
|||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
.indent.pro
|
.indent.pro
|
||||||
|
|
||||||
ubindir = ${prefix}/bin
|
ubindir = ${bindir}
|
||||||
usbindir = ${prefix}/sbin
|
usbindir = ${sbindir}
|
||||||
suidperms = 4755
|
suidperms = 4755
|
||||||
sgidperms = 2755
|
sgidperms = 2755
|
||||||
|
|
||||||
@@ -23,12 +23,15 @@ AM_CPPFLAGS = \
|
|||||||
# and installation would be much simpler (just two directories,
|
# and installation would be much simpler (just two directories,
|
||||||
# $prefix/bin and $prefix/sbin, no install-data hacks...)
|
# $prefix/bin and $prefix/sbin, no install-data hacks...)
|
||||||
|
|
||||||
bin_PROGRAMS = groups login su
|
bin_PROGRAMS = groups login
|
||||||
sbin_PROGRAMS = nologin
|
sbin_PROGRAMS = nologin
|
||||||
ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
|
ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
|
||||||
if ENABLE_SUBIDS
|
if ENABLE_SUBIDS
|
||||||
ubin_PROGRAMS += newgidmap newuidmap
|
ubin_PROGRAMS += newgidmap newuidmap
|
||||||
endif
|
endif
|
||||||
|
if WITH_SU
|
||||||
|
bin_PROGRAMS += su
|
||||||
|
endif
|
||||||
usbin_PROGRAMS = \
|
usbin_PROGRAMS = \
|
||||||
chgpasswd \
|
chgpasswd \
|
||||||
chpasswd \
|
chpasswd \
|
||||||
@@ -52,13 +55,17 @@ usbin_PROGRAMS = \
|
|||||||
# id and groups are from gnu, sulogin from sysvinit
|
# id and groups are from gnu, sulogin from sysvinit
|
||||||
noinst_PROGRAMS = id sulogin
|
noinst_PROGRAMS = id sulogin
|
||||||
|
|
||||||
suidbins = su
|
suidusbins =
|
||||||
|
suidbins =
|
||||||
suidubins = chage chfn chsh expiry gpasswd newgrp
|
suidubins = chage chfn chsh expiry gpasswd newgrp
|
||||||
|
if WITH_SU
|
||||||
|
suidbins += su
|
||||||
|
endif
|
||||||
if !WITH_TCB
|
if !WITH_TCB
|
||||||
suidubins += passwd
|
suidubins += passwd
|
||||||
endif
|
endif
|
||||||
if ACCT_TOOLS_SETUID
|
if ACCT_TOOLS_SETUID
|
||||||
suidubins += chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
|
suidusbins += chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
|
||||||
endif
|
endif
|
||||||
if ENABLE_SUBIDS
|
if ENABLE_SUBIDS
|
||||||
if !FCAPS
|
if !FCAPS
|
||||||
@@ -87,42 +94,43 @@ else
|
|||||||
LIBCRYPT_NOPAM = $(LIBCRYPT)
|
LIBCRYPT_NOPAM = $(LIBCRYPT)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
newuidmap_LDADD = $(LDADD) $(LIBSELINUX) $(LIBCAP)
|
newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP)
|
||||||
newgidmap_LDADD = $(LDADD) $(LIBSELINUX) $(LIBCAP)
|
newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP)
|
||||||
chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
|
||||||
chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT)
|
chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
|
||||||
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
|
||||||
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT)
|
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
|
||||||
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT)
|
expiry_LDADD = $(LDADD) $(LIBECONF)
|
||||||
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
|
||||||
groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
groupmems_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX)
|
groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
groupmems_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
grpck_LDADD = $(LDADD) $(LIBSELINUX)
|
groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
grpconv_LDADD = $(LDADD) $(LIBSELINUX)
|
grpck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
grpunconv_LDADD = $(LDADD) $(LIBSELINUX)
|
grpconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
lastlog_LDADD = $(LDADD) $(LIBAUDIT)
|
grpunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
|
lastlog_LDADD = $(LDADD) $(LIBAUDIT) $(LIBECONF)
|
||||||
login_SOURCES = \
|
login_SOURCES = \
|
||||||
login.c \
|
login.c \
|
||||||
login_nopam.c
|
login_nopam.c
|
||||||
login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
|
||||||
newgrp_LDADD = $(LDADD) $(LIBAUDIT) $(LIBCRYPT)
|
newgrp_LDADD = $(LDADD) $(LIBAUDIT) $(LIBCRYPT) $(LIBECONF)
|
||||||
newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT)
|
newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
|
||||||
nologin_LDADD =
|
nologin_LDADD =
|
||||||
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM)
|
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF)
|
||||||
pwck_LDADD = $(LDADD) $(LIBSELINUX)
|
pwck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
pwconv_LDADD = $(LDADD) $(LIBSELINUX)
|
pwconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
pwunconv_LDADD = $(LDADD) $(LIBSELINUX)
|
pwunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
su_SOURCES = \
|
su_SOURCES = \
|
||||||
su.c \
|
su.c \
|
||||||
suauth.c
|
suauth.c
|
||||||
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
|
||||||
sulogin_LDADD = $(LDADD) $(LIBCRYPT)
|
sulogin_LDADD = $(LDADD) $(LIBCRYPT) $(LIBECONF)
|
||||||
useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR)
|
useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF)
|
||||||
userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE)
|
userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF)
|
||||||
usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR)
|
usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF)
|
||||||
vipw_LDADD = $(LDADD) $(LIBSELINUX)
|
vipw_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
|
||||||
|
|
||||||
install-am: all-am
|
install-am: all-am
|
||||||
$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
@@ -134,6 +142,9 @@ install-am: all-am
|
|||||||
for i in $(suidubins); do \
|
for i in $(suidubins); do \
|
||||||
chmod $(suidperms) $(DESTDIR)$(ubindir)/$$i; \
|
chmod $(suidperms) $(DESTDIR)$(ubindir)/$$i; \
|
||||||
done
|
done
|
||||||
|
for i in $(suidusbins); do \
|
||||||
|
chmod $(suidperms) $(DESTDIR)$(usbindir)/$$i; \
|
||||||
|
done
|
||||||
if WITH_TCB
|
if WITH_TCB
|
||||||
for i in $(shadowsgidubins); do \
|
for i in $(shadowsgidubins); do \
|
||||||
chown root:shadow $(DESTDIR)$(ubindir)/$$i; \
|
chown root:shadow $(DESTDIR)$(ubindir)/$$i; \
|
||||||
|
|||||||
26
src/chage.c
26
src/chage.c
@@ -48,10 +48,6 @@
|
|||||||
#endif /* USE_PAM */
|
#endif /* USE_PAM */
|
||||||
#endif /* ACCT_TOOLS_SETUID */
|
#endif /* ACCT_TOOLS_SETUID */
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
#include <selinux/selinux.h>
|
|
||||||
#include <selinux/av_permissions.h>
|
|
||||||
#endif
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "pwio.h"
|
#include "pwio.h"
|
||||||
@@ -70,6 +66,7 @@ const char *Prog;
|
|||||||
static bool
|
static bool
|
||||||
dflg = false, /* set last password change date */
|
dflg = false, /* set last password change date */
|
||||||
Eflg = false, /* set account expiration date */
|
Eflg = false, /* set account expiration date */
|
||||||
|
iflg = false, /* set iso8601 date formatting */
|
||||||
Iflg = false, /* set password inactive after expiration */
|
Iflg = false, /* set password inactive after expiration */
|
||||||
lflg = false, /* show account aging information */
|
lflg = false, /* show account aging information */
|
||||||
mflg = false, /* set minimum number of days before password change */
|
mflg = false, /* set minimum number of days before password change */
|
||||||
@@ -149,6 +146,7 @@ static /*@noreturn@*/void usage (int status)
|
|||||||
(void) fputs (_(" -d, --lastday LAST_DAY set date of last password change to LAST_DAY\n"), usageout);
|
(void) fputs (_(" -d, --lastday LAST_DAY set date of last password change to LAST_DAY\n"), usageout);
|
||||||
(void) fputs (_(" -E, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE\n"), usageout);
|
(void) fputs (_(" -E, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE\n"), usageout);
|
||||||
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
||||||
|
(void) fputs (_(" -i, --iso8601 use YYYY-MM-DD when printing dates\n"), usageout);
|
||||||
(void) fputs (_(" -I, --inactive INACTIVE set password inactive after expiration\n"
|
(void) fputs (_(" -I, --inactive INACTIVE set password inactive after expiration\n"
|
||||||
" to INACTIVE\n"), usageout);
|
" to INACTIVE\n"), usageout);
|
||||||
(void) fputs (_(" -l, --list show account aging information\n"), usageout);
|
(void) fputs (_(" -l, --list show account aging information\n"), usageout);
|
||||||
@@ -262,12 +260,20 @@ static void print_date (time_t date)
|
|||||||
#ifdef HAVE_STRFTIME
|
#ifdef HAVE_STRFTIME
|
||||||
struct tm *tp;
|
struct tm *tp;
|
||||||
char buf[80];
|
char buf[80];
|
||||||
|
char format[80];
|
||||||
|
|
||||||
|
if( iflg ) {
|
||||||
|
(void) snprintf (format, 80, "%%Y-%%m-%%d");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(void) snprintf (format, 80, "%%b %%d, %%Y");
|
||||||
|
}
|
||||||
|
|
||||||
tp = gmtime (&date);
|
tp = gmtime (&date);
|
||||||
if (NULL == tp) {
|
if (NULL == tp) {
|
||||||
(void) printf ("time_t: %lu\n", (unsigned long)date);
|
(void) printf ("time_t: %lu\n", (unsigned long)date);
|
||||||
} else {
|
} else {
|
||||||
(void) strftime (buf, sizeof buf, "%b %d, %Y", tp);
|
(void) strftime (buf, sizeof buf, format, tp);
|
||||||
(void) puts (buf);
|
(void) puts (buf);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -395,10 +401,11 @@ static void process_flags (int argc, char **argv)
|
|||||||
{"maxdays", required_argument, NULL, 'M'},
|
{"maxdays", required_argument, NULL, 'M'},
|
||||||
{"root", required_argument, NULL, 'R'},
|
{"root", required_argument, NULL, 'R'},
|
||||||
{"warndays", required_argument, NULL, 'W'},
|
{"warndays", required_argument, NULL, 'W'},
|
||||||
|
{"iso8601", no_argument, NULL, 'i'},
|
||||||
{NULL, 0, NULL, '\0'}
|
{NULL, 0, NULL, '\0'}
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((c = getopt_long (argc, argv, "d:E:hI:lm:M:R:W:",
|
while ((c = getopt_long (argc, argv, "d:E:hiI:lm:M:R:W:",
|
||||||
long_options, NULL)) != -1) {
|
long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'd':
|
case 'd':
|
||||||
@@ -424,6 +431,9 @@ static void process_flags (int argc, char **argv)
|
|||||||
case 'h':
|
case 'h':
|
||||||
usage (E_SUCCESS);
|
usage (E_SUCCESS);
|
||||||
/*@notreached@*/break;
|
/*@notreached@*/break;
|
||||||
|
case 'i':
|
||||||
|
iflg = true;
|
||||||
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
Iflg = true;
|
Iflg = true;
|
||||||
if ( (getlong (optarg, &inactdays) == 0)
|
if ( (getlong (optarg, &inactdays) == 0)
|
||||||
@@ -818,8 +828,8 @@ int main (int argc, char **argv)
|
|||||||
rgid = getgid ();
|
rgid = getgid ();
|
||||||
amroot = (ruid == 0);
|
amroot = (ruid == 0);
|
||||||
#ifdef WITH_SELINUX
|
#ifdef WITH_SELINUX
|
||||||
if (amroot && (is_selinux_enabled () > 0)) {
|
if (amroot) {
|
||||||
amroot = (selinux_check_passwd_access (PASSWD__ROOTOK) == 0);
|
amroot = (check_selinux_permit ("rootok") == 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
#include <selinux/selinux.h>
|
|
||||||
#include <selinux/av_permissions.h>
|
|
||||||
#endif
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
#include "nscd.h"
|
#include "nscd.h"
|
||||||
@@ -379,8 +375,7 @@ static void check_perms (const struct passwd *pw)
|
|||||||
* check if the change is allowed by SELinux policy.
|
* check if the change is allowed by SELinux policy.
|
||||||
*/
|
*/
|
||||||
if ((pw->pw_uid != getuid ())
|
if ((pw->pw_uid != getuid ())
|
||||||
&& (is_selinux_enabled () > 0)
|
&& (check_selinux_permit ("chfn") != 0)) {
|
||||||
&& (selinux_check_passwd_access (PASSWD__CHFN) != 0)) {
|
|
||||||
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
||||||
closelog ();
|
closelog ();
|
||||||
exit (E_NOPERM);
|
exit (E_NOPERM);
|
||||||
|
|||||||
@@ -61,15 +61,18 @@
|
|||||||
const char *Prog;
|
const char *Prog;
|
||||||
static bool eflg = false;
|
static bool eflg = false;
|
||||||
static bool md5flg = false;
|
static bool md5flg = false;
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
static bool sflg = false;
|
static bool sflg = false;
|
||||||
#endif
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
|
|
||||||
static /*@null@*//*@observer@*/const char *crypt_method = NULL;
|
static /*@null@*//*@observer@*/const char *crypt_method = NULL;
|
||||||
#define cflg (NULL != crypt_method)
|
#define cflg (NULL != crypt_method)
|
||||||
#ifdef USE_SHA_CRYPT
|
#ifdef USE_SHA_CRYPT
|
||||||
static long sha_rounds = 5000;
|
static long sha_rounds = 5000;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
static long bcrypt_rounds = 13;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SHADOWGRP
|
#ifdef SHADOWGRP
|
||||||
static bool is_shadow_grp;
|
static bool is_shadow_grp;
|
||||||
@@ -125,11 +128,15 @@ static /*@noreturn@*/void usage (int status)
|
|||||||
Prog);
|
Prog);
|
||||||
(void) fprintf (usageout,
|
(void) fprintf (usageout,
|
||||||
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
|
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
|
||||||
#ifndef USE_SHA_CRYPT
|
#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
|
||||||
"NONE DES MD5"
|
"NONE DES MD5"
|
||||||
#else /* USE_SHA_CRYPT */
|
#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
|
"NONE DES MD5 SHA256 SHA512 BCRYPT"
|
||||||
|
#elif defined(USE_SHA_CRYPT)
|
||||||
"NONE DES MD5 SHA256 SHA512"
|
"NONE DES MD5 SHA256 SHA512"
|
||||||
#endif /* USE_SHA_CRYPT */
|
#else
|
||||||
|
"NONE DES MD5 BCRYPT"
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
|
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
|
||||||
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
||||||
@@ -137,11 +144,11 @@ static /*@noreturn@*/void usage (int status)
|
|||||||
" the MD5 algorithm\n"),
|
" the MD5 algorithm\n"),
|
||||||
usageout);
|
usageout);
|
||||||
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
(void) fputs (_(" -s, --sha-rounds number of SHA rounds for the SHA*\n"
|
(void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
|
||||||
" crypt algorithms\n"),
|
" crypt algorithms\n"),
|
||||||
usageout);
|
usageout);
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
(void) fputs ("\n", usageout);
|
(void) fputs ("\n", usageout);
|
||||||
|
|
||||||
exit (status);
|
exit (status);
|
||||||
@@ -161,14 +168,13 @@ static void process_flags (int argc, char **argv)
|
|||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"md5", no_argument, NULL, 'm'},
|
{"md5", no_argument, NULL, 'm'},
|
||||||
{"root", required_argument, NULL, 'R'},
|
{"root", required_argument, NULL, 'R'},
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
{"sha-rounds", required_argument, NULL, 's'},
|
{"sha-rounds", required_argument, NULL, 's'},
|
||||||
#endif
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
{NULL, 0, NULL, '\0'}
|
{NULL, 0, NULL, '\0'}
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((c = getopt_long (argc, argv,
|
while ((c = getopt_long (argc, argv,
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
"c:ehmR:s:",
|
"c:ehmR:s:",
|
||||||
#else
|
#else
|
||||||
"c:ehmR:",
|
"c:ehmR:",
|
||||||
@@ -189,10 +195,33 @@ static void process_flags (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'R': /* no-op, handled in process_root_flag () */
|
case 'R': /* no-op, handled in process_root_flag () */
|
||||||
break;
|
break;
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
case 's':
|
case 's':
|
||||||
sflg = true;
|
sflg = true;
|
||||||
if (getlong(optarg, &sha_rounds) == 0) {
|
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
|
||||||
|
&& (0 == getlong(optarg, &sha_rounds)))
|
||||||
|
|| ( (0 == strcmp (crypt_method, "BCRYPT"))
|
||||||
|
&& (0 == getlong(optarg, &bcrypt_rounds)))) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
|
Prog, optarg);
|
||||||
|
usage (E_USAGE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#elif defined(USE_SHA_CRYPT)
|
||||||
|
case 's':
|
||||||
|
sflg = true;
|
||||||
|
if (0 == getlong(optarg, &sha_rounds)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
|
Prog, optarg);
|
||||||
|
usage (E_USAGE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#elif defined(USE_BCRYPT)
|
||||||
|
case 's':
|
||||||
|
sflg = true;
|
||||||
|
if (0 == getlong(optarg, &bcrypt_rounds)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: invalid numeric argument '%s'\n"),
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
Prog, optarg);
|
Prog, optarg);
|
||||||
@@ -200,6 +229,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
usage (E_USAGE);
|
usage (E_USAGE);
|
||||||
/*@notreached@*/break;
|
/*@notreached@*/break;
|
||||||
@@ -217,7 +247,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
static void check_flags (void)
|
static void check_flags (void)
|
||||||
{
|
{
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
if (sflg && !cflg) {
|
if (sflg && !cflg) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: %s flag is only allowed with the %s flag\n"),
|
_("%s: %s flag is only allowed with the %s flag\n"),
|
||||||
@@ -241,6 +271,9 @@ static void check_flags (void)
|
|||||||
#ifdef USE_SHA_CRYPT
|
#ifdef USE_SHA_CRYPT
|
||||||
&& (0 != strcmp (crypt_method, "SHA256"))
|
&& (0 != strcmp (crypt_method, "SHA256"))
|
||||||
&& (0 != strcmp (crypt_method, "SHA512"))
|
&& (0 != strcmp (crypt_method, "SHA512"))
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
&& (0 != strcmp (crypt_method, "BCRYPT"))
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@@ -464,10 +497,24 @@ int main (int argc, char **argv)
|
|||||||
if (md5flg) {
|
if (md5flg) {
|
||||||
crypt_method = "MD5";
|
crypt_method = "MD5";
|
||||||
}
|
}
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
|
if (sflg) {
|
||||||
|
if ( (0 == strcmp (crypt_method, "SHA256"))
|
||||||
|
|| (0 == strcmp (crypt_method, "SHA512"))) {
|
||||||
|
arg = &sha_rounds;
|
||||||
|
}
|
||||||
|
else if (0 == strcmp (crypt_method, "BCRYPT")) {
|
||||||
|
arg = &bcrypt_rounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(USE_SHA_CRYPT)
|
||||||
if (sflg) {
|
if (sflg) {
|
||||||
arg = &sha_rounds;
|
arg = &sha_rounds;
|
||||||
}
|
}
|
||||||
|
#elif defined(USE_BCRYPT)
|
||||||
|
if (sflg) {
|
||||||
|
arg = &bcrypt_rounds;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
salt = crypt_make_salt (crypt_method, arg);
|
salt = crypt_make_salt (crypt_method, arg);
|
||||||
cp = pw_encrypt (newpwd, salt);
|
cp = pw_encrypt (newpwd, salt);
|
||||||
|
|||||||
@@ -58,15 +58,18 @@
|
|||||||
const char *Prog;
|
const char *Prog;
|
||||||
static bool eflg = false;
|
static bool eflg = false;
|
||||||
static bool md5flg = false;
|
static bool md5flg = false;
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
static bool sflg = false;
|
static bool sflg = false;
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif
|
||||||
|
|
||||||
static /*@null@*//*@observer@*/const char *crypt_method = NULL;
|
static /*@null@*//*@observer@*/const char *crypt_method = NULL;
|
||||||
#define cflg (NULL != crypt_method)
|
#define cflg (NULL != crypt_method)
|
||||||
#ifdef USE_SHA_CRYPT
|
#ifdef USE_SHA_CRYPT
|
||||||
static long sha_rounds = 5000;
|
static long sha_rounds = 5000;
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
static long bcrypt_rounds = 13;
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool is_shadow_pwd;
|
static bool is_shadow_pwd;
|
||||||
static bool pw_locked = false;
|
static bool pw_locked = false;
|
||||||
@@ -118,11 +121,15 @@ static /*@noreturn@*/void usage (int status)
|
|||||||
Prog);
|
Prog);
|
||||||
(void) fprintf (usageout,
|
(void) fprintf (usageout,
|
||||||
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
|
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
|
||||||
#ifndef USE_SHA_CRYPT
|
#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
|
||||||
"NONE DES MD5"
|
"NONE DES MD5"
|
||||||
#else /* USE_SHA_CRYPT */
|
#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
|
"NONE DES MD5 SHA256 SHA512 BCRYPT"
|
||||||
|
#elif defined(USE_SHA_CRYPT)
|
||||||
"NONE DES MD5 SHA256 SHA512"
|
"NONE DES MD5 SHA256 SHA512"
|
||||||
#endif /* USE_SHA_CRYPT */
|
#else
|
||||||
|
"NONE DES MD5 BCRYPT"
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
|
(void) fputs (_(" -e, --encrypted supplied passwords are encrypted\n"), usageout);
|
||||||
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
||||||
@@ -130,11 +137,11 @@ static /*@noreturn@*/void usage (int status)
|
|||||||
" the MD5 algorithm\n"),
|
" the MD5 algorithm\n"),
|
||||||
usageout);
|
usageout);
|
||||||
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
(void) fputs (_(" -s, --sha-rounds number of SHA rounds for the SHA*\n"
|
(void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
|
||||||
" crypt algorithms\n"),
|
" crypt algorithms\n"),
|
||||||
usageout);
|
usageout);
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
(void) fputs ("\n", usageout);
|
(void) fputs ("\n", usageout);
|
||||||
|
|
||||||
exit (status);
|
exit (status);
|
||||||
@@ -154,18 +161,18 @@ static void process_flags (int argc, char **argv)
|
|||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"md5", no_argument, NULL, 'm'},
|
{"md5", no_argument, NULL, 'm'},
|
||||||
{"root", required_argument, NULL, 'R'},
|
{"root", required_argument, NULL, 'R'},
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
{"sha-rounds", required_argument, NULL, 's'},
|
{"sha-rounds", required_argument, NULL, 's'},
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
{NULL, 0, NULL, '\0'}
|
{NULL, 0, NULL, '\0'}
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((c = getopt_long (argc, argv,
|
while ((c = getopt_long (argc, argv,
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
"c:ehmR:s:",
|
"c:ehmR:s:",
|
||||||
#else /* !USE_SHA_CRYPT */
|
#else
|
||||||
"c:ehmR:",
|
"c:ehmR:",
|
||||||
#endif /* !USE_SHA_CRYPT */
|
#endif
|
||||||
long_options, NULL)) != -1) {
|
long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
@@ -182,17 +189,41 @@ static void process_flags (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'R': /* no-op, handled in process_root_flag () */
|
case 'R': /* no-op, handled in process_root_flag () */
|
||||||
break;
|
break;
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
case 's':
|
case 's':
|
||||||
sflg = true;
|
sflg = true;
|
||||||
if (getlong(optarg, &sha_rounds) == 0) {
|
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
|
||||||
|
&& (0 == getlong(optarg, &sha_rounds)))
|
||||||
|
|| ( (0 == strcmp (crypt_method, "BCRYPT"))
|
||||||
|
&& (0 == getlong(optarg, &bcrypt_rounds)))) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: invalid numeric argument '%s'\n"),
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
Prog, optarg);
|
Prog, optarg);
|
||||||
usage (E_USAGE);
|
usage (E_USAGE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* USE_SHA_CRYPT */
|
#elif defined(USE_SHA_CRYPT)
|
||||||
|
case 's':
|
||||||
|
sflg = true;
|
||||||
|
if (0 == getlong(optarg, &sha_rounds)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
|
Prog, optarg);
|
||||||
|
usage (E_USAGE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#elif defined(USE_BCRYPT)
|
||||||
|
case 's':
|
||||||
|
sflg = true;
|
||||||
|
if (0 == getlong(optarg, &bcrypt_rounds)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
|
Prog, optarg);
|
||||||
|
usage (E_USAGE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
usage (E_USAGE);
|
usage (E_USAGE);
|
||||||
/*@notreached@*/break;
|
/*@notreached@*/break;
|
||||||
@@ -210,7 +241,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
static void check_flags (void)
|
static void check_flags (void)
|
||||||
{
|
{
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
if (sflg && !cflg) {
|
if (sflg && !cflg) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: %s flag is only allowed with the %s flag\n"),
|
_("%s: %s flag is only allowed with the %s flag\n"),
|
||||||
@@ -235,6 +266,9 @@ static void check_flags (void)
|
|||||||
&& (0 != strcmp (crypt_method, "SHA256"))
|
&& (0 != strcmp (crypt_method, "SHA256"))
|
||||||
&& (0 != strcmp (crypt_method, "SHA512"))
|
&& (0 != strcmp (crypt_method, "SHA512"))
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT */
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
&& (0 != strcmp (crypt_method, "BCRYPT"))
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
) {
|
) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: unsupported crypt method: %s\n"),
|
_("%s: unsupported crypt method: %s\n"),
|
||||||
@@ -496,10 +530,24 @@ int main (int argc, char **argv)
|
|||||||
if (md5flg) {
|
if (md5flg) {
|
||||||
crypt_method = "MD5";
|
crypt_method = "MD5";
|
||||||
}
|
}
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
|
if (sflg) {
|
||||||
|
if ( (0 == strcmp (crypt_method, "SHA256"))
|
||||||
|
|| (0 == strcmp (crypt_method, "SHA512"))) {
|
||||||
|
arg = &sha_rounds;
|
||||||
|
}
|
||||||
|
else if (0 == strcmp (crypt_method, "BCRYPT")) {
|
||||||
|
arg = &bcrypt_rounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(USE_SHA_CRYPT)
|
||||||
if (sflg) {
|
if (sflg) {
|
||||||
arg = &sha_rounds;
|
arg = &sha_rounds;
|
||||||
}
|
}
|
||||||
|
#elif defined(USE_BCRYPT)
|
||||||
|
if (sflg) {
|
||||||
|
arg = &bcrypt_rounds;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
salt = crypt_make_salt (crypt_method, arg);
|
salt = crypt_make_salt (crypt_method, arg);
|
||||||
cp = pw_encrypt (newpwd, salt);
|
cp = pw_encrypt (newpwd, salt);
|
||||||
|
|||||||
@@ -39,10 +39,6 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
#include <selinux/selinux.h>
|
|
||||||
#include <selinux/av_permissions.h>
|
|
||||||
#endif
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
#include "nscd.h"
|
#include "nscd.h"
|
||||||
@@ -286,8 +282,7 @@ static void check_perms (const struct passwd *pw)
|
|||||||
* check if the change is allowed by SELinux policy.
|
* check if the change is allowed by SELinux policy.
|
||||||
*/
|
*/
|
||||||
if ((pw->pw_uid != getuid ())
|
if ((pw->pw_uid != getuid ())
|
||||||
&& (is_selinux_enabled () > 0)
|
&& (check_selinux_permit("chsh") != 0)) {
|
||||||
&& (selinux_check_passwd_access (PASSWD__CHSH) != 0)) {
|
|
||||||
SYSLOG ((LOG_WARN, "can't change shell for '%s'", pw->pw_name));
|
SYSLOG ((LOG_WARN, "can't change shell for '%s'", pw->pw_name));
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("You may not change the shell for '%s'.\n"),
|
_("You may not change the shell for '%s'.\n"),
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
char proc_dir_name[32];
|
char proc_dir_name[32];
|
||||||
char *target_str;
|
char *target_str;
|
||||||
pid_t target, parent;
|
pid_t target;
|
||||||
int proc_dir_fd;
|
int proc_dir_fd;
|
||||||
int ranges;
|
int ranges;
|
||||||
struct map_range *mappings;
|
struct map_range *mappings;
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
char proc_dir_name[32];
|
char proc_dir_name[32];
|
||||||
char *target_str;
|
char *target_str;
|
||||||
pid_t target, parent;
|
pid_t target;
|
||||||
int proc_dir_fd;
|
int proc_dir_fd;
|
||||||
int ranges;
|
int ranges;
|
||||||
struct map_range *mappings;
|
struct map_range *mappings;
|
||||||
|
|||||||
122
src/newusers.c
122
src/newusers.c
@@ -80,10 +80,15 @@ static bool rflg = false; /* create a system account */
|
|||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
static /*@null@*//*@observer@*/char *crypt_method = NULL;
|
static /*@null@*//*@observer@*/char *crypt_method = NULL;
|
||||||
#define cflg (NULL != crypt_method)
|
#define cflg (NULL != crypt_method)
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
static bool sflg = false;
|
static bool sflg = false;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SHA_CRYPT
|
||||||
static long sha_rounds = 5000;
|
static long sha_rounds = 5000;
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT */
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
static long bcrypt_rounds = 13;
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
#endif /* !USE_PAM */
|
#endif /* !USE_PAM */
|
||||||
|
|
||||||
static bool is_shadow;
|
static bool is_shadow;
|
||||||
@@ -117,6 +122,8 @@ static void check_perms (void);
|
|||||||
static void open_files (void);
|
static void open_files (void);
|
||||||
static void close_files (void);
|
static void close_files (void);
|
||||||
|
|
||||||
|
extern int allow_bad_names;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usage - display usage message and exit
|
* usage - display usage message and exit
|
||||||
*/
|
*/
|
||||||
@@ -128,25 +135,30 @@ static void usage (int status)
|
|||||||
"\n"
|
"\n"
|
||||||
"Options:\n"),
|
"Options:\n"),
|
||||||
Prog);
|
Prog);
|
||||||
|
(void) fputs (_(" -b, --badnames allow bad names\n"), usageout);
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
(void) fprintf (usageout,
|
(void) fprintf (usageout,
|
||||||
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
|
_(" -c, --crypt-method METHOD the crypt method (one of %s)\n"),
|
||||||
#ifndef USE_SHA_CRYPT
|
#if !defined(USE_SHA_CRYPT) && !defined(USE_BCRYPT)
|
||||||
"NONE DES MD5"
|
"NONE DES MD5"
|
||||||
#else /* USE_SHA_CRYPT */
|
#elif defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
|
"NONE DES MD5 SHA256 SHA512 BCRYPT"
|
||||||
|
#elif defined(USE_SHA_CRYPT)
|
||||||
"NONE DES MD5 SHA256 SHA512"
|
"NONE DES MD5 SHA256 SHA512"
|
||||||
#endif /* USE_SHA_CRYPT */
|
#else
|
||||||
|
"NONE DES MD5 BCRYPT"
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
#endif /* !USE_PAM */
|
#endif /* !USE_PAM */
|
||||||
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
||||||
(void) fputs (_(" -r, --system create system accounts\n"), usageout);
|
(void) fputs (_(" -r, --system create system accounts\n"), usageout);
|
||||||
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
(void) fputs (_(" -s, --sha-rounds number of SHA rounds for the SHA*\n"
|
(void) fputs (_(" -s, --sha-rounds number of rounds for the SHA or BCRYPT\n"
|
||||||
" crypt algorithms\n"),
|
" crypt algorithms\n"),
|
||||||
usageout);
|
usageout);
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
#endif /* !USE_PAM */
|
#endif /* !USE_PAM */
|
||||||
(void) fputs ("\n", usageout);
|
(void) fputs ("\n", usageout);
|
||||||
|
|
||||||
@@ -420,15 +432,29 @@ static int update_passwd (struct passwd *pwd, const char *password)
|
|||||||
{
|
{
|
||||||
void *crypt_arg = NULL;
|
void *crypt_arg = NULL;
|
||||||
char *cp;
|
char *cp;
|
||||||
if (crypt_method != NULL) {
|
if (NULL != crypt_method) {
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
|
if (sflg) {
|
||||||
|
if ( (0 == strcmp (crypt_method, "SHA256"))
|
||||||
|
|| (0 == strcmp (crypt_method, "SHA512"))) {
|
||||||
|
crypt_arg = &sha_rounds;
|
||||||
|
}
|
||||||
|
else if (0 == strcmp (crypt_method, "BCRYPT")) {
|
||||||
|
crypt_arg = &bcrypt_rounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(USE_SHA_CRYPT)
|
||||||
if (sflg) {
|
if (sflg) {
|
||||||
crypt_arg = &sha_rounds;
|
crypt_arg = &sha_rounds;
|
||||||
}
|
}
|
||||||
|
#elif defined(USE_BCRYPT)
|
||||||
|
if (sflg) {
|
||||||
|
crypt_arg = &bcrypt_rounds;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) {
|
if ((NULL != crypt_method) && (0 == strcmp(crypt_method, "NONE"))) {
|
||||||
pwd->pw_passwd = (char *)password;
|
pwd->pw_passwd = (char *)password;
|
||||||
} else {
|
} else {
|
||||||
const char *salt = crypt_make_salt (crypt_method, crypt_arg);
|
const char *salt = crypt_make_salt (crypt_method, crypt_arg);
|
||||||
@@ -457,12 +483,26 @@ static int add_passwd (struct passwd *pwd, const char *password)
|
|||||||
|
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
void *crypt_arg = NULL;
|
void *crypt_arg = NULL;
|
||||||
if (crypt_method != NULL) {
|
if (NULL != crypt_method) {
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
|
if (sflg) {
|
||||||
|
if ( (0 == strcmp (crypt_method, "SHA256"))
|
||||||
|
|| (0 == strcmp (crypt_method, "SHA512"))) {
|
||||||
|
crypt_arg = &sha_rounds;
|
||||||
|
}
|
||||||
|
else if (0 == strcmp (crypt_method, "BCRYPT")) {
|
||||||
|
crypt_arg = &bcrypt_rounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif defined(USE_SHA_CRYPT)
|
||||||
if (sflg) {
|
if (sflg) {
|
||||||
crypt_arg = &sha_rounds;
|
crypt_arg = &sha_rounds;
|
||||||
}
|
}
|
||||||
#endif /* USE_SHA_CRYPT */
|
#elif defined(USE_BCRYPT)
|
||||||
|
if (sflg) {
|
||||||
|
crypt_arg = &bcrypt_rounds;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -580,6 +620,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
|
{"badnames", no_argument, NULL, 'b'},
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
{"crypt-method", required_argument, NULL, 'c'},
|
{"crypt-method", required_argument, NULL, 'c'},
|
||||||
#endif /* !USE_PAM */
|
#endif /* !USE_PAM */
|
||||||
@@ -587,25 +628,28 @@ static void process_flags (int argc, char **argv)
|
|||||||
{"system", no_argument, NULL, 'r'},
|
{"system", no_argument, NULL, 'r'},
|
||||||
{"root", required_argument, NULL, 'R'},
|
{"root", required_argument, NULL, 'R'},
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
{"sha-rounds", required_argument, NULL, 's'},
|
{"sha-rounds", required_argument, NULL, 's'},
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
#endif /* !USE_PAM */
|
#endif /* !USE_PAM */
|
||||||
{NULL, 0, NULL, '\0'}
|
{NULL, 0, NULL, '\0'}
|
||||||
};
|
};
|
||||||
|
|
||||||
while ((c = getopt_long (argc, argv,
|
while ((c = getopt_long (argc, argv,
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
"c:hrs:",
|
"c:bhrs:",
|
||||||
#else /* !USE_SHA_CRYPT */
|
#else /* !USE_SHA_CRYPT && !USE_BCRYPT */
|
||||||
"c:hr",
|
"c:bhr",
|
||||||
#endif /* !USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT || USE_BCRYPT */
|
||||||
#else /* USE_PAM */
|
#else /* USE_PAM */
|
||||||
"hr",
|
"bhr",
|
||||||
#endif
|
#endif
|
||||||
long_options, NULL)) != -1) {
|
long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'b':
|
||||||
|
allow_bad_names = true;
|
||||||
|
break;
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
case 'c':
|
case 'c':
|
||||||
crypt_method = optarg;
|
crypt_method = optarg;
|
||||||
@@ -620,17 +664,40 @@ static void process_flags (int argc, char **argv)
|
|||||||
case 'R': /* no-op, handled in process_root_flag () */
|
case 'R': /* no-op, handled in process_root_flag () */
|
||||||
break;
|
break;
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) && defined(USE_BCRYPT)
|
||||||
case 's':
|
case 's':
|
||||||
sflg = true;
|
sflg = true;
|
||||||
if (getlong(optarg, &sha_rounds) == 0) {
|
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
|
||||||
|
&& (0 == getlong(optarg, &sha_rounds)))
|
||||||
|
|| ( (0 == strcmp (crypt_method, "BCRYPT"))
|
||||||
|
&& (0 == getlong(optarg, &bcrypt_rounds)))) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: invalid numeric argument '%s'\n"),
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
Prog, optarg);
|
Prog, optarg);
|
||||||
usage (EXIT_FAILURE);
|
usage (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* USE_SHA_CRYPT */
|
#elif defined(USE_SHA_CRYPT)
|
||||||
|
case 's':
|
||||||
|
sflg = true;
|
||||||
|
if (0 == getlong(optarg, &sha_rounds)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
|
Prog, optarg);
|
||||||
|
usage (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#elif defined(USE_BCRYPT)
|
||||||
|
case 's':
|
||||||
|
sflg = true;
|
||||||
|
if (0 == getlong(optarg, &bcrypt_rounds)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: invalid numeric argument '%s'\n"),
|
||||||
|
Prog, optarg);
|
||||||
|
usage (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#endif /* !USE_PAM */
|
#endif /* !USE_PAM */
|
||||||
default:
|
default:
|
||||||
usage (EXIT_FAILURE);
|
usage (EXIT_FAILURE);
|
||||||
@@ -664,14 +731,14 @@ static void process_flags (int argc, char **argv)
|
|||||||
static void check_flags (void)
|
static void check_flags (void)
|
||||||
{
|
{
|
||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
#ifdef USE_SHA_CRYPT
|
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
|
||||||
if (sflg && !cflg) {
|
if (sflg && !cflg) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: %s flag is only allowed with the %s flag\n"),
|
_("%s: %s flag is only allowed with the %s flag\n"),
|
||||||
Prog, "-s", "-c");
|
Prog, "-s", "-c");
|
||||||
usage (EXIT_FAILURE);
|
usage (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif
|
||||||
|
|
||||||
if (cflg) {
|
if (cflg) {
|
||||||
if ( (0 != strcmp (crypt_method, "DES"))
|
if ( (0 != strcmp (crypt_method, "DES"))
|
||||||
@@ -681,6 +748,9 @@ static void check_flags (void)
|
|||||||
&& (0 != strcmp (crypt_method, "SHA256"))
|
&& (0 != strcmp (crypt_method, "SHA256"))
|
||||||
&& (0 != strcmp (crypt_method, "SHA512"))
|
&& (0 != strcmp (crypt_method, "SHA512"))
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT */
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
&& (0 != strcmp (crypt_method, "BCRYPT"))
|
||||||
|
#endif /* USE_BCRYPT */
|
||||||
) {
|
) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: unsupported crypt method: %s\n"),
|
_("%s: unsupported crypt method: %s\n"),
|
||||||
|
|||||||
85
src/passwd.c
85
src/passwd.c
@@ -41,12 +41,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
#include <selinux/selinux.h>
|
|
||||||
#include <selinux/flask.h>
|
|
||||||
#include <selinux/av_permissions.h>
|
|
||||||
#include <selinux/context.h>
|
|
||||||
#endif /* WITH_SELINUX */
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
@@ -149,11 +143,6 @@ static char *update_crypt_pw (char *);
|
|||||||
static void update_noshadow (void);
|
static void update_noshadow (void);
|
||||||
|
|
||||||
static void update_shadow (void);
|
static void update_shadow (void);
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
static int check_selinux_access (const char *changed_user,
|
|
||||||
uid_t changed_uid,
|
|
||||||
access_vector_t requested_access);
|
|
||||||
#endif /* WITH_SELINUX */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usage - print command usage and exit
|
* usage - print command usage and exit
|
||||||
@@ -290,7 +279,11 @@ static int new_password (const struct passwd *pw)
|
|||||||
#ifdef USE_SHA_CRYPT
|
#ifdef USE_SHA_CRYPT
|
||||||
|| (strcmp (method, "SHA256") == 0)
|
|| (strcmp (method, "SHA256") == 0)
|
||||||
|| (strcmp (method, "SHA512") == 0)
|
|| (strcmp (method, "SHA512") == 0)
|
||||||
#endif /* USE_SHA_CRYPT */
|
#endif /* USE_SHA_CRYPT */
|
||||||
|
#ifdef USE_BCRYPT
|
||||||
|
|| (strcmp (method, "BCRYPT") == 0)
|
||||||
|
#endif /* USE_SHA_CRYPT */
|
||||||
|
|
||||||
) {
|
) {
|
||||||
pass_max_len = -1;
|
pass_max_len = -1;
|
||||||
} else {
|
} else {
|
||||||
@@ -710,55 +703,6 @@ static void update_shadow (void)
|
|||||||
spw_locked = false;
|
spw_locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_SELINUX
|
|
||||||
static int check_selinux_access (const char *changed_user,
|
|
||||||
uid_t changed_uid,
|
|
||||||
access_vector_t requested_access)
|
|
||||||
{
|
|
||||||
int status = -1;
|
|
||||||
security_context_t user_context;
|
|
||||||
context_t c;
|
|
||||||
const char *user;
|
|
||||||
|
|
||||||
/* if in permissive mode then allow the operation */
|
|
||||||
if (security_getenforce() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the context of the process which executed passwd */
|
|
||||||
if (getprevcon(&user_context) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the "user" portion of the context (the part before the first
|
|
||||||
colon) */
|
|
||||||
c = context_new(user_context);
|
|
||||||
user = context_user_get(c);
|
|
||||||
|
|
||||||
/* if changing a password for an account with UID==0 or for an account
|
|
||||||
where the identity matches then return success */
|
|
||||||
if (changed_uid != 0 && strcmp(changed_user, user) == 0) {
|
|
||||||
status = 0;
|
|
||||||
} else {
|
|
||||||
struct av_decision avd;
|
|
||||||
int retval;
|
|
||||||
retval = security_compute_av(user_context,
|
|
||||||
user_context,
|
|
||||||
SECCLASS_PASSWD,
|
|
||||||
requested_access,
|
|
||||||
&avd);
|
|
||||||
if ((retval == 0) &&
|
|
||||||
((requested_access & avd.allowed) == requested_access)) {
|
|
||||||
status = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
context_free(c);
|
|
||||||
freecon(user_context);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* WITH_SELINUX */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* passwd - change a user's password file information
|
* passwd - change a user's password file information
|
||||||
*
|
*
|
||||||
@@ -1034,22 +978,13 @@ int main (int argc, char **argv)
|
|||||||
#ifdef WITH_SELINUX
|
#ifdef WITH_SELINUX
|
||||||
/* only do this check when getuid()==0 because it's a pre-condition for
|
/* only do this check when getuid()==0 because it's a pre-condition for
|
||||||
changing a password without entering the old one */
|
changing a password without entering the old one */
|
||||||
if ((is_selinux_enabled() > 0) && (getuid() == 0) &&
|
if (amroot && (check_selinux_permit ("passwd") != 0)) {
|
||||||
(check_selinux_access (name, pw->pw_uid, PASSWD__PASSWD) != 0)) {
|
|
||||||
security_context_t user_context = NULL;
|
|
||||||
const char *user = "Unknown user context";
|
|
||||||
if (getprevcon (&user_context) == 0) {
|
|
||||||
user = user_context; /* FIXME: use context_user_get? */
|
|
||||||
}
|
|
||||||
SYSLOG ((LOG_ALERT,
|
SYSLOG ((LOG_ALERT,
|
||||||
"%s is not authorized to change the password of %s",
|
"root is not authorized by SELinux to change the password of %s",
|
||||||
user, name));
|
name));
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
_("%s: %s is not authorized to change the password of %s\n"),
|
_("%s: root is not authorized by SELinux to change the password of %s\n"),
|
||||||
Prog, user, name);
|
Prog, name);
|
||||||
if (NULL != user_context) {
|
|
||||||
freecon (user_context);
|
|
||||||
}
|
|
||||||
exit (E_NOPERM);
|
exit (E_NOPERM);
|
||||||
}
|
}
|
||||||
#endif /* WITH_SELINUX */
|
#endif /* WITH_SELINUX */
|
||||||
|
|||||||
29
src/pwck.c
29
src/pwck.c
@@ -95,6 +95,8 @@ static void close_files (bool changed);
|
|||||||
static void check_pw_file (int *errors, bool *changed);
|
static void check_pw_file (int *errors, bool *changed);
|
||||||
static void check_spw_file (int *errors, bool *changed);
|
static void check_spw_file (int *errors, bool *changed);
|
||||||
|
|
||||||
|
extern int allow_bad_names;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fail_exit - do some cleanup and exit with the given error code
|
* fail_exit - do some cleanup and exit with the given error code
|
||||||
*/
|
*/
|
||||||
@@ -148,6 +150,7 @@ static /*@noreturn@*/void usage (int status)
|
|||||||
"Options:\n"),
|
"Options:\n"),
|
||||||
Prog);
|
Prog);
|
||||||
}
|
}
|
||||||
|
(void) fputs (_(" -b, --badnames allow bad names\n"), usageout);
|
||||||
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
||||||
(void) fputs (_(" -q, --quiet report errors only\n"), usageout);
|
(void) fputs (_(" -q, --quiet report errors only\n"), usageout);
|
||||||
(void) fputs (_(" -r, --read-only display errors and warnings\n"
|
(void) fputs (_(" -r, --read-only display errors and warnings\n"
|
||||||
@@ -172,6 +175,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
|
{"badnames", no_argument, NULL, 'b'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"quiet", no_argument, NULL, 'q'},
|
{"quiet", no_argument, NULL, 'q'},
|
||||||
{"read-only", no_argument, NULL, 'r'},
|
{"read-only", no_argument, NULL, 'r'},
|
||||||
@@ -183,9 +187,12 @@ static void process_flags (int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Parse the command line arguments
|
* Parse the command line arguments
|
||||||
*/
|
*/
|
||||||
while ((c = getopt_long (argc, argv, "ehqrR:s",
|
while ((c = getopt_long (argc, argv, "behqrR:s",
|
||||||
long_options, NULL)) != -1) {
|
long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'b':
|
||||||
|
allow_bad_names = true;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage (E_SUCCESS);
|
usage (E_SUCCESS);
|
||||||
/*@notreached@*/break;
|
/*@notreached@*/break;
|
||||||
@@ -382,6 +389,8 @@ static void check_pw_file (int *errors, bool *changed)
|
|||||||
struct commonio_entry *pfe, *tpfe;
|
struct commonio_entry *pfe, *tpfe;
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
struct spwd *spw;
|
struct spwd *spw;
|
||||||
|
uid_t min_sys_id = (uid_t) getdef_ulong ("SYS_UID_MIN", 101UL);
|
||||||
|
uid_t max_sys_id = (uid_t) getdef_ulong ("SYS_UID_MAX", 999UL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop through the entire password file.
|
* Loop through the entire password file.
|
||||||
@@ -481,6 +490,7 @@ static void check_pw_file (int *errors, bool *changed)
|
|||||||
/*
|
/*
|
||||||
* Check for invalid usernames. --marekm
|
* Check for invalid usernames. --marekm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!is_valid_user_name (pwd->pw_name)) {
|
if (!is_valid_user_name (pwd->pw_name)) {
|
||||||
printf (_("invalid user name '%s'\n"), pwd->pw_name);
|
printf (_("invalid user name '%s'\n"), pwd->pw_name);
|
||||||
*errors += 1;
|
*errors += 1;
|
||||||
@@ -510,15 +520,20 @@ static void check_pw_file (int *errors, bool *changed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the home directory exists
|
* If uid is system and has a home directory, then check
|
||||||
*/
|
*/
|
||||||
if (!quiet && (access (pwd->pw_dir, F_OK) != 0)) {
|
if (!(pwd->pw_uid >= min_sys_id && pwd->pw_uid <= max_sys_id && pwd->pw_dir && pwd->pw_dir[0])) {
|
||||||
/*
|
/*
|
||||||
* Home directory doesn't exist, give a warning
|
* Make sure the home directory exists
|
||||||
*/
|
*/
|
||||||
printf (_("user '%s': directory '%s' does not exist\n"),
|
if (!quiet && (access (pwd->pw_dir, F_OK) != 0)) {
|
||||||
pwd->pw_name, pwd->pw_dir);
|
/*
|
||||||
*errors += 1;
|
* Home directory doesn't exist, give a warning
|
||||||
|
*/
|
||||||
|
printf (_("user '%s': directory '%s' does not exist\n"),
|
||||||
|
pwd->pw_name, pwd->pw_dir);
|
||||||
|
*errors += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -148,6 +148,8 @@ static char **user_groups; /* NULL-terminated list */
|
|||||||
static long sys_ngroups;
|
static long sys_ngroups;
|
||||||
static bool do_grp_update = false; /* group files need to be updated */
|
static bool do_grp_update = false; /* group files need to be updated */
|
||||||
|
|
||||||
|
extern int allow_bad_names;
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
bflg = false, /* new default root of home directory */
|
bflg = false, /* new default root of home directory */
|
||||||
cflg = false, /* comment (GECOS) field for new account */
|
cflg = false, /* comment (GECOS) field for new account */
|
||||||
@@ -821,6 +823,7 @@ static void usage (int status)
|
|||||||
"\n"
|
"\n"
|
||||||
"Options:\n"),
|
"Options:\n"),
|
||||||
Prog, Prog, Prog);
|
Prog, Prog, Prog);
|
||||||
|
(void) fputs (_(" --badnames do not check for bad names\n"), usageout);
|
||||||
(void) fputs (_(" -b, --base-dir BASE_DIR base directory for the home directory of the\n"
|
(void) fputs (_(" -b, --base-dir BASE_DIR base directory for the home directory of the\n"
|
||||||
" new account\n"), usageout);
|
" new account\n"), usageout);
|
||||||
#ifdef WITH_BTRFS
|
#ifdef WITH_BTRFS
|
||||||
@@ -1098,6 +1101,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
const struct group *grp;
|
const struct group *grp;
|
||||||
bool anyflag = false;
|
bool anyflag = false;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -1109,6 +1113,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
#ifdef WITH_BTRFS
|
#ifdef WITH_BTRFS
|
||||||
{"btrfs-subvolume-home", no_argument, NULL, 200},
|
{"btrfs-subvolume-home", no_argument, NULL, 200},
|
||||||
#endif
|
#endif
|
||||||
|
{"badnames", no_argument, NULL, 201},
|
||||||
{"comment", required_argument, NULL, 'c'},
|
{"comment", required_argument, NULL, 'c'},
|
||||||
{"home-dir", required_argument, NULL, 'd'},
|
{"home-dir", required_argument, NULL, 'd'},
|
||||||
{"defaults", no_argument, NULL, 'D'},
|
{"defaults", no_argument, NULL, 'D'},
|
||||||
@@ -1158,6 +1163,9 @@ static void process_flags (int argc, char **argv)
|
|||||||
case 200:
|
case 200:
|
||||||
subvolflg = true;
|
subvolflg = true;
|
||||||
break;
|
break;
|
||||||
|
case 201:
|
||||||
|
allow_bad_names = true;
|
||||||
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
if (!VALID (optarg)) {
|
if (!VALID (optarg)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@@ -1320,7 +1328,10 @@ static void process_flags (int argc, char **argv)
|
|||||||
if ( ( !VALID (optarg) )
|
if ( ( !VALID (optarg) )
|
||||||
|| ( ('\0' != optarg[0])
|
|| ( ('\0' != optarg[0])
|
||||||
&& ('/' != optarg[0])
|
&& ('/' != optarg[0])
|
||||||
&& ('*' != optarg[0]) )) {
|
&& ('*' != optarg[0]) )
|
||||||
|
|| (stat(optarg, &st) != 0)
|
||||||
|
|| (S_ISDIR(st.st_mode))
|
||||||
|
|| (access(optarg, X_OK) != 0)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: invalid shell '%s'\n"),
|
_("%s: invalid shell '%s'\n"),
|
||||||
Prog, optarg);
|
Prog, optarg);
|
||||||
@@ -2449,9 +2460,9 @@ int main (int argc, char **argv)
|
|||||||
(uid_t)-1, user_id, (gid_t)-1, user_gid);
|
(uid_t)-1, user_id, (gid_t)-1, user_gid);
|
||||||
} else {
|
} else {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: warning: the home directory already exists.\n"
|
_("%s: warning: the home directory %s already exists.\n"
|
||||||
"Not copying any file from skel directory into it.\n"),
|
"%s: Not copying any file from skel directory into it.\n"),
|
||||||
Prog);
|
Prog, user_home, Prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,9 @@ static char *user_home;
|
|||||||
|
|
||||||
static bool fflg = false;
|
static bool fflg = false;
|
||||||
static bool rflg = false;
|
static bool rflg = false;
|
||||||
|
#ifdef WITH_SELINUX
|
||||||
static bool Zflg = false;
|
static bool Zflg = false;
|
||||||
|
#endif
|
||||||
static bool Rflg = false;
|
static bool Rflg = false;
|
||||||
|
|
||||||
static bool is_shadow_pwd;
|
static bool is_shadow_pwd;
|
||||||
|
|||||||
@@ -206,6 +206,8 @@ static void update_faillog (void);
|
|||||||
static void move_mailbox (void);
|
static void move_mailbox (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern int allow_bad_names;
|
||||||
|
|
||||||
static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize,
|
static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize,
|
||||||
long int date)
|
long int date)
|
||||||
{
|
{
|
||||||
@@ -408,6 +410,7 @@ static /*@noreturn@*/void usage (int status)
|
|||||||
"\n"
|
"\n"
|
||||||
"Options:\n"),
|
"Options:\n"),
|
||||||
Prog);
|
Prog);
|
||||||
|
(void) fputs (_(" -b, --badnames allow bad names\n"), usageout);
|
||||||
(void) fputs (_(" -c, --comment COMMENT new value of the GECOS field\n"), usageout);
|
(void) fputs (_(" -c, --comment COMMENT new value of the GECOS field\n"), usageout);
|
||||||
(void) fputs (_(" -d, --home HOME_DIR new home directory for the user account\n"), usageout);
|
(void) fputs (_(" -d, --home HOME_DIR new home directory for the user account\n"), usageout);
|
||||||
(void) fputs (_(" -e, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE\n"), usageout);
|
(void) fputs (_(" -e, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE\n"), usageout);
|
||||||
@@ -991,6 +994,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
int c;
|
int c;
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"append", no_argument, NULL, 'a'},
|
{"append", no_argument, NULL, 'a'},
|
||||||
|
{"badnames", no_argument, NULL, 'b'},
|
||||||
{"comment", required_argument, NULL, 'c'},
|
{"comment", required_argument, NULL, 'c'},
|
||||||
{"home", required_argument, NULL, 'd'},
|
{"home", required_argument, NULL, 'd'},
|
||||||
{"expiredate", required_argument, NULL, 'e'},
|
{"expiredate", required_argument, NULL, 'e'},
|
||||||
@@ -1020,7 +1024,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
{NULL, 0, NULL, '\0'}
|
{NULL, 0, NULL, '\0'}
|
||||||
};
|
};
|
||||||
while ((c = getopt_long (argc, argv,
|
while ((c = getopt_long (argc, argv,
|
||||||
"ac:d:e:f:g:G:hl:Lmop:R:s:u:UP:"
|
"abc:d:e:f:g:G:hl:Lmop:R:s:u:UP:"
|
||||||
#ifdef ENABLE_SUBIDS
|
#ifdef ENABLE_SUBIDS
|
||||||
"v:w:V:W:"
|
"v:w:V:W:"
|
||||||
#endif /* ENABLE_SUBIDS */
|
#endif /* ENABLE_SUBIDS */
|
||||||
@@ -1032,6 +1036,9 @@ static void process_flags (int argc, char **argv)
|
|||||||
case 'a':
|
case 'a':
|
||||||
aflg = true;
|
aflg = true;
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
allow_bad_names = true;
|
||||||
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
if (!VALID (optarg)) {
|
if (!VALID (optarg)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@@ -1879,7 +1886,7 @@ static void update_lastlog (void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
max_uid = (uid_t) getdef_ulong ("LASTLOG_MAX_UID", 0xFFFFFFFFUL);
|
max_uid = (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL);
|
||||||
if (user_newid > max_uid) {
|
if (user_newid > max_uid) {
|
||||||
/* do not touch lastlog for large uids */
|
/* do not touch lastlog for large uids */
|
||||||
return;
|
return;
|
||||||
|
|||||||
47
src/vipw.c
47
src/vipw.c
@@ -207,6 +207,8 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
|||||||
struct stat st1, st2;
|
struct stat st1, st2;
|
||||||
int status;
|
int status;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
pid_t orig_pgrp, editor_pgrp = -1;
|
||||||
|
sigset_t mask, omask;
|
||||||
/* FIXME: the following should have variable sizes */
|
/* FIXME: the following should have variable sizes */
|
||||||
char filebackup[1024], fileedit[1024];
|
char filebackup[1024], fileedit[1024];
|
||||||
char *to_rename;
|
char *to_rename;
|
||||||
@@ -294,6 +296,8 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
|||||||
editor = DEFAULT_EDITOR;
|
editor = DEFAULT_EDITOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
orig_pgrp = tcgetpgrp(STDIN_FILENO);
|
||||||
|
|
||||||
pid = fork ();
|
pid = fork ();
|
||||||
if (-1 == pid) {
|
if (-1 == pid) {
|
||||||
vipwexit ("fork", 1, 1);
|
vipwexit ("fork", 1, 1);
|
||||||
@@ -303,6 +307,14 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
|||||||
char *buf;
|
char *buf;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
/* Wait for parent to make us the foreground pgrp. */
|
||||||
|
if (orig_pgrp != -1) {
|
||||||
|
pid = getpid();
|
||||||
|
setpgid(0, 0);
|
||||||
|
while (tcgetpgrp(STDIN_FILENO) != pid)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
buf = (char *) malloc (strlen (editor) + strlen (fileedit) + 2);
|
buf = (char *) malloc (strlen (editor) + strlen (fileedit) + 2);
|
||||||
snprintf (buf, strlen (editor) + strlen (fileedit) + 2,
|
snprintf (buf, strlen (editor) + strlen (fileedit) + 2,
|
||||||
"%s %s", editor, fileedit);
|
"%s %s", editor, fileedit);
|
||||||
@@ -325,19 +337,50 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Run child in a new pgrp and make it the foreground pgrp. */
|
||||||
|
if (orig_pgrp != -1) {
|
||||||
|
setpgid(pid, pid);
|
||||||
|
tcsetpgrp(STDIN_FILENO, pid);
|
||||||
|
|
||||||
|
/* Avoid SIGTTOU when changing foreground pgrp below. */
|
||||||
|
sigemptyset(&mask);
|
||||||
|
sigaddset(&mask, SIGTTOU);
|
||||||
|
sigprocmask(SIG_BLOCK, &mask, &omask);
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pid = waitpid (pid, &status, WUNTRACED);
|
pid = waitpid (pid, &status, WUNTRACED);
|
||||||
if ((pid != -1) && (WIFSTOPPED (status) != 0)) {
|
if ((pid != -1) && (WIFSTOPPED (status) != 0)) {
|
||||||
/* The child (editor) was suspended.
|
/* The child (editor) was suspended.
|
||||||
* Suspend vipw. */
|
* Restore terminal pgrp and suspend vipw. */
|
||||||
|
if (orig_pgrp != -1) {
|
||||||
|
editor_pgrp = tcgetpgrp(STDIN_FILENO);
|
||||||
|
if (editor_pgrp == -1) {
|
||||||
|
fprintf (stderr, "%s: %s: %s", Prog,
|
||||||
|
"tcgetpgrp", strerror (errno));
|
||||||
|
}
|
||||||
|
if (tcsetpgrp(STDIN_FILENO, orig_pgrp) == -1) {
|
||||||
|
fprintf (stderr, "%s: %s: %s", Prog,
|
||||||
|
"tcsetpgrp", strerror (errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
kill (getpid (), SIGSTOP);
|
kill (getpid (), SIGSTOP);
|
||||||
/* wake child when resumed */
|
/* wake child when resumed */
|
||||||
kill (pid, SIGCONT);
|
if (editor_pgrp != -1) {
|
||||||
|
if (tcsetpgrp(STDIN_FILENO, editor_pgrp) == -1) {
|
||||||
|
fprintf (stderr, "%s: %s: %s", Prog,
|
||||||
|
"tcsetpgrp", strerror (errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
killpg (pid, SIGCONT);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (orig_pgrp != -1)
|
||||||
|
sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||||
|
|
||||||
if (-1 == pid) {
|
if (-1 == pid) {
|
||||||
vipwexit (editor, 1, 1);
|
vipwexit (editor, 1, 1);
|
||||||
} else if ( WIFEXITED (status)
|
} else if ( WIFEXITED (status)
|
||||||
|
|||||||
Reference in New Issue
Block a user