2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
vipw, vigr edit the password or group file
|
|
|
|
with -s will edit shadow or gshadow file
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
|
2008-04-27 06:10:09 +05:30
|
|
|
Copyright (c) 1997 , Guy Maor <maor@ece.utexas.edu>
|
|
|
|
Copyright (c) 1999 - 2000, Marek Michałkiewicz
|
|
|
|
Copyright (c) 2002 - 2006, Tomasz Kłoczko
|
|
|
|
Copyright (c) 2007 - 2008, Nicolas François
|
|
|
|
All rights reserved.
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
2007-10-07 17:14:59 +05:30
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2007-10-07 17:14:02 +05:30
|
|
|
General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2008-04-27 06:10:09 +05:30
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA. */
|
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:14:02 +05:30
|
|
|
#include <errno.h>
|
2007-10-07 17:17:11 +05:30
|
|
|
#include <getopt.h>
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
#ifdef WITH_SELINUX
|
|
|
|
#include <selinux/selinux.h>
|
* 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
|
|
|
#endif
|
2007-10-07 17:17:01 +05:30
|
|
|
#include <signal.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2007-10-07 17:17:01 +05:30
|
|
|
#include <sys/stat.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include <sys/types.h>
|
2007-10-07 17:17:01 +05:30
|
|
|
#include <unistd.h>
|
2007-10-07 17:14:02 +05:30
|
|
|
#include <utime.h>
|
2007-10-07 17:17:01 +05:30
|
|
|
#include "defines.h"
|
|
|
|
#include "groupio.h"
|
|
|
|
#include "nscd.h"
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "prototypes.h"
|
|
|
|
#include "pwio.h"
|
|
|
|
#include "sgroupio.h"
|
2007-10-07 17:17:01 +05:30
|
|
|
#include "shadowio.h"
|
* 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@*/
|
|
|
|
#include "exitcodes.h"
|
2009-04-15 23:12:27 +05:30
|
|
|
|
2007-12-27 05:13:55 +05:30
|
|
|
#define MSG_WARN_EDIT_OTHER_FILE _( \
|
|
|
|
"You have modified %s.\n"\
|
|
|
|
"You may need to modify %s for consistency.\n"\
|
* 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
|
|
|
"Please use the command '%s' to do so.\n")
|
2007-12-27 05:13:55 +05:30
|
|
|
|
2007-10-07 17:17:01 +05:30
|
|
|
/*
|
|
|
|
* Global variables
|
|
|
|
*/
|
2007-10-07 17:14:02 +05:30
|
|
|
static const char *progname, *filename, *fileeditname;
|
2008-06-10 02:48:28 +05:30
|
|
|
static bool filelocked = false;
|
|
|
|
static bool createedit = false;
|
2007-10-07 17:14:59 +05:30
|
|
|
static int (*unlock) (void);
|
2008-06-10 02:48:28 +05:30
|
|
|
static bool quiet = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/* local function prototypes */
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
static void usage (int status);
|
2007-10-07 17:14:59 +05:30
|
|
|
static int create_backup_file (FILE *, const char *, struct stat *);
|
2008-08-10 05:01:36 +05:30
|
|
|
static void vipwexit (const char *msg, int syserr, int ret);
|
2007-10-07 17:14:59 +05:30
|
|
|
static void vipwedit (const char *, int (*)(void), int (*)(void));
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:17:11 +05:30
|
|
|
/*
|
|
|
|
* usage - display usage message and exit
|
|
|
|
*/
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
static void usage (int status)
|
2007-10-07 17:17:11 +05:30
|
|
|
{
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
(void)
|
2008-01-25 01:08:06 +05:30
|
|
|
fputs (_("Usage: vipw [options]\n"
|
2008-01-25 01:20:09 +05:30
|
|
|
"\n"
|
|
|
|
"Options:\n"
|
|
|
|
" -g, --group edit group database\n"
|
|
|
|
" -h, --help display this help message and exit\n"
|
|
|
|
" -p, --passwd edit passwd database\n"
|
|
|
|
" -q, --quiet quiet mode\n"
|
|
|
|
" -s, --shadow edit shadow or gshadow database\n"
|
* src/userdel.c, src/lastlog.c, src/gpasswd.c, src/newusers.c,
src/chpasswd.c, src/groupmems.c, src/usermod.c, src/chgpasswd.c,
src/vipw.c, src/su.c, src/useradd.c, src/groupmod.c, src/passwd.c,
src/groupadd.c, src/chage.c, src/faillog.c, src/chsh.c: Use
booleans for tests.
* src/userdel.c, src/gpasswd.c, src/groupmems.c, src/usermod.c,
src/groupmod.c, src/passwd.c: Use a break even after usage().
2009-09-06 04:01:29 +05:30
|
|
|
"\n"), (E_SUCCESS != status) ? stderr : stdout);
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
exit (status);
|
2007-10-07 17:17:11 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
2007-10-07 17:16:07 +05:30
|
|
|
static int create_backup_file (FILE * fp, const char *backup, struct stat *sb)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-10-07 17:14:59 +05:30
|
|
|
struct utimbuf ub;
|
|
|
|
FILE *bkfp;
|
|
|
|
int c;
|
|
|
|
mode_t mask;
|
|
|
|
|
|
|
|
mask = umask (077);
|
|
|
|
bkfp = fopen (backup, "w");
|
2008-06-10 02:48:28 +05:30
|
|
|
(void) umask (mask);
|
|
|
|
if (NULL == bkfp) {
|
2007-10-07 17:14:59 +05:30
|
|
|
return -1;
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2007-10-07 17:15:40 +05:30
|
|
|
c = 0;
|
2007-10-07 17:16:07 +05:30
|
|
|
if (fseeko (fp, 0, SEEK_SET) == 0)
|
|
|
|
while ((c = getc (fp)) != EOF) {
|
2008-06-10 02:48:28 +05:30
|
|
|
if (putc (c, bkfp) == EOF) {
|
2007-10-07 17:15:40 +05:30
|
|
|
break;
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2007-10-07 17:15:40 +05:30
|
|
|
}
|
2008-06-10 02:48:28 +05:30
|
|
|
if ((EOF != c) || (ferror (fp) != 0) || (fflush (bkfp) != 0)) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fclose (bkfp);
|
|
|
|
unlink (backup);
|
|
|
|
return -1;
|
|
|
|
}
|
2009-05-26 01:21:23 +05:30
|
|
|
if (fsync (fileno (bkfp)) != 0) {
|
|
|
|
(void) fclose (bkfp);
|
|
|
|
unlink (backup);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (fclose (bkfp) != 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
unlink (backup);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ub.actime = sb->st_atime;
|
|
|
|
ub.modtime = sb->st_mtime;
|
2008-06-10 02:48:28 +05:30
|
|
|
if ( (utime (backup, &ub) != 0)
|
|
|
|
|| (chmod (backup, sb->st_mode) != 0)
|
|
|
|
|| (chown (backup, sb->st_uid, sb->st_gid) != 0)) {
|
2007-10-07 17:14:59 +05:30
|
|
|
unlink (backup);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2007-10-07 17:17:11 +05:30
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
static void vipwexit (const char *msg, int syserr, int ret)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-10-07 17:14:59 +05:30
|
|
|
int err = errno;
|
|
|
|
|
2008-06-10 02:48:28 +05:30
|
|
|
if (createedit) {
|
2008-08-10 05:01:36 +05:30
|
|
|
if (unlink (fileeditname) != 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to remove %s\n"), progname, fileeditname);
|
|
|
|
/* continue */
|
|
|
|
}
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
|
|
|
if (filelocked) {
|
2008-08-10 05:01:36 +05:30
|
|
|
if ((*unlock) () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), progname, fileeditname);
|
* 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", fileeditname));
|
2008-08-10 05:01:36 +05:30
|
|
|
/* continue */
|
|
|
|
}
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
|
|
|
if (NULL != msg) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr, "%s: %s", progname, msg);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
|
|
|
if (0 != syserr) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr, ": %s", strerror (err));
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2008-08-10 05:01:36 +05:30
|
|
|
(void) fputs ("\n", stderr);
|
2008-06-10 02:48:28 +05:30
|
|
|
if (!quiet) {
|
2008-08-10 05:01:36 +05:30
|
|
|
fprintf (stdout, _("%s: %s is unchanged\n"), progname,
|
2007-10-07 17:17:11 +05:30
|
|
|
filename);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
exit (ret);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DEFAULT_EDITOR
|
|
|
|
#define DEFAULT_EDITOR "vi"
|
|
|
|
#endif
|
|
|
|
|
2007-10-07 17:17:11 +05:30
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
2007-10-07 17:14:02 +05:30
|
|
|
static void
|
2007-10-07 17:16:07 +05:30
|
|
|
vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-10-07 17:14:59 +05:30
|
|
|
const char *editor;
|
|
|
|
pid_t pid;
|
|
|
|
struct stat st1, st2;
|
|
|
|
int status;
|
|
|
|
FILE *f;
|
|
|
|
char filebackup[1024], fileedit[1024];
|
|
|
|
|
|
|
|
snprintf (filebackup, sizeof filebackup, "%s-", file);
|
|
|
|
snprintf (fileedit, sizeof fileedit, "%s.edit", file);
|
|
|
|
unlock = file_unlock;
|
|
|
|
filename = file;
|
|
|
|
fileeditname = fileedit;
|
|
|
|
|
2008-06-10 02:48:28 +05:30
|
|
|
if (access (file, F_OK) != 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (file, 1, 1);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2009-04-15 23:12:27 +05:30
|
|
|
#ifdef WITH_SELINUX
|
|
|
|
/* if SE Linux is enabled then set the context of all new files
|
|
|
|
to be the context of the file we are editing */
|
|
|
|
if (is_selinux_enabled ()) {
|
|
|
|
security_context_t passwd_context=NULL;
|
|
|
|
int ret = 0;
|
|
|
|
if (getfilecon (file, &passwd_context) < 0) {
|
|
|
|
vipwexit (_("Couldn't get file context"), errno, 1);
|
|
|
|
}
|
|
|
|
ret = setfscreatecon (passwd_context);
|
|
|
|
freecon (passwd_context);
|
|
|
|
if (0 != ret) {
|
|
|
|
vipwexit (_("setfscreatecon () failed"), errno, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2008-06-10 02:48:28 +05:30
|
|
|
if (file_lock () == 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (_("Couldn't lock file"), errno, 5);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
|
|
|
filelocked = true;
|
2007-10-07 17:14:59 +05:30
|
|
|
|
|
|
|
/* edited copy has same owners, perm */
|
2008-06-10 02:48:28 +05:30
|
|
|
if (stat (file, &st1) != 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (file, 1, 1);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
|
|
|
f = fopen (file, "r");
|
|
|
|
if (NULL == f) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (file, 1, 1);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
|
|
|
if (create_backup_file (f, fileedit, &st1) != 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (_("Couldn't make backup"), errno, 1);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2009-05-26 01:21:23 +05:30
|
|
|
(void) fclose (f);
|
2008-06-10 02:48:28 +05:30
|
|
|
createedit = true;
|
2007-10-07 17:14:59 +05:30
|
|
|
|
|
|
|
editor = getenv ("VISUAL");
|
2008-06-10 02:48:28 +05:30
|
|
|
if (NULL == editor) {
|
2007-10-07 17:14:59 +05:30
|
|
|
editor = getenv ("EDITOR");
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
|
|
|
if (NULL == editor) {
|
2007-10-07 17:14:59 +05:30
|
|
|
editor = DEFAULT_EDITOR;
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2008-06-10 02:48:28 +05:30
|
|
|
pid = fork ();
|
|
|
|
if (-1 == pid) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit ("fork", 1, 1);
|
2008-06-10 02:48:28 +05:30
|
|
|
} else if (0 == pid) {
|
2007-10-07 17:14:59 +05:30
|
|
|
/* use the system() call to invoke the editor so that it accepts
|
|
|
|
command line args in the EDITOR and VISUAL environment vars */
|
|
|
|
char *buf;
|
|
|
|
|
2007-10-07 17:16:07 +05:30
|
|
|
buf = (char *) malloc (strlen (editor) + strlen (fileedit) + 2);
|
2007-10-07 17:14:59 +05:30
|
|
|
snprintf (buf, strlen (editor) + strlen (fileedit) + 2,
|
|
|
|
"%s %s", editor, fileedit);
|
|
|
|
if (system (buf) != 0) {
|
|
|
|
fprintf (stderr, "%s: %s: %s\n", progname, editor,
|
|
|
|
strerror (errno));
|
|
|
|
exit (1);
|
2008-06-10 02:48:28 +05:30
|
|
|
} else {
|
2007-10-07 17:14:59 +05:30
|
|
|
exit (0);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
pid = waitpid (pid, &status, WUNTRACED);
|
2008-06-10 02:48:28 +05:30
|
|
|
if ((pid != -1) && (WIFSTOPPED (status) != 0)) {
|
2008-05-18 19:11:56 +05:30
|
|
|
/* The child (editor) was suspended.
|
|
|
|
* Suspend vipw. */
|
|
|
|
kill (getpid (), WSTOPSIG(status));
|
|
|
|
/* wake child when resumed */
|
|
|
|
kill (pid, SIGCONT);
|
2008-06-10 02:48:28 +05:30
|
|
|
} else {
|
2007-10-07 17:14:59 +05:30
|
|
|
break;
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
}
|
|
|
|
|
2008-06-10 02:48:28 +05:30
|
|
|
if ( (-1 == pid)
|
|
|
|
|| (WIFEXITED (status) == 0)
|
|
|
|
|| (WEXITSTATUS (status) != 0)) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (editor, 1, 1);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2008-06-10 02:48:28 +05:30
|
|
|
if (stat (fileedit, &st2) != 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (fileedit, 1, 1);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
|
|
|
if (st1.st_mtime == st2.st_mtime) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (0, 0, 0);
|
2008-06-10 02:48:28 +05:30
|
|
|
}
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
#ifdef WITH_SELINUX
|
|
|
|
/* unset the fscreatecon */
|
2009-04-15 23:12:27 +05:30
|
|
|
if (is_selinux_enabled ()) {
|
|
|
|
if (setfscreatecon (NULL)) {
|
2009-04-29 00:56:27 +05:30
|
|
|
vipwexit (_("setfscreatecon () failed"), errno, 1);
|
2009-04-15 23:12:27 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX - here we should check fileedit for errors; if there are any,
|
|
|
|
* ask the user what to do (edit again, save changes anyway, or quit
|
|
|
|
* without saving). Use pwck or grpck to do the check. --marekm
|
|
|
|
*/
|
2008-06-10 02:48:28 +05:30
|
|
|
createedit = false;
|
2007-10-07 17:14:59 +05:30
|
|
|
unlink (filebackup);
|
|
|
|
link (file, filebackup);
|
|
|
|
if (rename (fileedit, file) == -1) {
|
|
|
|
fprintf (stderr,
|
2008-08-10 05:01:36 +05:30
|
|
|
_("%s: can't restore %s: %s (your changes are in %s)\n"),
|
|
|
|
progname, file, strerror (errno), fileedit);
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwexit (0, 0, 1);
|
|
|
|
}
|
|
|
|
|
2008-08-10 05:01:36 +05:30
|
|
|
if ((*file_unlock) () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), progname, fileeditname);
|
* 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", fileeditname));
|
2008-08-10 05:01:36 +05:30
|
|
|
/* continue */
|
|
|
|
}
|
* 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_INFO, "file %s edited", fileeditname));
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:59 +05:30
|
|
|
int main (int argc, char **argv)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2008-06-10 02:48:28 +05:30
|
|
|
bool editshadow = false;
|
2007-10-07 17:17:11 +05:30
|
|
|
char *a;
|
2008-06-10 02:48:28 +05:30
|
|
|
bool do_vipw;
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2008-06-10 02:48:28 +05:30
|
|
|
(void) setlocale (LC_ALL, "");
|
|
|
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
|
|
|
(void) textdomain (PACKAGE);
|
2007-10-07 17:14:59 +05:30
|
|
|
|
2007-10-07 17:17:11 +05:30
|
|
|
progname = ((a = strrchr (*argv, '/')) ? a + 1 : *argv);
|
2007-10-07 17:14:59 +05:30
|
|
|
do_vipw = (strcmp (progname, "vigr") != 0);
|
|
|
|
|
* 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
|
|
|
OPENLOG (do_vipw ? "vipw" : "vigr");
|
|
|
|
|
2007-10-07 17:17:11 +05:30
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Parse the command line options.
|
|
|
|
*/
|
|
|
|
int c;
|
|
|
|
static struct option long_options[] = {
|
|
|
|
{"group", no_argument, NULL, 'g'},
|
|
|
|
{"help", no_argument, NULL, 'h'},
|
|
|
|
{"passwd", no_argument, NULL, 'p'},
|
|
|
|
{"quiet", no_argument, NULL, 'q'},
|
|
|
|
{"shadow", no_argument, NULL, 's'},
|
2008-06-10 02:48:28 +05:30
|
|
|
{NULL, 0, NULL, '\0'}
|
2007-10-07 17:17:11 +05:30
|
|
|
};
|
|
|
|
while ((c =
|
|
|
|
getopt_long (argc, argv, "ghpqs",
|
|
|
|
long_options, NULL)) != -1) {
|
|
|
|
switch (c) {
|
|
|
|
case 'g':
|
2008-06-10 02:48:28 +05:30
|
|
|
do_vipw = false;
|
2007-10-07 17:17:11 +05:30
|
|
|
break;
|
|
|
|
case 'h':
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
usage (E_SUCCESS);
|
2007-10-07 17:17:11 +05:30
|
|
|
break;
|
|
|
|
case 'p':
|
2008-06-10 02:48:28 +05:30
|
|
|
do_vipw = true;
|
2007-10-07 17:17:11 +05:30
|
|
|
break;
|
|
|
|
case 'q':
|
2008-06-10 02:48:28 +05:30
|
|
|
quiet = true;
|
2007-10-07 17:17:11 +05:30
|
|
|
break;
|
|
|
|
case 's':
|
2008-06-10 02:48:28 +05:30
|
|
|
editshadow = true;
|
2007-10-07 17:17:11 +05:30
|
|
|
break;
|
|
|
|
default:
|
* NEWS, src/userdel.c, src/lastlog.c, src/gpasswd.c,
src/newusers.c, src/chpasswd.c, src/groupmems.c, src/usermod.c,
src/chgpasswd.c, src/vipw.c, src/su.c, src/useradd.c,
src/groupmod.c, src/passwd.c, src/groupadd.c, src/chage.c,
src/faillog.c, src/chsh.c: If someone uses the -h/--help options,
the usage should not go to stderr nor should the utility exit with
non-zero status. All of the shadow utils do just this
unfortunately, so convert them over to sanity.
* man/groupmems.8.xml, man/gpasswd.1.xml: Added option -h/--help.
2009-09-05 04:32:33 +05:30
|
|
|
usage (E_USAGE);
|
2007-10-07 17:17:11 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
}
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:14:59 +05:30
|
|
|
if (do_vipw) {
|
2007-12-27 05:13:55 +05:30
|
|
|
if (editshadow) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwedit (SHADOW_FILE, spw_lock, spw_unlock);
|
2007-12-27 05:13:55 +05:30
|
|
|
printf (MSG_WARN_EDIT_OTHER_FILE,
|
|
|
|
SHADOW_FILE,
|
|
|
|
PASSWD_FILE,
|
|
|
|
"vipw");
|
|
|
|
} else {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwedit (PASSWD_FILE, pw_lock, pw_unlock);
|
2007-12-27 05:13:55 +05:30
|
|
|
if (spw_file_present ()) {
|
|
|
|
printf (MSG_WARN_EDIT_OTHER_FILE,
|
|
|
|
PASSWD_FILE,
|
|
|
|
SHADOW_FILE,
|
|
|
|
"vipw -s");
|
|
|
|
}
|
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
} else {
|
2007-10-07 17:14:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
2007-12-27 05:13:55 +05:30
|
|
|
if (editshadow) {
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwedit (SGROUP_FILE, sgr_lock, sgr_unlock);
|
2007-12-27 05:13:55 +05:30
|
|
|
printf (MSG_WARN_EDIT_OTHER_FILE,
|
|
|
|
SGROUP_FILE,
|
|
|
|
GROUP_FILE,
|
|
|
|
"vigr");
|
|
|
|
} else {
|
2007-10-07 17:14:02 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
vipwedit (GROUP_FILE, gr_lock, gr_unlock);
|
2007-12-27 05:13:55 +05:30
|
|
|
#ifdef SHADOWGRP
|
|
|
|
if (sgr_file_present ()) {
|
|
|
|
printf (MSG_WARN_EDIT_OTHER_FILE,
|
|
|
|
GROUP_FILE,
|
|
|
|
SGROUP_FILE,
|
|
|
|
"vigr -s");
|
|
|
|
}
|
|
|
|
}
|
2007-12-31 03:09:57 +05:30
|
|
|
#endif
|
2007-10-07 17:14:59 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2007-10-07 17:15:23 +05:30
|
|
|
nscd_flush_cache ("passwd");
|
|
|
|
nscd_flush_cache ("group");
|
2007-10-07 17:16:52 +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 E_SUCCESS;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2008-06-10 02:48:28 +05:30
|
|
|
|