2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2008-04-27 06:10:09 +05:30
|
|
|
* Copyright (c) 1992 - 1994, Julianne Frances Haugh
|
|
|
|
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
|
|
|
* Copyright (c) 2001 , Michał Moskal
|
|
|
|
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
|
2011-07-23 03:37:23 +05:30
|
|
|
* Copyright (c) 2007 - 2011, 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>
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <grp.h>
|
|
|
|
#include <pwd.h>
|
2007-10-07 17:17:01 +05:30
|
|
|
#include <stdio.h>
|
2011-11-07 00:09:36 +05:30
|
|
|
#include <getopt.h>
|
2007-10-07 17:17:01 +05:30
|
|
|
#include "chkname.h"
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "commonio.h"
|
2007-10-07 17:17:01 +05:30
|
|
|
#include "defines.h"
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "groupio.h"
|
2007-10-07 17:17:22 +05:30
|
|
|
#include "nscd.h"
|
Flush sssd caches in addition to nscd caches
Some distributions, notably Fedora, have the following order of nsswitch
modules by default:
passwd: sss files
group: sss files
The advantage of serving local users through SSSD is that the nss_sss
module has a fast mmapped-cache that speeds up NSS lookups compared to
accessing the disk an opening the files on each NSS request.
Traditionally, this has been done with the help of nscd, but using nscd
in parallel with sssd is cumbersome, as both SSSD and nscd use their own
independent caching, so using nscd in setups where sssd is also serving
users from some remote domain (LDAP, AD, ...) can result in a bit of
unpredictability.
More details about why Fedora chose to use sss before files can be found
on e.g.:
https://fedoraproject.org//wiki/Changes/SSSDCacheForLocalUsers
or:
https://docs.pagure.org/SSSD.sssd/design_pages/files_provider.html
Now, even though sssd watches the passwd and group files with the help
of inotify, there can still be a small window where someone requests a
user or a group, finds that it doesn't exist, adds the entry and checks
again. Without some support in shadow-utils that would explicitly drop
the sssd caches, the inotify watch can fire a little late, so a
combination of commands like this:
getent passwd user || useradd user; getent passwd user
can result in the second getent passwd not finding the newly added user
as the racy behaviour might still return the cached negative hit from
the first getent passwd.
This patch more or less copies the already existing support that
shadow-utils had for dropping nscd caches, except using the "sss_cache"
tool that sssd ships.
2018-09-12 17:52:11 +05:30
|
|
|
#include "sssd.h"
|
2007-10-07 17:17:01 +05:30
|
|
|
#include "prototypes.h"
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
#include "sgroupio.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Exit codes
|
|
|
|
*/
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
/*@-exitarg@*/
|
2007-10-07 17:14:02 +05:30
|
|
|
#define E_OKAY 0
|
2011-11-07 00:09:36 +05:30
|
|
|
#define E_SUCCESS 0
|
2007-10-07 17:14:02 +05:30
|
|
|
#define E_USAGE 1
|
|
|
|
#define E_BAD_ENTRY 2
|
|
|
|
#define E_CANT_OPEN 3
|
|
|
|
#define E_CANT_LOCK 4
|
|
|
|
#define E_CANT_UPDATE 5
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:17:01 +05:30
|
|
|
* Global variables
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
* src/newgrp.c, src/userdel.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/pwconv.c, src/chpasswd.c, src/logoutd.c,
src/chfn.c, src/groupmems.c, src/usermod.c, src/pwunconv.c,
src/expiry.c, src/groupdel.c, src/chgpasswd.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/chage.c,
src/groupadd.c, src/login.c, src/grpconv.c, src/groups.c,
src/grpunconv.c, src/chsh.c: Prog changed to a constant string.
2010-08-23 01:06:09 +05:30
|
|
|
const char *Prog;
|
2021-05-09 04:12:14 +05:30
|
|
|
FILE *shadow_logfd = NULL;
|
* src/newgrp.c, src/userdel.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/pwconv.c, src/chpasswd.c, src/logoutd.c,
src/chfn.c, src/groupmems.c, src/usermod.c, src/pwunconv.c,
src/expiry.c, src/groupdel.c, src/chgpasswd.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/grpconv.c,
src/groups.c, src/grpunconv.c, src/chsh.c: Prog is now global (not
static to the file) so that it can be used by the helper functions
of libmisc.
* lib/prototypes.h: Added extern char *Prog.
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Indicate the
program name with the warning.
2008-09-06 18:21:53 +05:30
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
static const char *grp_file = GROUP_FILE;
|
2008-06-10 00:50:00 +05:30
|
|
|
static bool use_system_grp_file = true;
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
|
|
|
static const char *sgr_file = SGROUP_FILE;
|
2008-06-10 00:50:00 +05:30
|
|
|
static bool use_system_sgr_file = true;
|
|
|
|
static bool is_shadow = false;
|
2008-08-22 07:56:46 +05:30
|
|
|
static bool sgr_locked = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2008-08-22 07:56:46 +05:30
|
|
|
static bool gr_locked = false;
|
2008-01-01 18:43:47 +05:30
|
|
|
/* Options */
|
2008-06-10 00:50:00 +05:30
|
|
|
static bool read_only = false;
|
|
|
|
static bool sort_mode = false;
|
2020-06-13 13:32:32 +05:30
|
|
|
static bool silence_warnings = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/* local function prototypes */
|
2008-08-22 07:56:46 +05:30
|
|
|
static void fail_exit (int status);
|
2011-11-07 00:09:36 +05:30
|
|
|
static /*@noreturn@*/void usage (int status);
|
2007-10-07 17:14:59 +05:30
|
|
|
static void delete_member (char **, const char *);
|
2008-01-01 19:40:21 +05:30
|
|
|
static void process_flags (int argc, char **argv);
|
2008-01-01 21:58:01 +05:30
|
|
|
static void open_files (void);
|
2008-06-10 00:50:00 +05:30
|
|
|
static void close_files (bool changed);
|
2008-01-01 19:40:21 +05:30
|
|
|
static int check_members (const char *groupname,
|
|
|
|
char **members,
|
|
|
|
const char *fmt_info,
|
|
|
|
const char *fmt_prompt,
|
|
|
|
const char *fmt_syslog,
|
|
|
|
int *errors);
|
2008-06-10 00:50:00 +05:30
|
|
|
static void check_grp_file (int *errors, bool *changed);
|
2008-03-18 04:30:49 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-01-01 19:40:21 +05:30
|
|
|
static void compare_members_lists (const char *groupname,
|
|
|
|
char **members,
|
|
|
|
char **other_members,
|
|
|
|
const char *file,
|
|
|
|
const char *other_file);
|
2008-06-10 00:50:00 +05:30
|
|
|
static void check_sgr_file (int *errors, bool *changed);
|
2008-01-01 19:40:21 +05:30
|
|
|
#endif
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-08-22 07:56:46 +05:30
|
|
|
/*
|
|
|
|
* fail_exit - exit with an error code after unlocking files
|
|
|
|
*/
|
|
|
|
static void fail_exit (int status)
|
|
|
|
{
|
|
|
|
if (gr_locked) {
|
|
|
|
if (gr_unlock () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
|
|
|
|
/* continue */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
if (sgr_locked) {
|
|
|
|
if (sgr_unlock () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
|
|
|
|
/* continue */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
closelog ();
|
|
|
|
|
|
|
|
exit (status);
|
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
* usage - print syntax message and exit
|
|
|
|
*/
|
2011-11-07 00:09:36 +05:30
|
|
|
static /*@noreturn@*/void usage (int status)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2011-11-07 00:09:36 +05:30
|
|
|
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
|
2007-10-07 17:14:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
2011-11-07 00:09:36 +05:30
|
|
|
(void) fprintf (usageout,
|
|
|
|
_("Usage: %s [options] [group [gshadow]]\n"
|
|
|
|
"\n"
|
|
|
|
"Options:\n"),
|
|
|
|
Prog);
|
|
|
|
#else /* !SHADOWGRP */
|
|
|
|
(void) fprintf (usageout,
|
|
|
|
_("Usage: %s [options] [group]\n"
|
|
|
|
"\n"
|
|
|
|
"Options:\n"),
|
|
|
|
Prog);
|
|
|
|
#endif /* !SHADOWGRP */
|
|
|
|
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
|
|
|
(void) fputs (_(" -r, --read-only display errors and warnings\n"
|
|
|
|
" but do not change files\n"), usageout);
|
2011-11-07 00:09:53 +05:30
|
|
|
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
2011-11-07 00:09:36 +05:30
|
|
|
(void) fputs (_(" -s, --sort sort entries by UID\n"), usageout);
|
2020-08-12 22:23:28 +05:30
|
|
|
(void) fputs (_(" -S, --silence-warnings silence controversial/paranoid warnings\n"), usageout);
|
2011-11-07 00:09:36 +05:30
|
|
|
(void) fputs ("\n", usageout);
|
|
|
|
exit (status);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* delete_member - delete an entry in a list of members
|
2009-03-22 01:12:48 +05:30
|
|
|
*
|
|
|
|
* It only deletes the first entry with the given name.
|
2011-07-23 03:37:23 +05:30
|
|
|
* The member is defined by its address, no string comparison are
|
|
|
|
* performed.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
static void delete_member (char **list, const char *member)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2011-07-23 03:37:23 +05:30
|
|
|
for (i = 0; NULL != list[i]; i++) {
|
2008-01-01 22:24:18 +05:30
|
|
|
if (list[i] == member) {
|
2007-10-07 17:14:02 +05:30
|
|
|
break;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2011-07-23 03:37:23 +05:30
|
|
|
for (; NULL != list[i]; i++) {
|
|
|
|
list[i] = list[i + 1];
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2008-01-01 19:40:21 +05:30
|
|
|
* process_flags - parse the command line options
|
|
|
|
*
|
|
|
|
* It will not return if an error is encountered.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-01-01 18:43:47 +05:30
|
|
|
static void process_flags (int argc, char **argv)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2011-11-07 00:09:36 +05:30
|
|
|
int c;
|
|
|
|
static struct option long_options[] = {
|
2020-06-13 13:32:32 +05:30
|
|
|
{"help", no_argument, NULL, 'h'},
|
|
|
|
{"quiet", no_argument, NULL, 'q'},
|
|
|
|
{"read-only", no_argument, NULL, 'r'},
|
|
|
|
{"root", required_argument, NULL, 'R'},
|
|
|
|
{"silence-warnings", no_argument, NULL, 'S'},
|
|
|
|
{"sort", no_argument, NULL, 's'},
|
2011-11-07 00:09:36 +05:30
|
|
|
{NULL, 0, NULL, '\0'}
|
|
|
|
};
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse the command line arguments
|
|
|
|
*/
|
2020-06-13 13:32:32 +05:30
|
|
|
while ((c = getopt_long (argc, argv, "hqrR:sS",
|
2011-11-07 00:09:36 +05:30
|
|
|
long_options, NULL)) != -1) {
|
|
|
|
switch (c) {
|
|
|
|
case 'h':
|
|
|
|
usage (E_SUCCESS);
|
|
|
|
/*@notreached@*/break;
|
2007-10-07 17:14:02 +05:30
|
|
|
case 'q':
|
|
|
|
/* quiet - ignored for now */
|
|
|
|
break;
|
|
|
|
case 'r':
|
2008-06-10 00:50:00 +05:30
|
|
|
read_only = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
break;
|
2011-11-07 00:09:53 +05:30
|
|
|
case 'R': /* no-op, handled in process_root_flag () */
|
|
|
|
break;
|
2007-10-07 17:14:51 +05:30
|
|
|
case 's':
|
2008-06-10 00:50:00 +05:30
|
|
|
sort_mode = true;
|
2007-10-07 17:14:51 +05:30
|
|
|
break;
|
2020-06-13 13:32:32 +05:30
|
|
|
case 'S':
|
|
|
|
silence_warnings = true;
|
|
|
|
break;
|
2007-10-07 17:14:02 +05:30
|
|
|
default:
|
2011-11-07 00:09:36 +05:30
|
|
|
usage (E_USAGE);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:51 +05:30
|
|
|
if (sort_mode && read_only) {
|
2011-11-07 00:09:36 +05:30
|
|
|
fprintf (stderr, _("%s: -s and -r are incompatible\n"), Prog);
|
2007-10-07 17:14:59 +05:30
|
|
|
exit (E_USAGE);
|
2007-10-07 17:14:51 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
* Make certain we have the right number of arguments
|
|
|
|
*/
|
|
|
|
#ifdef SHADOWGRP
|
2011-07-23 03:37:23 +05:30
|
|
|
if (argc > (optind + 2))
|
2007-10-07 17:14:02 +05:30
|
|
|
#else
|
2011-07-23 03:37:23 +05:30
|
|
|
if (argc > (optind + 1))
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2008-01-01 18:43:47 +05:30
|
|
|
{
|
2011-11-07 00:09:36 +05:30
|
|
|
usage (E_USAGE);
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* If there are two left over filenames, use those as the group and
|
|
|
|
* group password filenames.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
if (optind != argc) {
|
|
|
|
grp_file = argv[optind];
|
* 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
|
|
|
gr_setdbname (grp_file);
|
2008-06-10 00:50:00 +05:30
|
|
|
use_system_grp_file = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
#ifdef SHADOWGRP
|
2008-01-01 18:43:47 +05:30
|
|
|
if ((optind + 2) == argc) {
|
2007-10-07 17:14:02 +05:30
|
|
|
sgr_file = argv[optind + 1];
|
* 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
|
|
|
sgr_setdbname (sgr_file);
|
2008-06-10 00:50:00 +05:30
|
|
|
is_shadow = true;
|
|
|
|
use_system_sgr_file = false;
|
2008-01-01 18:43:47 +05:30
|
|
|
} else if (optind == argc) {
|
2007-10-07 17:14:59 +05:30
|
|
|
is_shadow = sgr_file_present ();
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-01-01 19:40:21 +05:30
|
|
|
/*
|
|
|
|
* open_files - open the shadow database
|
|
|
|
*
|
|
|
|
* In read-only mode, the databases are not locked and are opened
|
|
|
|
* only for reading.
|
|
|
|
*/
|
2008-01-01 21:58:01 +05:30
|
|
|
static void open_files (void)
|
2008-01-01 18:43:47 +05:30
|
|
|
{
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
* Lock the files if we aren't in "read-only" mode
|
|
|
|
*/
|
|
|
|
if (!read_only) {
|
2008-01-01 18:43:47 +05:30
|
|
|
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"),
|
2008-01-01 18:43:47 +05:30
|
|
|
Prog, grp_file);
|
2008-08-22 07:56:46 +05:30
|
|
|
fail_exit (E_CANT_LOCK);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2008-08-22 07:56:46 +05:30
|
|
|
gr_locked = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-08-22 07:56:46 +05:30
|
|
|
if (is_shadow) {
|
|
|
|
if (sgr_lock () == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: cannot lock %s; try again later.\n"),
|
|
|
|
Prog, sgr_file);
|
|
|
|
fail_exit (E_CANT_LOCK);
|
|
|
|
}
|
|
|
|
sgr_locked = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Open the files. Use O_RDONLY if we are in read_only mode,
|
2007-10-07 17:14:02 +05:30
|
|
|
* O_RDWR otherwise.
|
|
|
|
*/
|
2015-02-27 18:47:25 +05:30
|
|
|
if (gr_open (read_only ? O_RDONLY : O_CREAT | 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,
|
2008-01-01 18:43:47 +05:30
|
|
|
grp_file);
|
|
|
|
if (use_system_grp_file) {
|
2007-10-07 17:14:59 +05:30
|
|
|
SYSLOG ((LOG_WARN, "cannot open %s", grp_file));
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
2008-08-22 07:56:46 +05:30
|
|
|
fail_exit (E_CANT_OPEN);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
#ifdef SHADOWGRP
|
2015-02-27 18:47:25 +05:30
|
|
|
if (is_shadow && (sgr_open (read_only ? O_RDONLY : O_CREAT | 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,
|
2008-01-01 18:43:47 +05:30
|
|
|
sgr_file);
|
|
|
|
if (use_system_sgr_file) {
|
2007-10-07 17:14:59 +05:30
|
|
|
SYSLOG ((LOG_WARN, "cannot open %s", sgr_file));
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
2008-08-22 07:56:46 +05:30
|
|
|
fail_exit (E_CANT_OPEN);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
#endif
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
|
|
|
|
2008-01-01 19:40:21 +05:30
|
|
|
/*
|
2008-01-01 21:58:01 +05:30
|
|
|
* close_files - close and unlock the group/gshadow databases
|
2008-01-01 19:40:21 +05:30
|
|
|
*
|
|
|
|
* If changed is not set, the databases are not closed, and no
|
|
|
|
* changes are committed in the databases. The databases are
|
|
|
|
* unlocked anyway.
|
|
|
|
*/
|
2008-06-10 00:50:00 +05:30
|
|
|
static void close_files (bool changed)
|
2008-01-01 18:43:47 +05:30
|
|
|
{
|
|
|
|
/*
|
|
|
|
* All done. If there were no change we can just abandon any
|
|
|
|
* changes to the files.
|
|
|
|
*/
|
|
|
|
if (changed) {
|
|
|
|
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"),
|
2008-01-01 22:28:13 +05:30
|
|
|
Prog, grp_file);
|
2008-08-22 07:56:46 +05:30
|
|
|
fail_exit (E_CANT_UPDATE);
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
if (is_shadow && (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"),
|
2008-01-01 22:28:13 +05:30
|
|
|
Prog, sgr_file);
|
2008-08-22 07:56:46 +05:30
|
|
|
fail_exit (E_CANT_UPDATE);
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't be anti-social - unlock the files when you're done.
|
|
|
|
*/
|
|
|
|
#ifdef SHADOWGRP
|
2008-08-22 07:56:46 +05:30
|
|
|
if (sgr_locked) {
|
|
|
|
if (sgr_unlock () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
|
|
|
|
/* continue */
|
|
|
|
}
|
|
|
|
sgr_locked = false;
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
|
|
|
#endif
|
2008-08-22 07:56:46 +05:30
|
|
|
if (gr_locked) {
|
|
|
|
if (gr_unlock () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
|
|
|
|
/* continue */
|
|
|
|
}
|
|
|
|
gr_locked = false;
|
|
|
|
}
|
2008-01-01 18:43:47 +05:30
|
|
|
}
|
|
|
|
|
2008-01-01 19:40:21 +05:30
|
|
|
/*
|
|
|
|
* check_members - check that every members of a group exist
|
|
|
|
*
|
|
|
|
* If an error is detected, *errors is incremented.
|
|
|
|
*
|
|
|
|
* The user will be prompted for the removal of the non-existent
|
|
|
|
* user.
|
|
|
|
*
|
|
|
|
* If any changes are performed, the return value will be 1,
|
|
|
|
* otherwise check_members() returns 0.
|
|
|
|
*
|
|
|
|
* fmt_info, fmt_prompt, and fmt_syslog are used for logging.
|
|
|
|
* * fmt_info must contain two string flags (%s): for the group's
|
|
|
|
* name and the missing member.
|
|
|
|
* * fmt_prompt must contain one string flags (%s): the missing
|
|
|
|
* member.
|
|
|
|
* * fmt_syslog must contain two string flags (%s): for the
|
|
|
|
* group's name and the missing member.
|
|
|
|
*/
|
2008-01-01 19:20:06 +05:30
|
|
|
static int check_members (const char *groupname,
|
|
|
|
char **members,
|
|
|
|
const char *fmt_info,
|
|
|
|
const char *fmt_prompt,
|
|
|
|
const char *fmt_syslog,
|
|
|
|
int *errors)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int members_changed = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure each member exists
|
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
for (i = 0; NULL != members[i]; i++) {
|
2008-01-01 19:20:06 +05:30
|
|
|
/* local, no need for xgetpwnam */
|
2008-01-01 23:21:54 +05:30
|
|
|
if (getpwnam (members[i]) != NULL) {
|
2008-01-01 19:20:06 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2008-01-01 19:20:06 +05:30
|
|
|
/*
|
|
|
|
* Can't find this user. Remove them
|
|
|
|
* from the list.
|
|
|
|
*/
|
|
|
|
*errors += 1;
|
|
|
|
printf (fmt_info, groupname, members[i]);
|
|
|
|
printf (fmt_prompt, members[i]);
|
|
|
|
|
2008-01-01 22:24:18 +05:30
|
|
|
if (!yes_or_no (read_only)) {
|
2008-01-01 19:20:06 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2008-01-01 19:20:06 +05:30
|
|
|
|
|
|
|
SYSLOG ((LOG_INFO, fmt_syslog, members[i], groupname));
|
|
|
|
members_changed = 1;
|
|
|
|
delete_member (members, members[i]);
|
2009-03-22 01:12:48 +05:30
|
|
|
|
|
|
|
/* Rewind in case of removal */
|
|
|
|
i--;
|
2008-01-01 19:20:06 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
return members_changed;
|
|
|
|
}
|
|
|
|
|
2008-03-18 04:30:49 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-01-01 19:40:21 +05:30
|
|
|
/*
|
|
|
|
* compare_members_lists - make sure the list of members is contained in
|
|
|
|
* another list.
|
|
|
|
*
|
|
|
|
* compare_members_lists() checks that all the members of members are
|
|
|
|
* also in other_members.
|
|
|
|
* file and other_file are used for logging.
|
|
|
|
*
|
|
|
|
* TODO: No changes are performed on the lists.
|
|
|
|
*/
|
2008-01-01 19:20:06 +05:30
|
|
|
static void compare_members_lists (const char *groupname,
|
|
|
|
char **members,
|
|
|
|
char **other_members,
|
|
|
|
const char *file,
|
|
|
|
const char *other_file)
|
|
|
|
{
|
|
|
|
char **pmem, **other_pmem;
|
|
|
|
|
2008-01-01 23:21:54 +05:30
|
|
|
for (pmem = members; NULL != *pmem; pmem++) {
|
|
|
|
for (other_pmem = other_members; NULL != *other_pmem; other_pmem++) {
|
2008-01-01 22:24:18 +05:30
|
|
|
if (strcmp (*pmem, *other_pmem) == 0) {
|
2008-01-01 19:20:06 +05:30
|
|
|
break;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2008-01-01 19:20:06 +05:30
|
|
|
}
|
2020-06-13 13:32:32 +05:30
|
|
|
if (!silence_warnings && *other_pmem == NULL) {
|
2008-01-01 19:20:06 +05:30
|
|
|
printf
|
|
|
|
("'%s' is a member of the '%s' group in %s but not in %s\n",
|
|
|
|
*pmem, groupname, file, other_file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-03-18 04:30:49 +05:30
|
|
|
#endif /* SHADOWGRP */
|
2008-01-01 19:20:06 +05:30
|
|
|
|
2008-01-01 19:40:21 +05:30
|
|
|
/*
|
|
|
|
* check_grp_file - check the content of the group file
|
|
|
|
*/
|
2008-06-10 00:50:00 +05:30
|
|
|
static void check_grp_file (int *errors, bool *changed)
|
2008-01-01 18:43:47 +05:30
|
|
|
{
|
|
|
|
struct commonio_entry *gre, *tgre;
|
|
|
|
struct group *grp;
|
2008-01-01 19:18:49 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-01-01 18:43:47 +05:30
|
|
|
struct sgrp *sgr;
|
|
|
|
#endif
|
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
* Loop through the entire group file.
|
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
for (gre = __gr_get_head (); NULL != gre; gre = gre->next) {
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
* Skip all NIS entries.
|
|
|
|
*/
|
|
|
|
|
2008-01-01 22:24:18 +05:30
|
|
|
if ((gre->line[0] == '+') || (gre->line[0] == '-')) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Start with the entries that are completely corrupt. They
|
|
|
|
* have no (struct group) entry because they couldn't be
|
|
|
|
* parsed properly.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
if (NULL == gre->eptr) {
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Tell the user this entire line is bogus and ask
|
|
|
|
* them to delete it.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2009-04-23 16:51:57 +05:30
|
|
|
(void) puts (_("invalid group file entry"));
|
2007-10-07 17:17:33 +05:30
|
|
|
printf (_("delete line '%s'? "), gre->line);
|
2008-01-01 19:18:49 +05:30
|
|
|
*errors += 1;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* prompt the user to delete the entry or not
|
|
|
|
*/
|
2008-01-01 22:24:18 +05:30
|
|
|
if (!yes_or_no (read_only)) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* All group file deletions wind up here. This code
|
|
|
|
* removes the current entry from the linked list.
|
|
|
|
* When done, it skips back to the top of the loop
|
|
|
|
* to try out the next list element.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
delete_gr:
|
* src/chfn.c, src/chsh.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/login.c, src/logoutd.c,
src/newgrp.c, src/newusers.c, src/passwd.c, src/pwck.c,
src/suauth.c, src/useradd.c, src/userdel.c, src/usermod.c,
src/vipw.c: Complete the switch from the `' quotation style to ''.
Do it also in SYSLOG messages. Quote some parameters. All this
permits to merge some messages.
2008-08-06 21:21:52 +05:30
|
|
|
SYSLOG ((LOG_INFO, "delete group line '%s'",
|
2008-01-01 22:28:13 +05:30
|
|
|
gre->line));
|
2008-06-10 00:50:00 +05:30
|
|
|
*changed = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:14:59 +05:30
|
|
|
__gr_del_entry (gre);
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Group structure is good, start using it.
|
|
|
|
*/
|
2007-10-07 17:14:14 +05:30
|
|
|
grp = gre->eptr;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure this entry has a unique name.
|
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
for (tgre = __gr_get_head (); NULL != tgre; tgre = tgre->next) {
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:14:14 +05:30
|
|
|
const struct group *ent = tgre->eptr;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't check this entry
|
|
|
|
*/
|
2008-01-01 22:24:18 +05:30
|
|
|
if (tgre == gre) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't check invalid entries.
|
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
if (NULL == ent) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-01-01 22:24:18 +05:30
|
|
|
if (strcmp (grp->gr_name, ent->gr_name) != 0) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Tell the user this entry is a duplicate of
|
|
|
|
* another and ask them to delete it.
|
|
|
|
*/
|
2009-04-23 16:51:57 +05:30
|
|
|
(void) puts (_("duplicate group entry"));
|
2007-10-07 17:17:33 +05:30
|
|
|
printf (_("delete line '%s'? "), gre->line);
|
2008-01-01 19:18:49 +05:30
|
|
|
*errors += 1;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* prompt the user to delete the entry or not
|
|
|
|
*/
|
2008-01-01 22:24:18 +05:30
|
|
|
if (yes_or_no (read_only)) {
|
2007-10-07 17:14:02 +05:30
|
|
|
goto delete_gr;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check for invalid group names. --marekm
|
|
|
|
*/
|
2008-05-26 02:28:16 +05:30
|
|
|
if (!is_valid_group_name (grp->gr_name)) {
|
2008-01-01 19:18:49 +05:30
|
|
|
*errors += 1;
|
2007-10-07 17:17:33 +05:30
|
|
|
printf (_("invalid group name '%s'\n"), grp->gr_name);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2009-03-09 01:58:55 +05:30
|
|
|
/*
|
2009-03-22 01:12:48 +05:30
|
|
|
* Check for invalid group ID.
|
2009-03-09 01:58:55 +05:30
|
|
|
*/
|
|
|
|
if (grp->gr_gid == (gid_t)-1) {
|
2009-03-22 01:12:48 +05:30
|
|
|
printf (_("invalid group ID '%lu'\n"), (long unsigned int)grp->gr_gid);
|
2009-03-09 01:58:55 +05:30
|
|
|
*errors += 1;
|
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
* Workaround for a NYS libc 5.3.12 bug on RedHat 4.2 -
|
2007-10-07 17:14:59 +05:30
|
|
|
* groups with no members are returned as groups with one
|
|
|
|
* member "", causing grpck to fail. --marekm
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
if ( (NULL != grp->gr_mem[0])
|
|
|
|
&& (NULL == grp->gr_mem[1])
|
|
|
|
&& ('\0' == grp->gr_mem[0][0])) {
|
|
|
|
grp->gr_mem[0] = NULL;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-01-01 19:20:06 +05:30
|
|
|
if (check_members (grp->gr_name, grp->gr_mem,
|
|
|
|
_("group %s: no user %s\n"),
|
|
|
|
_("delete member '%s'? "),
|
* src/chfn.c, src/chsh.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/login.c, src/logoutd.c,
src/newgrp.c, src/newusers.c, src/passwd.c, src/pwck.c,
src/suauth.c, src/useradd.c, src/userdel.c, src/usermod.c,
src/vipw.c: Complete the switch from the `' quotation style to ''.
Do it also in SYSLOG messages. Quote some parameters. All this
permits to merge some messages.
2008-08-06 21:21:52 +05:30
|
|
|
"delete member '%s' from group '%s'",
|
2008-01-01 19:20:06 +05:30
|
|
|
errors) == 1) {
|
2008-06-10 00:50:00 +05:30
|
|
|
*changed = true;
|
|
|
|
gre->changed = true;
|
2007-10-07 17:14:59 +05:30
|
|
|
__gr_set_changed ();
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2007-10-07 17:17:33 +05:30
|
|
|
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
/*
|
|
|
|
* Make sure this entry exists in the /etc/gshadow file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (is_shadow) {
|
|
|
|
sgr = (struct sgrp *) sgr_locate (grp->gr_name);
|
|
|
|
if (sgr == NULL) {
|
2009-03-22 18:02:40 +05:30
|
|
|
printf (_("no matching group file entry in %s\n"),
|
2008-01-01 22:28:13 +05:30
|
|
|
sgr_file);
|
2009-03-22 18:02:40 +05:30
|
|
|
printf (_("add group '%s' in %s? "),
|
2008-01-01 22:28:13 +05:30
|
|
|
grp->gr_name, sgr_file);
|
2008-01-01 19:18:49 +05:30
|
|
|
*errors += 1;
|
2007-12-26 22:20:38 +05:30
|
|
|
if (yes_or_no (read_only)) {
|
2007-10-07 17:17:33 +05:30
|
|
|
struct sgrp sg;
|
|
|
|
struct group gr;
|
|
|
|
static char *empty = NULL;
|
|
|
|
|
|
|
|
sg.sg_name = grp->gr_name;
|
|
|
|
sg.sg_passwd = grp->gr_passwd;
|
|
|
|
sg.sg_adm = ∅
|
|
|
|
sg.sg_mem = grp->gr_mem;
|
|
|
|
SYSLOG ((LOG_INFO,
|
* src/chfn.c, src/chsh.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/login.c, src/logoutd.c,
src/newgrp.c, src/newusers.c, src/passwd.c, src/pwck.c,
src/suauth.c, src/useradd.c, src/userdel.c, src/usermod.c,
src/vipw.c: Complete the switch from the `' quotation style to ''.
Do it also in SYSLOG messages. Quote some parameters. All this
permits to merge some messages.
2008-08-06 21:21:52 +05:30
|
|
|
"add group '%s' to '%s'",
|
2008-01-01 22:28:13 +05:30
|
|
|
grp->gr_name, sgr_file));
|
2008-06-10 00:50:00 +05:30
|
|
|
*changed = true;
|
2007-10-07 17:17:33 +05:30
|
|
|
|
2008-01-01 23:21:54 +05:30
|
|
|
if (sgr_update (&sg) == 0) {
|
2007-10-07 17:17:33 +05:30
|
|
|
fprintf (stderr,
|
* 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
|
|
|
_("%s: failed to prepare the new %s entry '%s'\n"),
|
|
|
|
Prog, sgr_dbname (), sg.sg_name);
|
2008-08-22 07:56:46 +05:30
|
|
|
fail_exit (E_CANT_UPDATE);
|
2007-10-07 17:17:33 +05:30
|
|
|
}
|
|
|
|
/* remove password from /etc/group */
|
|
|
|
gr = *grp;
|
|
|
|
gr.gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
|
2008-01-01 23:21:54 +05:30
|
|
|
if (gr_update (&gr) == 0) {
|
2007-10-07 17:17:33 +05:30
|
|
|
fprintf (stderr,
|
* 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
|
|
|
_("%s: failed to prepare the new %s entry '%s'\n"),
|
|
|
|
Prog, gr_dbname (), gr.gr_name);
|
2008-08-22 07:56:46 +05:30
|
|
|
fail_exit (E_CANT_UPDATE);
|
2007-10-07 17:17:33 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/**
|
2008-01-01 19:20:06 +05:30
|
|
|
* Verify that all the members defined in /etc/group are also
|
2007-10-07 17:17:33 +05:30
|
|
|
* present in /etc/gshadow.
|
|
|
|
*/
|
2008-01-01 19:20:06 +05:30
|
|
|
compare_members_lists (grp->gr_name,
|
|
|
|
grp->gr_mem, sgr->sg_mem,
|
|
|
|
grp_file, sgr_file);
|
2009-05-10 02:50:54 +05:30
|
|
|
|
|
|
|
/* The group entry has a gshadow counterpart.
|
|
|
|
* Make sure no passwords are in group.
|
|
|
|
*/
|
|
|
|
if (strcmp (grp->gr_passwd, SHADOW_PASSWD_STRING) != 0) {
|
|
|
|
printf (_("group %s has an entry in %s, but its password field in %s is not set to 'x'\n"),
|
|
|
|
grp->gr_name, sgr_file, grp_file);
|
|
|
|
*errors += 1;
|
|
|
|
}
|
2007-10-07 17:17:33 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2008-01-01 19:18:49 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-01-01 19:18:49 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-01-01 19:40:21 +05:30
|
|
|
/*
|
|
|
|
* check_sgr_file - check the content of the shadowed group file (gshadow)
|
|
|
|
*/
|
2008-06-10 00:50:00 +05:30
|
|
|
static void check_sgr_file (int *errors, bool *changed)
|
2008-01-01 19:18:49 +05:30
|
|
|
{
|
|
|
|
struct group *grp;
|
|
|
|
struct commonio_entry *sge, *tsge;
|
|
|
|
struct sgrp *sgr;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Loop through the entire shadow group file.
|
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
for (sge = __sgr_get_head (); NULL != sge; sge = sge->next) {
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Start with the entries that are completely corrupt. They
|
|
|
|
* have no (struct sgrp) entry because they couldn't be
|
|
|
|
* parsed properly.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
if (NULL == sge->eptr) {
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Tell the user this entire line is bogus and ask
|
|
|
|
* them to delete it.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2009-04-23 16:51:57 +05:30
|
|
|
(void) puts (_("invalid shadow group file entry"));
|
2007-10-07 17:17:33 +05:30
|
|
|
printf (_("delete line '%s'? "), sge->line);
|
2008-01-01 19:18:49 +05:30
|
|
|
*errors += 1;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* prompt the user to delete the entry or not
|
|
|
|
*/
|
2008-01-01 22:24:18 +05:30
|
|
|
if (!yes_or_no (read_only)) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* All shadow group file deletions wind up here.
|
2007-10-07 17:14:02 +05:30
|
|
|
* This code removes the current entry from the
|
2007-10-07 17:14:59 +05:30
|
|
|
* linked list. When done, it skips back to the top
|
|
|
|
* of the loop to try out the next list element.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
delete_sg:
|
* src/chfn.c, src/chsh.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/login.c, src/logoutd.c,
src/newgrp.c, src/newusers.c, src/passwd.c, src/pwck.c,
src/suauth.c, src/useradd.c, src/userdel.c, src/usermod.c,
src/vipw.c: Complete the switch from the `' quotation style to ''.
Do it also in SYSLOG messages. Quote some parameters. All this
permits to merge some messages.
2008-08-06 21:21:52 +05:30
|
|
|
SYSLOG ((LOG_INFO, "delete shadow line '%s'",
|
2008-01-01 22:28:13 +05:30
|
|
|
sge->line));
|
2008-06-10 00:50:00 +05:30
|
|
|
*changed = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:14:59 +05:30
|
|
|
__sgr_del_entry (sge);
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Shadow group structure is good, start using it.
|
|
|
|
*/
|
2007-10-07 17:14:14 +05:30
|
|
|
sgr = sge->eptr;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure this entry has a unique name.
|
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
for (tsge = __sgr_get_head (); NULL != tsge; tsge = tsge->next) {
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:14:14 +05:30
|
|
|
const struct sgrp *ent = tsge->eptr;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't check this entry
|
|
|
|
*/
|
2008-01-01 22:24:18 +05:30
|
|
|
if (tsge == sge) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't check invalid entries.
|
|
|
|
*/
|
2008-01-01 23:21:54 +05:30
|
|
|
if (NULL == ent) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-01-01 22:24:18 +05:30
|
|
|
if (strcmp (sgr->sg_name, ent->sg_name) != 0) {
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Tell the user this entry is a duplicate of
|
|
|
|
* another and ask them to delete it.
|
|
|
|
*/
|
2009-04-23 16:51:57 +05:30
|
|
|
(void) puts (_("duplicate shadow group entry"));
|
2007-10-07 17:17:33 +05:30
|
|
|
printf (_("delete line '%s'? "), sge->line);
|
2008-01-01 19:18:49 +05:30
|
|
|
*errors += 1;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* prompt the user to delete the entry or not
|
|
|
|
*/
|
2008-01-01 22:24:18 +05:30
|
|
|
if (yes_or_no (read_only)) {
|
2007-10-07 17:14:02 +05:30
|
|
|
goto delete_sg;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure this entry exists in the /etc/group file.
|
|
|
|
*/
|
2007-10-07 17:17:33 +05:30
|
|
|
grp = (struct group *) gr_locate (sgr->sg_name);
|
|
|
|
if (grp == NULL) {
|
|
|
|
printf (_("no matching group file entry in %s\n"),
|
2008-01-01 22:28:13 +05:30
|
|
|
grp_file);
|
2007-10-07 17:17:33 +05:30
|
|
|
printf (_("delete line '%s'? "), sge->line);
|
2008-01-01 19:18:49 +05:30
|
|
|
*errors += 1;
|
2008-01-01 22:24:18 +05:30
|
|
|
if (yes_or_no (read_only)) {
|
2007-10-07 17:14:02 +05:30
|
|
|
goto delete_sg;
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:17:33 +05:30
|
|
|
} else {
|
|
|
|
/**
|
|
|
|
* Verify that the all members defined in /etc/gshadow are also
|
|
|
|
* present in /etc/group.
|
|
|
|
*/
|
2008-01-01 19:20:06 +05:30
|
|
|
compare_members_lists (sgr->sg_name,
|
|
|
|
sgr->sg_mem, grp->gr_mem,
|
|
|
|
sgr_file, grp_file);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure each administrator exists
|
|
|
|
*/
|
2008-01-01 19:20:06 +05:30
|
|
|
if (check_members (sgr->sg_name, sgr->sg_adm,
|
|
|
|
_("shadow group %s: no administrative user %s\n"),
|
|
|
|
_("delete administrative member '%s'? "),
|
* src/chfn.c, src/chsh.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/login.c, src/logoutd.c,
src/newgrp.c, src/newusers.c, src/passwd.c, src/pwck.c,
src/suauth.c, src/useradd.c, src/userdel.c, src/usermod.c,
src/vipw.c: Complete the switch from the `' quotation style to ''.
Do it also in SYSLOG messages. Quote some parameters. All this
permits to merge some messages.
2008-08-06 21:21:52 +05:30
|
|
|
"delete admin '%s' from shadow group '%s'",
|
2008-01-01 19:20:06 +05:30
|
|
|
errors) == 1) {
|
2008-06-10 00:50:00 +05:30
|
|
|
*changed = true;
|
|
|
|
sge->changed = true;
|
2007-10-07 17:14:59 +05:30
|
|
|
__sgr_set_changed ();
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure each member exists
|
|
|
|
*/
|
2008-01-01 19:20:06 +05:30
|
|
|
if (check_members (sgr->sg_name, sgr->sg_mem,
|
|
|
|
_("shadow group %s: no user %s\n"),
|
|
|
|
_("delete member '%s'? "),
|
* src/chfn.c, src/chsh.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/login.c, src/logoutd.c,
src/newgrp.c, src/newusers.c, src/passwd.c, src/pwck.c,
src/suauth.c, src/useradd.c, src/userdel.c, src/usermod.c,
src/vipw.c: Complete the switch from the `' quotation style to ''.
Do it also in SYSLOG messages. Quote some parameters. All this
permits to merge some messages.
2008-08-06 21:21:52 +05:30
|
|
|
"delete member '%s' from shadow group '%s'",
|
2008-01-01 19:20:06 +05:30
|
|
|
errors) == 1) {
|
2008-06-10 00:50:00 +05:30
|
|
|
*changed = true;
|
|
|
|
sge->changed = true;
|
2007-10-07 17:14:59 +05:30
|
|
|
__sgr_set_changed ();
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
}
|
2008-01-01 19:18:49 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
#endif /* SHADOWGRP */
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-01-01 19:18:49 +05:30
|
|
|
/*
|
|
|
|
* grpck - verify group file integrity
|
|
|
|
*/
|
|
|
|
int main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
int errors = 0;
|
2008-06-10 00:50:00 +05:30
|
|
|
bool changed = false;
|
2008-01-01 19:18:49 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* Get my name so that I can use it to report errors.
|
|
|
|
*/
|
|
|
|
Prog = Basename (argv[0]);
|
2021-05-09 04:12:14 +05:30
|
|
|
shadow_logfd = stderr;
|
2008-01-01 19:18:49 +05:30
|
|
|
|
2008-06-10 00:50:00 +05:30
|
|
|
(void) setlocale (LC_ALL, "");
|
|
|
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
|
|
|
(void) textdomain (PACKAGE);
|
2008-01-01 19:18:49 +05:30
|
|
|
|
2011-11-07 00:09:53 +05:30
|
|
|
process_root_flag ("-R", argc, argv);
|
|
|
|
|
2008-01-01 19:18:49 +05:30
|
|
|
OPENLOG ("grpck");
|
|
|
|
|
|
|
|
/* Parse the command line arguments */
|
|
|
|
process_flags (argc, argv);
|
|
|
|
|
|
|
|
open_files ();
|
|
|
|
|
|
|
|
if (sort_mode) {
|
|
|
|
gr_sort ();
|
|
|
|
#ifdef SHADOWGRP
|
2008-01-01 22:24:18 +05:30
|
|
|
if (is_shadow) {
|
2008-01-01 19:18:49 +05:30
|
|
|
sgr_sort ();
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2008-06-10 00:50:00 +05:30
|
|
|
changed = true;
|
2008-01-01 19:18:49 +05:30
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
check_grp_file (&errors, &changed);
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
if (is_shadow) {
|
|
|
|
check_sgr_file (&errors, &changed);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-01-01 18:43:47 +05:30
|
|
|
/* Commit the change in the database if needed */
|
|
|
|
close_files (changed);
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2019-02-27 21:58:39 +05:30
|
|
|
if (!read_only) {
|
|
|
|
nscd_flush_cache ("group");
|
|
|
|
sssd_flush_cache (SSSD_DB_GROUP);
|
|
|
|
}
|
2007-10-07 17:16:52 +05:30
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
* Tell the user what we did and exit.
|
|
|
|
*/
|
2008-06-10 00:50:00 +05:30
|
|
|
if (0 != errors) {
|
2009-04-23 16:51:57 +05:30
|
|
|
if (changed) {
|
|
|
|
printf (_("%s: the files have been updated\n"), Prog);
|
|
|
|
} else {
|
|
|
|
printf (_("%s: no changes\n"), Prog);
|
|
|
|
}
|
2008-01-01 22:24:18 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
src/sulogin.c, src/usermod.c: Use return instead of exit at the
end of main().
* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
exit codes.
* src/chpasswd.c: Added missing ||.
* src/nologin.c: Do not include exitcodes.h.
* src/nologin.c: Added brackets.
* src/nologin.c: Avoid assignments in comparisons.
2009-05-01 03:09:38 +05:30
|
|
|
return ((0 != errors) ? E_BAD_ENTRY : E_OKAY);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2008-01-01 22:24:18 +05:30
|
|
|
|