Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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)
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -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,19 @@ 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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -103,6 +103,17 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-C</option>, <option>--clear</option>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Clear lastlog record of an 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 an 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>
|
||||
|
||||
@@ -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>
|
||||
@@ -85,6 +82,8 @@
|
||||
<para>
|
||||
The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename> based on it's
|
||||
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>
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
<para>
|
||||
The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename> based on it's
|
||||
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>
|
||||
|
||||
@@ -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> "
|
||||
|
||||
@@ -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'>
|
||||
|
||||
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);
|
||||
|
||||
@@ -370,7 +370,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 +380,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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -120,6 +120,7 @@ int main(int argc, char **argv)
|
||||
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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -120,6 +120,7 @@ int main(int argc, char **argv)
|
||||
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 ());
|
||||
|
||||
@@ -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
|
||||
26
tests/chage/03_chsh_usage/config/etc/shadow
Normal file
26
tests/chage/03_chsh_usage/config/etc/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/03_chsh_usage/data/usage.out
Normal file
16
tests/chage/03_chsh_usage/data/usage.out
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
|
||||
|
||||
54
tests/chage/04_chsh_usage_invalid_option/chage.test
Executable file
54
tests/chage/04_chsh_usage_invalid_option/chage.test
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
. ../../common/config.sh
|
||||
. ../../common/log.sh
|
||||
|
||||
log_start "$0" "chage displays its usage message when an invalid option is used"
|
||||
|
||||
save_config
|
||||
|
||||
# restore the files on exit
|
||||
trap 'log_status "$0" "FAILURE"; restore_config' 0
|
||||
|
||||
change_config
|
||||
|
||||
echo -n "Use chage with an invalid option (chage -Z bin)..."
|
||||
chage -Z bin 2>tmp/usage.out && exit 1 || {
|
||||
status=$?
|
||||
}
|
||||
echo "OK"
|
||||
|
||||
echo -n "Check returned status ($status)..."
|
||||
test "$status" = "2"
|
||||
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/04_chsh_usage_invalid_option/config.txt
Normal file
0
tests/chage/04_chsh_usage_invalid_option/config.txt
Normal file
42
tests/chage/04_chsh_usage_invalid_option/config/etc/group
Normal file
42
tests/chage/04_chsh_usage_invalid_option/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/04_chsh_usage_invalid_option/config/etc/gshadow
Normal file
42
tests/chage/04_chsh_usage_invalid_option/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/04_chsh_usage_invalid_option/config/etc/passwd
Normal file
26
tests/chage/04_chsh_usage_invalid_option/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
|
||||
26
tests/chage/04_chsh_usage_invalid_option/config/etc/shadow
Normal file
26
tests/chage/04_chsh_usage_invalid_option/config/etc/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::
|
||||
17
tests/chage/04_chsh_usage_invalid_option/data/usage.out
Normal file
17
tests/chage/04_chsh_usage_invalid_option/data/usage.out
Normal file
@@ -0,0 +1,17 @@
|
||||
chage: invalid option -- 'Z'
|
||||
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
|
||||
|
||||
54
tests/chage/05_chsh_usage_2_users/chage.test
Executable file
54
tests/chage/05_chsh_usage_2_users/chage.test
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
. ../../common/config.sh
|
||||
. ../../common/log.sh
|
||||
|
||||
log_start "$0" "chage displays its usage message when 2 users are provided"
|
||||
|
||||
save_config
|
||||
|
||||
# restore the files on exit
|
||||
trap 'log_status "$0" "FAILURE"; restore_config' 0
|
||||
|
||||
change_config
|
||||
|
||||
echo -n "Use chage with 2 users (chage -I 12 bin nobody)..."
|
||||
chage -I 12 bin nobody 2>tmp/usage.out && exit 1 || {
|
||||
status=$?
|
||||
}
|
||||
echo "OK"
|
||||
|
||||
echo -n "Check returned status ($status)..."
|
||||
test "$status" = "2"
|
||||
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/05_chsh_usage_2_users/config.txt
Normal file
0
tests/chage/05_chsh_usage_2_users/config.txt
Normal file
42
tests/chage/05_chsh_usage_2_users/config/etc/group
Normal file
42
tests/chage/05_chsh_usage_2_users/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/05_chsh_usage_2_users/config/etc/gshadow
Normal file
42
tests/chage/05_chsh_usage_2_users/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/05_chsh_usage_2_users/config/etc/passwd
Normal file
26
tests/chage/05_chsh_usage_2_users/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
|
||||
26
tests/chage/05_chsh_usage_2_users/config/etc/shadow
Normal file
26
tests/chage/05_chsh_usage_2_users/config/etc/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/05_chsh_usage_2_users/data/usage.out
Normal file
16
tests/chage/05_chsh_usage_2_users/data/usage.out
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
|
||||
|
||||
54
tests/chage/06_chsh_usage_no_users/chage.test
Executable file
54
tests/chage/06_chsh_usage_no_users/chage.test
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
. ../../common/config.sh
|
||||
. ../../common/log.sh
|
||||
|
||||
log_start "$0" "chage displays its usage message when no users are provided"
|
||||
|
||||
save_config
|
||||
|
||||
# restore the files on exit
|
||||
trap 'log_status "$0" "FAILURE"; restore_config' 0
|
||||
|
||||
change_config
|
||||
|
||||
echo -n "Use chage without an user (chage -I 12)..."
|
||||
chage -I 12 2>tmp/usage.out && exit 1 || {
|
||||
status=$?
|
||||
}
|
||||
echo "OK"
|
||||
|
||||
echo -n "Check returned status ($status)..."
|
||||
test "$status" = "2"
|
||||
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/06_chsh_usage_no_users/config.txt
Normal file
0
tests/chage/06_chsh_usage_no_users/config.txt
Normal file
42
tests/chage/06_chsh_usage_no_users/config/etc/group
Normal file
42
tests/chage/06_chsh_usage_no_users/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:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user