2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2008-04-27 06:10:09 +05:30
|
|
|
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
|
|
|
|
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
|
|
|
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
|
|
|
|
* Copyright (c) 2007 - 2008, Nicolas François
|
2007-10-07 17:14:02 +05:30
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2008-04-27 06:10:09 +05:30
|
|
|
* 3. The name of the copyright holders or contributors may not be used to
|
|
|
|
* endorse or promote products derived from this software without
|
|
|
|
* specific prior written permission.
|
2007-10-07 17:14:02 +05:30
|
|
|
*
|
2008-04-27 06:10:09 +05:30
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
|
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2007-11-11 05:16:11 +05:30
|
|
|
#ident "$Id$"
|
2007-10-07 17:17:01 +05:30
|
|
|
|
2007-10-07 17:16:52 +05:30
|
|
|
#include <errno.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include <fcntl.h>
|
2008-08-22 07:58:15 +05:30
|
|
|
#include <getopt.h>
|
2007-10-07 17:16:52 +05:30
|
|
|
#include <grp.h>
|
|
|
|
#include <pwd.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include <signal.h>
|
2007-10-07 17:16:52 +05:30
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "defines.h"
|
2007-10-07 17:16:52 +05:30
|
|
|
#include "exitcodes.h"
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "groupio.h"
|
2007-10-07 17:17:22 +05:30
|
|
|
#include "nscd.h"
|
2007-10-07 17:16:52 +05:30
|
|
|
#include "prototypes.h"
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "sgroupio.h"
|
|
|
|
#endif
|
2007-10-07 17:17:01 +05:30
|
|
|
/*
|
|
|
|
* Global variables
|
|
|
|
*/
|
2007-12-27 23:06:08 +05:30
|
|
|
/* The name of this command, as it is invoked */
|
2007-10-07 17:14:02 +05:30
|
|
|
static char *Prog;
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-12-27 23:06:08 +05:30
|
|
|
/* Indicate if shadow groups are enabled on the system
|
|
|
|
* (/etc/gshadow present) */
|
2008-06-10 00:56:19 +05:30
|
|
|
static bool is_shadowgrp;
|
* src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
of the variables keeping the lock status, to match the shadow
library prefixes.
2008-08-22 07:52:34 +05:30
|
|
|
static bool sgr_locked = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
* src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
of the variables keeping the lock status, to match the shadow
library prefixes.
2008-08-22 07:52:34 +05:30
|
|
|
static bool gr_locked = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-12-27 23:57:57 +05:30
|
|
|
/* Flags set by options */
|
2008-06-10 00:56:19 +05:30
|
|
|
static bool aflg = false;
|
|
|
|
static bool Aflg = false;
|
|
|
|
static bool dflg = false;
|
|
|
|
static bool Mflg = false;
|
|
|
|
static bool rflg = false;
|
|
|
|
static bool Rflg = false;
|
2007-12-27 23:57:57 +05:30
|
|
|
/* The name of the group that is being affected */
|
|
|
|
static char *group = NULL;
|
|
|
|
/* The name of the user being added (-a) or removed (-d) from group */
|
|
|
|
static char *user = NULL;
|
|
|
|
/* The new list of members set with -M */
|
|
|
|
static char *members = NULL;
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
/* The new list of group administrators set with -A */
|
2007-12-28 00:22:40 +05:30
|
|
|
static char *admins = NULL;
|
2007-12-27 23:57:57 +05:30
|
|
|
#endif
|
|
|
|
/* The name of the caller */
|
|
|
|
static char *myname = NULL;
|
2007-12-27 23:06:08 +05:30
|
|
|
/* The UID of the caller */
|
2008-06-10 00:56:19 +05:30
|
|
|
static uid_t bywho;
|
2007-12-27 23:57:57 +05:30
|
|
|
/* Indicate if gpasswd was called by root */
|
|
|
|
#define amroot (0 == bywho)
|
2007-10-07 17:17:01 +05:30
|
|
|
|
2007-12-27 23:06:08 +05:30
|
|
|
/* The number of retries for th user to provide and repeat a new password */
|
2007-10-07 17:14:02 +05:30
|
|
|
#ifndef RETRIES
|
|
|
|
#define RETRIES 3
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* local function prototypes */
|
2007-10-07 17:14:59 +05:30
|
|
|
static void usage (void);
|
2007-12-27 23:06:08 +05:30
|
|
|
static RETSIGTYPE catch_signals (int killed);
|
2008-03-09 02:24:54 +05:30
|
|
|
static void fail_exit (int status);
|
2008-06-10 00:56:19 +05:30
|
|
|
static bool is_valid_user_list (const char *users);
|
2007-12-27 23:57:57 +05:30
|
|
|
static void process_flags (int argc, char **argv);
|
2007-12-28 02:49:57 +05:30
|
|
|
static void check_flags (int argc, int opt_index);
|
2007-12-28 00:22:40 +05:30
|
|
|
static void open_files (void);
|
|
|
|
static void close_files (void);
|
|
|
|
#ifdef SHADOWGRP
|
2007-12-28 02:34:22 +05:30
|
|
|
static void get_group (struct group *gr, struct sgrp *sg);
|
2008-02-27 00:39:10 +05:30
|
|
|
static void check_perms (const struct group *gr, const struct sgrp *sg);
|
2007-12-28 00:22:40 +05:30
|
|
|
static void update_group (struct group *gr, struct sgrp *sg);
|
2007-12-28 02:34:22 +05:30
|
|
|
static void change_passwd (struct group *gr, struct sgrp *sg);
|
2007-12-28 00:22:40 +05:30
|
|
|
#else
|
2007-12-28 02:34:22 +05:30
|
|
|
static void get_group (struct group *gr);
|
2007-12-28 00:38:31 +05:30
|
|
|
static void check_perms (const struct group *gr);
|
2007-12-28 00:22:40 +05:30
|
|
|
static void update_group (struct group *gr);
|
2007-12-28 02:34:22 +05:30
|
|
|
static void change_passwd (struct group *gr);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* usage - display usage message
|
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
static void usage (void)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-10-07 17:15:23 +05:30
|
|
|
fprintf (stderr, _("Usage: %s [-r|-R] group\n"), Prog);
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr, _(" %s [-a user] group\n"), Prog);
|
|
|
|
fprintf (stderr, _(" %s [-d user] group\n"), Prog);
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
|
|
|
_(" %s [-A user,...] [-M user,...] group\n"), Prog);
|
2007-10-07 17:14:02 +05:30
|
|
|
#else
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr, _(" %s [-M user,...] group\n"), Prog);
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2007-10-07 17:16:52 +05:30
|
|
|
exit (E_USAGE);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:17:22 +05:30
|
|
|
* catch_signals - set or reset termio modes.
|
2007-10-07 17:14:02 +05:30
|
|
|
*
|
2007-10-07 17:17:22 +05:30
|
|
|
* catch_signals() is called before processing begins. signal() is then
|
|
|
|
* called with catch_signals() as the signal handler. If signal later
|
|
|
|
* calls catch_signals() with a signal number, the terminal modes are
|
|
|
|
* then reset.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-10-07 17:17:22 +05:30
|
|
|
static RETSIGTYPE catch_signals (int killed)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
|
|
|
static TERMIO sgtty;
|
|
|
|
|
2008-06-10 00:56:19 +05:30
|
|
|
if (0 != killed) {
|
2007-10-07 17:14:59 +05:30
|
|
|
STTY (0, &sgtty);
|
2007-12-28 02:58:50 +05:30
|
|
|
} else {
|
2007-10-07 17:14:59 +05:30
|
|
|
GTTY (0, &sgtty);
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-10 00:56:19 +05:30
|
|
|
if (0 != killed) {
|
|
|
|
(void) putchar ('\n');
|
|
|
|
(void) fflush (stdout);
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (killed);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-09 02:24:54 +05:30
|
|
|
/*
|
|
|
|
* fail_exit - undo as much as possible
|
|
|
|
*/
|
|
|
|
static void fail_exit (int status)
|
|
|
|
{
|
* src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
of the variables keeping the lock status, to match the shadow
library prefixes.
2008-08-22 07:52:34 +05:30
|
|
|
if (gr_locked) {
|
2008-08-06 21:22:42 +05:30
|
|
|
if (gr_unlock () == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
|
* src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
src/vipw.c: Open syslog with the right identification name.
* src/vipw.c: Log unlock errors to syslog.
* src/vipw.c: Log edits to syslog.
* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
to close or unlock are errors. Failure to open files are warnings.
2008-08-22 08:00:33 +05:30
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
|
2008-08-06 21:22:42 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"unlocking group file",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
|
|
|
#endif
|
|
|
|
}
|
2008-03-09 02:24:54 +05:30
|
|
|
}
|
2008-03-18 04:32:23 +05:30
|
|
|
#ifdef SHADOWGRP
|
* src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
of the variables keeping the lock status, to match the shadow
library prefixes.
2008-08-22 07:52:34 +05:30
|
|
|
if (sgr_locked) {
|
2008-08-06 21:22:42 +05:30
|
|
|
if (sgr_unlock () == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
|
* src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
src/vipw.c: Open syslog with the right identification name.
* src/vipw.c: Log unlock errors to syslog.
* src/vipw.c: Log edits to syslog.
* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
to close or unlock are errors. Failure to open files are warnings.
2008-08-22 08:00:33 +05:30
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
|
2008-08-06 21:22:42 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"unlocking gshadow file",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
|
|
|
#endif
|
|
|
|
}
|
2008-03-09 02:24:54 +05:30
|
|
|
}
|
2008-03-18 04:32:23 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
|
|
|
|
exit (status);
|
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2008-06-10 00:56:19 +05:30
|
|
|
* is_valid_user_list - check a comma-separated list of user names for validity
|
2007-10-07 17:14:02 +05:30
|
|
|
*
|
2008-06-10 00:56:19 +05:30
|
|
|
* is_valid_user_list scans a comma-separated list of user names and
|
|
|
|
* checks that each listed name exists is the user database.
|
2007-12-28 03:00:12 +05:30
|
|
|
*
|
2008-06-10 00:56:19 +05:30
|
|
|
* It returns true if the list of users is valid.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-06-10 00:56:19 +05:30
|
|
|
static bool is_valid_user_list (const char *users)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
|
|
|
const char *start, *end;
|
|
|
|
char username[32];
|
2008-08-31 22:58:59 +05:30
|
|
|
bool is_valid = true;
|
2007-11-21 01:30:16 +05:30
|
|
|
size_t len;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-12-28 03:26:45 +05:30
|
|
|
for (start = users; (NULL != start) && ('\0' != *start); start = end) {
|
2007-12-28 03:13:29 +05:30
|
|
|
end = strchr (start, ',');
|
|
|
|
if (NULL != end) {
|
2008-06-14 01:59:58 +05:30
|
|
|
len = (size_t) (end - start);
|
2007-10-07 17:14:02 +05:30
|
|
|
end++;
|
|
|
|
} else {
|
2007-10-07 17:14:59 +05:30
|
|
|
len = strlen (start);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2007-12-28 02:58:50 +05:30
|
|
|
if (len > sizeof (username) - 1) {
|
2007-10-07 17:14:59 +05:30
|
|
|
len = sizeof (username) - 1;
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
strncpy (username, start, len);
|
2007-10-07 17:14:02 +05:30
|
|
|
username[len] = '\0';
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This user must exist.
|
|
|
|
*/
|
|
|
|
|
2007-12-28 03:26:45 +05:30
|
|
|
/* local, no need for xgetpwnam */
|
|
|
|
if (getpwnam (username) == NULL) {
|
2008-08-06 21:22:21 +05:30
|
|
|
fprintf (stderr, _("%s: user '%s' does not exist\n"),
|
2007-12-28 02:58:50 +05:30
|
|
|
Prog, username);
|
2008-08-31 22:58:59 +05:30
|
|
|
is_valid = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
}
|
2008-08-31 22:58:59 +05:30
|
|
|
return is_valid;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:59 +05:30
|
|
|
static void failure (void)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-10-07 17:16:25 +05:30
|
|
|
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:17:01 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-12-27 23:57:57 +05:30
|
|
|
* process_flags - process the command line options and arguments
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-12-27 23:57:57 +05:30
|
|
|
static void process_flags (int argc, char **argv)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-10-07 17:14:59 +05:30
|
|
|
int flag;
|
2008-08-22 07:58:15 +05:30
|
|
|
int option_index = 0;
|
|
|
|
static struct option long_options[] = {
|
|
|
|
{"add", required_argument, NULL, 'a'},
|
|
|
|
{"delete", required_argument, NULL, 'd'},
|
|
|
|
{"remove-password", no_argument, NULL, 'r'},
|
|
|
|
{"restrict", no_argument, NULL, 'R'},
|
|
|
|
{"administrators", required_argument, NULL, 'A'},
|
|
|
|
{"members", required_argument, NULL, 'M'},
|
|
|
|
{NULL, 0, NULL, '\0'}
|
|
|
|
};
|
|
|
|
|
|
|
|
while ((flag = getopt_long (argc, argv, "a:A:d:gM:rR", long_options, &option_index)) != -1) {
|
2007-10-07 17:14:02 +05:30
|
|
|
switch (flag) {
|
|
|
|
case 'a': /* add a user */
|
|
|
|
user = optarg;
|
* lib/prototypes.h, configure.in, libmisc/Makefile.am,
libmisc/xgetXXbyYY.c, libmisc/xgetpwnam.c, libmisc/xgetpwuid.c,
libmisc/xgetgrnam.c, libmisc/xgetgrgid.c, libmisc/xgetspnam.c:
Added functions xgetpwnam(), xgetpwuid(), xgetgrnam(),
xgetgrgid(), and xgetspnam(). They allocate memory for the
returned structure and are more robust to successive calls. They
are implemented with the libc's getxxyyy_r() functions if
available.
* libmisc/limits.c, libmisc/entry.c, libmisc/chowntty.c,
libmisc/addgrps.c, libmisc/myname.c, libmisc/rlogin.c,
libmisc/pwdcheck.c, src/newgrp.c, src/login_nopam.c,
src/userdel.c, src/lastlog.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/chfn.c, src/groupmems.c,
src/usermod.c, src/expiry.c, src/groupdel.c, src/chgpasswd.c,
src/su.c, src/useradd.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/suauth.c,
src/faillog.c, src/groups.c, src/chsh.c, src/id.c: Review all the
usage of one of the getpwnam(), getpwuid(), getgrnam(),
getgrgid(), and getspnam() functions. It was noticed on
http://bugs.debian.org/341230 that chfn and chsh use a passwd
structure after calling a pam function, which result in using
information from the passwd structure requested by pam, not the
original one. It is much easier to use the new xget... functions
to avoid these issues. I've checked which call to the original
get... functions could be left (reducing the scope of the
structure if possible), and I've left comments to ease future
reviews (e.g. /* local, no need for xgetpwnam */).
Note: the getpwent/getgrent calls should probably be checked also.
* src/groupdel.c, src/expiry.c: Fix typos in comments.
* src/groupmod.c: Re-indent.
* libmisc/Makefile.am, lib/groupmem.c, lib/groupio.c, lib/pwmem.c,
lib/pwio.c, lib/shadowmem.c, lib/shadowio.c: Move the __<xx>_dup
functions (used by the xget... functions) from the <xx>io.c files
to the new <xx>mem.c files. This avoid linking some utils against
the SELinux library.
2007-11-19 04:45:26 +05:30
|
|
|
/* local, no need for xgetpwnam */
|
2007-12-28 03:26:45 +05:30
|
|
|
if (getpwnam (user) == NULL) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2008-08-06 21:22:21 +05:30
|
|
|
_("%s: user '%s' does not exist\n"), Prog,
|
|
|
|
user);
|
2007-10-07 17:17:01 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"adding to group",
|
|
|
|
user, AUDIT_NO_ID, 0);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2008-06-10 00:56:19 +05:30
|
|
|
aflg = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
break;
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
case 'A':
|
2007-10-07 17:17:01 +05:30
|
|
|
if (!amroot) {
|
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"Listing administrators",
|
|
|
|
NULL, (unsigned int) bywho, 0);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
failure ();
|
2007-10-07 17:17:01 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
if (!is_shadowgrp) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2008-08-06 21:22:21 +05:30
|
|
|
_("%s: shadow group passwords required for -A\n"),
|
2007-10-07 17:14:59 +05:30
|
|
|
Prog);
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (2);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
admins = optarg;
|
2008-06-10 00:56:19 +05:30
|
|
|
if (!is_valid_user_list (admins)) {
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2008-06-10 00:56:19 +05:30
|
|
|
Aflg = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 'd': /* delete a user */
|
2008-06-10 00:56:19 +05:30
|
|
|
dflg = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
user = optarg;
|
|
|
|
break;
|
|
|
|
case 'g': /* no-op from normal password */
|
|
|
|
break;
|
|
|
|
case 'M':
|
2007-10-07 17:17:01 +05:30
|
|
|
if (!amroot) {
|
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"listing members",
|
|
|
|
NULL, (unsigned int) bywho, 0);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
failure ();
|
2007-10-07 17:17:01 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
members = optarg;
|
2008-06-10 00:56:19 +05:30
|
|
|
if (!is_valid_user_list (members)) {
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2008-06-10 00:56:19 +05:30
|
|
|
Mflg = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
break;
|
|
|
|
case 'r': /* remove group password */
|
2008-06-10 00:56:19 +05:30
|
|
|
rflg = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
break;
|
|
|
|
case 'R': /* restrict group password */
|
2008-06-10 00:56:19 +05:30
|
|
|
Rflg = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
break;
|
|
|
|
default:
|
2007-10-07 17:14:59 +05:30
|
|
|
usage ();
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
}
|
2007-12-28 02:49:57 +05:30
|
|
|
|
|
|
|
/* Get the name of the group that is being affected. */
|
|
|
|
group = argv[optind];
|
|
|
|
|
|
|
|
check_flags (argc, optind);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* check_flags - check the validity of options
|
|
|
|
*/
|
|
|
|
static void check_flags (int argc, int opt_index)
|
|
|
|
{
|
2008-06-10 00:56:19 +05:30
|
|
|
int exclusive = 0;
|
2007-12-28 02:49:57 +05:30
|
|
|
/*
|
|
|
|
* Make sure exclusive flags are exclusive
|
|
|
|
*/
|
2008-06-10 00:56:19 +05:30
|
|
|
if (aflg) {
|
|
|
|
exclusive++;
|
|
|
|
}
|
|
|
|
if (dflg) {
|
|
|
|
exclusive++;
|
|
|
|
}
|
|
|
|
if (rflg) {
|
|
|
|
exclusive++;
|
|
|
|
}
|
|
|
|
if (Rflg) {
|
|
|
|
exclusive++;
|
|
|
|
}
|
|
|
|
if (Aflg || Mflg) {
|
|
|
|
exclusive++;
|
|
|
|
}
|
|
|
|
if (exclusive > 1) {
|
2007-12-28 02:49:57 +05:30
|
|
|
usage ();
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2007-12-28 02:49:57 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure one (and only one) group was provided
|
|
|
|
*/
|
|
|
|
if ((argc != (opt_index+1)) || (NULL == group)) {
|
|
|
|
usage ();
|
|
|
|
}
|
2007-12-27 23:57:57 +05:30
|
|
|
}
|
|
|
|
|
2007-12-28 00:22:40 +05:30
|
|
|
/*
|
|
|
|
* open_files - lock and open the group databases
|
|
|
|
*
|
|
|
|
* It will call exit in case of error.
|
|
|
|
*/
|
|
|
|
static void open_files (void)
|
|
|
|
{
|
|
|
|
if (gr_lock () == 0) {
|
* src/chage.c, src/chgpasswd.c, src/chpasswd.c, src/chsh.c,
src/gpasswd.c, src/groupadd.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c: In
case of a lock failure, indicate to the user that she can try
again later. Do not log to syslog.
2008-08-22 07:50:53 +05:30
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: cannot lock %s; try again later.\n"),
|
|
|
|
Prog, gr_dbname ());
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"locking /etc/group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
* src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
of the variables keeping the lock status, to match the shadow
library prefixes.
2008-08-22 07:52:34 +05:30
|
|
|
gr_locked = true;
|
2007-12-28 03:13:29 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-03-09 02:24:54 +05:30
|
|
|
if (is_shadowgrp) {
|
|
|
|
if (sgr_lock () == 0) {
|
|
|
|
fprintf (stderr,
|
* src/chage.c, src/chgpasswd.c, src/chpasswd.c, src/chsh.c,
src/gpasswd.c, src/groupadd.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c: In
case of a lock failure, indicate to the user that she can try
again later. Do not log to syslog.
2008-08-22 07:50:53 +05:30
|
|
|
_("%s: cannot lock %s; try again later.\n"),
|
|
|
|
Prog, sgr_dbname ());
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-03-09 02:24:54 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"locking /etc/gshadow",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
|
|
|
}
|
* src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
of the variables keeping the lock status, to match the shadow
library prefixes.
2008-08-22 07:52:34 +05:30
|
|
|
sgr_locked = true;
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (gr_open (O_RDWR) == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
|
|
|
SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ()));
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"opening /etc/group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
2007-12-28 03:13:29 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-12-28 00:22:40 +05:30
|
|
|
if (is_shadowgrp && (sgr_open (O_RDWR) == 0)) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ());
|
|
|
|
SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ()));
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"opening /etc/gshadow",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* close_files - close and unlock the group databases
|
|
|
|
*
|
|
|
|
* This cause any changes in the databases to be committed.
|
|
|
|
*
|
|
|
|
* It will call exit in case of error.
|
|
|
|
*/
|
|
|
|
static void close_files (void)
|
|
|
|
{
|
|
|
|
if (gr_close () == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ());
|
* src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
src/vipw.c: Open syslog with the right identification name.
* src/vipw.c: Log unlock errors to syslog.
* src/vipw.c: Log edits to syslog.
* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
to close or unlock are errors. Failure to open files are warnings.
2008-08-22 08:00:33 +05:30
|
|
|
SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ()));
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"rewriting /etc/group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
2007-12-28 03:13:29 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-08-06 21:25:57 +05:30
|
|
|
if (is_shadowgrp) {
|
|
|
|
if (sgr_close () == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ());
|
* src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
src/vipw.c: Open syslog with the right identification name.
* src/vipw.c: Log unlock errors to syslog.
* src/vipw.c: Log edits to syslog.
* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
to close or unlock are errors. Failure to open files are warnings.
2008-08-22 08:00:33 +05:30
|
|
|
SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ()));
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-08-06 21:25:57 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"rewriting /etc/gshadow",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-08-06 21:25:57 +05:30
|
|
|
fail_exit (1);
|
|
|
|
}
|
2008-08-06 21:22:42 +05:30
|
|
|
if (sgr_unlock () == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
|
* src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
src/vipw.c: Open syslog with the right identification name.
* src/vipw.c: Log unlock errors to syslog.
* src/vipw.c: Log edits to syslog.
* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
to close or unlock are errors. Failure to open files are warnings.
2008-08-22 08:00:33 +05:30
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
|
2008-08-06 21:22:42 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"unlocking gshadow file",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
|
|
|
#endif
|
2008-08-06 21:25:57 +05:30
|
|
|
/* continue */
|
2008-08-06 21:22:42 +05:30
|
|
|
}
|
* src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
of the variables keeping the lock status, to match the shadow
library prefixes.
2008-08-22 07:52:34 +05:30
|
|
|
sgr_locked = false;
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (gr_unlock () == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
|
* src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
src/vipw.c: Open syslog with the right identification name.
* src/vipw.c: Log unlock errors to syslog.
* src/vipw.c: Log edits to syslog.
* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
to close or unlock are errors. Failure to open files are warnings.
2008-08-22 08:00:33 +05:30
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"unlocking group file",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-08-06 21:25:57 +05:30
|
|
|
/* continue */
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
* src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
of the variables keeping the lock status, to match the shadow
library prefixes.
2008-08-22 07:52:34 +05:30
|
|
|
gr_locked = false;
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
|
|
|
|
2007-12-28 00:38:31 +05:30
|
|
|
/*
|
|
|
|
* check_perms - check if the user is allowed to change the password of
|
|
|
|
* the specified group.
|
|
|
|
*
|
|
|
|
* It only returns if the user is allowed.
|
|
|
|
*/
|
|
|
|
#ifdef SHADOWGRP
|
2008-02-27 00:39:10 +05:30
|
|
|
static void check_perms (const struct group *gr, const struct sgrp *sg)
|
2007-12-28 00:38:31 +05:30
|
|
|
#else
|
|
|
|
static void check_perms (const struct group *gr)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
#ifdef SHADOWGRP
|
2008-02-27 00:39:10 +05:30
|
|
|
if (is_shadowgrp) {
|
2008-02-27 00:47:20 +05:30
|
|
|
/*
|
|
|
|
* The policy here for changing a group is that
|
|
|
|
* 1) you must be root or
|
|
|
|
* 2) you must be listed as an administrative member.
|
|
|
|
* Administrative members can do anything to a group that
|
|
|
|
* the root user can.
|
|
|
|
*/
|
|
|
|
if (!amroot && !is_on_list (sg->sg_adm, myname)) {
|
2007-12-28 00:38:31 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-02-27 00:47:20 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"modify group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:38:31 +05:30
|
|
|
#endif
|
2008-02-27 00:47:20 +05:30
|
|
|
failure ();
|
|
|
|
}
|
2008-02-27 00:39:10 +05:30
|
|
|
} else
|
|
|
|
#endif /* ! SHADOWGRP */
|
|
|
|
{
|
2007-12-28 00:38:31 +05:30
|
|
|
#ifdef FIRST_MEMBER_IS_ADMIN
|
2008-02-27 00:47:20 +05:30
|
|
|
/*
|
|
|
|
* The policy here for changing a group is that
|
|
|
|
* 1) you must be root or
|
|
|
|
* 2) you must be the first listed member of the group.
|
|
|
|
* The first listed member of a group can do anything to
|
|
|
|
* that group that the root user can. The rationale for
|
|
|
|
* this hack is that the FIRST user is probably the most
|
|
|
|
* important user in this entire group.
|
|
|
|
*
|
|
|
|
* This feature enabled by default could be a security
|
|
|
|
* problem when installed on existing systems where the
|
|
|
|
* first group member might be just a normal user.
|
|
|
|
* --marekm
|
|
|
|
*/
|
|
|
|
if (!amroot) {
|
|
|
|
if (gr->gr_mem[0] == (char *) 0) {
|
2007-12-28 00:38:31 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-02-27 00:47:20 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"modifying group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:38:31 +05:30
|
|
|
#endif
|
2008-02-27 00:47:20 +05:30
|
|
|
failure ();
|
|
|
|
}
|
2007-12-28 00:38:31 +05:30
|
|
|
|
2008-02-27 00:47:20 +05:30
|
|
|
if (strcmp (gr->gr_mem[0], myname) != 0) {
|
2007-12-28 00:38:31 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-02-27 00:47:20 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"modifying group",
|
|
|
|
myname, AUDIT_NO_ID, 0);
|
2007-12-28 00:38:31 +05:30
|
|
|
#endif
|
2008-02-27 00:47:20 +05:30
|
|
|
failure ();
|
|
|
|
}
|
2007-12-28 00:38:31 +05:30
|
|
|
}
|
2008-02-27 00:29:28 +05:30
|
|
|
#else /* ! FIRST_MEMBER_IS_ADMIN */
|
2008-02-27 00:47:20 +05:30
|
|
|
if (!amroot) {
|
2007-12-28 00:38:31 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-02-27 00:47:20 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"modifying group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:38:31 +05:30
|
|
|
#endif
|
2008-02-27 00:47:20 +05:30
|
|
|
failure ();
|
|
|
|
}
|
2007-12-28 00:38:31 +05:30
|
|
|
#endif
|
2008-02-27 00:39:10 +05:30
|
|
|
}
|
2007-12-28 00:38:31 +05:30
|
|
|
}
|
|
|
|
|
2007-12-28 02:34:22 +05:30
|
|
|
/*
|
|
|
|
* update_group - Update the group information in the databases
|
|
|
|
*/
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
|
|
|
static void update_group (struct group *gr, struct sgrp *sg)
|
|
|
|
#else
|
|
|
|
static void update_group (struct group *gr)
|
|
|
|
#endif
|
|
|
|
{
|
2007-12-28 03:26:45 +05:30
|
|
|
if (gr_update (gr) == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr,
|
2008-08-30 23:58:24 +05:30
|
|
|
_("%s: failed to prepare the new %s entry '%s'\n"),
|
|
|
|
Prog, gr_dbname (), gr->gr_name);
|
|
|
|
SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), gr->gr_name));
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"updating /etc/group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
|
|
|
#ifdef SHADOWGRP
|
2007-12-28 03:26:45 +05:30
|
|
|
if (is_shadowgrp && (sgr_update (sg) == 0)) {
|
* src/groupmems.c: Check the return value of gr_update().
* src/chage.c, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/passwd.c, src/pwck.c, src/pwconv.c, src/pwunconv.c,
src/useradd.c, src/userdel.c, src/usermod.c: Harmonize the error
message sent to stderr in case of *_update () failure.
* src/chage.c, src/chsh.c, src/groupadd.c, src/passwd.c: Do not
log to syslog when pw_update() or spw_update() fail.
* src/newusers.c: Do not log specific error message to stderr when
sgr_update() fails.
* src/pwconv.c: Remove duplicated definition of Prog.
2008-08-30 23:57:34 +05:30
|
|
|
fprintf (stderr,
|
2008-08-30 23:58:24 +05:30
|
|
|
_("%s: failed to prepare the new %s entry '%s'\n"),
|
|
|
|
Prog, sgr_dbname (), sg->sg_name);
|
|
|
|
SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", sgr_dbname (), sg->sg_name));
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"updating /etc/gshadow",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 00:22:40 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 00:22:40 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2007-12-28 02:34:22 +05:30
|
|
|
/*
|
|
|
|
* get_group - get the current information for the group
|
|
|
|
*
|
|
|
|
* The information are copied in group structure(s) so that they can be
|
|
|
|
* modified later.
|
2008-02-27 00:39:10 +05:30
|
|
|
*
|
|
|
|
* Note: If !is_shadowgrp, *sg will not be initialized.
|
2007-12-28 02:34:22 +05:30
|
|
|
*/
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
static void get_group (struct group *gr, struct sgrp *sg)
|
|
|
|
#else
|
|
|
|
static void get_group (struct group *gr)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
struct group const*tmpgr = NULL;
|
2008-08-22 07:58:15 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-12-28 02:34:22 +05:30
|
|
|
struct sgrp const*tmpsg = NULL;
|
2008-08-22 07:58:15 +05:30
|
|
|
#endif
|
2007-12-28 02:34:22 +05:30
|
|
|
|
2007-12-28 03:26:45 +05:30
|
|
|
if (gr_open (O_RDONLY) == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
|
|
|
SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ()));
|
2007-12-28 02:34:22 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"opening /etc/group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 02:34:22 +05:30
|
|
|
}
|
|
|
|
|
2007-12-28 03:13:29 +05:30
|
|
|
tmpgr = gr_locate (group);
|
|
|
|
if (NULL == tmpgr) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: group '%s' does not exist in %s\n"), Prog, group, gr_dbname ());
|
2007-12-28 02:34:22 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"group lookup",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
|
|
|
failure ();
|
|
|
|
}
|
|
|
|
|
|
|
|
*gr = *tmpgr;
|
|
|
|
gr->gr_name = xstrdup (tmpgr->gr_name);
|
|
|
|
gr->gr_passwd = xstrdup (tmpgr->gr_passwd);
|
|
|
|
gr->gr_mem = dup_list (tmpgr->gr_mem);
|
|
|
|
|
2007-12-28 03:26:45 +05:30
|
|
|
if (gr_close () == 0) {
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, gr_dbname ());
|
* src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
src/vipw.c: Open syslog with the right identification name.
* src/vipw.c: Log unlock errors to syslog.
* src/vipw.c: Log edits to syslog.
* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
to close or unlock are errors. Failure to open files are warnings.
2008-08-22 08:00:33 +05:30
|
|
|
SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ()));
|
2007-12-28 02:34:22 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"closing /etc/group",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 02:34:22 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SHADOWGRP
|
2008-02-27 00:39:10 +05:30
|
|
|
if (is_shadowgrp) {
|
2008-02-27 00:47:20 +05:30
|
|
|
if (sgr_open (O_RDONLY) == 0) {
|
|
|
|
fprintf (stderr,
|
2008-08-22 08:01:15 +05:30
|
|
|
_("%s: cannot open %s\n"), Prog, sgr_dbname ());
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ()));
|
2007-12-28 02:34:22 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-02-27 00:47:20 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"opening /etc/gshadow",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2008-02-27 00:47:20 +05:30
|
|
|
}
|
|
|
|
tmpsg = sgr_locate (group);
|
|
|
|
if (NULL != tmpsg) {
|
|
|
|
*sg = *tmpsg;
|
|
|
|
sg->sg_name = xstrdup (tmpsg->sg_name);
|
|
|
|
sg->sg_passwd = xstrdup (tmpsg->sg_passwd);
|
|
|
|
|
|
|
|
sg->sg_mem = dup_list (tmpsg->sg_mem);
|
|
|
|
sg->sg_adm = dup_list (tmpsg->sg_adm);
|
|
|
|
} else {
|
|
|
|
sg->sg_name = xstrdup (group);
|
|
|
|
sg->sg_passwd = gr->gr_passwd;
|
2008-02-27 01:39:56 +05:30
|
|
|
gr->gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
|
2007-12-28 02:34:22 +05:30
|
|
|
|
2008-02-27 00:47:20 +05:30
|
|
|
sg->sg_mem = dup_list (gr->gr_mem);
|
2007-12-28 02:34:22 +05:30
|
|
|
|
2008-02-27 00:47:20 +05:30
|
|
|
sg->sg_adm = (char **) xmalloc (sizeof (char *) * 2);
|
2007-12-28 02:34:22 +05:30
|
|
|
#ifdef FIRST_MEMBER_IS_ADMIN
|
2008-02-27 00:47:20 +05:30
|
|
|
if (sg->sg_mem[0]) {
|
|
|
|
sg->sg_adm[0] = xstrdup (sg->sg_mem[0]);
|
|
|
|
sg->sg_adm[1] = NULL;
|
|
|
|
} else
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
2008-02-27 00:47:20 +05:30
|
|
|
{
|
|
|
|
sg->sg_adm[0] = NULL;
|
|
|
|
}
|
2007-12-28 02:34:22 +05:30
|
|
|
|
2008-02-27 00:47:20 +05:30
|
|
|
}
|
|
|
|
if (sgr_close () == 0) {
|
|
|
|
fprintf (stderr,
|
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
Added *_dbname() functions to retrieve the name of the databases.
* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
*_name() functions renamed *setname().
* src/grpck.c, src/pwck.c: Likewise.
* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
the name of the arguments to the prototypes.
* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
Harmonize the erro & syslog messages in case of failure of the
*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
capitalized messages.
* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
in case of inexistent entries.
* src/usermod.c: Harmonize messages in case of already existing
entries.
* src/newusers.c, src/useradd.c: Simplify PAM error handling.
* src/useradd.c: Report failures to unlock files (stderr, syslog,
and audit). But do not fail (continue).
* src/useradd.c (open_files): Do not report to syslog & audit
failures to lock or open the databases. This might be harmless,
and the logs were not already informed that a change was
requested.
* src/usermod.c: It's not the account which is unlocked, but its
password.
2008-08-06 21:27:31 +05:30
|
|
|
_("%s: failure while writing changes to %s\n"), Prog, sgr_dbname ());
|
* src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
src/vipw.c: Open syslog with the right identification name.
* src/vipw.c: Log unlock errors to syslog.
* src/vipw.c: Log edits to syslog.
* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
to close or unlock are errors. Failure to open files are warnings.
2008-08-22 08:00:33 +05:30
|
|
|
SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ()));
|
2007-12-28 02:34:22 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-02-27 00:47:20 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"closing /etc/gshadow",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2008-02-27 00:47:20 +05:30
|
|
|
}
|
2008-02-27 00:39:10 +05:30
|
|
|
}
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif /* SHADOWGRP */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* change_passwd - change the group's password
|
|
|
|
*
|
|
|
|
* Get the new password from the user and update the password in the
|
|
|
|
* group's structure.
|
|
|
|
*
|
|
|
|
* It will call exit in case of error.
|
|
|
|
*/
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
static void change_passwd (struct group *gr, struct sgrp *sg)
|
|
|
|
#else
|
|
|
|
static void change_passwd (struct group *gr)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
char *cp;
|
|
|
|
static char pass[BUFSIZ];
|
|
|
|
int retries;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* A new password is to be entered and it must be encrypted, etc.
|
|
|
|
* The password will be prompted for twice, and both entries must be
|
|
|
|
* identical. There is no need to validate the old password since
|
|
|
|
* the invoker is either the group owner, or root.
|
|
|
|
*/
|
|
|
|
printf (_("Changing the password for group %s\n"), group);
|
|
|
|
|
|
|
|
for (retries = 0; retries < RETRIES; retries++) {
|
2007-12-28 03:13:29 +05:30
|
|
|
cp = getpass (_("New Password: "));
|
|
|
|
if (NULL == cp) {
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2007-12-28 02:34:22 +05:30
|
|
|
|
|
|
|
STRFCPY (pass, cp);
|
|
|
|
strzero (cp);
|
2007-12-28 03:13:29 +05:30
|
|
|
cp = getpass (_("Re-enter new password: "));
|
|
|
|
if (NULL == cp) {
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2007-12-28 02:34:22 +05:30
|
|
|
|
|
|
|
if (strcmp (pass, cp) == 0) {
|
|
|
|
strzero (cp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
strzero (cp);
|
|
|
|
memzero (pass, sizeof pass);
|
|
|
|
|
|
|
|
if (retries + 1 < RETRIES) {
|
|
|
|
puts (_("They don't match; try again"));
|
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"changing password",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (retries == RETRIES) {
|
|
|
|
fprintf (stderr, _("%s: Try again later\n"), Prog);
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-12-28 02:34:22 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL));
|
|
|
|
memzero (pass, sizeof pass);
|
|
|
|
#ifdef SHADOWGRP
|
2007-12-28 02:58:50 +05:30
|
|
|
if (is_shadowgrp) {
|
2007-12-28 02:34:22 +05:30
|
|
|
sg->sg_passwd = cp;
|
2007-12-28 02:58:50 +05:30
|
|
|
} else
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
2007-12-28 02:58:50 +05:30
|
|
|
{
|
2007-12-28 02:34:22 +05:30
|
|
|
gr->gr_passwd = cp;
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2007-12-28 02:34:22 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"changing password",
|
|
|
|
group, AUDIT_NO_ID, 1);
|
2007-12-28 02:34:22 +05:30
|
|
|
#endif
|
|
|
|
SYSLOG ((LOG_INFO, "change the password for group %s by %s", group,
|
|
|
|
myname));
|
|
|
|
}
|
|
|
|
|
2007-12-27 23:57:57 +05:30
|
|
|
/*
|
|
|
|
* gpasswd - administer the /etc/group file
|
|
|
|
*
|
|
|
|
* -a user add user to the named group
|
|
|
|
* -d user remove user from the named group
|
|
|
|
* -r remove password from the named group
|
|
|
|
* -R restrict access to the named group
|
|
|
|
* -A user,... make list of users the administrative users
|
|
|
|
* -M user,... make list of users the group members
|
|
|
|
*/
|
|
|
|
int main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct group grent;
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-12-27 23:57:57 +05:30
|
|
|
struct sgrp sgent;
|
|
|
|
#endif
|
|
|
|
struct passwd *pw = NULL;
|
|
|
|
|
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_help_open ();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
sanitize_env ();
|
2008-06-10 00:56:19 +05:30
|
|
|
(void) setlocale (LC_ALL, "");
|
|
|
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
|
|
|
(void) textdomain (PACKAGE);
|
2007-12-27 23:57:57 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Make a note of whether or not this command was invoked by root.
|
|
|
|
* This will be used to bypass certain checks later on. Also, set
|
|
|
|
* the real user ID to match the effective user ID. This will
|
|
|
|
* prevent the invoker from issuing signals which would interfer
|
|
|
|
* with this command.
|
|
|
|
*/
|
|
|
|
bywho = getuid ();
|
|
|
|
Prog = Basename (argv[0]);
|
|
|
|
|
|
|
|
OPENLOG ("gpasswd");
|
|
|
|
setbuf (stdout, NULL);
|
|
|
|
setbuf (stderr, NULL);
|
|
|
|
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
is_shadowgrp = sgr_file_present ();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Parse the options */
|
|
|
|
process_flags (argc, argv);
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Determine the name of the user that invoked this command. This
|
|
|
|
* is really hit or miss because there are so many ways that command
|
|
|
|
* can be executed and so many ways to trip up the routines that
|
|
|
|
* report the user name.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
|
2007-10-07 17:14:59 +05:30
|
|
|
pw = get_my_pwent ();
|
2007-12-28 03:26:45 +05:30
|
|
|
if (NULL == pw) {
|
2008-08-30 23:57:07 +05:30
|
|
|
fprintf (stderr, _("%s: Cannot determine your user name.\n"),
|
|
|
|
Prog);
|
2007-10-07 17:17:01 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-06-14 01:59:58 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"user lookup",
|
|
|
|
NULL, (unsigned int) bywho, 0);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2008-08-30 23:57:07 +05:30
|
|
|
SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
|
|
|
|
(unsigned long) getuid ()));
|
2007-10-07 17:17:01 +05:30
|
|
|
failure ();
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
myname = xstrdup (pw->pw_name);
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-12-28 02:34:22 +05:30
|
|
|
/*
|
|
|
|
* Replicate the group so it can be modified later on.
|
|
|
|
*/
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-12-28 02:34:22 +05:30
|
|
|
get_group (&grent, &sgent);
|
|
|
|
#else
|
|
|
|
get_group (&grent);
|
2007-11-23 03:25:12 +05:30
|
|
|
#endif
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-12-28 00:38:31 +05:30
|
|
|
* Check if the user is allowed to change the password of this group.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-12-28 00:38:31 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-02-27 00:39:10 +05:30
|
|
|
check_perms (&grent, &sgent);
|
2007-10-07 17:14:02 +05:30
|
|
|
#else
|
2007-12-28 00:38:31 +05:30
|
|
|
check_perms (&grent);
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Removing a password is straight forward. Just set the password
|
|
|
|
* field to a "".
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
if (rflg) {
|
2007-10-07 17:14:59 +05:30
|
|
|
grent.gr_passwd = ""; /* XXX warning: const */
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-10-07 17:14:59 +05:30
|
|
|
sgent.sg_passwd = ""; /* XXX warning: const */
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"deleting group password",
|
|
|
|
group, AUDIT_NO_ID, 1);
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
SYSLOG ((LOG_INFO, "remove password from group %s by %s",
|
2008-02-27 00:47:20 +05:30
|
|
|
group, myname));
|
2007-10-07 17:14:02 +05:30
|
|
|
goto output;
|
|
|
|
} else if (Rflg) {
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Same thing for restricting the group. Set the password
|
2007-10-07 17:14:02 +05:30
|
|
|
* field to "!".
|
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
grent.gr_passwd = "!"; /* XXX warning: const */
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-10-07 17:14:59 +05:30
|
|
|
sgent.sg_passwd = "!"; /* XXX warning: const */
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"restrict access to group",
|
|
|
|
group, AUDIT_NO_ID, 1);
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
SYSLOG ((LOG_INFO, "restrict access to group %s by %s",
|
|
|
|
group, myname));
|
2007-10-07 17:14:02 +05:30
|
|
|
goto output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Adding a member to a member list is pretty straightforward as
|
|
|
|
* well. Call the appropriate routine and split.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
if (aflg) {
|
2007-10-07 17:14:59 +05:30
|
|
|
printf (_("Adding user %s to group %s\n"), user, group);
|
2007-10-07 17:14:02 +05:30
|
|
|
grent.gr_mem = add_list (grent.gr_mem, user);
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-02-27 00:39:10 +05:30
|
|
|
if (is_shadowgrp) {
|
2008-02-27 00:47:20 +05:30
|
|
|
sgent.sg_mem = add_list (sgent.sg_mem, user);
|
2008-02-27 00:39:10 +05:30
|
|
|
}
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
|
|
|
#ifdef WITH_AUDIT
|
2008-06-14 01:59:58 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"adding group member",
|
|
|
|
user, AUDIT_NO_ID, 1);
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
SYSLOG ((LOG_INFO, "add member %s to group %s by %s", user,
|
2008-02-27 00:47:20 +05:30
|
|
|
group, myname));
|
2007-10-07 17:14:02 +05:30
|
|
|
goto output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Removing a member from the member list is the same deal as adding
|
|
|
|
* one, except the routine is different.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
if (dflg) {
|
2008-06-10 00:56:19 +05:30
|
|
|
bool removed = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:16:07 +05:30
|
|
|
printf (_("Removing user %s from group %s\n"), user, group);
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:14:59 +05:30
|
|
|
if (is_on_list (grent.gr_mem, user)) {
|
2008-06-10 00:56:19 +05:30
|
|
|
removed = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
grent.gr_mem = del_list (grent.gr_mem, user);
|
|
|
|
}
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-02-27 00:39:10 +05:30
|
|
|
if (is_shadowgrp) {
|
2008-02-27 00:47:20 +05:30
|
|
|
if (is_on_list (sgent.sg_mem, user)) {
|
2008-06-10 00:56:19 +05:30
|
|
|
removed = true;
|
2008-02-27 00:47:20 +05:30
|
|
|
sgent.sg_mem = del_list (sgent.sg_mem, user);
|
|
|
|
}
|
2008-02-27 00:39:10 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
if (!removed) {
|
2008-08-06 21:22:21 +05:30
|
|
|
fprintf (stderr, _("%s: user '%s' is not a member of '%s'\n"),
|
|
|
|
Prog, user, group);
|
2007-10-07 17:17:01 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"deleting member",
|
|
|
|
user, AUDIT_NO_ID, 0);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2007-10-07 17:17:01 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-06-14 01:59:58 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"deleting member",
|
|
|
|
user, AUDIT_NO_ID, 1);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
SYSLOG ((LOG_INFO, "remove member %s from group %s by %s",
|
2008-02-27 00:47:20 +05:30
|
|
|
user, group, myname));
|
2007-10-07 17:14:02 +05:30
|
|
|
goto output;
|
|
|
|
}
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2008-06-14 01:59:58 +05:30
|
|
|
* Replacing the entire list of administrators is simple. Check the
|
2007-10-07 17:14:59 +05:30
|
|
|
* list to make sure everyone is a real user. Then slap the new list
|
|
|
|
* in place.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
if (Aflg) {
|
2007-10-07 17:17:01 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-06-14 01:59:58 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"setting group admin",
|
|
|
|
group, AUDIT_NO_ID, 1);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
SYSLOG ((LOG_INFO, "set administrators of %s to %s",
|
2008-02-27 00:47:20 +05:30
|
|
|
group, admins));
|
2007-10-07 17:14:59 +05:30
|
|
|
sgent.sg_adm = comma_to_list (admins);
|
2007-12-28 02:58:50 +05:30
|
|
|
if (!Mflg) {
|
2007-10-07 17:14:02 +05:30
|
|
|
goto output;
|
2007-12-28 02:58:50 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Replacing the entire list of members is simple. Check the list to
|
|
|
|
* make sure everyone is a real user. Then slap the new list in
|
|
|
|
* place.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
if (Mflg) {
|
2007-10-07 17:17:01 +05:30
|
|
|
#ifdef WITH_AUDIT
|
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
2008-06-14 01:59:58 +05:30
|
|
|
"setting group members",
|
|
|
|
group, AUDIT_NO_ID, 1);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2007-10-07 17:16:07 +05:30
|
|
|
SYSLOG ((LOG_INFO, "set members of %s to %s", group, members));
|
2007-10-07 17:14:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-10-07 17:14:59 +05:30
|
|
|
sgent.sg_mem = comma_to_list (members);
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
grent.gr_mem = comma_to_list (members);
|
2007-10-07 17:14:02 +05:30
|
|
|
goto output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* If the password is being changed, the input and output must both
|
|
|
|
* be a tty. The typical keyboard signals are caught so the termio
|
|
|
|
* modes can be restored.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-12-28 03:26:45 +05:30
|
|
|
if ((isatty (0) == 0) || (isatty (1) == 0)) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr, _("%s: Not a tty\n"), Prog);
|
2007-10-07 17:17:01 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-06-14 01:59:58 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"changing password",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2007-10-07 17:17:22 +05:30
|
|
|
catch_signals (0); /* save tty modes */
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-14 01:59:58 +05:30
|
|
|
(void) signal (SIGHUP, catch_signals);
|
|
|
|
(void) signal (SIGINT, catch_signals);
|
|
|
|
(void) signal (SIGQUIT, catch_signals);
|
|
|
|
(void) signal (SIGTERM, catch_signals);
|
2007-12-28 00:22:40 +05:30
|
|
|
#ifdef SIGTSTP
|
2008-06-14 01:59:58 +05:30
|
|
|
(void) signal (SIGTSTP, catch_signals);
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
|
|
|
|
2007-12-28 02:34:22 +05:30
|
|
|
/* Prompt for the new password */
|
2007-10-07 17:14:14 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-12-28 02:34:22 +05:30
|
|
|
change_passwd (&grent, &sgent);
|
|
|
|
#else
|
|
|
|
change_passwd (&grent);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* This is the common arrival point to output the new group file.
|
|
|
|
* The freshly crafted entry is in allocated space. The group file
|
|
|
|
* will be locked and opened for writing. The new entry will be
|
|
|
|
* output, etc.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
output:
|
2007-12-28 03:26:45 +05:30
|
|
|
if (setuid (0) != 0) {
|
2008-01-25 00:09:05 +05:30
|
|
|
fputs (_("Cannot change ID to root.\n"), stderr);
|
2007-10-07 17:14:59 +05:30
|
|
|
SYSLOG ((LOG_ERR, "can't setuid(0)"));
|
2007-10-07 17:17:01 +05:30
|
|
|
#ifdef WITH_AUDIT
|
2008-06-14 01:59:58 +05:30
|
|
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
|
"changing id to root",
|
|
|
|
group, AUDIT_NO_ID, 0);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
closelog ();
|
2008-03-09 02:24:54 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
pwd_init ();
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-12-28 00:22:40 +05:30
|
|
|
open_files ();
|
|
|
|
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
update_group (&grent, &sgent);
|
|
|
|
#else
|
|
|
|
update_group (&grent);
|
2007-10-07 17:17:01 +05:30
|
|
|
#endif
|
2007-12-28 00:22:40 +05:30
|
|
|
|
|
|
|
close_files ();
|
2007-10-07 17:16:52 +05:30
|
|
|
|
|
|
|
nscd_flush_cache ("group");
|
|
|
|
|
|
|
|
exit (E_SUCCESS);
|
2007-10-07 17:15:23 +05:30
|
|
|
}
|
2008-06-14 01:59:58 +05:30
|
|
|
|