Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fbc11ce21 | ||
|
|
ff2baed5db | ||
|
|
94da3dc5c8 | ||
|
|
9df58a7545 | ||
|
|
5b017af90d | ||
|
|
a7a7a1fdea | ||
|
|
ca0ccaba27 | ||
|
|
8f1836bad9 | ||
|
|
61fc90b268 | ||
|
|
1d5a926cc2 | ||
|
|
7f5a14817d | ||
|
|
9bf01bf010 | ||
|
|
358bd9b359 | ||
|
|
dd50014055 | ||
|
|
a84b0cafdd | ||
|
|
a4dee3d1ad | ||
|
|
340729bbe8 | ||
|
|
4518826376 | ||
|
|
aa38e0da9a | ||
|
|
ef45bb2496 | ||
|
|
edec2d057d | ||
|
|
66897b6f6d | ||
|
|
af064545bf | ||
|
|
9ab9e6f331 | ||
|
|
65c2617140 | ||
|
|
24468e4525 | ||
|
|
df11d701e1 | ||
|
|
d2fa8c5d4b | ||
|
|
e01bad7d3c | ||
|
|
4c4896f0d5 | ||
|
|
5fadb341c3 | ||
|
|
29ee91ae7d | ||
|
|
5533eb40d1 | ||
|
|
533d2bab3d | ||
|
|
f68f813073 | ||
|
|
7edb32e75f | ||
|
|
acf11efe54 | ||
|
|
a887847ca2 | ||
|
|
c17f5ec460 | ||
|
|
df5dafe049 | ||
|
|
3c32fd4a29 | ||
|
|
ecb6f0c3e3 | ||
|
|
169e14c7ac | ||
|
|
316fa38dbc | ||
|
|
884895ae25 | ||
|
|
464456fa31 | ||
|
|
bab349b46e | ||
|
|
46a72bc342 | ||
|
|
ee43f47f45 | ||
|
|
71c6165dcd | ||
|
|
51c1fc93e3 | ||
|
|
17887b216d | ||
|
|
01eab0c3b9 | ||
|
|
6b65c6aeae | ||
|
|
3fb292f3c7 | ||
|
|
a8bf8af5aa | ||
|
|
d8c8e8b4b6 | ||
|
|
930e76ad0d | ||
|
|
83b5a746d9 | ||
|
|
a7f8176be6 | ||
|
|
1b4db814ea | ||
|
|
9ae9ca833a | ||
|
|
66f87b8caf | ||
|
|
bba85fcae3 | ||
|
|
a0104a9ed8 | ||
|
|
112e015f05 | ||
|
|
e6246599eb | ||
|
|
1d049b6aed | ||
|
|
37e2a687e3 | ||
|
|
a113b87c45 | ||
|
|
b999d48941 | ||
|
|
2cb54158b8 | ||
|
|
420943657c | ||
|
|
4911773b77 | ||
|
|
980c804153 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,6 +17,7 @@ Makefile.in
|
||||
/ABOUT-NLS
|
||||
/aclocal.m4
|
||||
/autom4te.cache
|
||||
/compile
|
||||
/config.guess
|
||||
/config.h
|
||||
/config.h.in
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT
|
||||
AM_INIT_AUTOMAKE(shadow, 4.2)
|
||||
AM_INIT_AUTOMAKE(shadow, 4.3.1)
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
dnl Some hacks...
|
||||
@@ -335,16 +335,10 @@ if test "$enable_subids" != "no"; then
|
||||
dnl
|
||||
dnl FIXME: check if 32 bit UIDs/GIDs are supported by libc
|
||||
dnl
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||
#include <sys/types.h>
|
||||
int main(void) {
|
||||
uid_t u;
|
||||
gid_t g;
|
||||
return (sizeof u < 4) || (sizeof g < 4);
|
||||
}
|
||||
])], [id32bit="yes"], [id32bit="no"])
|
||||
AC_CHECK_SIZEOF([uid_t],, [#include "sys/types.h"])
|
||||
AC_CHECK_SIZEOF([gid_t],, [#include "sys/types.h"])
|
||||
|
||||
if test "x$id32bit" = "xyes"; then
|
||||
if test "$ac_cv_sizeof_uid_t" -ge 4 && test "$ac_cv_sizeof_gid_t" -ge 4; then
|
||||
AC_DEFINE(ENABLE_SUBIDS, 1, [Define to support the subordinate IDs.])
|
||||
enable_subids="yes"
|
||||
else
|
||||
@@ -229,7 +229,7 @@ SYS_UID_MAX 999
|
||||
# Extra per user uids
|
||||
SUB_UID_MIN 100000
|
||||
SUB_UID_MAX 600100000
|
||||
SUB_UID_COUNT 10000
|
||||
SUB_UID_COUNT 65536
|
||||
|
||||
#
|
||||
# Min/max values for automatic gid selection in groupadd(8)
|
||||
@@ -242,7 +242,7 @@ SYS_GID_MAX 999
|
||||
# Extra per user group ids
|
||||
SUB_GID_MIN 100000
|
||||
SUB_GID_MAX 600100000
|
||||
SUB_GID_COUNT 10000
|
||||
SUB_GID_COUNT 65536
|
||||
|
||||
#
|
||||
# Max number of login(1) retries if password is bad
|
||||
@@ -393,3 +393,8 @@ USERGROUPS_ENAB yes
|
||||
#
|
||||
#CREATE_HOME yes
|
||||
|
||||
#
|
||||
# Force use shadow, even if shadow passwd & shadow group files are
|
||||
# missing.
|
||||
#
|
||||
#FORCE_SHADOW yes
|
||||
|
||||
@@ -968,11 +968,10 @@ int commonio_close (struct commonio_db *db)
|
||||
} else {
|
||||
/*
|
||||
* Default permissions for new [g]shadow files.
|
||||
* (passwd and group always exist...)
|
||||
*/
|
||||
sb.st_mode = 0400;
|
||||
sb.st_uid = 0;
|
||||
sb.st_gid = 0;
|
||||
sb.st_mode = db->st_mode;
|
||||
sb.st_uid = db->st_uid;
|
||||
sb.st_gid = db->st_gid;
|
||||
}
|
||||
|
||||
snprintf (buf, sizeof buf, "%s+", db->filename);
|
||||
@@ -1081,6 +1080,7 @@ int commonio_update (struct commonio_db *db, const void *eptr)
|
||||
if (NULL != p) {
|
||||
if (next_entry_by_name (db, p->next, db->ops->getname (eptr)) != NULL) {
|
||||
fprintf (stderr, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename);
|
||||
db->ops->free (nentry);
|
||||
return 0;
|
||||
}
|
||||
db->ops->free (p->eptr);
|
||||
|
||||
@@ -123,6 +123,12 @@ struct commonio_db {
|
||||
#ifdef WITH_SELINUX
|
||||
/*@null@*/security_context_t scontext;
|
||||
#endif
|
||||
/*
|
||||
* Default permissions and owner for newly created data file.
|
||||
*/
|
||||
mode_t st_mode;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
/*
|
||||
* Head, tail, current position in linked list.
|
||||
*/
|
||||
|
||||
80
lib/getdef.c
80
lib/getdef.c
@@ -49,6 +49,32 @@ struct itemdef {
|
||||
/*@null@*/char *value; /* value given, or NULL if no value */
|
||||
};
|
||||
|
||||
#define PAMDEFS \
|
||||
{"CHFN_AUTH", NULL}, \
|
||||
{"CHSH_AUTH", NULL}, \
|
||||
{"CRACKLIB_DICTPATH", NULL}, \
|
||||
{"ENV_HZ", NULL}, \
|
||||
{"ENVIRON_FILE", NULL}, \
|
||||
{"ENV_TZ", NULL}, \
|
||||
{"FAILLOG_ENAB", NULL}, \
|
||||
{"FTMP_FILE", NULL}, \
|
||||
{"ISSUE_FILE", NULL}, \
|
||||
{"LASTLOG_ENAB", NULL}, \
|
||||
{"LOGIN_STRING", NULL}, \
|
||||
{"MAIL_CHECK_ENAB", NULL}, \
|
||||
{"MOTD_FILE", NULL}, \
|
||||
{"NOLOGINS_FILE", NULL}, \
|
||||
{"OBSCURE_CHECKS_ENAB", NULL}, \
|
||||
{"PASS_ALWAYS_WARN", NULL}, \
|
||||
{"PASS_CHANGE_TRIES", NULL}, \
|
||||
{"PASS_MAX_LEN", NULL}, \
|
||||
{"PASS_MIN_LEN", NULL}, \
|
||||
{"PORTTIME_CHECKS_ENAB", NULL}, \
|
||||
{"QUOTAS_ENAB", NULL}, \
|
||||
{"SU_WHEEL_ONLY", NULL}, \
|
||||
{"ULIMIT", NULL},
|
||||
|
||||
|
||||
#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
|
||||
static struct itemdef def_table[] = {
|
||||
{"CHFN_RESTRICT", NULL},
|
||||
@@ -102,29 +128,7 @@ static struct itemdef def_table[] = {
|
||||
{"USERDEL_CMD", NULL},
|
||||
{"USERGROUPS_ENAB", NULL},
|
||||
#ifndef USE_PAM
|
||||
{"CHFN_AUTH", NULL},
|
||||
{"CHSH_AUTH", NULL},
|
||||
{"CRACKLIB_DICTPATH", NULL},
|
||||
{"ENV_HZ", NULL},
|
||||
{"ENVIRON_FILE", NULL},
|
||||
{"ENV_TZ", NULL},
|
||||
{"FAILLOG_ENAB", NULL},
|
||||
{"FTMP_FILE", NULL},
|
||||
{"ISSUE_FILE", NULL},
|
||||
{"LASTLOG_ENAB", NULL},
|
||||
{"LOGIN_STRING", NULL},
|
||||
{"MAIL_CHECK_ENAB", NULL},
|
||||
{"MOTD_FILE", NULL},
|
||||
{"NOLOGINS_FILE", NULL},
|
||||
{"OBSCURE_CHECKS_ENAB", NULL},
|
||||
{"PASS_ALWAYS_WARN", NULL},
|
||||
{"PASS_CHANGE_TRIES", NULL},
|
||||
{"PASS_MAX_LEN", NULL},
|
||||
{"PASS_MIN_LEN", NULL},
|
||||
{"PORTTIME_CHECKS_ENAB", NULL},
|
||||
{"QUOTAS_ENAB", NULL},
|
||||
{"SU_WHEEL_ONLY", NULL},
|
||||
{"ULIMIT", NULL},
|
||||
PAMDEFS
|
||||
#endif
|
||||
#ifdef USE_SYSLOG
|
||||
{"SYSLOG_SG_ENAB", NULL},
|
||||
@@ -135,9 +139,17 @@ static struct itemdef def_table[] = {
|
||||
{"TCB_SYMLINKS", NULL},
|
||||
{"USE_TCB", NULL},
|
||||
#endif
|
||||
{"FORCE_SHADOW", NULL},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#define NUMKNOWNDEFS (sizeof(knowndef_table)/sizeof(knowndef_table[0]))
|
||||
static struct itemdef knowndef_table[] = {
|
||||
#ifdef USE_PAM
|
||||
PAMDEFS
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef LOGINDEFS
|
||||
#define LOGINDEFS "/etc/login.defs"
|
||||
#endif
|
||||
@@ -397,10 +409,17 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name)
|
||||
* Item was never found.
|
||||
*/
|
||||
|
||||
for (ptr = knowndef_table; NULL != ptr->name; ptr++) {
|
||||
if (strcmp (ptr->name, name) == 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
fprintf (stderr,
|
||||
_("configuration error - unknown item '%s' (notify administrator)\n"),
|
||||
name);
|
||||
SYSLOG ((LOG_CRIT, "unknown configuration item `%s'", name));
|
||||
|
||||
out:
|
||||
return (struct itemdef *) NULL;
|
||||
}
|
||||
|
||||
@@ -416,23 +435,26 @@ static void def_load (void)
|
||||
FILE *fp;
|
||||
char buf[1024], *name, *value, *s;
|
||||
|
||||
/*
|
||||
* Set the initialized flag.
|
||||
* (do it early to prevent recursion in putdef_str())
|
||||
*/
|
||||
def_loaded = true;
|
||||
|
||||
/*
|
||||
* Open the configuration definitions file.
|
||||
*/
|
||||
fp = fopen (def_fname, "r");
|
||||
if (NULL == fp) {
|
||||
if (errno == ENOENT)
|
||||
return;
|
||||
|
||||
int err = errno;
|
||||
SYSLOG ((LOG_CRIT, "cannot open login definitions %s [%s]",
|
||||
def_fname, strerror (err)));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the initialized flag.
|
||||
* (do it early to prevent recursion in putdef_str())
|
||||
*/
|
||||
def_loaded = true;
|
||||
|
||||
/*
|
||||
* Go through all of the lines in the file.
|
||||
*/
|
||||
|
||||
@@ -44,22 +44,19 @@
|
||||
*/
|
||||
int getulong (const char *numstr, /*@out@*/unsigned long int *result)
|
||||
{
|
||||
long long int val;
|
||||
unsigned long int val;
|
||||
char *endptr;
|
||||
|
||||
errno = 0;
|
||||
val = strtoll (numstr, &endptr, 0);
|
||||
val = strtoul (numstr, &endptr, 0);
|
||||
if ( ('\0' == *numstr)
|
||||
|| ('\0' != *endptr)
|
||||
|| (ERANGE == errno)
|
||||
/*@+ignoresigns@*/
|
||||
|| (val != (unsigned long int)val)
|
||||
/*@=ignoresigns@*/
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = (unsigned long int)val;
|
||||
*result = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,9 @@ static /*@owned@*/struct commonio_db group_db = {
|
||||
#ifdef WITH_SELINUX
|
||||
NULL, /* scontext */
|
||||
#endif
|
||||
0644, /* st_mode */
|
||||
0, /* st_uid */
|
||||
0, /* st_gid */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
|
||||
@@ -55,15 +55,14 @@
|
||||
gr->gr_name = strdup (grent->gr_name);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == gr->gr_name) {
|
||||
free(gr);
|
||||
gr_free(gr);
|
||||
return NULL;
|
||||
}
|
||||
/*@-mustfreeonly@*/
|
||||
gr->gr_passwd = strdup (grent->gr_passwd);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == gr->gr_passwd) {
|
||||
free(gr->gr_name);
|
||||
free(gr);
|
||||
gr_free(gr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -73,21 +72,13 @@
|
||||
gr->gr_mem = (char **) malloc ((i + 1) * sizeof (char *));
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == gr->gr_mem) {
|
||||
free(gr->gr_passwd);
|
||||
free(gr->gr_name);
|
||||
free(gr);
|
||||
gr_free(gr);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; grent->gr_mem[i]; i++) {
|
||||
gr->gr_mem[i] = strdup (grent->gr_mem[i]);
|
||||
if (NULL == gr->gr_mem[i]) {
|
||||
int j;
|
||||
for (j=0; j<i; j++)
|
||||
free(gr->gr_mem[j]);
|
||||
free(gr->gr_mem);
|
||||
free(gr->gr_passwd);
|
||||
free(gr->gr_name);
|
||||
free(gr);
|
||||
gr_free(gr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,9 @@ static struct commonio_db passwd_db = {
|
||||
#ifdef WITH_SELINUX
|
||||
NULL, /* scontext */
|
||||
#endif
|
||||
0644, /* st_mode */
|
||||
0, /* st_uid */
|
||||
0, /* st_gid */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
|
||||
20
lib/pwmem.c
20
lib/pwmem.c
@@ -56,45 +56,35 @@
|
||||
pw->pw_name = strdup (pwent->pw_name);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == pw->pw_name) {
|
||||
free(pw);
|
||||
pw_free(pw);
|
||||
return NULL;
|
||||
}
|
||||
/*@-mustfreeonly@*/
|
||||
pw->pw_passwd = strdup (pwent->pw_passwd);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == pw->pw_passwd) {
|
||||
free(pw->pw_name);
|
||||
free(pw);
|
||||
pw_free(pw);
|
||||
return NULL;
|
||||
}
|
||||
/*@-mustfreeonly@*/
|
||||
pw->pw_gecos = strdup (pwent->pw_gecos);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == pw->pw_gecos) {
|
||||
free(pw->pw_passwd);
|
||||
free(pw->pw_name);
|
||||
free(pw);
|
||||
pw_free(pw);
|
||||
return NULL;
|
||||
}
|
||||
/*@-mustfreeonly@*/
|
||||
pw->pw_dir = strdup (pwent->pw_dir);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == pw->pw_dir) {
|
||||
free(pw->pw_gecos);
|
||||
free(pw->pw_passwd);
|
||||
free(pw->pw_name);
|
||||
free(pw);
|
||||
pw_free(pw);
|
||||
return NULL;
|
||||
}
|
||||
/*@-mustfreeonly@*/
|
||||
pw->pw_shell = strdup (pwent->pw_shell);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == pw->pw_shell) {
|
||||
free(pw->pw_dir);
|
||||
free(pw->pw_gecos);
|
||||
free(pw->pw_passwd);
|
||||
free(pw->pw_name);
|
||||
free(pw);
|
||||
pw_free(pw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -228,6 +228,9 @@ static struct commonio_db gshadow_db = {
|
||||
#ifdef WITH_SELINUX
|
||||
NULL, /* scontext */
|
||||
#endif
|
||||
0400, /* st_mode */
|
||||
0, /* st_uid */
|
||||
0, /* st_gid */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
@@ -249,6 +252,8 @@ int sgr_setdbname (const char *filename)
|
||||
|
||||
bool sgr_file_present (void)
|
||||
{
|
||||
if (getdef_bool ("FORCE_SHADOW"))
|
||||
return true;
|
||||
return commonio_present (&gshadow_db);
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,9 @@ static struct commonio_db shadow_db = {
|
||||
#ifdef WITH_SELINUX
|
||||
NULL, /* scontext */
|
||||
#endif /* WITH_SELINUX */
|
||||
0400, /* st_mode */
|
||||
0, /* st_uid */
|
||||
0, /* st_gid */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
@@ -125,6 +128,8 @@ int spw_setdbname (const char *filename)
|
||||
|
||||
bool spw_file_present (void)
|
||||
{
|
||||
if (getdef_bool ("FORCE_SHADOW"))
|
||||
return true;
|
||||
return commonio_present (&shadow_db);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <stdio.h>
|
||||
#include "commonio.h"
|
||||
#include "subordinateio.h"
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
|
||||
struct subordinate_range {
|
||||
const char *owner;
|
||||
@@ -189,6 +191,15 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
|
||||
const char *owner, unsigned long val)
|
||||
{
|
||||
const struct subordinate_range *range;
|
||||
|
||||
/*
|
||||
* Search for exact username/group specification
|
||||
*
|
||||
* This is the original method - go fast through the db, doing only
|
||||
* exact username/group string comparison. Therefore we leave it as-is
|
||||
* for the time being, in order to keep it equally fast as it was
|
||||
* before.
|
||||
*/
|
||||
commonio_rewind(db);
|
||||
while ((range = commonio_next(db)) != NULL) {
|
||||
unsigned long first = range->start;
|
||||
@@ -200,6 +211,76 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
|
||||
if ((val >= first) && (val <= last))
|
||||
return range;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We only do special handling for these two files
|
||||
*/
|
||||
if ((0 != strcmp(db->filename, "/etc/subuid")) && (0 != strcmp(db->filename, "/etc/subgid")))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Search loop above did not produce any result. Let's rerun it,
|
||||
* but this time try to matcha actual UIDs. The first entry that
|
||||
* matches is considered a success.
|
||||
* (It may be specified as literal UID or as another username which
|
||||
* has the same UID as the username we are looking for.)
|
||||
*/
|
||||
struct passwd *pwd;
|
||||
uid_t owner_uid;
|
||||
char owner_uid_string[33] = "";
|
||||
|
||||
|
||||
/* Get UID of the username we are looking for */
|
||||
pwd = getpwnam(owner);
|
||||
if (NULL == pwd) {
|
||||
/* Username not defined in /etc/passwd, or error occured during lookup */
|
||||
return NULL;
|
||||
}
|
||||
owner_uid = pwd->pw_uid;
|
||||
sprintf(owner_uid_string, "%lu", (unsigned long int)owner_uid);
|
||||
|
||||
commonio_rewind(db);
|
||||
while ((range = commonio_next(db)) != NULL) {
|
||||
unsigned long first = range->start;
|
||||
unsigned long last = first + range->count - 1;
|
||||
|
||||
/* For performance reasons check range before using getpwnam() */
|
||||
if ((val < first) || (val > last)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Range matches. Check if range owner is specified
|
||||
* as numeric UID and if it matches.
|
||||
*/
|
||||
if (0 == strcmp(range->owner, owner_uid_string)) {
|
||||
return range;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok, this range owner is not specified as numeric UID
|
||||
* we are looking for. It may be specified as another
|
||||
* UID or as a literal username.
|
||||
*
|
||||
* If specified as another UID, the call to getpwnam()
|
||||
* will return NULL.
|
||||
*
|
||||
* If specified as literal username, we will get its
|
||||
* UID and compare that to UID we are looking for.
|
||||
*/
|
||||
const struct passwd *range_owner_pwd;
|
||||
|
||||
range_owner_pwd = getpwnam(range->owner);
|
||||
if (NULL == range_owner_pwd) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (owner_uid == range_owner_pwd->pw_uid) {
|
||||
return range;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -460,6 +541,9 @@ static struct commonio_db subordinate_uid_db = {
|
||||
#ifdef WITH_SELINUX
|
||||
NULL, /* scontext */
|
||||
#endif
|
||||
0644, /* st_mode */
|
||||
0, /* st_uid */
|
||||
0, /* st_gid */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
@@ -538,6 +622,9 @@ static struct commonio_db subordinate_gid_db = {
|
||||
#ifdef WITH_SELINUX
|
||||
NULL, /* scontext */
|
||||
#endif
|
||||
0644, /* st_mode */
|
||||
0, /* st_uid */
|
||||
0, /* st_gid */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
|
||||
@@ -58,7 +58,7 @@ int find_new_sub_gids (const char *owner,
|
||||
|
||||
min = getdef_ulong ("SUB_GID_MIN", 100000UL);
|
||||
max = getdef_ulong ("SUB_GID_MAX", 600100000UL);
|
||||
count = getdef_ulong ("SUB_GID_COUNT", 10000);
|
||||
count = getdef_ulong ("SUB_GID_COUNT", 65536);
|
||||
|
||||
if (min > max || count >= max || (min + count - 1) > max) {
|
||||
(void) fprintf (stderr,
|
||||
|
||||
@@ -58,7 +58,7 @@ int find_new_sub_uids (const char *owner,
|
||||
|
||||
min = getdef_ulong ("SUB_UID_MIN", 100000UL);
|
||||
max = getdef_ulong ("SUB_UID_MAX", 600100000UL);
|
||||
count = getdef_ulong ("SUB_UID_COUNT", 10000);
|
||||
count = getdef_ulong ("SUB_UID_COUNT", 65536);
|
||||
|
||||
if (min > max || count >= max || (min + count - 1) > max) {
|
||||
(void) fprintf (stderr,
|
||||
|
||||
@@ -70,13 +70,40 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv)
|
||||
|
||||
/* Gather up the ranges from the command line */
|
||||
mapping = mappings;
|
||||
for (idx = 0; idx < ranges; idx++, argidx += 3, mapping++) {
|
||||
if (!getulong(argv[argidx + 0], &mapping->upper))
|
||||
for (idx = 0, argidx = 0; idx < ranges; idx++, argidx += 3, mapping++) {
|
||||
if (!getulong(argv[argidx + 0], &mapping->upper)) {
|
||||
free(mappings);
|
||||
return NULL;
|
||||
if (!getulong(argv[argidx + 1], &mapping->lower))
|
||||
}
|
||||
if (!getulong(argv[argidx + 1], &mapping->lower)) {
|
||||
free(mappings);
|
||||
return NULL;
|
||||
if (!getulong(argv[argidx + 2], &mapping->count))
|
||||
}
|
||||
if (!getulong(argv[argidx + 2], &mapping->count)) {
|
||||
free(mappings);
|
||||
return NULL;
|
||||
}
|
||||
if (ULONG_MAX - mapping->upper <= mapping->count || ULONG_MAX - mapping->lower <= mapping->count) {
|
||||
fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (mapping->upper > UINT_MAX ||
|
||||
mapping->lower > UINT_MAX ||
|
||||
mapping->count > UINT_MAX) {
|
||||
fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (mapping->lower + mapping->count > UINT_MAX ||
|
||||
mapping->upper + mapping->count > UINT_MAX) {
|
||||
fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (mapping->lower + mapping->count < mapping->lower ||
|
||||
mapping->upper + mapping->count < mapping->upper) {
|
||||
/* this one really shouldn't be possible given previous checks */
|
||||
fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
|
||||
@@ -175,6 +175,9 @@ static int user_busy_processes (const char *name, uid_t uid)
|
||||
if (stat ("/", &sbroot) != 0) {
|
||||
perror ("stat (\"/\")");
|
||||
(void) closedir (proc);
|
||||
#ifdef ENABLE_SUBIDS
|
||||
sub_uid_close();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -212,6 +215,9 @@ static int user_busy_processes (const char *name, uid_t uid)
|
||||
|
||||
if (check_status (name, tmp_d_name, uid) != 0) {
|
||||
(void) closedir (proc);
|
||||
#ifdef ENABLE_SUBIDS
|
||||
sub_uid_close();
|
||||
#endif
|
||||
fprintf (stderr,
|
||||
_("%s: user %s is currently used by process %d\n"),
|
||||
Prog, name, pid);
|
||||
@@ -232,6 +238,9 @@ static int user_busy_processes (const char *name, uid_t uid)
|
||||
}
|
||||
if (check_status (name, task_path+6, uid) != 0) {
|
||||
(void) closedir (proc);
|
||||
#ifdef ENABLE_SUBIDS
|
||||
sub_uid_close();
|
||||
#endif
|
||||
fprintf (stderr,
|
||||
_("%s: user %s is currently used by process %d\n"),
|
||||
Prog, name, pid);
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<para>
|
||||
The default encryption algorithm can be defined for the system with
|
||||
the <option>ENCRYPT_METHOD</option> variable of <filename>/etc/login.defs</filename>,
|
||||
and can be overwiten with the <option>-e</option>,
|
||||
and can be overwritten with the <option>-e</option>,
|
||||
<option>-m</option>, or <option>-c</option> options.
|
||||
</para>
|
||||
<para>
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
The default encryption algorithm can be defined for the system with
|
||||
the <option>ENCRYPT_METHOD</option> or
|
||||
<option>MD5_CRYPT_ENAB</option> variables of
|
||||
<filename>/etc/login.defs</filename>, and can be overwitten with the
|
||||
<filename>/etc/login.defs</filename>, and can be overwritten with the
|
||||
<option>-e</option>, <option>-m</option>, or <option>-c</option>
|
||||
options.
|
||||
</para>
|
||||
@@ -112,7 +112,7 @@
|
||||
<phrase condition="pam">Except when PAM is used to encrypt the
|
||||
passwords,</phrase> <command>chpasswd</command> first updates all the
|
||||
passwords in memory, and then commits all the changes to disk if no
|
||||
errors occured for any user.
|
||||
errors occurred for any user.
|
||||
</para>
|
||||
<para condition="pam">
|
||||
When PAM is used to encrypt the passwords (and update the passwords in
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
<varlistentry>
|
||||
<term><option>-a</option>, <option>--add</option> <replaceable>user_name</replaceable></term>
|
||||
<listitem>
|
||||
<para>Add an user to the group membership list.</para>
|
||||
<para>Add a user to the group membership list.</para>
|
||||
<para condition="gshadow">
|
||||
If the <filename>/etc/gshadow</filename> file exist, and the
|
||||
group has no entry in the <filename>/etc/gshadow</filename>
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
group (but group members do not need the password).
|
||||
</para>
|
||||
<para>
|
||||
The password is used when an user who is not a member of the
|
||||
The password is used when a user who is not a member of the
|
||||
group wants to gain the permissions of this group (see
|
||||
<citerefentry><refentrytitle>newgrp</refentrytitle>
|
||||
<manvolnum>1</manvolnum></citerefentry>).
|
||||
@@ -105,7 +105,7 @@
|
||||
can gain the group permissions.
|
||||
</para>
|
||||
<para>
|
||||
A password field which starts with a exclamation mark means
|
||||
A password field which starts with an exclamation mark means
|
||||
that the password is locked. The remaining characters on the
|
||||
line represent the password field before the password was
|
||||
locked.
|
||||
|
||||
@@ -103,6 +103,17 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-C</option>, <option>--clear</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Clear lastlog record of a user. This option can be used only together
|
||||
with <option>-u</option> (<option>--user</option>)).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-h</option>, <option>--help</option>
|
||||
@@ -123,6 +134,17 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-S</option>, <option>--set</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set lastlog record of a user to the current time. This option can be
|
||||
used only together with <option>-u</option> (<option>--user</option>)).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-t</option>, <option>--time</option> <replaceable>DAYS</replaceable>
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
<listitem><para>A: max address space (KB)</para></listitem>
|
||||
<listitem><para>C: max core file size (KB)</para></listitem>
|
||||
<listitem><para>D: max data size (KB)</para></listitem>
|
||||
<listitem><para>F: maximum filesize (KB)</para></listitem>
|
||||
<listitem><para>F: maximum file size (KB)</para></listitem>
|
||||
<listitem><para>K: file creation mask, set by
|
||||
<citerefentry>
|
||||
<refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum>
|
||||
@@ -145,7 +145,7 @@
|
||||
<para>
|
||||
Be aware that after <emphasis remap='I'>username</emphasis> the rest
|
||||
of the line is considered a limit string, thus comments are not
|
||||
allowed. A invalid limits string will be rejected (not considered) by
|
||||
allowed. An invalid limits string will be rejected (not considered) by
|
||||
the <command>login</command> program.
|
||||
</para>
|
||||
|
||||
@@ -163,12 +163,12 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If more than one line with limits for an user exist, only the first line for
|
||||
If more than one line with limits for a user exist, only the first line for
|
||||
this user will be considered.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If no lines are specified for an user, the last
|
||||
If no lines are specified for a user, the last
|
||||
<replaceable>@group</replaceable> line matching a group whose the
|
||||
user is a member of will be considered, or the last line with
|
||||
default limits if no groups contain the user.
|
||||
|
||||
@@ -61,9 +61,6 @@
|
||||
<replaceable>count</replaceable>
|
||||
</arg>
|
||||
<arg choice='opt'>
|
||||
<arg choice='plain'>
|
||||
<replaceable>pid</replaceable>
|
||||
</arg>
|
||||
<arg choice='plain'>
|
||||
<replaceable>gid</replaceable>
|
||||
</arg>
|
||||
@@ -83,8 +80,10 @@
|
||||
<refsect1 id='description'>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename> based on it's
|
||||
The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename> based on its
|
||||
command line arguments and the gids allowed in <filename>/etc/subgid</filename>.
|
||||
Note that the root user is not exempted from the requirement for a valid
|
||||
<filename>/etc/subgid</filename> entry.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -94,7 +93,7 @@
|
||||
<term>gid</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Begining of the range of GIDs inside the user namespace.
|
||||
Beginning of the range of GIDs inside the user namespace.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -102,7 +101,7 @@
|
||||
<term>lowergid</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Begining of the range of GIDs outside the user namespace.
|
||||
Beginning of the range of GIDs outside the user namespace.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -146,7 +145,7 @@
|
||||
<varlistentry>
|
||||
<term><filename>/etc/subgid</filename></term>
|
||||
<listitem>
|
||||
<para>List of users subordinate group IDs.</para>
|
||||
<para>List of user's subordinate group IDs.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
||||
@@ -80,8 +80,10 @@
|
||||
<refsect1 id='description'>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename> based on it's
|
||||
The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename> based on its
|
||||
command line arguments and the uids allowed in <filename>/etc/subuid</filename>.
|
||||
Note that the root user is not exempted from the requirement for a valid
|
||||
<filename>/etc/subuid</filename> entry.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -91,7 +93,7 @@
|
||||
<term>uid</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Begining of the range of UIDs inside the user namespace.
|
||||
Beginning of the range of UIDs inside the user namespace.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -99,7 +101,7 @@
|
||||
<term>loweruid</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Begining of the range of UIDs outside the user namespace.
|
||||
Beginning of the range of UIDs outside the user namespace.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@@ -142,7 +144,7 @@
|
||||
<varlistentry>
|
||||
<term><filename>/etc/subuid</filename></term>
|
||||
<listitem>
|
||||
<para>List of users subordinate user IDs.</para>
|
||||
<para>List of user's subordinate user IDs.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
</para>
|
||||
<para>
|
||||
It can be the name of a new user or the name of an existing
|
||||
user (or an user created before by
|
||||
user (or a user created before by
|
||||
<command>newusers</command>). In case of an existing user,
|
||||
the user's information will be changed, otherwise a new user
|
||||
will be created.
|
||||
@@ -142,7 +142,7 @@
|
||||
This field is used to define the UID of the user.
|
||||
</para>
|
||||
<para>
|
||||
If the field is empty, an new (unused) UID will be defined
|
||||
If the field is empty, a new (unused) UID will be defined
|
||||
automatically by <command>newusers</command>.
|
||||
</para>
|
||||
<para>
|
||||
@@ -151,7 +151,7 @@
|
||||
</para>
|
||||
<para>
|
||||
If this field contains the name of an existing user (or the
|
||||
name of an user created before by
|
||||
name of a user created before by
|
||||
<command>newusers</command>), the UID of the specified user
|
||||
will be used.
|
||||
</para>
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<refsect1 id='history'>
|
||||
<title>HISTORY</title>
|
||||
<para>
|
||||
The <command>nologin</command> command appearred in BSD 4.4.
|
||||
The <command>nologin</command> command appeared in BSD 4.4.
|
||||
</para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can find advices on how to choose a strong password on
|
||||
You can find advice on how to choose a strong password on
|
||||
http://en.wikipedia.org/wiki/Password_strength
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
@@ -2226,8 +2226,8 @@ msgid ""
|
||||
"default."
|
||||
msgstr ""
|
||||
"Falls nicht definiert, hängt das Verhalten von <command>useradd</command> "
|
||||
"von der Variable <option>USERGROUPS_ENAB</option> in <filename>/etc/default/"
|
||||
"useradd</filename> ab. Wenn diese Variable auf <replaceable>yes</"
|
||||
"von der Variable <option>USERGROUPS_ENAB</option> in <filename>/etc/login.def"
|
||||
"s</filename> ab. Wenn diese Variable auf <replaceable>yes</"
|
||||
"replaceable> gesetzt ist (oder auf der Befehlszeile <option>-U/--user-group</"
|
||||
"option> angegeben wurde), wird für den Benutzer eine Gruppe, die auf seinen "
|
||||
"Namen lautet, erstellt. Wenn die Variable auf <replaceable>no</replaceable> "
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
<para condition="tcb">
|
||||
Note that when <option>USE_TCB</option> is enabled, you cannot
|
||||
specify an alternative <replaceable>shadow</replaceable> file. In
|
||||
future releases, this paramater could be replaced by an alternate
|
||||
future releases, this parameter could be replaced by an alternate
|
||||
TCB directory.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
any access at all if the password field is empty.
|
||||
</para>
|
||||
<para>
|
||||
A password field which starts with a exclamation mark means
|
||||
A password field which starts with an exclamation mark means
|
||||
that the password is locked. The remaining characters on the
|
||||
line represent the password field before the password was
|
||||
locked.
|
||||
@@ -133,7 +133,7 @@
|
||||
</para>
|
||||
<para>
|
||||
The value 0 has a special meaning, which is that the user
|
||||
should change her pasword the next time she will log in the
|
||||
should change her password the next time she will log in the
|
||||
system.
|
||||
</para>
|
||||
<para>
|
||||
@@ -228,7 +228,7 @@
|
||||
</para>
|
||||
<para>
|
||||
Note that an account expiration differs from a password
|
||||
expiration. In case of an acount expiration, the user shall
|
||||
expiration. In case of an account expiration, the user shall
|
||||
not be allowed to login. In case of a password expiration,
|
||||
the user is not allowed to login using her password.
|
||||
</para>
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
</para>
|
||||
<para>
|
||||
The executed command will have no controlling terminal. This
|
||||
option cannot be used to execute interractive programs which
|
||||
option cannot be used to execute interactive programs which
|
||||
need a controlling TTY.
|
||||
<!-- This avoids TTY hijacking when su is used to lower
|
||||
privileges -->
|
||||
@@ -191,7 +191,7 @@
|
||||
<para>The shell that will be invoked.</para>
|
||||
<para>
|
||||
The invoked shell is chosen from (highest priority first):
|
||||
<!--This should be an orderedlist, but lists inside another
|
||||
<!--This should be an ordered list, but lists inside another
|
||||
list does not work well with current docbook.
|
||||
- nekral - 2009.06.03 -->
|
||||
<variablelist>
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
<!-- .RS -->
|
||||
<literallayout remap='.nf'>
|
||||
1) the user su is targetting
|
||||
1) the user su is targeting
|
||||
</literallayout>
|
||||
<!-- .fi -->
|
||||
<para>
|
||||
@@ -106,13 +106,13 @@
|
||||
|
||||
<para>
|
||||
from-id is formatted the same as to-id except the extra word
|
||||
<emphasis>GROUP</emphasis> is recognised. <emphasis>ALL EXCEPT
|
||||
<emphasis>GROUP</emphasis> is recognized. <emphasis>ALL EXCEPT
|
||||
GROUP</emphasis> is perfectly valid too. Following
|
||||
<emphasis>GROUP</emphasis> appears one or more group names, delimited
|
||||
by ",". It is not sufficient to have primary group id of the relevant
|
||||
group, an entry in
|
||||
<citerefentry><refentrytitle>/etc/group</refentrytitle>
|
||||
<manvolnum>5</manvolnum></citerefentry> is neccessary.
|
||||
<manvolnum>5</manvolnum></citerefentry> is necessary.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</para>
|
||||
<itemizedlist mark='bullet'>
|
||||
<listitem>
|
||||
<para>login name</para>
|
||||
<para>login name or UID</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>numerical subordinate group ID</para>
|
||||
@@ -77,6 +77,13 @@
|
||||
Multiple ranges may be specified per user.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When large number of entries (10000-100000 or more) are defined in
|
||||
<filename>/etc/subgid</filename>, parsing performance penalty will
|
||||
become noticeable. In this case it is recommended to use UIDs
|
||||
instead of login names. Benchmarks have shown speed-ups up to 20x.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id='files'>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</para>
|
||||
<itemizedlist mark='bullet'>
|
||||
<listitem>
|
||||
<para>login name</para>
|
||||
<para>login name or UID</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>numerical subordinate user ID</para>
|
||||
@@ -77,6 +77,13 @@
|
||||
Multiple ranges may be specified per user.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When large number of entries (10000-100000 or more) are defined in
|
||||
<filename>/etc/subuid</filename>, parsing performance penalty will
|
||||
become noticeable. In this case it is recommended to use UIDs
|
||||
instead of login names. Benchmarks have shown speed-ups up to 20x.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id='files'>
|
||||
|
||||
@@ -307,7 +307,7 @@
|
||||
</para>
|
||||
Example: <option>-K</option> <replaceable>PASS_MAX_DAYS</replaceable>=<replaceable>-1</replaceable>
|
||||
can be used when creating system account to turn off password
|
||||
ageing, even though system account has no password at all.
|
||||
aging, even though system account has no password at all.
|
||||
Multiple <option>-K</option> options can be specified, e.g.:
|
||||
<option>-K</option> <replaceable>UID_MIN</replaceable>=<replaceable>100</replaceable>
|
||||
<option>-K</option> <replaceable>UID_MAX</replaceable>=<replaceable>499</replaceable>
|
||||
@@ -326,7 +326,7 @@
|
||||
</para>
|
||||
<para>
|
||||
By default, the user's entries in the lastlog and faillog
|
||||
databases are resetted to avoid reusing the entry from a previously
|
||||
databases are reset to avoid reusing the entry from a previously
|
||||
deleted user.
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -351,7 +351,7 @@
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-M</option>
|
||||
<option>-M</option>, <option>--no-create-home</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
@@ -433,7 +433,7 @@
|
||||
</para>
|
||||
<para>
|
||||
Note that <command>useradd</command> will not create a home
|
||||
directory for such an user, regardless of the default setting
|
||||
directory for such a user, regardless of the default setting
|
||||
in <filename>/etc/login.defs</filename>
|
||||
(<option>CREATE_HOME</option>). You have to specify the
|
||||
<option>-m</option> options if you want a home directory for a
|
||||
|
||||
@@ -481,8 +481,7 @@
|
||||
not executing any processes when this command is being executed if the
|
||||
user's numerical user ID, the user's name, or the user's home
|
||||
directory is being changed. <command>usermod</command> checks this
|
||||
on Linux, but only check if the user is logged in according to utmp
|
||||
on other architectures.
|
||||
on Linux. On other platforms it only uses utmp to check if the user is logged in.
|
||||
</para>
|
||||
<para>
|
||||
You must change the owner of any <command>crontab</command> files or
|
||||
|
||||
2
po/ja.po
2
po/ja.po
@@ -2017,7 +2017,7 @@ msgid " -s, --shell SHELL login shell of the new account\n"
|
||||
msgstr " -s, --shell SHELL 新アカウントのログインシェル\n"
|
||||
|
||||
msgid " -u, --uid UID user ID of the new account\n"
|
||||
msgstr " -u, --iud UID 新アカウントのユーザ ID\n"
|
||||
msgstr " -u, --uid UID 新アカウントのユーザ ID\n"
|
||||
|
||||
msgid ""
|
||||
" -U, --user-group create a group with the same name as the "
|
||||
|
||||
@@ -52,10 +52,13 @@ usbin_PROGRAMS = \
|
||||
noinst_PROGRAMS = id sulogin
|
||||
|
||||
suidbins = su
|
||||
suidubins = chage chfn chsh expiry gpasswd newgrp passwd newuidmap newgidmap
|
||||
suidubins = chage chfn chsh expiry gpasswd newgrp passwd
|
||||
if ACCT_TOOLS_SETUID
|
||||
suidubins += chage chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
|
||||
endif
|
||||
if ENABLE_SUBIDS
|
||||
suidubins += newgidmap newuidmap
|
||||
endif
|
||||
|
||||
if WITH_TCB
|
||||
suidubins -= passwd
|
||||
@@ -95,6 +98,7 @@ groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
||||
grpck_LDADD = $(LDADD) $(LIBSELINUX)
|
||||
grpconv_LDADD = $(LDADD) $(LIBSELINUX)
|
||||
grpunconv_LDADD = $(LDADD) $(LIBSELINUX)
|
||||
lastlog_LDADD = $(LDADD) $(LIBAUDIT)
|
||||
login_SOURCES = \
|
||||
login.c \
|
||||
login_nopam.c
|
||||
|
||||
@@ -592,7 +592,7 @@ static void open_files (bool readonly)
|
||||
}
|
||||
pw_locked = true;
|
||||
}
|
||||
if (pw_open (readonly ? O_RDONLY: O_RDWR) == 0) {
|
||||
if (pw_open (readonly ? O_RDONLY: O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ()));
|
||||
fail_exit (E_NOPERM);
|
||||
@@ -613,7 +613,7 @@ static void open_files (bool readonly)
|
||||
}
|
||||
spw_locked = true;
|
||||
}
|
||||
if (spw_open (readonly ? O_RDONLY: O_RDWR) == 0) {
|
||||
if (spw_open (readonly ? O_RDONLY: O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, spw_dbname ());
|
||||
SYSLOG ((LOG_WARN, "cannot open %s", spw_dbname ()));
|
||||
|
||||
@@ -463,7 +463,7 @@ static void update_gecos (const char *user, char *gecos)
|
||||
fail_exit (E_NOPERM);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
fail_exit (E_NOPERM);
|
||||
|
||||
@@ -316,7 +316,7 @@ static void open_files (void)
|
||||
fail_exit (1);
|
||||
}
|
||||
gr_locked = true;
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
fail_exit (1);
|
||||
@@ -332,7 +332,7 @@ static void open_files (void)
|
||||
fail_exit (1);
|
||||
}
|
||||
sgr_locked = true;
|
||||
if (sgr_open (O_RDWR) == 0) {
|
||||
if (sgr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
fail_exit (1);
|
||||
|
||||
@@ -313,7 +313,7 @@ static void open_files (void)
|
||||
fail_exit (1);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
fail_exit (1);
|
||||
@@ -328,7 +328,7 @@ static void open_files (void)
|
||||
fail_exit (1);
|
||||
}
|
||||
spw_locked = true;
|
||||
if (spw_open (O_RDWR) == 0) {
|
||||
if (spw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, spw_dbname ());
|
||||
|
||||
@@ -373,7 +373,7 @@ static void update_shell (const char *user, char *newshell)
|
||||
fail_exit (1);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ()));
|
||||
fail_exit (1);
|
||||
|
||||
@@ -58,7 +58,7 @@ static void process_flags (int argc, char **argv);
|
||||
*/
|
||||
static RETSIGTYPE catch_signals (unused int sig)
|
||||
{
|
||||
exit (10);
|
||||
_exit (10);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -169,9 +169,8 @@ static RETSIGTYPE catch_signals (int killed)
|
||||
}
|
||||
|
||||
if (0 != killed) {
|
||||
(void) putchar ('\n');
|
||||
(void) fflush (stdout);
|
||||
exit (killed);
|
||||
(void) write (STDOUT_FILENO, "\n", 1);
|
||||
_exit (killed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,7 +369,7 @@ static void open_files (void)
|
||||
|
||||
add_cleanup (log_gpasswd_failure_system, NULL);
|
||||
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, gr_dbname ());
|
||||
@@ -380,7 +379,7 @@ static void open_files (void)
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadowgrp) {
|
||||
if (sgr_open (O_RDWR) == 0) {
|
||||
if (sgr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
|
||||
@@ -346,7 +346,7 @@ static void open_files (void)
|
||||
add_cleanup (cleanup_report_add_group, group_name);
|
||||
|
||||
/* And now open the databases */
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ()));
|
||||
exit (E_GRP_UPDATE);
|
||||
@@ -354,7 +354,7 @@ static void open_files (void)
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow_grp) {
|
||||
if (sgr_open (O_RDWR) == 0) {
|
||||
if (sgr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
|
||||
@@ -60,6 +60,7 @@ const char *Prog;
|
||||
|
||||
static char *group_name;
|
||||
static gid_t group_id = -1;
|
||||
static bool check_group_busy = true;
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
static bool is_shadow_grp;
|
||||
@@ -96,6 +97,7 @@ static /*@noreturn@*/void usage (int status)
|
||||
Prog);
|
||||
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
||||
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
||||
(void) fputs (_(" -f, --force delete group even if it is the primary group of a user\n"), usageout);
|
||||
(void) fputs ("\n", usageout);
|
||||
exit (status);
|
||||
}
|
||||
@@ -246,7 +248,7 @@ static void open_files (void)
|
||||
add_cleanup (cleanup_report_del_group, group_name);
|
||||
|
||||
/* An now open the databases */
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, gr_dbname ());
|
||||
@@ -255,7 +257,7 @@ static void open_files (void)
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow_grp) {
|
||||
if (sgr_open (O_RDWR) == 0) {
|
||||
if (sgr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
@@ -321,7 +323,7 @@ static void process_flags (int argc, char **argv)
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
|
||||
while ((c = getopt_long (argc, argv, "hR:",
|
||||
while ((c = getopt_long (argc, argv, "hfR:",
|
||||
long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
@@ -329,6 +331,9 @@ static void process_flags (int argc, char **argv)
|
||||
/*@notreached@*/break;
|
||||
case 'R': /* no-op, handled in process_root_flag () */
|
||||
break;
|
||||
case 'f':
|
||||
check_group_busy = false;
|
||||
break;
|
||||
default:
|
||||
usage (E_USAGE);
|
||||
}
|
||||
@@ -465,7 +470,9 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make sure this isn't the primary group of anyone.
|
||||
*/
|
||||
group_busy (group_id);
|
||||
if (check_group_busy) {
|
||||
group_busy (group_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the hard stuff - open the files, delete the group entries,
|
||||
|
||||
@@ -536,14 +536,14 @@ static void open_files (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (gr_open (list ? O_RDONLY : O_RDWR) == 0) {
|
||||
if (gr_open (list ? O_RDONLY : O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
fail_exit (EXIT_GROUP_FILE);
|
||||
}
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadowgrp) {
|
||||
if (sgr_open (list ? O_RDONLY : O_RDWR) == 0) {
|
||||
if (sgr_open (list ? O_RDONLY : O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ());
|
||||
fail_exit (EXIT_GROUP_FILE);
|
||||
}
|
||||
|
||||
@@ -663,7 +663,7 @@ static void lock_files (void)
|
||||
*/
|
||||
static void open_files (void)
|
||||
{
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ()));
|
||||
exit (E_GRP_UPDATE);
|
||||
@@ -672,7 +672,7 @@ static void open_files (void)
|
||||
#ifdef SHADOWGRP
|
||||
if ( is_shadow_grp
|
||||
&& (pflg || nflg)) {
|
||||
if (sgr_open (O_RDWR) == 0) {
|
||||
if (sgr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
@@ -683,7 +683,7 @@ static void open_files (void)
|
||||
#endif /* SHADOWGRP */
|
||||
|
||||
if (gflg) {
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, pw_dbname ());
|
||||
|
||||
@@ -299,7 +299,7 @@ static void open_files (void)
|
||||
* Open the files. Use O_RDONLY if we are in read_only mode,
|
||||
* O_RDWR otherwise.
|
||||
*/
|
||||
if (gr_open (read_only ? O_RDONLY : O_RDWR) == 0) {
|
||||
if (gr_open (read_only ? O_RDONLY : O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog,
|
||||
grp_file);
|
||||
if (use_system_grp_file) {
|
||||
@@ -308,7 +308,7 @@ static void open_files (void)
|
||||
fail_exit (E_CANT_OPEN);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow && (sgr_open (read_only ? O_RDONLY : O_RDWR) == 0)) {
|
||||
if (is_shadow && (sgr_open (read_only ? O_RDONLY : O_CREAT | O_RDWR) == 0)) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog,
|
||||
sgr_file);
|
||||
if (use_system_sgr_file) {
|
||||
|
||||
@@ -163,7 +163,7 @@ int main (int argc, char **argv)
|
||||
fail_exit (5);
|
||||
}
|
||||
gr_locked = true;
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
fail_exit (1);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ int main (int argc, char **argv)
|
||||
fail_exit (5);
|
||||
}
|
||||
gr_locked = true;
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
fail_exit (1);
|
||||
|
||||
115
src/lastlog.c
115
src/lastlog.c
@@ -71,6 +71,8 @@ static struct stat statbuf; /* fstat buffer for file size */
|
||||
static bool uflg = false; /* print only an user of range of users */
|
||||
static bool tflg = false; /* print is restricted to most recent days */
|
||||
static bool bflg = false; /* print excludes most recent days */
|
||||
static bool Cflg = false; /* clear record for user */
|
||||
static bool Sflg = false; /* set record for user */
|
||||
|
||||
#define NOW (time ((time_t *) 0))
|
||||
|
||||
@@ -83,8 +85,10 @@ static /*@noreturn@*/void usage (int status)
|
||||
"Options:\n"),
|
||||
Prog);
|
||||
(void) fputs (_(" -b, --before DAYS print only lastlog records older than DAYS\n"), usageout);
|
||||
(void) fputs (_(" -C, --clear clear lastlog record of an user (usable only with -u)\n"), usageout);
|
||||
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
||||
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
||||
(void) fputs (_(" -S, --set set lastlog record to current time (usable only with -u)\n"), usageout);
|
||||
(void) fputs (_(" -t, --time DAYS print only lastlog records more recent than DAYS\n"), usageout);
|
||||
(void) fputs (_(" -u, --user LOGIN print lastlog record of the specified LOGIN\n"), usageout);
|
||||
(void) fputs ("\n", usageout);
|
||||
@@ -194,6 +198,80 @@ static void print (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void update_one (/*@null@*/const struct passwd *pw)
|
||||
{
|
||||
off_t offset;
|
||||
struct lastlog ll;
|
||||
int err;
|
||||
|
||||
if (NULL == pw) {
|
||||
return;
|
||||
}
|
||||
|
||||
offset = (off_t) pw->pw_uid * sizeof (ll);
|
||||
/* fseeko errors are not really relevant for us. */
|
||||
err = fseeko (lastlogfile, offset, SEEK_SET);
|
||||
assert (0 == err);
|
||||
|
||||
memzero (&ll, sizeof (ll));
|
||||
|
||||
if (Sflg) {
|
||||
ll.ll_time = NOW;
|
||||
#ifdef HAVE_LL_HOST
|
||||
strcpy (ll.ll_host, "localhost");
|
||||
#endif
|
||||
strcpy (ll.ll_line, "lastlog");
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ACCT_UNLOCK, Prog,
|
||||
"clearing-lastlog",
|
||||
pw->pw_name, (unsigned int) pw->pw_uid, SHADOW_AUDIT_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
else {
|
||||
audit_logger (AUDIT_ACCT_UNLOCK, Prog,
|
||||
"refreshing-lastlog",
|
||||
pw->pw_name, (unsigned int) pw->pw_uid, SHADOW_AUDIT_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fwrite (&ll, sizeof(ll), 1, lastlogfile) != 1) {
|
||||
fprintf (stderr,
|
||||
_("%s: Failed to update the entry for UID %lu\n"),
|
||||
Prog, (unsigned long int)pw->pw_uid);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static void update (void)
|
||||
{
|
||||
const struct passwd *pwent;
|
||||
|
||||
if (!uflg) /* safety measure */
|
||||
return;
|
||||
|
||||
if (has_umin && has_umax && (umin == umax)) {
|
||||
update_one (getpwuid ((uid_t)umin));
|
||||
} else {
|
||||
setpwent ();
|
||||
while ( (pwent = getpwent ()) != NULL ) {
|
||||
if ((has_umin && (pwent->pw_uid < (uid_t)umin))
|
||||
|| (has_umax && (pwent->pw_uid > (uid_t)umax))) {
|
||||
continue;
|
||||
}
|
||||
update_one (pwent);
|
||||
}
|
||||
endpwent ();
|
||||
}
|
||||
|
||||
if (fflush (lastlogfile) != 0 || fsync (fileno (lastlogfile)) != 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: Failed to update the lastlog file\n"),
|
||||
Prog);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
@@ -208,18 +286,24 @@ int main (int argc, char **argv)
|
||||
|
||||
process_root_flag ("-R", argc, argv);
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
|
||||
{
|
||||
int c;
|
||||
static struct option const longopts[] = {
|
||||
{"before", required_argument, NULL, 'b'},
|
||||
{"clear", no_argument, NULL, 'C'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"root", required_argument, NULL, 'R'},
|
||||
{"set", no_argument, NULL, 'S'},
|
||||
{"time", required_argument, NULL, 't'},
|
||||
{"user", required_argument, NULL, 'u'},
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
|
||||
while ((c = getopt_long (argc, argv, "b:hR:t:u:", longopts,
|
||||
while ((c = getopt_long (argc, argv, "b:ChR:St:u:", longopts,
|
||||
NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
@@ -235,11 +319,21 @@ int main (int argc, char **argv)
|
||||
bflg = true;
|
||||
break;
|
||||
}
|
||||
case 'C':
|
||||
{
|
||||
Cflg = true;
|
||||
break;
|
||||
}
|
||||
case 'h':
|
||||
usage (EXIT_SUCCESS);
|
||||
/*@notreached@*/break;
|
||||
case 'R': /* no-op, handled in process_root_flag () */
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
Sflg = true;
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
{
|
||||
unsigned long days;
|
||||
@@ -294,9 +388,21 @@ int main (int argc, char **argv)
|
||||
Prog, argv[optind]);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
if (Cflg && Sflg) {
|
||||
fprintf (stderr,
|
||||
_("%s: Option -C cannot be used together with option -S\n"),
|
||||
Prog);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
if ((Cflg || Sflg) && !uflg) {
|
||||
fprintf (stderr,
|
||||
_("%s: Options -C and -S require option -u to specify the user\n"),
|
||||
Prog);
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
lastlogfile = fopen (LASTLOG_FILE, "r");
|
||||
lastlogfile = fopen (LASTLOG_FILE, (Cflg || Sflg)?"r+":"r");
|
||||
if (NULL == lastlogfile) {
|
||||
perror (LASTLOG_FILE);
|
||||
exit (EXIT_FAILURE);
|
||||
@@ -310,7 +416,10 @@ int main (int argc, char **argv)
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
print ();
|
||||
if (Cflg || Sflg)
|
||||
update ();
|
||||
else
|
||||
print ();
|
||||
|
||||
(void) fclose (lastlogfile);
|
||||
|
||||
|
||||
11
src/login.c
11
src/login.c
@@ -103,7 +103,7 @@ static bool hflg = false;
|
||||
static bool preauth_flag = false;
|
||||
|
||||
static bool amroot;
|
||||
static unsigned int timeout;
|
||||
static char tmsg[256];
|
||||
|
||||
/*
|
||||
* External identifiers.
|
||||
@@ -416,8 +416,8 @@ static void init_env (void)
|
||||
|
||||
static RETSIGTYPE alarm_handler (unused int sig)
|
||||
{
|
||||
fprintf (stderr, _("\nLogin timed out after %u seconds.\n"), timeout);
|
||||
exit (0);
|
||||
write (STDERR_FILENO, tmsg, strlen (tmsg));
|
||||
_exit (0);
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
@@ -532,6 +532,7 @@ int main (int argc, char **argv)
|
||||
bool is_console;
|
||||
#endif
|
||||
int err;
|
||||
unsigned int timeout;
|
||||
const char *cp;
|
||||
const char *tmp;
|
||||
char fromhost[512];
|
||||
@@ -698,8 +699,10 @@ int main (int argc, char **argv)
|
||||
|
||||
top:
|
||||
/* only allow ALARM sec. for login */
|
||||
(void) signal (SIGALRM, alarm_handler);
|
||||
timeout = getdef_unum ("LOGIN_TIMEOUT", ALARM);
|
||||
snprintf (tmsg, sizeof tmsg,
|
||||
_("\nLogin timed out after %u seconds.\n"), timeout);
|
||||
(void) signal (SIGALRM, alarm_handler);
|
||||
if (timeout > 0) {
|
||||
(void) alarm (timeout);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ static bool verify_range(struct passwd *pw, struct map_range *range)
|
||||
if (have_sub_gids(pw->pw_name, range->lower, range->count))
|
||||
return true;
|
||||
|
||||
/* Allow a process to map it's own gid */
|
||||
/* Allow a process to map its own gid */
|
||||
if ((range->count == 1) && (pw->pw_gid == range->lower))
|
||||
return true;
|
||||
|
||||
@@ -94,7 +94,7 @@ static void usage(void)
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char proc_dir_name[PATH_MAX];
|
||||
char proc_dir_name[32];
|
||||
char *target_str;
|
||||
pid_t target, parent;
|
||||
int proc_dir_fd;
|
||||
@@ -113,13 +113,14 @@ int main(int argc, char **argv)
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
/* Find the process that needs it's user namespace
|
||||
/* Find the process that needs its user namespace
|
||||
* gid mapping set.
|
||||
*/
|
||||
target_str = argv[1];
|
||||
if (!get_pid(target_str, &target))
|
||||
usage();
|
||||
|
||||
/* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
|
||||
written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
|
||||
target);
|
||||
if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
|
||||
@@ -160,8 +161,10 @@ int main(int argc, char **argv)
|
||||
(getgid() != pw->pw_gid) ||
|
||||
(pw->pw_uid != st.st_uid) ||
|
||||
(pw->pw_gid != st.st_gid)) {
|
||||
fprintf(stderr, _( "%s: Target %u is owned by a different user\n" ),
|
||||
Prog, target);
|
||||
fprintf(stderr, _( "%s: Target %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
|
||||
Prog, target,
|
||||
(unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid,
|
||||
(unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -255,12 +255,15 @@ static void syslog_sg (const char *name, const char *group)
|
||||
{
|
||||
const char *loginname = getlogin ();
|
||||
const char *tty = ttyname (0);
|
||||
char *free_login = NULL, *free_tty = NULL;
|
||||
|
||||
if (loginname != NULL) {
|
||||
loginname = xstrdup (loginname);
|
||||
free_login = xstrdup (loginname);
|
||||
loginname = free_login;
|
||||
}
|
||||
if (tty != NULL) {
|
||||
tty = xstrdup (tty);
|
||||
free_tty = xstrdup (tty);
|
||||
tty = free_tty;
|
||||
}
|
||||
|
||||
if (loginname == NULL) {
|
||||
@@ -372,6 +375,8 @@ static void syslog_sg (const char *name, const char *group)
|
||||
(void) signal (SIGTTOU, SIG_DFL);
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
free(free_login);
|
||||
free(free_tty);
|
||||
}
|
||||
#endif /* USE_SYSLOG */
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ static bool verify_range(struct passwd *pw, struct map_range *range)
|
||||
if (have_sub_uids(pw->pw_name, range->lower, range->count))
|
||||
return true;
|
||||
|
||||
/* Allow a process to map it's own uid */
|
||||
/* Allow a process to map its own uid */
|
||||
if ((range->count == 1) && (pw->pw_uid == range->lower))
|
||||
return true;
|
||||
|
||||
@@ -94,7 +94,7 @@ void usage(void)
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char proc_dir_name[PATH_MAX];
|
||||
char proc_dir_name[32];
|
||||
char *target_str;
|
||||
pid_t target, parent;
|
||||
int proc_dir_fd;
|
||||
@@ -113,13 +113,14 @@ int main(int argc, char **argv)
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
/* Find the process that needs it's user namespace
|
||||
/* Find the process that needs its user namespace
|
||||
* uid mapping set.
|
||||
*/
|
||||
target_str = argv[1];
|
||||
if (!get_pid(target_str, &target))
|
||||
usage();
|
||||
|
||||
/* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
|
||||
written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
|
||||
target);
|
||||
if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
|
||||
@@ -160,8 +161,10 @@ int main(int argc, char **argv)
|
||||
(getgid() != pw->pw_gid) ||
|
||||
(pw->pw_uid != st.st_uid) ||
|
||||
(pw->pw_gid != st.st_gid)) {
|
||||
fprintf(stderr, _( "%s: Target %u is owned by a different user\n" ),
|
||||
Prog, target);
|
||||
fprintf(stderr, _( "%s: Target process %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
|
||||
Prog, target,
|
||||
(unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid,
|
||||
(unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -805,27 +805,27 @@ static void open_files (void)
|
||||
}
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
fail_exit (EXIT_FAILURE);
|
||||
}
|
||||
if (is_shadow && (spw_open (O_RDWR) == 0)) {
|
||||
if (is_shadow && (spw_open (O_CREAT | O_RDWR) == 0)) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ());
|
||||
fail_exit (EXIT_FAILURE);
|
||||
}
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
fail_exit (EXIT_FAILURE);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow_grp && (sgr_open (O_RDWR) == 0)) {
|
||||
if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ());
|
||||
fail_exit (EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_SUBIDS
|
||||
if (is_sub_uid) {
|
||||
if (sub_uid_open (O_RDWR) == 0) {
|
||||
if (sub_uid_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sub_uid_dbname ());
|
||||
@@ -833,7 +833,7 @@ static void open_files (void)
|
||||
}
|
||||
}
|
||||
if (is_sub_gid) {
|
||||
if (sub_gid_open (O_RDWR) == 0) {
|
||||
if (sub_gid_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sub_gid_dbname ());
|
||||
|
||||
@@ -573,7 +573,7 @@ static void update_noshadow (void)
|
||||
exit (E_PWDBUSY);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
(void) fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, pw_dbname ());
|
||||
@@ -627,7 +627,7 @@ static void update_shadow (void)
|
||||
exit (E_PWDBUSY);
|
||||
}
|
||||
spw_locked = true;
|
||||
if (spw_open (O_RDWR) == 0) {
|
||||
if (spw_open (O_CREAT | O_RDWR) == 0) {
|
||||
(void) fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, spw_dbname ());
|
||||
|
||||
@@ -281,7 +281,7 @@ static void open_files (void)
|
||||
* Open the files. Use O_RDONLY if we are in read_only mode, O_RDWR
|
||||
* otherwise.
|
||||
*/
|
||||
if (pw_open (read_only ? O_RDONLY : O_RDWR) == 0) {
|
||||
if (pw_open (read_only ? O_RDONLY : O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"),
|
||||
Prog, pw_dbname ());
|
||||
if (use_system_pw_file) {
|
||||
@@ -290,7 +290,7 @@ static void open_files (void)
|
||||
fail_exit (E_CANTOPEN);
|
||||
}
|
||||
if (is_shadow && !use_tcb) {
|
||||
if (spw_open (read_only ? O_RDONLY : O_RDWR) == 0) {
|
||||
if (spw_open (read_only ? O_RDONLY : O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"),
|
||||
Prog, spw_dbname ());
|
||||
if (use_system_spw_file) {
|
||||
@@ -566,7 +566,7 @@ static void check_pw_file (int *errors, bool *changed)
|
||||
continue;
|
||||
}
|
||||
spw_locked = true;
|
||||
if (spw_open (read_only ? O_RDONLY : O_RDWR) == 0) {
|
||||
if (spw_open (read_only ? O_RDONLY : O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, spw_dbname ());
|
||||
|
||||
@@ -200,7 +200,7 @@ int main (int argc, char **argv)
|
||||
fail_exit (E_PWDBUSY);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
fail_exit (E_MISSING);
|
||||
@@ -305,7 +305,8 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
/* /etc/passwd- (backup file) */
|
||||
if (chmod (PASSWD_FILE "-", 0600) != 0) {
|
||||
errno = 0;
|
||||
if ((chmod (PASSWD_FILE "-", 0600) != 0) && (errno != ENOENT)) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to change the mode of %s to 0600\n"),
|
||||
Prog, PASSWD_FILE "-");
|
||||
|
||||
@@ -166,7 +166,7 @@ int main (int argc, char **argv)
|
||||
fail_exit (5);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, pw_dbname ());
|
||||
|
||||
21
src/su.c
21
src/su.c
@@ -105,6 +105,8 @@ static char caller_name[BUFSIZ];
|
||||
static bool change_environment = true;
|
||||
|
||||
#ifdef USE_PAM
|
||||
static char kill_msg[256];
|
||||
static char wait_msg[256];
|
||||
static pam_handle_t *pamh = NULL;
|
||||
static int caught = 0;
|
||||
/* PID of the child, in case it needs to be killed */
|
||||
@@ -161,8 +163,7 @@ static RETSIGTYPE die (int killed)
|
||||
}
|
||||
|
||||
if (killed != 0) {
|
||||
closelog ();
|
||||
exit (128+killed);
|
||||
_exit (128+killed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,12 +183,11 @@ static RETSIGTYPE kill_child (int unused(s))
|
||||
{
|
||||
if (0 != pid_child) {
|
||||
(void) kill (-pid_child, SIGKILL);
|
||||
(void) fputs (_(" ...killed.\n"), stderr);
|
||||
(void) write (STDERR_FILENO, kill_msg, strlen (kill_msg));
|
||||
} else {
|
||||
(void) fputs (_(" ...waiting for child to terminate.\n"),
|
||||
stderr);
|
||||
(void) write (STDERR_FILENO, wait_msg, strlen (wait_msg));
|
||||
}
|
||||
exit (255);
|
||||
_exit (255);
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
@@ -373,6 +373,9 @@ static void prepare_pam_close_session (void)
|
||||
stderr);
|
||||
(void) kill (-pid_child, caught);
|
||||
|
||||
snprintf (kill_msg, _(" ...killed.\n"));
|
||||
snprintf (wait_msg, _(" ...waiting for child to terminate.\n"));
|
||||
|
||||
(void) signal (SIGALRM, kill_child);
|
||||
(void) alarm (2);
|
||||
|
||||
@@ -422,7 +425,7 @@ static void check_perms_pam (const struct passwd *pw)
|
||||
int ret;
|
||||
ret = pam_authenticate (pamh, 0);
|
||||
if (PAM_SUCCESS != ret) {
|
||||
SYSLOG ((LOG_ERR, "pam_authenticate: %s",
|
||||
SYSLOG (((pw->pw_uid != 0)? LOG_NOTICE : LOG_WARN, "pam_authenticate: %s",
|
||||
pam_strerror (pamh, ret)));
|
||||
fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
|
||||
(void) pam_end (pamh, ret);
|
||||
@@ -585,7 +588,7 @@ static /*@only@*/struct passwd * check_perms (void)
|
||||
if (NULL == pw) {
|
||||
(void) fprintf (stderr,
|
||||
_("No passwd entry for user '%s'\n"), name);
|
||||
SYSLOG ((LOG_ERR, "No passwd entry for user '%s'", name));
|
||||
SYSLOG ((LOG_NOTICE, "No passwd entry for user '%s'", name));
|
||||
su_failure (caller_tty, true);
|
||||
}
|
||||
|
||||
@@ -615,7 +618,7 @@ static /*@only@*/struct passwd * check_perms (void)
|
||||
(void) fprintf (stderr,
|
||||
_("No passwd entry for user '%s'\n"),
|
||||
name);
|
||||
SYSLOG ((LOG_ERR,
|
||||
SYSLOG ((LOG_NOTICE,
|
||||
"No passwd entry for user '%s'", name));
|
||||
su_failure (caller_tty, true);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ static RETSIGTYPE catch_signals (int);
|
||||
|
||||
static RETSIGTYPE catch_signals (unused int sig)
|
||||
{
|
||||
exit (1);
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1537,7 +1537,7 @@ static void open_files (void)
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
@@ -1554,7 +1554,7 @@ static void open_files (void)
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
gr_locked = true;
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
@@ -1567,7 +1567,7 @@ static void open_files (void)
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
sgr_locked = true;
|
||||
if (sgr_open (O_RDWR) == 0) {
|
||||
if (sgr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
@@ -1584,7 +1584,7 @@ static void open_files (void)
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
}
|
||||
sub_uid_locked = true;
|
||||
if (sub_uid_open (O_RDWR) == 0) {
|
||||
if (sub_uid_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sub_uid_dbname ());
|
||||
@@ -1599,7 +1599,7 @@ static void open_files (void)
|
||||
fail_exit (E_SUB_GID_UPDATE);
|
||||
}
|
||||
sub_gid_locked = true;
|
||||
if (sub_gid_open (O_RDWR) == 0) {
|
||||
if (sub_gid_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sub_gid_dbname ());
|
||||
@@ -1621,7 +1621,7 @@ static void open_shadow (void)
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
spw_locked = true;
|
||||
if (spw_open (O_RDWR) == 0) {
|
||||
if (spw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, spw_dbname ());
|
||||
@@ -1993,6 +1993,11 @@ int main (int argc, char **argv)
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
uid_t uid_min = (uid_t) getdef_ulong ("UID_MIN", 1000UL);
|
||||
uid_t uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
@@ -2021,15 +2026,18 @@ int main (int argc, char **argv)
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
|
||||
process_flags (argc, argv);
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
is_sub_uid = sub_uid_file_present ();
|
||||
is_sub_gid = sub_gid_file_present ();
|
||||
is_sub_uid = sub_uid_file_present () && !rflg &&
|
||||
(!user_id || (user_id <= uid_max && user_id >= uid_min));
|
||||
is_sub_gid = sub_gid_file_present () && !rflg &&
|
||||
(!user_id || (user_id <= uid_max && user_id >= uid_min));
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
|
||||
get_defaults ();
|
||||
|
||||
process_flags (argc, argv);
|
||||
|
||||
#ifdef ACCT_TOOLS_SETUID
|
||||
#ifdef USE_PAM
|
||||
{
|
||||
|
||||
@@ -565,7 +565,7 @@ static void open_files (void)
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
#ifdef WITH_AUDIT
|
||||
@@ -590,7 +590,7 @@ static void open_files (void)
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
spw_locked = true;
|
||||
if (spw_open (O_RDWR) == 0) {
|
||||
if (spw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, spw_dbname ());
|
||||
@@ -616,7 +616,7 @@ static void open_files (void)
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
gr_locked = true;
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_DEL_USER, Prog,
|
||||
@@ -641,7 +641,7 @@ static void open_files (void)
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
sgr_locked= true;
|
||||
if (sgr_open (O_RDWR) == 0) {
|
||||
if (sgr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
#ifdef WITH_AUDIT
|
||||
@@ -669,7 +669,7 @@ static void open_files (void)
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
}
|
||||
sub_uid_locked = true;
|
||||
if (sub_uid_open (O_RDWR) == 0) {
|
||||
if (sub_uid_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, sub_uid_dbname ());
|
||||
#ifdef WITH_AUDIT
|
||||
@@ -695,7 +695,7 @@ static void open_files (void)
|
||||
fail_exit (E_SUB_GID_UPDATE);
|
||||
}
|
||||
sub_gid_locked = true;
|
||||
if (sub_gid_open (O_RDWR) == 0) {
|
||||
if (sub_gid_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"), Prog, sub_gid_dbname ());
|
||||
#ifdef WITH_AUDIT
|
||||
|
||||
128
src/usermod.c
128
src/usermod.c
@@ -1361,6 +1361,7 @@ static void process_flags (int argc, char **argv)
|
||||
exit (E_UID_IN_USE);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
if ( (vflg || Vflg)
|
||||
&& !is_sub_uid) {
|
||||
fprintf (stderr,
|
||||
@@ -1376,6 +1377,7 @@ static void process_flags (int argc, char **argv)
|
||||
Prog, sub_gid_dbname (), "-w", "-W");
|
||||
exit (E_USAGE);
|
||||
}
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1530,7 +1532,7 @@ static void open_files (void)
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
pw_locked = true;
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
if (pw_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, pw_dbname ());
|
||||
@@ -1543,7 +1545,7 @@ static void open_files (void)
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
spw_locked = true;
|
||||
if (is_shadow_pwd && (spw_open (O_RDWR) == 0)) {
|
||||
if (is_shadow_pwd && (spw_open (O_CREAT | O_RDWR) == 0)) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, spw_dbname ());
|
||||
@@ -1562,7 +1564,7 @@ static void open_files (void)
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
gr_locked = true;
|
||||
if (gr_open (O_RDWR) == 0) {
|
||||
if (gr_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, gr_dbname ());
|
||||
@@ -1576,7 +1578,7 @@ static void open_files (void)
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
sgr_locked = true;
|
||||
if (is_shadow_grp && (sgr_open (O_RDWR) == 0)) {
|
||||
if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sgr_dbname ());
|
||||
@@ -1593,7 +1595,7 @@ static void open_files (void)
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
}
|
||||
sub_uid_locked = true;
|
||||
if (sub_uid_open (O_RDWR) == 0) {
|
||||
if (sub_uid_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sub_uid_dbname ());
|
||||
@@ -1608,7 +1610,7 @@ static void open_files (void)
|
||||
fail_exit (E_SUB_GID_UPDATE);
|
||||
}
|
||||
sub_gid_locked = true;
|
||||
if (sub_gid_open (O_RDWR) == 0) {
|
||||
if (sub_gid_open (O_CREAT | O_RDWR) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open %s\n"),
|
||||
Prog, sub_gid_dbname ());
|
||||
@@ -1717,60 +1719,6 @@ static void usr_update (void)
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
}
|
||||
#ifdef ENABLE_SUBIDS
|
||||
if (Vflg) {
|
||||
struct ulong_range_list_entry *ptr;
|
||||
for (ptr = del_sub_uids; ptr != NULL; ptr = ptr->next) {
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_uid_remove(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to remove uid range %lu-%lu from '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_uid_dbname ());
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vflg) {
|
||||
struct ulong_range_list_entry *ptr;
|
||||
for (ptr = add_sub_uids; ptr != NULL; ptr = ptr->next) {
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_uid_add(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to add uid range %lu-%lu from '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_uid_dbname ());
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Wflg) {
|
||||
struct ulong_range_list_entry *ptr;
|
||||
for (ptr = del_sub_gids; ptr != NULL; ptr = ptr->next) {
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_gid_remove(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to remove gid range %lu-%lu from '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_gid_dbname ());
|
||||
fail_exit (E_SUB_GID_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wflg) {
|
||||
struct ulong_range_list_entry *ptr;
|
||||
for (ptr = add_sub_gids; ptr != NULL; ptr = ptr->next) {
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_gid_add(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to add gid range %lu-%lu from '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_gid_dbname ());
|
||||
fail_exit (E_SUB_GID_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2174,16 +2122,66 @@ int main (int argc, char **argv)
|
||||
*/
|
||||
open_files ();
|
||||
if ( cflg || dflg || eflg || fflg || gflg || Lflg || lflg || pflg
|
||||
|| sflg || uflg || Uflg
|
||||
#ifdef ENABLE_SUBIDS
|
||||
|| vflg || Vflg || wflg || Wflg
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
) {
|
||||
|| sflg || uflg || Uflg) {
|
||||
usr_update ();
|
||||
}
|
||||
if (Gflg || lflg) {
|
||||
grp_update ();
|
||||
}
|
||||
#ifdef ENABLE_SUBIDS
|
||||
if (Vflg) {
|
||||
struct ulong_range_list_entry *ptr;
|
||||
for (ptr = del_sub_uids; ptr != NULL; ptr = ptr->next) {
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_uid_remove(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to remove uid range %lu-%lu from '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_uid_dbname ());
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vflg) {
|
||||
struct ulong_range_list_entry *ptr;
|
||||
for (ptr = add_sub_uids; ptr != NULL; ptr = ptr->next) {
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_uid_add(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to add uid range %lu-%lu from '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_uid_dbname ());
|
||||
fail_exit (E_SUB_UID_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Wflg) {
|
||||
struct ulong_range_list_entry *ptr;
|
||||
for (ptr = del_sub_gids; ptr != NULL; ptr = ptr->next) {
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_gid_remove(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to remove gid range %lu-%lu from '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_gid_dbname ());
|
||||
fail_exit (E_SUB_GID_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wflg) {
|
||||
struct ulong_range_list_entry *ptr;
|
||||
for (ptr = add_sub_gids; ptr != NULL; ptr = ptr->next) {
|
||||
unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
if (sub_gid_add(user_name, ptr->range.first, count) == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to add gid range %lu-%lu from '%s'\n"),
|
||||
Prog, ptr->range.first, ptr->range.last,
|
||||
sub_gid_dbname ());
|
||||
fail_exit (E_SUB_GID_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
close_files ();
|
||||
|
||||
#ifdef WITH_TCB
|
||||
|
||||
21
tests/README
Normal file
21
tests/README
Normal file
@@ -0,0 +1,21 @@
|
||||
This testsuite is NOT SECURE: it will temporarily change your passwords file
|
||||
with known passwords.
|
||||
You should run it on a chroot, or on a secured dedicated system.
|
||||
|
||||
|
||||
|
||||
To test a Debian system:
|
||||
$ mkdir sid-chroot
|
||||
$ sudo debootstrap sid sid-chroot/ http://ftp.fr.debian.org/debian/
|
||||
edit or copy a sources.list
|
||||
$ sudo cp /etc/apt/sources.list sid-chroot/etc/apt/
|
||||
edit or copy a resolv.conf
|
||||
$ sudo cp /etc/resolv.conf sid-chroot/etc/
|
||||
$ su - root -c "chroot sid-chroot/ /bin/bash"
|
||||
# mount -t proc proc /proc
|
||||
# mount -t devpts devpts /dev/pts
|
||||
# aptitude update
|
||||
# aptitude install expect
|
||||
# cd /dev ; mknod --mode=666 /dev/ptmx c 5 2
|
||||
|
||||
|
||||
61
tests/bug332198-test.exp
Executable file
61
tests/bug332198-test.exp
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
# This is a script for repeatedly logging into the localhost
|
||||
# using `rlogin` in order to apparently see a symptoms described
|
||||
# in bug #332198.
|
||||
# As described in the bug log, sometimes `rlogind` will fail to
|
||||
# establish a connection, because it starts "login" process and
|
||||
# the latter fails with "unable to determine TTY name, got /dev/pts/1"
|
||||
# message.
|
||||
#
|
||||
# BUGS
|
||||
#
|
||||
# * the script rlogins to localhost
|
||||
# * the script doesn't handle passwdord prompt, because it's intended
|
||||
# to use .rhosts auth and expects shell prompt immediately after
|
||||
# `rlogin`
|
||||
# * the regexp for shell prompt is hardcoded
|
||||
|
||||
log_user 0
|
||||
match_max 8192
|
||||
|
||||
while {1} {
|
||||
set rlogin_spawn [spawn rlogin localhost]
|
||||
if { $rlogin_spawn == 0 } { exit 1 }
|
||||
expect {
|
||||
-timeout 10 -re "^.*(Last login\[^\r\n\]*).*\n(\[^\r\n\]*\[#$\] )$" {
|
||||
send_error "$expect_out(1,string)\n"
|
||||
send_error "$expect_out(2,string)\n"
|
||||
# send_error "$expect_out(0,string)\n"
|
||||
}
|
||||
timeout {
|
||||
send_error "TIMEOUT/prompt\n"
|
||||
send_error "$expect_out(buffer)\n"
|
||||
send_error "RETRYING\n"
|
||||
log_user 1
|
||||
send "tty /\r"
|
||||
expect -timeout 2 -re "^.*\r?\n(\[^\r\n\]*# )$" {}
|
||||
send "tty /\r"
|
||||
expect -timeout 2 -re "^.*\r?\n(\[^\r\n\]*# )$" {}
|
||||
send_error "\n"
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
send "tty\r"
|
||||
expect {
|
||||
-timeout 4 -re "tty\r?\n(\[^\r\n\]*)\r?\n(\[^\r\n\]*\[#$\] )$" {
|
||||
send_error "$expect_out(2,string)$expect_out(1,string)\n"
|
||||
# send_error "$expect_out(0,string)\n"
|
||||
}
|
||||
timeout { send_error "TIMEOUT/tty\n" ; exit 3 }
|
||||
}
|
||||
send "exit\r"
|
||||
expect {
|
||||
-timeout 2 eof {
|
||||
# send_error "OK4: EOF\n"
|
||||
}
|
||||
timeout { send_error "TIMEOUT/eof\n" ; exit 4 }
|
||||
}
|
||||
wait
|
||||
}
|
||||
# vi: set sw=4:
|
||||
83
tests/bug334803-test.exp
Executable file
83
tests/bug334803-test.exp
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/expect --
|
||||
|
||||
# This is a script for switching to another user and then
|
||||
# suspending (`suspend -f`) and resuming (`fg`) his shell
|
||||
|
||||
package require cmdline
|
||||
set opts {
|
||||
{s.arg "sudo su -" "user switching method"}
|
||||
{u.arg "" "username to switch to"}
|
||||
}
|
||||
set usage ": \[options]\noptions:"
|
||||
array set conf [::cmdline::getoptions argv $opts $usage]
|
||||
|
||||
log_user 1
|
||||
match_max 8192
|
||||
expect_after {
|
||||
timeout { send_error "TIMEOUT\n" ; exit 1 }
|
||||
eof { send_error "EXITED\n" ; exit 2 }
|
||||
}
|
||||
set timeout 2
|
||||
|
||||
# user switching command, by default `sudo su -`
|
||||
set swcmd $conf(s)
|
||||
# ending of typicall shell prompt (zsh/sh):
|
||||
set shpmt "(%|#|\\$) \\Z"
|
||||
catch {set shpmt $env(EXPECT_PROMPT)}
|
||||
# initial username:
|
||||
set user0 [exec id -un]
|
||||
# user we switch to (with $swcmd), by default initial user
|
||||
if {$conf(u) != ""} {set swuser $conf(u)} else {set swuser $user0}
|
||||
|
||||
# 1. start shell
|
||||
spawn bash
|
||||
expect -re "$shpmt" {}
|
||||
|
||||
# 2. sudo-ing swuser's shell:
|
||||
send "$swcmd $swuser\r"
|
||||
expect {
|
||||
-re "$swuser.*$shpmt" {}
|
||||
-re "assword: ?\\Z" {
|
||||
stty -echo
|
||||
expect_user -timeout -1 -re "(.*)\n" {set swpwd $expect_out(1,string)}
|
||||
stty echo
|
||||
send "$swpwd\r"
|
||||
expect -re "$swuser.*$shpmt" {}
|
||||
}
|
||||
}
|
||||
|
||||
# 3. getting pid and ppid of swuser's shell (needed for 5b):
|
||||
send "echo \$\$:\$PPID\r"
|
||||
expect -re "(?n)^(\[\[:digit:\]\]*):(\[\[:digit:\]\]*)\r?\n(.*)$shpmt" {}
|
||||
set swpid $expect_out(1,string)
|
||||
set swppid $expect_out(2,string)
|
||||
|
||||
#send_error "$user0:$swpid:$swppid\n"
|
||||
|
||||
# 4. suspending swuser's shell (trying to return to parent shell):
|
||||
send "suspend -f\r"
|
||||
expect {
|
||||
-re "$shpmt" {
|
||||
# 5a. got to parent shell -- resuming swuser's shell by `fg`:
|
||||
send "fg\r"
|
||||
set hung no
|
||||
}
|
||||
timeout {
|
||||
# 5b. `suspend -f` has hung -- resuming swuser's shell by SIGCONT:
|
||||
send_error "kill $swppid\n"
|
||||
send_error [exec kill -CONT $swppid]
|
||||
set hung yes
|
||||
}
|
||||
}
|
||||
expect -re "$shpmt" {}
|
||||
|
||||
# 6. exiting [both] shells
|
||||
#set swstat [wait -nowait]
|
||||
#send_error [pid]:[exp_pid]:$swstat\n
|
||||
send "exit\rexit\r"
|
||||
expect eof {}
|
||||
#send_error [wait -nowait]\n
|
||||
#exec kill -KILL -[exp_pid]
|
||||
if {$hung} {send_error "BUGGY\n" ; exit 3 }
|
||||
|
||||
# vi:set sw=4:
|
||||
7
tests/chage/01/data/chage1
Normal file
7
tests/chage/01/data/chage1
Normal file
@@ -0,0 +1,7 @@
|
||||
Last password change : Jul 27, 2005
|
||||
Password expires : never
|
||||
Password inactive : never
|
||||
Account expires : never
|
||||
Minimum number of days between password change : 0
|
||||
Maximum number of days between password change : 99999
|
||||
Number of days of warning before password expires : 7
|
||||
7
tests/chage/01/data/chage2
Normal file
7
tests/chage/01/data/chage2
Normal file
@@ -0,0 +1,7 @@
|
||||
Last password change : Jul 28, 2005
|
||||
Password expires : never
|
||||
Password inactive : never
|
||||
Account expires : never
|
||||
Minimum number of days between password change : 1
|
||||
Maximum number of days between password change : 99996
|
||||
Number of days of warning before password expires : 5
|
||||
7
tests/chage/01/data/chage3
Normal file
7
tests/chage/01/data/chage3
Normal file
@@ -0,0 +1,7 @@
|
||||
Last password change : Jul 27, 2005
|
||||
Password expires : never
|
||||
Password inactive : never
|
||||
Account expires : Jan 01, 1970
|
||||
Minimum number of days between password change : 0
|
||||
Maximum number of days between password change : 99999
|
||||
Number of days of warning before password expires : 7
|
||||
7
tests/chage/01/data/chage4
Normal file
7
tests/chage/01/data/chage4
Normal file
@@ -0,0 +1,7 @@
|
||||
Last password change : Jul 27, 2005
|
||||
Password expires : never
|
||||
Password inactive : never
|
||||
Account expires : Jan 02, 1970
|
||||
Minimum number of days between password change : 0
|
||||
Maximum number of days between password change : 99999
|
||||
Number of days of warning before password expires : 7
|
||||
7
tests/chage/01/data/chage5
Normal file
7
tests/chage/01/data/chage5
Normal file
@@ -0,0 +1,7 @@
|
||||
Last password change : Jul 27, 2005
|
||||
Password expires : never
|
||||
Password inactive : never
|
||||
Account expires : never
|
||||
Minimum number of days between password change : 0
|
||||
Maximum number of days between password change : 99999
|
||||
Number of days of warning before password expires : 7
|
||||
7
tests/chage/01/data/chage6
Normal file
7
tests/chage/01/data/chage6
Normal file
@@ -0,0 +1,7 @@
|
||||
Last password change : Jul 27, 2005
|
||||
Password expires : never
|
||||
Password inactive : never
|
||||
Account expires : never
|
||||
Minimum number of days between password change : 0
|
||||
Maximum number of days between password change : 99999
|
||||
Number of days of warning before password expires : 7
|
||||
7
tests/chage/01/data/chage7
Normal file
7
tests/chage/01/data/chage7
Normal file
@@ -0,0 +1,7 @@
|
||||
Last password change : Jul 27, 2005
|
||||
Password expires : never
|
||||
Password inactive : never
|
||||
Account expires : never
|
||||
Minimum number of days between password change : 0
|
||||
Maximum number of days between password change : 99999
|
||||
Number of days of warning before password expires : 7
|
||||
7
tests/chage/01/data/chage7b
Normal file
7
tests/chage/01/data/chage7b
Normal file
@@ -0,0 +1,7 @@
|
||||
Last password change : Jul 26, 2005
|
||||
Password expires : Aug 09, 2005
|
||||
Password inactive : Sep 13, 2005
|
||||
Account expires : Jul 27, 2012
|
||||
Minimum number of days between password change : 13
|
||||
Maximum number of days between password change : 14
|
||||
Number of days of warning before password expires : 9
|
||||
1
tests/chage/01/data/chage8
Normal file
1
tests/chage/01/data/chage8
Normal file
@@ -0,0 +1 @@
|
||||
chage: user 'myuser8' does not exist in /etc/passwd
|
||||
42
tests/chage/01/data/group
Normal file
42
tests/chage/01/data/group
Normal file
@@ -0,0 +1,42 @@
|
||||
root:x:0:
|
||||
daemon:x:1:
|
||||
bin:x:2:
|
||||
sys:x:3:
|
||||
adm:x:4:
|
||||
tty:x:5:
|
||||
disk:x:6:
|
||||
lp:x:7:
|
||||
mail:x:8:
|
||||
news:x:9:
|
||||
uucp:x:10:
|
||||
man:x:12:
|
||||
proxy:x:13:
|
||||
kmem:x:15:
|
||||
dialout:x:20:
|
||||
fax:x:21:
|
||||
voice:x:22:
|
||||
cdrom:x:24:
|
||||
floppy:x:25:
|
||||
tape:x:26:
|
||||
sudo:x:27:
|
||||
audio:x:29:
|
||||
dip:x:30:
|
||||
www-data:x:33:
|
||||
backup:x:34:
|
||||
operator:x:37:
|
||||
list:x:38:
|
||||
irc:x:39:
|
||||
src:x:40:
|
||||
gnats:x:41:
|
||||
shadow:x:42:
|
||||
utmp:x:43:
|
||||
video:x:44:
|
||||
sasl:x:45:
|
||||
plugdev:x:46:
|
||||
staff:x:50:
|
||||
games:x:60:
|
||||
users:x:100:
|
||||
nogroup:x:65534:
|
||||
crontab:x:101:
|
||||
Debian-exim:x:102:
|
||||
myuser:x:424242:
|
||||
42
tests/chage/01/data/gshadow
Normal file
42
tests/chage/01/data/gshadow
Normal file
@@ -0,0 +1,42 @@
|
||||
root:*::
|
||||
daemon:*::
|
||||
bin:*::
|
||||
sys:*::
|
||||
adm:*::
|
||||
tty:*::
|
||||
disk:*::
|
||||
lp:*::
|
||||
mail:*::
|
||||
news:*::
|
||||
uucp:*::
|
||||
man:*::
|
||||
proxy:*::
|
||||
kmem:*::
|
||||
dialout:*::
|
||||
fax:*::
|
||||
voice:*::
|
||||
cdrom:*::
|
||||
floppy:*::
|
||||
tape:*::
|
||||
sudo:*::
|
||||
audio:*::
|
||||
dip:*::
|
||||
www-data:*::
|
||||
backup:*::
|
||||
operator:*::
|
||||
list:*::
|
||||
irc:*::
|
||||
src:*::
|
||||
gnats:*::
|
||||
shadow:*::
|
||||
utmp:*::
|
||||
video:*::
|
||||
sasl:*::
|
||||
plugdev:*::
|
||||
staff:*::
|
||||
games:*::
|
||||
users:*::
|
||||
nogroup:*::
|
||||
crontab:x::
|
||||
Debian-exim:x::
|
||||
myuser:x::
|
||||
26
tests/chage/01/data/passwd
Normal file
26
tests/chage/01/data/passwd
Normal file
@@ -0,0 +1,26 @@
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
|
||||
bin:x:2:2:bin:/bin:/bin/sh
|
||||
sys:x:3:3:sys:/dev:/bin/sh
|
||||
sync:x:4:65534:sync:/bin:/bin/sync
|
||||
games:x:5:60:games:/usr/games:/bin/sh
|
||||
man:x:6:12:man:/var/cache/man:/bin/sh
|
||||
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
|
||||
mail:x:8:8:mail:/var/mail:/bin/sh
|
||||
news:x:9:9:news:/var/spool/news:/bin/sh
|
||||
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
|
||||
proxy:x:13:13:proxy:/bin:/bin/sh
|
||||
www-data:x:33:33:www-data:/var/www:/bin/sh
|
||||
backup:x:34:34:backup:/var/backups:/bin/sh
|
||||
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
|
||||
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
|
||||
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
|
||||
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
|
||||
Debian-exim:x:102:102::/var/spool/exim4:/bin/false
|
||||
myuser1:x:424242:424242::/home:/bin/bash
|
||||
myuser2:x:424243:424242::/home:/bin/bash
|
||||
myuser3:x:424244:424242::/home:/bin/bash
|
||||
myuser4:x:424245:424242::/home:/bin/bash
|
||||
myuser5:x:424246:424242::/home:/bin/bash
|
||||
myuser6:x:424247:424242::/home:/bin/bash
|
||||
myuser7:x:424248:424242::/home:/bin/bash
|
||||
26
tests/chage/01/data/shadow
Normal file
26
tests/chage/01/data/shadow
Normal file
@@ -0,0 +1,26 @@
|
||||
root:$1$NBLBLIXb$WUgojj1bNuxWEADQGt1m9.:12991:0:99999:7:::
|
||||
daemon:*:12977:0:99999:7:::
|
||||
bin:*:12977:0:99999:7:::
|
||||
sys:*:12977:0:99999:7:::
|
||||
sync:*:12977:0:99999:7:::
|
||||
games:*:12977:0:99999:7:::
|
||||
man:*:12977:0:99999:7:::
|
||||
lp:*:12977:0:99999:7:::
|
||||
mail:*:12977:0:99999:7:::
|
||||
news:*:12977:0:99999:7:::
|
||||
uucp:*:12977:0:99999:7:::
|
||||
proxy:*:12977:0:99999:7:::
|
||||
www-data:*:12977:0:99999:7:::
|
||||
backup:*:12977:0:99999:7:::
|
||||
list:*:12977:0:99999:7:::
|
||||
irc:*:12977:0:99999:7:::
|
||||
gnats:*:12977:0:99999:7:::
|
||||
nobody:*:12977:0:99999:7:::
|
||||
Debian-exim:!:12977:0:99999:7:::
|
||||
myuser1:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12991:0:99999:7:::
|
||||
myuser2:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12992:1:99996:5:::
|
||||
myuser3:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12991:0:99999:7::0:
|
||||
myuser4:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12991:0:99999:7::1:
|
||||
myuser5:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12991:0:99999:7:0::
|
||||
myuser6:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12991:0:99999:7:1::
|
||||
myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12991:0:99999:7:1::
|
||||
16
tests/chage/01/data/usage
Normal file
16
tests/chage/01/data/usage
Normal file
@@ -0,0 +1,16 @@
|
||||
Usage: chage [options] LOGIN
|
||||
|
||||
Options:
|
||||
-d, --lastday LAST_DAY set date of last password change to LAST_DAY
|
||||
-E, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE
|
||||
-h, --help display this help message and exit
|
||||
-I, --inactive INACTIVE set password inactive after expiration
|
||||
to INACTIVE
|
||||
-l, --list show account aging information
|
||||
-m, --mindays MIN_DAYS set minimum number of days before password
|
||||
change to MIN_DAYS
|
||||
-M, --maxdays MAX_DAYS set maximim number of days before password
|
||||
change to MAX_DAYS
|
||||
-R, --root CHROOT_DIR directory to chroot into
|
||||
-W, --warndays WARN_DAYS set expiration warning days to WARN_DAYS
|
||||
|
||||
206
tests/chage/01/run
Executable file
206
tests/chage/01/run
Executable file
@@ -0,0 +1,206 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
# Rational:
|
||||
# Test chage options
|
||||
|
||||
# no testsuite password
|
||||
# root password: rootF00barbaz
|
||||
# myuser password: myuserF00barbaz
|
||||
|
||||
save()
|
||||
{
|
||||
[ ! -d tmp ] && mkdir tmp
|
||||
for i in passwd group shadow gshadow
|
||||
do
|
||||
[ -f /etc/$i ] && cp /etc/$i tmp/$i
|
||||
[ -f /etc/$i- ] && cp /etc/$i- tmp/$i-
|
||||
done
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
restore()
|
||||
{
|
||||
for i in passwd group shadow gshadow
|
||||
do
|
||||
[ -f tmp/$i ] && cp tmp/$i /etc/$i && rm tmp/$i
|
||||
[ -f tmp/$i- ] && cp tmp/$i- /etc/$i- && rm tmp/$i-
|
||||
done
|
||||
rm -f tmp/out
|
||||
rmdir tmp
|
||||
}
|
||||
|
||||
save
|
||||
|
||||
# restore the files on exit
|
||||
trap 'if [ "$?" != "0" ]; then echo "FAIL"; fi; restore' 0
|
||||
|
||||
for i in passwd group shadow gshadow
|
||||
do
|
||||
cp data/$i /etc
|
||||
done
|
||||
|
||||
echo -n "testing option -l"
|
||||
chage -l myuser1 > tmp/out
|
||||
diff -au data/chage1 tmp/out
|
||||
echo -n .
|
||||
chage -l myuser2 > tmp/out
|
||||
diff -au data/chage2 tmp/out
|
||||
echo -n .
|
||||
chage -l myuser3 > tmp/out
|
||||
diff -au data/chage3 tmp/out
|
||||
echo -n .
|
||||
chage -l myuser4 > tmp/out
|
||||
diff -au data/chage4 tmp/out
|
||||
echo -n .
|
||||
chage -l myuser5 > tmp/out
|
||||
diff -au data/chage5 tmp/out
|
||||
echo -n .
|
||||
chage -l myuser6 > tmp/out
|
||||
diff -au data/chage6 tmp/out
|
||||
echo -n .
|
||||
chage --list myuser7 > tmp/out
|
||||
diff -au data/chage7 tmp/out
|
||||
echo -n .
|
||||
msg=$(chage -l myuser8 2> tmp/out) || err=$?
|
||||
[ "$err" = "1" ] && [ "$msg" = "" ] || exit 1
|
||||
diff -au data/chage8 tmp/out
|
||||
echo .
|
||||
|
||||
echo "testing option -d"
|
||||
chage -d 2001-10-02 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:11597:0:99999:7:1::' ] || exit 1
|
||||
echo "testing option -d -1"
|
||||
chage -d -1 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.::0:99999:7:1::' ] || exit 1
|
||||
echo "testing option -d 0"
|
||||
chage -d 0 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:0:0:99999:7:1::' ] || exit 1
|
||||
echo "testing option --lastday"
|
||||
chage --lastday 2011-11-02 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:1::' ] || exit 1
|
||||
|
||||
echo "testing option -E"
|
||||
chage -E 2010-10-02 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:1:14884:' ] || exit 1
|
||||
echo "testing option -E -1"
|
||||
chage -E -1 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:1::' ] || exit 1
|
||||
echo "testing option -E 0"
|
||||
chage -E 0 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:1:0:' ] || exit 1
|
||||
echo "testing option --expiredate"
|
||||
chage --expiredate 2020-02-02 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:1:18294:' ] || exit 1
|
||||
|
||||
echo "testing option -I"
|
||||
# NOTE: I could pass a date to -I
|
||||
chage -I 42 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:42:18294:' ] || exit 1
|
||||
echo "testing option -I -1"
|
||||
# NOTE: this behavior is not documented
|
||||
chage -I -1 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7::18294:' ] || exit 1
|
||||
echo "testing option -I 0"
|
||||
# NOTE: We should check that this is the expected behavior
|
||||
chage -I 0 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:0:18294:' ] || exit 1
|
||||
echo "testing option --inactive"
|
||||
chage --inactive 12 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:12:18294:' ] || exit 1
|
||||
|
||||
echo "testing option -m"
|
||||
chage -m 24 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:24:99999:7:12:18294:' ] || exit 1
|
||||
echo "testing option -m -1"
|
||||
# NOTE: this behavior is not documented
|
||||
chage -m -1 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280::99999:7:12:18294:' ] || exit 1
|
||||
echo "testing option -m 0"
|
||||
chage -m 0 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:0:99999:7:12:18294:' ] || exit 1
|
||||
echo "testing option --mindays"
|
||||
chage --min 1 myuser7
|
||||
# NOTE: that shouldn't have work
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1:99999:7:12:18294:' ] || exit 1
|
||||
|
||||
echo "testing option -M"
|
||||
chage -M 25 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1:25:7:12:18294:' ] || exit 1
|
||||
echo "testing option -M -1"
|
||||
# NOTE: this behavior is not documented
|
||||
chage -M -1 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1::7:12:18294:' ] || exit 1
|
||||
echo "testing option -M 0"
|
||||
chage -M 0 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1:0:7:12:18294:' ] || exit 1
|
||||
echo "testing option --maxdays"
|
||||
chage --max 2 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1:2:7:12:18294:' ] || exit 1
|
||||
|
||||
echo "testing option -W"
|
||||
chage -W 26 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1:2:26:12:18294:' ] || exit 1
|
||||
echo "testing option -W -1"
|
||||
# NOTE: this behavior is not documented
|
||||
chage -W -1 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1:2::12:18294:' ] || exit 1
|
||||
echo "testing option -W 0"
|
||||
chage -W 0 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1:2:0:12:18294:' ] || exit 1
|
||||
echo "testing option --warndays"
|
||||
chage --warndays 3 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:15280:1:2:3:12:18294:' ] || exit 1
|
||||
|
||||
echo "testing with all options"
|
||||
chage -d 2030-03-02 -E 1979-11-24 -I 10 -m 11 -M 12 --warndays 4 myuser7
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:21975:11:12:4:10:3614:' ] || exit 1
|
||||
|
||||
echo "interractive test"
|
||||
./run1.exp
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12990:13:14:9:35:15548:' ] || exit 1
|
||||
|
||||
echo "interractive test (default)"
|
||||
./run2.exp
|
||||
ent=$(getent shadow myuser7)
|
||||
[ "$ent" = 'myuser7:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12990:13:14:9:35:15548:' ] || exit 1
|
||||
chage -l myuser7 > tmp/out
|
||||
diff -au data/chage7b tmp/out
|
||||
|
||||
echo "usage"
|
||||
chage -h > tmp/out || {
|
||||
if [ "$?" != "2" ]; then false; fi
|
||||
}
|
||||
diff -au data/usage tmp/out
|
||||
|
||||
echo "OK"
|
||||
31
tests/chage/01/run1.exp
Executable file
31
tests/chage/01/run1.exp
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 5
|
||||
|
||||
# I've not been able to put the opening bracket in the regular expressions
|
||||
# If anyone knows...
|
||||
|
||||
spawn /usr/bin/chage myuser7
|
||||
expect -re "Minimum Password Age .11\]: "
|
||||
send "13\r"
|
||||
expect -re "Maximum Password Age .12\]: "
|
||||
send "14\r"
|
||||
expect -re "Last Password Change \[(]YYYY-MM-DD\[)] .2030-03-02\]: "
|
||||
send "2005-07-26\r"
|
||||
expect -re "Password Expiration Warning .4\]: "
|
||||
send "9\r"
|
||||
expect -re "Password Inactive .10\]: "
|
||||
send "35\r"
|
||||
expect -re "Account Expiration Date \[(]YYYY-MM-DD\[)] .1979-11-24\]: "
|
||||
send "2012-07-27\r"
|
||||
expect {
|
||||
eof {
|
||||
} default {
|
||||
puts "\nFAIL"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
puts "\nPASS"
|
||||
exit 0
|
||||
|
||||
31
tests/chage/01/run2.exp
Executable file
31
tests/chage/01/run2.exp
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 5
|
||||
|
||||
# I've not been able to put the opening bracket in the regular expressions
|
||||
# If anyone knows...
|
||||
|
||||
spawn /usr/bin/chage myuser7
|
||||
expect -re "Minimum Password Age .13\]: "
|
||||
send "\r"
|
||||
expect -re "Maximum Password Age .14\]: "
|
||||
send "\r"
|
||||
expect -re "Last Password Change \[(]YYYY-MM-DD\[)] .2005-07-26\]: "
|
||||
send "\r"
|
||||
expect -re "Password Expiration Warning .9\]: "
|
||||
send "\r"
|
||||
expect -re "Password Inactive .35\]: "
|
||||
send "\r"
|
||||
expect -re "Account Expiration Date \[(]YYYY-MM-DD\[)] .2012-07-27\]: "
|
||||
send "\r"
|
||||
expect {
|
||||
eof {
|
||||
} default {
|
||||
puts "\nFAIL"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
puts "\nPASS"
|
||||
exit 0
|
||||
|
||||
42
tests/chage/02/data/group
Normal file
42
tests/chage/02/data/group
Normal file
@@ -0,0 +1,42 @@
|
||||
root:x:0:
|
||||
daemon:x:1:
|
||||
bin:x:2:
|
||||
sys:x:3:
|
||||
adm:x:4:
|
||||
tty:x:5:
|
||||
disk:x:6:
|
||||
lp:x:7:
|
||||
mail:x:8:
|
||||
news:x:9:
|
||||
uucp:x:10:
|
||||
man:x:12:
|
||||
proxy:x:13:
|
||||
kmem:x:15:
|
||||
dialout:x:20:
|
||||
fax:x:21:
|
||||
voice:x:22:
|
||||
cdrom:x:24:
|
||||
floppy:x:25:
|
||||
tape:x:26:
|
||||
sudo:x:27:
|
||||
audio:x:29:
|
||||
dip:x:30:
|
||||
www-data:x:33:
|
||||
backup:x:34:
|
||||
operator:x:37:
|
||||
list:x:38:
|
||||
irc:x:39:
|
||||
src:x:40:
|
||||
gnats:x:41:
|
||||
shadow:x:42:
|
||||
utmp:x:43:
|
||||
video:x:44:
|
||||
sasl:x:45:
|
||||
plugdev:x:46:
|
||||
staff:x:50:
|
||||
games:x:60:
|
||||
users:x:100:
|
||||
nogroup:x:65534:
|
||||
crontab:x:101:
|
||||
Debian-exim:x:102:
|
||||
myuser:x:424242:
|
||||
42
tests/chage/02/data/gshadow
Normal file
42
tests/chage/02/data/gshadow
Normal file
@@ -0,0 +1,42 @@
|
||||
root:*::
|
||||
daemon:*::
|
||||
bin:*::
|
||||
sys:*::
|
||||
adm:*::
|
||||
tty:*::
|
||||
disk:*::
|
||||
lp:*::
|
||||
mail:*::
|
||||
news:*::
|
||||
uucp:*::
|
||||
man:*::
|
||||
proxy:*::
|
||||
kmem:*::
|
||||
dialout:*::
|
||||
fax:*::
|
||||
voice:*::
|
||||
cdrom:*::
|
||||
floppy:*::
|
||||
tape:*::
|
||||
sudo:*::
|
||||
audio:*::
|
||||
dip:*::
|
||||
www-data:*::
|
||||
backup:*::
|
||||
operator:*::
|
||||
list:*::
|
||||
irc:*::
|
||||
src:*::
|
||||
gnats:*::
|
||||
shadow:*::
|
||||
utmp:*::
|
||||
video:*::
|
||||
sasl:*::
|
||||
plugdev:*::
|
||||
staff:*::
|
||||
games:*::
|
||||
users:*::
|
||||
nogroup:*::
|
||||
crontab:x::
|
||||
Debian-exim:x::
|
||||
myuser:x::
|
||||
20
tests/chage/02/data/passwd
Normal file
20
tests/chage/02/data/passwd
Normal file
@@ -0,0 +1,20 @@
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
|
||||
bin:x:2:2:bin:/bin:/bin/sh
|
||||
sys:x:3:3:sys:/dev:/bin/sh
|
||||
sync:x:4:65534:sync:/bin:/bin/sync
|
||||
games:x:5:60:games:/usr/games:/bin/sh
|
||||
man:x:6:12:man:/var/cache/man:/bin/sh
|
||||
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
|
||||
mail:x:8:8:mail:/var/mail:/bin/sh
|
||||
news:x:9:9:news:/var/spool/news:/bin/sh
|
||||
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
|
||||
proxy:x:13:13:proxy:/bin:/bin/sh
|
||||
www-data:x:33:33:www-data:/var/www:/bin/sh
|
||||
backup:x:34:34:backup:/var/backups:/bin/sh
|
||||
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
|
||||
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
|
||||
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
|
||||
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
|
||||
Debian-exim:x:102:102::/var/spool/exim4:/bin/false
|
||||
myuser:x:424248:424242::/home:/bin/bash
|
||||
20
tests/chage/02/data/shadow
Normal file
20
tests/chage/02/data/shadow
Normal file
@@ -0,0 +1,20 @@
|
||||
root:$1$NBLBLIXb$WUgojj1bNuxWEADQGt1m9.:12991:0:99999:7:::
|
||||
daemon:*:12977:0:99999:7:::
|
||||
bin:*:12977:0:99999:7:::
|
||||
sys:*:12977:0:99999:7:::
|
||||
sync:*:12977:0:99999:7:::
|
||||
games:*:12977:0:99999:7:::
|
||||
man:*:12977:0:99999:7:::
|
||||
lp:*:12977:0:99999:7:::
|
||||
mail:*:12977:0:99999:7:::
|
||||
news:*:12977:0:99999:7:::
|
||||
uucp:*:12977:0:99999:7:::
|
||||
proxy:*:12977:0:99999:7:::
|
||||
www-data:*:12977:0:99999:7:::
|
||||
backup:*:12977:0:99999:7:::
|
||||
list:*:12977:0:99999:7:::
|
||||
irc:*:12977:0:99999:7:::
|
||||
gnats:*:12977:0:99999:7:::
|
||||
nobody:*:12977:0:99999:7:::
|
||||
Debian-exim:!:12977:0:99999:7:::
|
||||
myuser:$1$yQnIAZWV$gDAMB2IkqaONgrQiRdo4y.:12991:0:99999:7:::
|
||||
50
tests/chage/02/run
Executable file
50
tests/chage/02/run
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
# Rational:
|
||||
# Test chage with bogus inputs
|
||||
|
||||
# no testsuite password
|
||||
# root password: rootF00barbaz
|
||||
# myuser password: myuserF00barbaz
|
||||
|
||||
save()
|
||||
{
|
||||
[ ! -d tmp ] && mkdir tmp
|
||||
for i in passwd group shadow gshadow
|
||||
do
|
||||
[ -f /etc/$i ] && cp /etc/$i tmp/$i
|
||||
[ -f /etc/$i- ] && cp /etc/$i- tmp/$i-
|
||||
done
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
restore()
|
||||
{
|
||||
for i in passwd group shadow gshadow
|
||||
do
|
||||
[ -f tmp/$i ] && cp tmp/$i /etc/$i && rm tmp/$i
|
||||
[ -f tmp/$i- ] && cp tmp/$i- /etc/$i- && rm tmp/$i-
|
||||
done
|
||||
rm -f tmp/out
|
||||
rmdir tmp
|
||||
}
|
||||
|
||||
save
|
||||
|
||||
# restore the files on exit
|
||||
trap 'if [ "$?" != "0" ]; then echo "FAIL"; fi; restore' 0
|
||||
|
||||
for i in passwd group shadow gshadow
|
||||
do
|
||||
cp data/$i /etc
|
||||
done
|
||||
|
||||
echo "interractive test"
|
||||
./run.exp $(date "+%Y-%m-%d")
|
||||
|
||||
echo "OK"
|
||||
83
tests/chage/02/run.exp
Executable file
83
tests/chage/02/run.exp
Executable file
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 5
|
||||
|
||||
proc expect_error {} {
|
||||
expect {
|
||||
"chage: error changing fields" {
|
||||
expect {
|
||||
eof {
|
||||
} default {
|
||||
puts "\nFAIL"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
} default {
|
||||
puts "\nFAIL"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# I've not been able to put the opening bracket in the regular expressions
|
||||
# If anyone knows...
|
||||
|
||||
spawn /usr/bin/chage myuser
|
||||
expect -re "Minimum Password Age .0\]: "
|
||||
send -- "-2\r"
|
||||
expect_error
|
||||
|
||||
spawn /usr/bin/chage myuser
|
||||
expect -re "Minimum Password Age .0\]: "
|
||||
send "foo\r"
|
||||
expect_error
|
||||
|
||||
# chage accepts to be given only spaces
|
||||
#spawn /usr/bin/chage myuser
|
||||
#expect -re "Minimum Password Age .0\]: "
|
||||
#send -- " \r"
|
||||
#expect_error
|
||||
#
|
||||
#chage may not parse all the arguments.
|
||||
#This may be a problem is a date is provided instead of just a number
|
||||
#spawn /usr/bin/chage myuser
|
||||
#expect -re "Minimum Password Age .0\]: "
|
||||
#send -- "1 2\r"
|
||||
#expect_error
|
||||
|
||||
spawn /usr/bin/chage myuser
|
||||
expect -re "Minimum Password Age .0\]: "
|
||||
send "11\r"
|
||||
expect -re "Maximum Password Age .99999\]: "
|
||||
send -- "-2\r"
|
||||
expect_error
|
||||
|
||||
spawn /usr/bin/chage myuser
|
||||
expect -re "Minimum Password Age .0\]: "
|
||||
send "\r"
|
||||
expect -re "Maximum Password Age .99999\]: "
|
||||
send "foo\r"
|
||||
expect_error
|
||||
|
||||
# chage should verify the range of the arguments
|
||||
#spawn /usr/bin/chage myuser
|
||||
#expect -re "Minimum Password Age .0\]: "
|
||||
#send "\r"
|
||||
#expect -re "Maximum Password Age .99999\]: "
|
||||
#send "100000\r"
|
||||
#expect_error
|
||||
|
||||
#spawn /usr/bin/chage myuser
|
||||
#expect -re "Minimum Password Age .0\]: "
|
||||
#send "\r"
|
||||
#expect -re "Maximum Password Age .99999\]: "
|
||||
#send "\r"
|
||||
#expect -re "Last Password Change \[(]YYYY-MM-DD\[)] .2005-07-25]: "
|
||||
#send "12\n"
|
||||
#expect_error
|
||||
|
||||
|
||||
puts "\nPASS"
|
||||
exit 0
|
||||
|
||||
48
tests/chage/03_chsh_usage/chage.test
Executable file
48
tests/chage/03_chsh_usage/chage.test
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
. ../../common/config.sh
|
||||
. ../../common/log.sh
|
||||
|
||||
log_start "$0" "chage can display its usage message"
|
||||
|
||||
save_config
|
||||
|
||||
# restore the files on exit
|
||||
trap 'log_status "$0" "FAILURE"; restore_config' 0
|
||||
|
||||
change_config
|
||||
|
||||
echo -n "Get chage usage (chage -h)..."
|
||||
chage -h >tmp/usage.out
|
||||
echo "OK"
|
||||
|
||||
echo "chage reported:"
|
||||
echo "======================================================================="
|
||||
cat tmp/usage.out
|
||||
echo "======================================================================="
|
||||
echo -n "Check the usage message..."
|
||||
diff -au data/usage.out tmp/usage.out
|
||||
echo "usage message OK."
|
||||
rm -f tmp/usage.out
|
||||
|
||||
echo -n "Check the passwd file..."
|
||||
../../common/compare_file.pl config/etc/passwd /etc/passwd
|
||||
echo "OK"
|
||||
echo -n "Check the group file..."
|
||||
../../common/compare_file.pl config/etc/group /etc/group
|
||||
echo "OK"
|
||||
echo -n "Check the shadow file..."
|
||||
../../common/compare_file.pl config/etc/shadow /etc/shadow
|
||||
echo "OK"
|
||||
echo -n "Check the gshadow file..."
|
||||
../../common/compare_file.pl config/etc/gshadow /etc/gshadow
|
||||
echo "OK"
|
||||
|
||||
log_status "$0" "SUCCESS"
|
||||
restore_config
|
||||
trap '' 0
|
||||
|
||||
0
tests/chage/03_chsh_usage/config.txt
Normal file
0
tests/chage/03_chsh_usage/config.txt
Normal file
42
tests/chage/03_chsh_usage/config/etc/group
Normal file
42
tests/chage/03_chsh_usage/config/etc/group
Normal file
@@ -0,0 +1,42 @@
|
||||
root:x:0:
|
||||
daemon:x:1:
|
||||
bin:x:2:
|
||||
sys:x:3:
|
||||
adm:x:4:
|
||||
tty:x:5:
|
||||
disk:x:6:
|
||||
lp:x:7:
|
||||
mail:x:8:
|
||||
news:x:9:
|
||||
uucp:x:10:
|
||||
man:x:12:
|
||||
proxy:x:13:
|
||||
kmem:x:15:
|
||||
dialout:x:20:
|
||||
fax:x:21:
|
||||
voice:x:22:
|
||||
cdrom:x:24:
|
||||
floppy:x:25:
|
||||
tape:x:26:
|
||||
sudo:x:27:
|
||||
audio:x:29:
|
||||
dip:x:30:
|
||||
www-data:x:33:
|
||||
backup:x:34:
|
||||
operator:x:37:
|
||||
list:x:38:
|
||||
irc:x:39:
|
||||
src:x:40:
|
||||
gnats:x:41:
|
||||
shadow:x:42:
|
||||
utmp:x:43:
|
||||
video:x:44:
|
||||
sasl:x:45:
|
||||
plugdev:x:46:
|
||||
staff:x:50:
|
||||
games:x:60:
|
||||
users:x:100:
|
||||
nogroup:x:65534:
|
||||
crontab:x:101:
|
||||
Debian-exim:x:102:
|
||||
myuser:x:424242:
|
||||
42
tests/chage/03_chsh_usage/config/etc/gshadow
Normal file
42
tests/chage/03_chsh_usage/config/etc/gshadow
Normal file
@@ -0,0 +1,42 @@
|
||||
root:*::
|
||||
daemon:*::
|
||||
bin:*::
|
||||
sys:*::
|
||||
adm:*::
|
||||
tty:*::
|
||||
disk:*::
|
||||
lp:*::
|
||||
mail:*::
|
||||
news:*::
|
||||
uucp:*::
|
||||
man:*::
|
||||
proxy:*::
|
||||
kmem:*::
|
||||
dialout:*::
|
||||
fax:*::
|
||||
voice:*::
|
||||
cdrom:*::
|
||||
floppy:*::
|
||||
tape:*::
|
||||
sudo:*::
|
||||
audio:*::
|
||||
dip:*::
|
||||
www-data:*::
|
||||
backup:*::
|
||||
operator:*::
|
||||
list:*::
|
||||
irc:*::
|
||||
src:*::
|
||||
gnats:*::
|
||||
shadow:*::
|
||||
utmp:*::
|
||||
video:*::
|
||||
sasl:*::
|
||||
plugdev:*::
|
||||
staff:*::
|
||||
games:*::
|
||||
users:*::
|
||||
nogroup:*::
|
||||
crontab:x::
|
||||
Debian-exim:x::
|
||||
myuser:x::
|
||||
26
tests/chage/03_chsh_usage/config/etc/passwd
Normal file
26
tests/chage/03_chsh_usage/config/etc/passwd
Normal file
@@ -0,0 +1,26 @@
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
|
||||
bin:x:2:2:bin:/bin:/bin/sh
|
||||
sys:x:3:3:sys:/dev:/bin/sh
|
||||
sync:x:4:65534:sync:/bin:/bin/sync
|
||||
games:x:5:60:games:/usr/games:/bin/sh
|
||||
man:x:6:12:man:/var/cache/man:/bin/sh
|
||||
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
|
||||
mail:x:8:8:mail:/var/mail:/bin/sh
|
||||
news:x:9:9:news:/var/spool/news:/bin/sh
|
||||
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
|
||||
proxy:x:13:13:proxy:/bin:/bin/sh
|
||||
www-data:x:33:33:www-data:/var/www:/bin/sh
|
||||
backup:x:34:34:backup:/var/backups:/bin/sh
|
||||
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
|
||||
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
|
||||
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
|
||||
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
|
||||
Debian-exim:x:102:102::/var/spool/exim4:/bin/false
|
||||
myuser1:x:424242:424242::/home:/bin/bash
|
||||
myuser2:x:424243:424242::/home:/bin/bash
|
||||
myuser3:x:424244:424242::/home:/bin/bash
|
||||
myuser4:x:424245:424242::/home:/bin/bash
|
||||
myuser5:x:424246:424242::/home:/bin/bash
|
||||
myuser6:x:424247:424242::/home:/bin/bash
|
||||
myuser7:x:424248:424242::/home:/bin/bash
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user