2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2008-04-27 06:10:09 +05:30
|
|
|
* Copyright (c) 1990 - 1993, Julianne Frances Haugh
|
|
|
|
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
|
|
|
|
* Copyright (c) 2000 - 2006, Tomasz Kłoczko
|
2009-03-09 02:13:15 +05:30
|
|
|
* Copyright (c) 2007 - 2009, 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
|
|
|
* newusers - create users from a batch file
|
|
|
|
*
|
|
|
|
* newusers creates a collection of entries in /etc/passwd
|
|
|
|
* and related files by reading a passwd-format file and
|
|
|
|
* adding entries in the related directories.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#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 <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <grp.h>
|
|
|
|
#include <fcntl.h>
|
2007-11-24 01:54:42 +05:30
|
|
|
#include <getopt.h>
|
2008-02-03 23:15:58 +05:30
|
|
|
#include <ctype.h>
|
2009-04-12 05:00:44 +05:30
|
|
|
#include <errno.h>
|
|
|
|
#include <string.h>
|
* configure.in: Added option --enable-account-tools-setuid to
enable/disable the usage of PAM to authenticate the callers of
account management tools: chage, chgpasswd, chpasswd, groupadd,
groupdel, groupmod, useradd, userdel, usermod.
* src/Makefile.am: Do not link the above tools with libpam if
account-tools-setuid is disabled.
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/usermod.c,
src/groupdel.c, src/chgpasswd.c, src/useradd.c, src/groupmod.c,
src/groupadd.c, src/chage.c: Implement ACCT_TOOLS_SETUID
(--enable-account-tools-setuid).
* etc/pam.d/Makefile.am: Install the pam service file for the
above tools only when needed.
* src/useradd.c, src/userdel.c, src/usermod.c: It is no more
needed to initialize retval to PAM_SUCCESS.
2008-09-07 03:05:37 +05:30
|
|
|
#ifdef ACCT_TOOLS_SETUID
|
2007-10-07 17:14:38 +05:30
|
|
|
#ifdef USE_PAM
|
2007-10-07 17:17:11 +05:30
|
|
|
#include "pam_defs.h"
|
2007-10-07 17:14:59 +05:30
|
|
|
#endif /* USE_PAM */
|
* configure.in: Added option --enable-account-tools-setuid to
enable/disable the usage of PAM to authenticate the callers of
account management tools: chage, chgpasswd, chpasswd, groupadd,
groupdel, groupmod, useradd, userdel, usermod.
* src/Makefile.am: Do not link the above tools with libpam if
account-tools-setuid is disabled.
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/usermod.c,
src/groupdel.c, src/chgpasswd.c, src/useradd.c, src/groupmod.c,
src/groupadd.c, src/chage.c: Implement ACCT_TOOLS_SETUID
(--enable-account-tools-setuid).
* etc/pam.d/Makefile.am: Install the pam service file for the
above tools only when needed.
* src/useradd.c, src/userdel.c, src/usermod.c: It is no more
needed to initialize retval to PAM_SUCCESS.
2008-09-07 03:05:37 +05:30
|
|
|
#endif /* ACCT_TOOLS_SETUID */
|
2007-10-07 17:17:01 +05:30
|
|
|
#include "prototypes.h"
|
|
|
|
#include "defines.h"
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "getdef.h"
|
|
|
|
#include "groupio.h"
|
2007-10-07 17:17:22 +05:30
|
|
|
#include "nscd.h"
|
|
|
|
#include "pwio.h"
|
2007-12-29 22:56:28 +05:30
|
|
|
#include "sgroupio.h"
|
2007-10-07 17:14:02 +05:30
|
|
|
#include "shadowio.h"
|
2008-02-03 23:15:58 +05:30
|
|
|
#include "chkname.h"
|
2009-04-12 05:00:44 +05:30
|
|
|
|
2007-10-07 17:17:01 +05:30
|
|
|
/*
|
|
|
|
* Global variables
|
|
|
|
*/
|
* 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
|
|
|
char *Prog;
|
|
|
|
|
2008-06-10 01:06:08 +05:30
|
|
|
static bool cflg = false;
|
|
|
|
static bool rflg = false; /* create a system account */
|
2009-03-14 03:56:35 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2008-06-10 01:06:08 +05:30
|
|
|
static bool sflg = false;
|
2009-03-14 03:56:35 +05:30
|
|
|
#endif
|
2007-11-24 01:54:42 +05:30
|
|
|
|
|
|
|
static char *crypt_method = NULL;
|
2009-03-14 03:56:35 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2007-11-24 01:54:42 +05:30
|
|
|
static long sha_rounds = 5000;
|
2009-03-14 03:56:35 +05:30
|
|
|
#endif
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-10 01:06:08 +05:30
|
|
|
static bool is_shadow;
|
2007-12-29 22:56:28 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-06-10 01:06:08 +05:30
|
|
|
static bool is_shadow_grp;
|
* 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-12-29 22:56:28 +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 pw_locked = false;
|
|
|
|
static bool gr_locked = false;
|
|
|
|
static bool spw_locked = false;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/* local function prototypes */
|
2007-10-07 17:14:59 +05:30
|
|
|
static void usage (void);
|
2008-03-09 02:34:31 +05:30
|
|
|
static void fail_exit (int);
|
2008-02-03 23:15:58 +05:30
|
|
|
static int add_group (const char *, const char *, gid_t *, gid_t);
|
2009-03-09 02:13:15 +05:30
|
|
|
static int get_user_id (const char *, uid_t *);
|
2008-02-03 23:15:58 +05:30
|
|
|
static int add_user (const char *, uid_t, gid_t);
|
2007-10-07 17:14:59 +05:30
|
|
|
static void update_passwd (struct passwd *, const char *);
|
|
|
|
static int add_passwd (struct passwd *, const char *);
|
2007-12-29 19:41:54 +05:30
|
|
|
static void process_flags (int argc, char **argv);
|
|
|
|
static void check_flags (void);
|
|
|
|
static void check_perms (void);
|
|
|
|
static void open_files (void);
|
|
|
|
static void close_files (void);
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
|
|
|
* usage - display usage message and exit
|
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
static void usage (void)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-11-24 01:54:42 +05:30
|
|
|
fprintf (stderr, _("Usage: %s [options] [input]\n"
|
|
|
|
"\n"
|
2007-12-29 20:04:39 +05:30
|
|
|
" -c, --crypt-method the crypt method (one of %s)\n"
|
2008-02-20 02:31:38 +05:30
|
|
|
" -r, --system create system accounts\n"
|
2007-12-29 20:04:39 +05:30
|
|
|
"%s"
|
|
|
|
"\n"),
|
|
|
|
Prog,
|
* configure.in: New configure option: --with-sha-crypt enabled by
default. Keeping the feature enabled is safe. Disabling it permits
to disable the references to the SHA256 and SHA512 password
encryption algorithms from the usage help and manuals (in addition
to the support for these algorithms in the code).
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: ENCRYPT_METHOD is
always supported in login.defs. Remove the ENCRYPTMETHOD_SELECT
preprocessor condition.
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: Disable SHA256 and
SHA512 if USE_SHA_CRYPT is not defined (this corresponds to a
subset of the ENCRYPTMETHOD_SELECT sections).
2007-11-24 18:38:08 +05:30
|
|
|
#ifndef USE_SHA_CRYPT
|
2007-12-29 20:04:39 +05:30
|
|
|
"NONE DES MD5", ""
|
2007-11-24 01:54:42 +05:30
|
|
|
#else
|
2007-12-29 20:04:39 +05:30
|
|
|
"NONE DES MD5 SHA256 SHA512",
|
|
|
|
_(" -s, --sha-rounds number of SHA rounds for the SHA*\n"
|
|
|
|
" crypt algorithms\n")
|
2007-11-24 01:54:42 +05:30
|
|
|
#endif
|
2007-12-29 20:04:39 +05:30
|
|
|
);
|
2007-10-07 17:14:59 +05:30
|
|
|
exit (1);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2008-03-09 02:34:31 +05:30
|
|
|
/*
|
|
|
|
* fail_exit - undo as much as possible
|
|
|
|
*/
|
|
|
|
static void fail_exit (int code)
|
|
|
|
{
|
* 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 (spw_locked) {
|
2008-08-07 13:33:13 +05:30
|
|
|
if (spw_unlock () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
|
|
|
|
/* continue */
|
|
|
|
}
|
2008-03-09 02:34:31 +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
|
|
|
if (pw_locked) {
|
2008-08-07 13:33:13 +05:30
|
|
|
if (pw_unlock () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
|
|
|
|
/* continue */
|
|
|
|
}
|
2008-03-09 02:34:31 +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
|
|
|
if (gr_locked) {
|
2008-08-07 13:33:13 +05:30
|
|
|
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 */
|
|
|
|
}
|
2008-03-09 02:34:31 +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-07 13:33:13 +05:30
|
|
|
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 */
|
|
|
|
}
|
2008-03-09 02:34:31 +05:30
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
exit (code);
|
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
|
|
|
* add_group - create a new group or add a user to an existing group
|
|
|
|
*/
|
2008-02-03 23:15:58 +05:30
|
|
|
static int add_group (const char *name, const char *gid, gid_t *ngid, uid_t uid)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
|
|
|
const struct group *grp;
|
2007-10-07 17:14:59 +05:30
|
|
|
struct group grent;
|
2007-12-29 22:35:13 +05:30
|
|
|
char *members[1];
|
2007-12-29 22:56:28 +05:30
|
|
|
#ifdef SHADOWGRP
|
|
|
|
const struct sgrp *sg;
|
|
|
|
#endif
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Start by seeing if the named group already exists. This will be
|
|
|
|
* very easy to deal with if it does.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-02-03 23:15:58 +05:30
|
|
|
grp = getgrnam (gid);
|
|
|
|
if (NULL == grp) {
|
|
|
|
grp = gr_locate (gid);
|
|
|
|
}
|
2007-12-29 20:18:33 +05:30
|
|
|
if (NULL != grp) {
|
2007-12-29 22:35:13 +05:30
|
|
|
/* The user will use this ID for her primary group */
|
|
|
|
*ngid = grp->gr_gid;
|
2007-12-29 22:56:28 +05:30
|
|
|
/* Don't check gshadow */
|
2007-12-29 22:35:13 +05:30
|
|
|
return 0;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2008-02-03 23:15:58 +05:30
|
|
|
if (isdigit (gid[0])) {
|
2007-10-07 17:14:59 +05:30
|
|
|
/*
|
|
|
|
* The GID is a number, which means either this is a brand
|
2007-12-29 22:35:13 +05:30
|
|
|
* new group, or an existing group.
|
2007-10-07 17:14:59 +05:30
|
|
|
*/
|
2009-03-09 02:13:15 +05:30
|
|
|
|
|
|
|
if (get_gid (gid, &grent.gr_gid) == 0) {
|
2008-02-03 23:15:58 +05:30
|
|
|
fprintf (stderr,
|
2009-03-09 02:13:15 +05:30
|
|
|
_("%s: invalid group ID '%s'\n"),
|
2008-02-03 23:15:58 +05:30
|
|
|
Prog, gid);
|
|
|
|
return -1;
|
|
|
|
}
|
2009-03-09 02:13:15 +05:30
|
|
|
|
2008-06-14 02:26:44 +05:30
|
|
|
/* Look in both the system database (getgrgid) and in the
|
|
|
|
* internal database (gr_locate_gid), which may contain
|
|
|
|
* uncommitted changes */
|
2009-03-09 02:13:15 +05:30
|
|
|
if ( (getgrgid ((gid_t) grent.gr_gid) != NULL)
|
|
|
|
|| (gr_locate_gid ((gid_t) grent.gr_gid) != NULL)) {
|
2008-02-03 23:15:58 +05:30
|
|
|
/* The user will use this ID for her
|
|
|
|
* primary group */
|
2009-03-09 02:13:15 +05:30
|
|
|
*ngid = (gid_t) grent.gr_gid;
|
2008-02-03 23:15:58 +05:30
|
|
|
return 0;
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2009-03-09 02:13:15 +05:30
|
|
|
|
|
|
|
/* Do not create groups with GID == (gid_t)-1 */
|
|
|
|
if (grent.gr_gid == (gid_t)-1) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: invalid group ID '%s'\n"),
|
|
|
|
Prog, gid);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-12-29 20:04:39 +05:30
|
|
|
} else {
|
2008-02-03 23:15:58 +05:30
|
|
|
/* The gid parameter can be "" or a name which is not
|
|
|
|
* already the name of an existing group.
|
|
|
|
* In both cases, figure out what group ID can be used.
|
2007-10-07 17:14:59 +05:30
|
|
|
*/
|
2008-02-20 02:31:38 +05:30
|
|
|
if (find_new_gid(rflg, &grent.gr_gid, &uid) < 0) {
|
2008-02-03 23:15:58 +05:30
|
|
|
return -1;
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Now I have all of the fields required to create the new group.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-02-03 23:15:58 +05:30
|
|
|
if (('\0' != gid[0]) && (!isdigit (gid[0]))) {
|
2007-10-07 17:14:59 +05:30
|
|
|
grent.gr_name = xstrdup (gid);
|
2007-12-29 20:04:39 +05:30
|
|
|
} else {
|
2007-10-07 17:14:59 +05:30
|
|
|
grent.gr_name = xstrdup (name);
|
2009-03-14 03:56:35 +05:30
|
|
|
/* FIXME: check if the group exist */
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-02-03 23:15:58 +05:30
|
|
|
/* Check if this is a valid group name */
|
2008-05-26 02:28:16 +05:30
|
|
|
if (!is_valid_group_name (grent.gr_name)) {
|
2008-02-03 23:15:58 +05:30
|
|
|
fprintf (stderr,
|
* 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
|
|
|
_("%s: invalid group name '%s'\n"),
|
2008-02-03 23:15:58 +05:30
|
|
|
Prog, grent.gr_name);
|
|
|
|
free (grent.gr_name);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:59 +05:30
|
|
|
grent.gr_passwd = "x"; /* XXX warning: const */
|
2007-12-29 22:35:13 +05:30
|
|
|
members[0] = NULL;
|
2007-10-07 17:14:02 +05:30
|
|
|
grent.gr_mem = members;
|
|
|
|
|
|
|
|
*ngid = grent.gr_gid;
|
2007-12-29 22:56:28 +05:30
|
|
|
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
if (is_shadow_grp) {
|
2008-02-03 23:15:58 +05:30
|
|
|
sg = sgr_locate (grent.gr_name);
|
2007-12-29 22:56:28 +05:30
|
|
|
|
|
|
|
if (NULL != sg) {
|
|
|
|
fprintf (stderr,
|
* 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
|
|
|
_("%s: group '%s' is a shadow group, but does not exist in /etc/group\n"),
|
2008-02-03 23:15:58 +05:30
|
|
|
Prog, grent.gr_name);
|
2007-12-29 22:56:28 +05:30
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (gr_update (&grent) == 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SHADOWGRP
|
|
|
|
if (is_shadow_grp) {
|
|
|
|
struct sgrp sgrent;
|
2008-02-03 23:15:58 +05:30
|
|
|
char *admins[1];
|
2007-12-29 22:56:28 +05:30
|
|
|
sgrent.sg_name = grent.gr_name;
|
|
|
|
sgrent.sg_passwd = "*"; /* XXX warning: const */
|
2008-02-03 23:15:58 +05:30
|
|
|
admins[0] = NULL;
|
|
|
|
sgrent.sg_adm = admins;
|
2007-12-29 22:56:28 +05:30
|
|
|
sgrent.sg_mem = members;
|
|
|
|
|
|
|
|
if (sgr_update (&sgrent) == 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2009-03-09 02:13:15 +05:30
|
|
|
static int get_user_id (const char *uid, uid_t *nuid) {
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* The first guess for the UID is either the numerical UID that the
|
|
|
|
* caller provided, or the next available UID.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-02-03 23:15:58 +05:30
|
|
|
if (isdigit (uid[0])) {
|
2009-03-09 02:13:15 +05:30
|
|
|
if ((get_uid (uid, nuid) == 0) || (*nuid == (uid_t)-1)) {
|
2008-02-03 23:15:58 +05:30
|
|
|
fprintf (stderr,
|
2009-03-09 02:13:15 +05:30
|
|
|
_("%s: invalid user ID '%s'\n"),
|
2008-02-03 23:15:58 +05:30
|
|
|
Prog, uid);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
} else {
|
2007-12-29 20:18:33 +05:30
|
|
|
if ('\0' != uid[0]) {
|
2008-08-30 23:58:24 +05:30
|
|
|
const struct passwd *pwd;
|
2008-02-03 23:15:58 +05:30
|
|
|
/* local, no need for xgetpwnam */
|
|
|
|
pwd = getpwnam (uid);
|
|
|
|
if (NULL == pwd) {
|
|
|
|
pwd = pw_locate (uid);
|
|
|
|
}
|
2007-12-29 20:18:33 +05:30
|
|
|
|
2008-02-03 23:15:58 +05:30
|
|
|
if (NULL != pwd) {
|
|
|
|
*nuid = pwd->pw_uid;
|
|
|
|
} else {
|
|
|
|
fprintf (stderr,
|
* 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
|
|
|
_("%s: user '%s' does not exist\n"),
|
2008-02-03 23:15:58 +05:30
|
|
|
Prog, uid);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-12-29 20:18:33 +05:30
|
|
|
} else {
|
2008-02-20 02:31:38 +05:30
|
|
|
if (find_new_uid (rflg, nuid, NULL) < 0) {
|
2008-02-03 23:15:58 +05:30
|
|
|
return -1;
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2008-02-03 23:15:58 +05:30
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* add_user - create a new user ID
|
|
|
|
*/
|
|
|
|
static int add_user (const char *name, uid_t uid, gid_t gid)
|
|
|
|
{
|
|
|
|
struct passwd pwent;
|
|
|
|
|
|
|
|
/* Check if this is a valid user name */
|
2008-05-26 02:28:16 +05:30
|
|
|
if (!is_valid_user_name (name)) {
|
2008-02-03 23:15:58 +05:30
|
|
|
fprintf (stderr,
|
* 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
|
|
|
_("%s: invalid user name '%s'\n"),
|
2008-02-03 23:15:58 +05:30
|
|
|
Prog, name);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* I don't want to fill in the entire password structure members
|
|
|
|
* JUST YET, since there is still more data to be added. So, I fill
|
|
|
|
* in the parts that I have.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
pwent.pw_name = xstrdup (name);
|
2008-02-03 23:15:58 +05:30
|
|
|
pwent.pw_uid = uid;
|
2007-10-07 17:14:59 +05:30
|
|
|
pwent.pw_passwd = "x"; /* XXX warning: const */
|
2007-10-07 17:14:02 +05:30
|
|
|
pwent.pw_gid = gid;
|
2007-10-07 17:14:59 +05:30
|
|
|
pwent.pw_gecos = ""; /* XXX warning: const */
|
|
|
|
pwent.pw_dir = ""; /* XXX warning: const */
|
|
|
|
pwent.pw_shell = ""; /* XXX warning: const */
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-10 01:06:08 +05:30
|
|
|
return (pw_update (&pwent) == 0);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2007-12-29 20:22:35 +05:30
|
|
|
static void update_passwd (struct passwd *pwd, const char *password)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-11-24 05:56:31 +05:30
|
|
|
void *crypt_arg = NULL;
|
2007-11-24 01:54:42 +05:30
|
|
|
if (crypt_method != NULL) {
|
2009-03-14 03:56:35 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2007-12-29 20:04:39 +05:30
|
|
|
if (sflg) {
|
2007-11-24 05:56:31 +05:30
|
|
|
crypt_arg = &sha_rounds;
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2009-03-14 03:56:35 +05:30
|
|
|
#endif
|
2007-11-24 01:54:42 +05:30
|
|
|
}
|
|
|
|
|
2007-12-29 20:04:39 +05:30
|
|
|
if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) {
|
2007-12-29 20:22:35 +05:30
|
|
|
pwd->pw_passwd = (char *)password;
|
2007-11-24 01:54:42 +05:30
|
|
|
} else {
|
2007-12-29 20:22:35 +05:30
|
|
|
pwd->pw_passwd = pw_encrypt (password,
|
2007-11-24 01:54:42 +05:30
|
|
|
crypt_make_salt (crypt_method,
|
2007-11-24 05:56:31 +05:30
|
|
|
crypt_arg));
|
2007-11-24 01:54:42 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* add_passwd - add or update the encrypted password
|
|
|
|
*/
|
2007-12-29 20:22:35 +05:30
|
|
|
static int add_passwd (struct passwd *pwd, const char *password)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
|
|
|
const struct spwd *sp;
|
2007-10-07 17:14:59 +05:30
|
|
|
struct spwd spent;
|
2007-11-24 05:56:31 +05:30
|
|
|
void *crypt_arg = NULL;
|
|
|
|
if (crypt_method != NULL) {
|
2009-03-14 03:56:35 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2007-12-29 20:04:39 +05:30
|
|
|
if (sflg) {
|
2007-11-24 05:56:31 +05:30
|
|
|
crypt_arg = &sha_rounds;
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2009-03-14 03:56:35 +05:30
|
|
|
#endif
|
2007-11-24 05:56:31 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* In the case of regular password files, this is real easy - pwd
|
|
|
|
* points to the entry in the password file. Shadow files are
|
|
|
|
* harder since there are zillions of things to do ...
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
if (!is_shadow) {
|
2007-12-29 20:22:35 +05:30
|
|
|
update_passwd (pwd, password);
|
2007-10-07 17:14:02 +05:30
|
|
|
return 0;
|
|
|
|
}
|
2007-10-07 17:17:01 +05:30
|
|
|
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Do the first and easiest shadow file case. The user already
|
|
|
|
* exists in the shadow password file.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-12-29 20:18:33 +05:30
|
|
|
sp = spw_locate (pwd->pw_name);
|
|
|
|
if (NULL != sp) {
|
2007-10-07 17:14:02 +05:30
|
|
|
spent = *sp;
|
2008-06-10 01:06:08 +05:30
|
|
|
if ( (NULL != crypt_method)
|
2008-02-03 23:15:58 +05:30
|
|
|
&& (0 == strcmp(crypt_method, "NONE"))) {
|
|
|
|
spent.sp_pwdp = (char *)password;
|
|
|
|
} else {
|
|
|
|
const char *salt = crypt_make_salt (crypt_method,
|
|
|
|
crypt_arg);
|
|
|
|
spent.sp_pwdp = pw_encrypt (password, salt);
|
|
|
|
}
|
2008-06-10 01:06:08 +05:30
|
|
|
return (spw_update (&spent) == 0);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Pick the next easiest case - the user has an encrypted password
|
|
|
|
* which isn't equal to "x". The password was set to "x" earlier
|
|
|
|
* when the entry was created, so this user would have to have had
|
|
|
|
* the password set someplace else.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
if (strcmp (pwd->pw_passwd, "x") != 0) {
|
2007-12-29 20:22:35 +05:30
|
|
|
update_passwd (pwd, password);
|
2007-10-07 17:14:02 +05:30
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Now the really hard case - I need to create an entirely new
|
|
|
|
* shadow password file entry.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
|
|
|
spent.sp_namp = pwd->pw_name;
|
2008-02-03 23:15:58 +05:30
|
|
|
if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) {
|
2008-02-11 00:44:20 +05:30
|
|
|
spent.sp_pwdp = (char *)password;
|
2008-02-03 23:15:58 +05:30
|
|
|
} else {
|
|
|
|
const char *salt = crypt_make_salt (crypt_method, crypt_arg);
|
|
|
|
spent.sp_pwdp = pw_encrypt (password, salt);
|
|
|
|
}
|
2008-06-14 02:26:44 +05:30
|
|
|
spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
* libmisc/pwd2spwd.c, src/chpasswd.c, src/newusers.c,
src/passwd.c, src/pwck.c, src/pwconv.c, src/useradd.c,
src/usermod.c: On Jan 01, 1970, do not set the sp_lstchg field to
0 (which means that the password shall be changed during the next
login), but use -1 (password aging disabled).
* src/passwd.c: Do not check sp_min if sp_lstchg is null or -1.
2009-04-06 02:53:27 +05:30
|
|
|
if (0 == spent.sp_lstchg) {
|
|
|
|
/* Better disable aging than requiring a password change */
|
|
|
|
spent.sp_lstchg = -1;
|
|
|
|
}
|
2008-06-14 02:26:44 +05:30
|
|
|
spent.sp_min = getdef_num ("PASS_MIN_DAYS", 0);
|
2007-10-07 17:14:59 +05:30
|
|
|
/* 10000 is infinity this week */
|
2008-06-14 02:26:44 +05:30
|
|
|
spent.sp_max = getdef_num ("PASS_MAX_DAYS", 10000);
|
|
|
|
spent.sp_warn = getdef_num ("PASS_WARN_AGE", -1);
|
|
|
|
spent.sp_inact = -1;
|
2007-10-07 17:14:02 +05:30
|
|
|
spent.sp_expire = -1;
|
2008-06-14 02:26:44 +05:30
|
|
|
spent.sp_flag = SHADOW_SP_FLAG_UNSET;
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-10 01:06:08 +05:30
|
|
|
return (spw_update (&spent) == 0);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
2007-12-29 19:41:54 +05:30
|
|
|
/*
|
|
|
|
* process_flags - parse the command line options
|
|
|
|
*
|
|
|
|
* It will not return if an error is encountered.
|
|
|
|
*/
|
|
|
|
static void process_flags (int argc, char **argv)
|
2007-10-07 17:14:02 +05:30
|
|
|
{
|
2007-12-29 19:41:54 +05:30
|
|
|
int option_index = 0;
|
|
|
|
int c;
|
|
|
|
static struct option long_options[] = {
|
|
|
|
{"crypt-method", required_argument, NULL, 'c'},
|
|
|
|
{"help", no_argument, NULL, 'h'},
|
* configure.in: New configure option: --with-sha-crypt enabled by
default. Keeping the feature enabled is safe. Disabling it permits
to disable the references to the SHA256 and SHA512 password
encryption algorithms from the usage help and manuals (in addition
to the support for these algorithms in the code).
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: ENCRYPT_METHOD is
always supported in login.defs. Remove the ENCRYPTMETHOD_SELECT
preprocessor condition.
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: Disable SHA256 and
SHA512 if USE_SHA_CRYPT is not defined (this corresponds to a
subset of the ENCRYPTMETHOD_SELECT sections).
2007-11-24 18:38:08 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2007-12-29 19:41:54 +05:30
|
|
|
{"sha-rounds", required_argument, NULL, 's'},
|
2007-11-24 05:56:31 +05:30
|
|
|
#endif
|
2008-06-10 01:06:08 +05:30
|
|
|
{"system", no_argument, NULL, 'r'},
|
2007-12-29 19:41:54 +05:30
|
|
|
{NULL, 0, NULL, '\0'}
|
|
|
|
};
|
2007-11-24 01:54:42 +05:30
|
|
|
|
2007-12-29 19:41:54 +05:30
|
|
|
while ((c = getopt_long (argc, argv,
|
* configure.in: New configure option: --with-sha-crypt enabled by
default. Keeping the feature enabled is safe. Disabling it permits
to disable the references to the SHA256 and SHA512 password
encryption algorithms from the usage help and manuals (in addition
to the support for these algorithms in the code).
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: ENCRYPT_METHOD is
always supported in login.defs. Remove the ENCRYPTMETHOD_SELECT
preprocessor condition.
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: Disable SHA256 and
SHA512 if USE_SHA_CRYPT is not defined (this corresponds to a
subset of the ENCRYPTMETHOD_SELECT sections).
2007-11-24 18:38:08 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2009-04-11 18:30:32 +05:30
|
|
|
"c:hrs:",
|
2007-11-24 05:56:31 +05:30
|
|
|
#else
|
2009-04-11 18:30:32 +05:30
|
|
|
"c:hr",
|
2007-11-24 05:56:31 +05:30
|
|
|
#endif
|
2007-12-29 19:41:54 +05:30
|
|
|
long_options, &option_index)) != -1) {
|
|
|
|
switch (c) {
|
|
|
|
case 'c':
|
2008-06-10 01:06:08 +05:30
|
|
|
cflg = true;
|
2007-12-29 19:41:54 +05:30
|
|
|
crypt_method = optarg;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
usage ();
|
|
|
|
break;
|
2008-06-10 01:06:08 +05:30
|
|
|
case 'r':
|
|
|
|
rflg = true;
|
|
|
|
break;
|
* configure.in: New configure option: --with-sha-crypt enabled by
default. Keeping the feature enabled is safe. Disabling it permits
to disable the references to the SHA256 and SHA512 password
encryption algorithms from the usage help and manuals (in addition
to the support for these algorithms in the code).
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: ENCRYPT_METHOD is
always supported in login.defs. Remove the ENCRYPTMETHOD_SELECT
preprocessor condition.
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: Disable SHA256 and
SHA512 if USE_SHA_CRYPT is not defined (this corresponds to a
subset of the ENCRYPTMETHOD_SELECT sections).
2007-11-24 18:38:08 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2007-12-29 19:41:54 +05:30
|
|
|
case 's':
|
2008-06-10 01:06:08 +05:30
|
|
|
sflg = true;
|
2009-03-14 03:56:35 +05:30
|
|
|
if (getlong(optarg, &sha_rounds) == 0) {
|
2007-12-29 19:41:54 +05:30
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: invalid numeric argument '%s'\n"),
|
|
|
|
Prog, optarg);
|
2007-11-24 01:54:42 +05:30
|
|
|
usage ();
|
|
|
|
}
|
2007-12-29 19:41:54 +05:30
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 0:
|
|
|
|
/* long option */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argv[optind] != NULL) {
|
2008-06-10 01:06:08 +05:30
|
|
|
if (freopen (argv[optind], "r", stdin) == NULL) {
|
2007-12-29 19:41:54 +05:30
|
|
|
char buf[BUFSIZ];
|
|
|
|
snprintf (buf, sizeof buf, "%s: %s", Prog, argv[1]);
|
|
|
|
perror (buf);
|
2008-03-09 02:34:31 +05:30
|
|
|
fail_exit (1);
|
2007-11-24 01:54:42 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* validate options */
|
2007-12-29 19:41:54 +05:30
|
|
|
check_flags ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* check_flags - check flags and parameters consistency
|
|
|
|
*
|
|
|
|
* It will not return if an error is encountered.
|
|
|
|
*/
|
|
|
|
static void check_flags (void)
|
|
|
|
{
|
2009-03-14 03:56:35 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2007-11-24 01:54:42 +05:30
|
|
|
if (sflg && !cflg) {
|
|
|
|
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: %s flag is only allowed with the %s flag\n"),
|
2007-11-24 01:54:42 +05:30
|
|
|
Prog, "-s", "-c");
|
2007-10-07 17:15:40 +05:30
|
|
|
usage ();
|
2007-11-24 01:54:42 +05:30
|
|
|
}
|
2009-03-14 03:56:35 +05:30
|
|
|
#endif
|
2007-12-29 19:41:54 +05:30
|
|
|
|
2007-11-24 01:54:42 +05:30
|
|
|
if (cflg) {
|
2007-12-29 20:04:39 +05:30
|
|
|
if ( (0 != strcmp (crypt_method, "DES"))
|
|
|
|
&& (0 != strcmp (crypt_method, "MD5"))
|
|
|
|
&& (0 != strcmp (crypt_method, "NONE"))
|
* configure.in: New configure option: --with-sha-crypt enabled by
default. Keeping the feature enabled is safe. Disabling it permits
to disable the references to the SHA256 and SHA512 password
encryption algorithms from the usage help and manuals (in addition
to the support for these algorithms in the code).
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: ENCRYPT_METHOD is
always supported in login.defs. Remove the ENCRYPTMETHOD_SELECT
preprocessor condition.
* libmisc/obscure.c, libmisc/salt.c, src/newusers.c,
src/chpasswd.c, src/chgpasswd.c, src/passwd.c: Disable SHA256 and
SHA512 if USE_SHA_CRYPT is not defined (this corresponds to a
subset of the ENCRYPTMETHOD_SELECT sections).
2007-11-24 18:38:08 +05:30
|
|
|
#ifdef USE_SHA_CRYPT
|
2007-12-29 20:04:39 +05:30
|
|
|
&& (0 != strcmp (crypt_method, "SHA256"))
|
|
|
|
&& (0 != strcmp (crypt_method, "SHA512"))
|
2007-11-24 01:54:42 +05:30
|
|
|
#endif
|
|
|
|
) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: unsupported crypt method: %s\n"),
|
|
|
|
Prog, crypt_method);
|
|
|
|
usage ();
|
|
|
|
}
|
|
|
|
}
|
2007-12-29 19:41:54 +05:30
|
|
|
}
|
2007-11-24 01:54:42 +05:30
|
|
|
|
2007-12-29 19:41:54 +05:30
|
|
|
/*
|
|
|
|
* check_perms - check if the caller is allowed to add a group
|
|
|
|
*
|
|
|
|
* With PAM support, the setuid bit can be set on groupadd to allow
|
|
|
|
* non-root users to groups.
|
|
|
|
* Without PAM support, only users who can write in the group databases
|
|
|
|
* can add groups.
|
|
|
|
*
|
|
|
|
* It will not return if the user is not allowed.
|
|
|
|
*/
|
|
|
|
static void check_perms (void)
|
|
|
|
{
|
* configure.in: Added option --enable-account-tools-setuid to
enable/disable the usage of PAM to authenticate the callers of
account management tools: chage, chgpasswd, chpasswd, groupadd,
groupdel, groupmod, useradd, userdel, usermod.
* src/Makefile.am: Do not link the above tools with libpam if
account-tools-setuid is disabled.
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/usermod.c,
src/groupdel.c, src/chgpasswd.c, src/useradd.c, src/groupmod.c,
src/groupadd.c, src/chage.c: Implement ACCT_TOOLS_SETUID
(--enable-account-tools-setuid).
* etc/pam.d/Makefile.am: Install the pam service file for the
above tools only when needed.
* src/useradd.c, src/userdel.c, src/usermod.c: It is no more
needed to initialize retval to PAM_SUCCESS.
2008-09-07 03:05:37 +05:30
|
|
|
#ifdef ACCT_TOOLS_SETUID
|
2007-10-07 17:14:38 +05:30
|
|
|
#ifdef USE_PAM
|
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/chfn.c,
src/groupmems.c, src/usermod.c, src/groupdel.c, src/chgpasswd.c,
src/useradd.c, src/groupmod.c, src/groupadd.c, src/chage.c,
src/chsh.c: Simplify the PAM error handling. Do not keep the pamh
handle, but terminate the PAM transaction as soon as possible if
there are no PAM session opened.
2008-09-06 18:58:02 +05:30
|
|
|
pam_handle_t *pamh = NULL;
|
|
|
|
int retval;
|
2007-12-29 19:41:54 +05:30
|
|
|
struct passwd *pampw;
|
2007-10-07 17:14:38 +05:30
|
|
|
|
2007-12-29 19:41:54 +05:30
|
|
|
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
* 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
|
|
|
if (NULL == pampw) {
|
Additional PAM cleanup:
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/chfn.c,
src/groupmems.c, src/usermod.c, src/groupdel.c, src/chgpasswd.c,
src/useradd.c, src/groupmod.c, src/groupadd.c, src/chage.c,
src/chsh.c: If the username cannot be determined, report it as
such (not a PAM authentication failure).
2008-09-07 05:16:44 +05:30
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: Cannot determine your user name.\n"),
|
|
|
|
Prog);
|
|
|
|
fail_exit (1);
|
2007-10-07 17:14:38 +05:30
|
|
|
}
|
|
|
|
|
Additional PAM cleanup:
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/chfn.c,
src/groupmems.c, src/usermod.c, src/groupdel.c, src/chgpasswd.c,
src/useradd.c, src/groupmod.c, src/groupadd.c, src/chage.c,
src/chsh.c: If the username cannot be determined, report it as
such (not a PAM authentication failure).
2008-09-07 05:16:44 +05:30
|
|
|
retval = pam_start ("newusers", pampw->pw_name, &conv, &pamh);
|
|
|
|
|
* 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
|
|
|
if (PAM_SUCCESS == retval) {
|
2007-10-07 17:14:59 +05:30
|
|
|
retval = pam_authenticate (pamh, 0);
|
2007-10-07 17:14:38 +05:30
|
|
|
}
|
|
|
|
|
* 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
|
|
|
if (PAM_SUCCESS == retval) {
|
2007-10-07 17:14:59 +05:30
|
|
|
retval = pam_acct_mgmt (pamh, 0);
|
2007-10-07 17:14:38 +05:30
|
|
|
}
|
|
|
|
|
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/chfn.c,
src/groupmems.c, src/usermod.c, src/groupdel.c, src/chgpasswd.c,
src/useradd.c, src/groupmod.c, src/groupadd.c, src/chage.c,
src/chsh.c: Simplify the PAM error handling. Do not keep the pamh
handle, but terminate the PAM transaction as soon as possible if
there are no PAM session opened.
2008-09-06 18:58:02 +05:30
|
|
|
if (NULL != pamh) {
|
* 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
|
|
|
(void) pam_end (pamh, retval);
|
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/chfn.c,
src/groupmems.c, src/usermod.c, src/groupdel.c, src/chgpasswd.c,
src/useradd.c, src/groupmod.c, src/groupadd.c, src/chage.c,
src/chsh.c: Simplify the PAM error handling. Do not keep the pamh
handle, but terminate the PAM transaction as soon as possible if
there are no PAM session opened.
2008-09-06 18:58:02 +05:30
|
|
|
}
|
|
|
|
if (PAM_SUCCESS != retval) {
|
2007-10-07 17:16:07 +05:30
|
|
|
fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
|
2008-03-09 02:34:31 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:14:38 +05:30
|
|
|
}
|
2007-10-07 17:14:59 +05:30
|
|
|
#endif /* USE_PAM */
|
* configure.in: Added option --enable-account-tools-setuid to
enable/disable the usage of PAM to authenticate the callers of
account management tools: chage, chgpasswd, chpasswd, groupadd,
groupdel, groupmod, useradd, userdel, usermod.
* src/Makefile.am: Do not link the above tools with libpam if
account-tools-setuid is disabled.
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/usermod.c,
src/groupdel.c, src/chgpasswd.c, src/useradd.c, src/groupmod.c,
src/groupadd.c, src/chage.c: Implement ACCT_TOOLS_SETUID
(--enable-account-tools-setuid).
* etc/pam.d/Makefile.am: Install the pam service file for the
above tools only when needed.
* src/useradd.c, src/userdel.c, src/usermod.c: It is no more
needed to initialize retval to PAM_SUCCESS.
2008-09-07 03:05:37 +05:30
|
|
|
#endif /* ACCT_TOOLS_SETUID */
|
2007-12-29 19:41:54 +05:30
|
|
|
}
|
2007-10-07 17:14:38 +05:30
|
|
|
|
2007-12-29 19:41:54 +05:30
|
|
|
/*
|
|
|
|
* open_files - lock and open the password, group and shadow databases
|
|
|
|
*/
|
|
|
|
static void open_files (void)
|
|
|
|
{
|
2007-10-07 17:14:02 +05:30
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Lock the password files and open them for update. This will bring
|
|
|
|
* all of the entries into memory where they may be searched for an
|
|
|
|
* modified, or new entries added. The password file is the key - if
|
|
|
|
* it gets locked, assume the others can be locked right away.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-06-10 01:06:08 +05:30
|
|
|
if (pw_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, pw_dbname ());
|
2008-03-09 02:34:31 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:14:02 +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
|
|
|
pw_locked = true;
|
2008-08-22 07:59:31 +05:30
|
|
|
if (is_shadow) {
|
|
|
|
if (spw_lock () == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: cannot lock %s; try again later.\n"),
|
|
|
|
Prog, spw_dbname ());
|
|
|
|
fail_exit (1);
|
|
|
|
}
|
|
|
|
spw_locked = true;
|
2008-03-09 02:34:31 +05:30
|
|
|
}
|
2008-06-10 01:06:08 +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"),
|
|
|
|
Prog, gr_dbname ());
|
2008-03-09 02:34:31 +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
|
|
|
gr_locked = true;
|
2007-12-29 23:04:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-08-22 07:59:31 +05:30
|
|
|
if (is_shadow_grp) {
|
|
|
|
if (sgr_lock () == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: cannot lock %s; try again later.\n"),
|
|
|
|
Prog, sgr_dbname ());
|
|
|
|
fail_exit (1);
|
|
|
|
}
|
|
|
|
sgr_locked = true;
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2008-03-09 02:34:31 +05:30
|
|
|
#endif
|
|
|
|
|
2008-08-10 04:53:12 +05:30
|
|
|
if (pw_open (O_RDWR) == 0) {
|
2008-08-07 13:33:13 +05:30
|
|
|
fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
|
|
|
|
fail_exit (1);
|
|
|
|
}
|
2008-08-10 04:53:12 +05:30
|
|
|
if (is_shadow && (spw_open (O_RDWR) == 0)) {
|
2008-08-07 13:33:13 +05:30
|
|
|
fprintf (stderr, _("%s: cannot open %s\n"), Prog, spw_dbname ());
|
|
|
|
fail_exit (1);
|
|
|
|
}
|
2008-08-10 04:53:12 +05:30
|
|
|
if (gr_open (O_RDWR) == 0) {
|
2008-08-07 13:33:13 +05:30
|
|
|
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
|
|
|
|
fail_exit (1);
|
|
|
|
}
|
2007-12-29 23:04:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
2008-08-10 04:53:12 +05:30
|
|
|
if (is_shadow_grp && (sgr_open (O_RDWR) == 0)) {
|
2008-08-07 13:33:13 +05:30
|
|
|
fprintf (stderr, _("%s: cannot open %s\n"), Prog, sgr_dbname ());
|
2008-03-09 02:34:31 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2008-08-07 13:33:13 +05:30
|
|
|
#endif
|
2007-12-29 19:41:54 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* close_files - close and unlock the password, group and shadow databases
|
|
|
|
*/
|
|
|
|
static void close_files (void)
|
|
|
|
{
|
2008-08-07 13:33:13 +05:30
|
|
|
if (pw_close () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ()));
|
|
|
|
fail_exit (1);
|
|
|
|
}
|
|
|
|
if (pw_unlock () == 0) {
|
|
|
|
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
|
|
|
|
/* continue */
|
|
|
|
}
|
* 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
|
|
|
pw_locked = false;
|
2008-08-07 13:33:13 +05:30
|
|
|
|
|
|
|
if (is_shadow) {
|
|
|
|
if (spw_close () == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: failure while writing changes to %s\n"),
|
|
|
|
Prog, spw_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ()));
|
|
|
|
fail_exit (1);
|
|
|
|
}
|
|
|
|
if (spw_unlock () == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: failed to unlock %s\n"),
|
|
|
|
Prog, spw_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
|
|
|
|
/* continue */
|
|
|
|
}
|
* 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
|
|
|
spw_locked = false;
|
2008-08-07 13:33:13 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
if (gr_close () == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: failure while writing changes to %s\n"),
|
|
|
|
Prog, gr_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ()));
|
2008-03-09 02:34:31 +05:30
|
|
|
fail_exit (1);
|
2007-12-29 19:41:54 +05:30
|
|
|
}
|
2008-08-07 13:33:13 +05:30
|
|
|
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 */
|
|
|
|
}
|
* 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;
|
2008-08-07 13:33:13 +05:30
|
|
|
|
2007-12-29 23:04:02 +05:30
|
|
|
#ifdef SHADOWGRP
|
|
|
|
if (is_shadow_grp) {
|
2008-08-07 13:33:13 +05:30
|
|
|
if (sgr_close () == 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: failure while writing changes to %s\n"),
|
|
|
|
Prog, sgr_dbname ());
|
|
|
|
SYSLOG ((LOG_ERR, "failure while writing changes to %s", sgr_dbname ()));
|
|
|
|
fail_exit (1);
|
|
|
|
}
|
|
|
|
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 */
|
|
|
|
}
|
* 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-29 23:04:02 +05:30
|
|
|
}
|
|
|
|
#endif
|
2007-12-29 19:41:54 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
int main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
char *fields[8];
|
|
|
|
int nfields;
|
|
|
|
char *cp;
|
|
|
|
const struct passwd *pw;
|
|
|
|
struct passwd newpw;
|
|
|
|
int errors = 0;
|
|
|
|
int line = 0;
|
|
|
|
uid_t uid;
|
|
|
|
gid_t gid;
|
|
|
|
|
|
|
|
Prog = Basename (argv[0]);
|
|
|
|
|
2008-06-10 01:06:08 +05:30
|
|
|
(void) setlocale (LC_ALL, "");
|
|
|
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
|
|
|
(void) textdomain (PACKAGE);
|
2007-12-29 19:41:54 +05:30
|
|
|
|
2008-08-22 07:59:31 +05:30
|
|
|
OPENLOG ("newusers");
|
|
|
|
|
2007-12-29 19:41:54 +05:30
|
|
|
process_flags (argc, argv);
|
|
|
|
|
|
|
|
check_perms ();
|
|
|
|
|
|
|
|
is_shadow = spw_file_present ();
|
|
|
|
|
2007-12-29 22:56:28 +05:30
|
|
|
#ifdef SHADOWGRP
|
|
|
|
is_shadow_grp = sgr_file_present ();
|
|
|
|
#endif
|
|
|
|
|
2007-12-29 19:41:54 +05:30
|
|
|
open_files ();
|
2007-10-07 17:14:02 +05:30
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Read each line. The line has the same format as a password file
|
2007-11-22 02:57:44 +05:30
|
|
|
* entry, except that certain fields are not constrained to be
|
2007-10-07 17:14:59 +05:30
|
|
|
* numerical values. If a group ID is entered which does not already
|
|
|
|
* exist, an attempt is made to allocate the same group ID as the
|
|
|
|
* numerical user ID. Should that fail, the next available group ID
|
|
|
|
* over 100 is allocated. The pw_gid field will be updated with that
|
|
|
|
* value.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-06-14 02:26:44 +05:30
|
|
|
while (fgets (buf, (int) sizeof buf, stdin) != (char *) 0) {
|
2007-10-07 17:14:02 +05:30
|
|
|
line++;
|
2007-12-29 20:18:33 +05:30
|
|
|
cp = strrchr (buf, '\n');
|
|
|
|
if (NULL != cp) {
|
2007-10-07 17:14:02 +05:30
|
|
|
*cp = '\0';
|
|
|
|
} else {
|
|
|
|
fprintf (stderr, _("%s: line %d: line too long\n"),
|
2007-12-29 20:04:39 +05:30
|
|
|
Prog, line);
|
2007-10-07 17:14:02 +05:30
|
|
|
errors++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Break the string into fields and screw around with them.
|
|
|
|
* There MUST be 7 colon separated fields, although the
|
|
|
|
* values aren't that particular.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-10-07 17:14:59 +05:30
|
|
|
for (cp = buf, nfields = 0; nfields < 7; nfields++) {
|
2007-10-07 17:14:02 +05:30
|
|
|
fields[nfields] = cp;
|
2007-12-29 20:18:33 +05:30
|
|
|
cp = strchr (cp, ':');
|
|
|
|
if (NULL != cp) {
|
2008-06-10 01:06:08 +05:30
|
|
|
*cp = '\0';
|
|
|
|
cp++;
|
2007-12-29 20:04:39 +05:30
|
|
|
} else {
|
2007-10-07 17:14:02 +05:30
|
|
|
break;
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
if (nfields != 6) {
|
|
|
|
fprintf (stderr, _("%s: line %d: invalid line\n"),
|
2007-12-29 20:04:39 +05:30
|
|
|
Prog, line);
|
2007-10-07 17:14:02 +05:30
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2008-02-03 23:15:58 +05:30
|
|
|
* First check if we have to create of update an user
|
|
|
|
*/
|
|
|
|
pw = pw_locate (fields[0]);
|
|
|
|
/* local, no need for xgetpwnam */
|
|
|
|
if ( (NULL == pw)
|
|
|
|
&& (getpwnam (fields[0]) != NULL)) {
|
|
|
|
fprintf (stderr, _("%s: cannot update the entry of user %s (not in the passwd database)\n"), Prog, fields[0]);
|
|
|
|
errors++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (NULL == pw)
|
2009-03-09 02:13:15 +05:30
|
|
|
&& (get_user_id (fields[2], &uid) != 0)) {
|
2008-02-03 23:15:58 +05:30
|
|
|
fprintf (stderr,
|
|
|
|
_("%s: line %d: can't create user\n"),
|
|
|
|
Prog, line);
|
|
|
|
errors++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Processed is the group name. A new group will be
|
2007-10-07 17:14:59 +05:30
|
|
|
* created if the group name is non-numeric and does not
|
2007-12-29 22:35:13 +05:30
|
|
|
* already exist. If the group name is a number (which is not
|
|
|
|
* an existing GID), a group with the same name as the user
|
|
|
|
* will be created, with the given GID. The given or created
|
|
|
|
* group will be the primary group of the user. If
|
2007-10-07 17:14:59 +05:30
|
|
|
* there is no named group to be a member of, the UID will
|
|
|
|
* be figured out and that value will be a candidate for a
|
|
|
|
* new group, if that group ID exists, a whole new group ID
|
|
|
|
* will be made up.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-12-29 20:18:33 +05:30
|
|
|
if ( (NULL == pw)
|
2008-02-03 23:15:58 +05:30
|
|
|
&& (add_group (fields[0], fields[3], &gid, uid) != 0)) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2008-02-03 23:15:58 +05:30
|
|
|
_("%s: line %d: can't create group\n"),
|
2007-12-29 20:04:39 +05:30
|
|
|
Prog, line);
|
2007-10-07 17:14:02 +05:30
|
|
|
errors++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Now we work on the user ID. It has to be specified either
|
|
|
|
* as a numerical value, or left blank. If it is a numerical
|
|
|
|
* value, that value will be used, otherwise the next
|
|
|
|
* available user ID is computed and used. After this there
|
|
|
|
* will at least be a (struct passwd) for the user.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2007-12-29 20:04:39 +05:30
|
|
|
if ( (NULL == pw)
|
2008-02-03 23:15:58 +05:30
|
|
|
&& (add_user (fields[0], uid, gid) != 0)) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2008-02-03 23:15:58 +05:30
|
|
|
_("%s: line %d: can't create user\n"),
|
2007-12-29 20:04:39 +05:30
|
|
|
Prog, line);
|
2007-10-07 17:14:02 +05:30
|
|
|
errors++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The password, gecos field, directory, and shell fields
|
|
|
|
* all come next.
|
|
|
|
*/
|
2007-12-29 20:18:33 +05:30
|
|
|
pw = pw_locate (fields[0]);
|
|
|
|
if (NULL == pw) {
|
2007-10-07 17:14:59 +05:30
|
|
|
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: line %d: user '%s' does not exist in %s\n"),
|
|
|
|
Prog, line, fields[0], pw_dbname ());
|
2007-10-07 17:14:02 +05:30
|
|
|
errors++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
newpw = *pw;
|
|
|
|
|
|
|
|
if (add_passwd (&newpw, fields[1])) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2007-12-29 20:04:39 +05:30
|
|
|
_("%s: line %d: can't update password\n"),
|
|
|
|
Prog, line);
|
2007-10-07 17:14:02 +05:30
|
|
|
errors++;
|
|
|
|
continue;
|
|
|
|
}
|
2008-06-10 01:06:08 +05:30
|
|
|
if ('\0' != fields[4][0]) {
|
2007-10-07 17:14:02 +05:30
|
|
|
newpw.pw_gecos = fields[4];
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-10 01:06:08 +05:30
|
|
|
if ('\0' != fields[5][0]) {
|
2007-10-07 17:14:02 +05:30
|
|
|
newpw.pw_dir = fields[5];
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-10 01:06:08 +05:30
|
|
|
if ('\0' != fields[6][0]) {
|
2007-10-07 17:14:02 +05:30
|
|
|
newpw.pw_shell = fields[6];
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
|
2008-06-10 01:06:08 +05:30
|
|
|
if ( ('\0' != newpw.pw_dir[0])
|
|
|
|
&& (access (newpw.pw_dir, F_OK) != 0)) {
|
2009-03-14 03:56:35 +05:30
|
|
|
/* FIXME: should check for directory */
|
2008-06-10 01:06:08 +05:30
|
|
|
mode_t msk = 0777 & ~getdef_num ("UMASK",
|
|
|
|
GETDEF_DEFAULT_UMASK);
|
|
|
|
if (mkdir (newpw.pw_dir, msk) != 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2009-04-12 05:00:44 +05:30
|
|
|
_("%s: line %d: mkdir %s failed: %s\n"),
|
|
|
|
Prog, line, newpw.pw_dir,
|
|
|
|
strerror (errno));
|
2008-06-10 01:06:08 +05:30
|
|
|
} else if (chown (newpw.pw_dir,
|
|
|
|
newpw.pw_uid,
|
|
|
|
newpw.pw_gid) != 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2009-04-12 05:00:44 +05:30
|
|
|
_("%s: line %d: chown %s failed: %s\n"),
|
|
|
|
Prog, line, newpw.pw_dir,
|
|
|
|
strerror (errno));
|
2007-12-29 20:04:39 +05:30
|
|
|
}
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Update the password entry with the new changes made.
|
|
|
|
*/
|
2008-06-10 01:06:08 +05:30
|
|
|
if (pw_update (&newpw) == 0) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2007-12-29 20:04:39 +05:30
|
|
|
_("%s: line %d: can't update entry\n"),
|
|
|
|
Prog, line);
|
2007-10-07 17:14:02 +05:30
|
|
|
errors++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-10-07 17:14:59 +05:30
|
|
|
* Any detected errors will cause the entire set of changes to be
|
|
|
|
* aborted. Unlocking the password file will cause all of the
|
|
|
|
* changes to be ignored. Otherwise the file is closed, causing the
|
|
|
|
* changes to be written out all at once, and then unlocked
|
|
|
|
* afterwards.
|
2007-10-07 17:14:02 +05:30
|
|
|
*/
|
2008-06-10 01:06:08 +05:30
|
|
|
if (0 != errors) {
|
2007-10-07 17:14:59 +05:30
|
|
|
fprintf (stderr,
|
2007-12-29 20:04:39 +05:30
|
|
|
_("%s: error detected, changes ignored\n"), Prog);
|
2008-03-09 02:34:31 +05:30
|
|
|
fail_exit (1);
|
2007-10-07 17:14:02 +05:30
|
|
|
}
|
2007-12-29 19:41:54 +05:30
|
|
|
|
|
|
|
close_files ();
|
2007-10-07 17:16:52 +05:30
|
|
|
|
|
|
|
nscd_flush_cache ("passwd");
|
|
|
|
nscd_flush_cache ("group");
|
|
|
|
|
2008-03-09 02:34:31 +05:30
|
|
|
return 0;
|
2007-10-07 17:15:23 +05:30
|
|
|
}
|
2007-12-29 19:41:54 +05:30
|
|
|
|