* New function: process_flags() split out of main().
The flags variables are now global. * New functions: check_perms(), update_gecos(), get_old_fields(), and check_fields() split out of main(). * Before pam_end(), the return value of the previous pam API was already checked. No need to validate it again.
This commit is contained in:
parent
d0b984528a
commit
7279ff37f3
@ -1,3 +1,12 @@
|
|||||||
|
2007-12-31 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
* src/chfn.c: New function: process_flags() split out of main().
|
||||||
|
The flags variables are now global.
|
||||||
|
* src/chfn.c: New functions: check_perms(), update_gecos(),
|
||||||
|
get_old_fields(), and check_fields() split out of main().
|
||||||
|
* src/chfn.c: Before pam_end(), the return value of the previous
|
||||||
|
pam API was already checked. No need to validate it again.
|
||||||
|
|
||||||
2007-12-31 Nicolas François <nicolas.francois@centraliens.net>
|
2007-12-31 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
* src/newusers.c: Compilation fix for PAM support (pamh needs to be
|
* src/newusers.c: Compilation fix for PAM support (pamh needs to be
|
||||||
|
464
src/chfn.c
464
src/chfn.c
@ -63,6 +63,15 @@ static char workph[BUFSIZ];
|
|||||||
static char homeph[BUFSIZ];
|
static char homeph[BUFSIZ];
|
||||||
static char slop[BUFSIZ];
|
static char slop[BUFSIZ];
|
||||||
static int amroot;
|
static int amroot;
|
||||||
|
/* Flags */
|
||||||
|
static int fflg = 0; /* -f - set full name */
|
||||||
|
static int rflg = 0; /* -r - set room number */
|
||||||
|
static int wflg = 0; /* -w - set work phone number */
|
||||||
|
static int hflg = 0; /* -h - set home phone number */
|
||||||
|
static int oflg = 0; /* -o - set other information */
|
||||||
|
#ifdef USE_PAM
|
||||||
|
static pam_handle_t *pamh = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External identifiers
|
* External identifiers
|
||||||
@ -73,6 +82,10 @@ static void usage (void);
|
|||||||
static int may_change_field (int);
|
static int may_change_field (int);
|
||||||
static void new_fields (void);
|
static void new_fields (void);
|
||||||
static char *copy_field (char *, char *, char *);
|
static char *copy_field (char *, char *, char *);
|
||||||
|
static void process_flags (int argc, char **argv);
|
||||||
|
static void check_perms (const struct passwd *pw);
|
||||||
|
static void update_gecos (const char *user, char *gecos);
|
||||||
|
static void get_old_fields (const char *gecos);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usage - print command line syntax and exit
|
* usage - print command line syntax and exit
|
||||||
@ -197,59 +210,13 @@ static char *copy_field (char *in, char *out, char *extra)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* chfn - change a user's password file information
|
* process_flags - parse the command line options
|
||||||
*
|
*
|
||||||
* This command controls the GECOS field information in the password
|
* It will not return if an error is encountered.
|
||||||
* file entry.
|
|
||||||
*
|
|
||||||
* The valid options are
|
|
||||||
*
|
|
||||||
* -f full name
|
|
||||||
* -r room number
|
|
||||||
* -w work phone number
|
|
||||||
* -h home phone number
|
|
||||||
* -o other information (*)
|
|
||||||
*
|
|
||||||
* (*) requires root permission to execute.
|
|
||||||
*/
|
*/
|
||||||
int main (int argc, char **argv)
|
static void process_flags (int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *cp; /* temporary character pointer */
|
|
||||||
const struct passwd *pw; /* password file entry */
|
|
||||||
struct passwd pwent; /* modified password file entry */
|
|
||||||
char old_gecos[BUFSIZ]; /* buffer for old GECOS fields */
|
|
||||||
char new_gecos[BUFSIZ]; /* buffer for new GECOS fields */
|
|
||||||
int flag; /* flag currently being processed */
|
int flag; /* flag currently being processed */
|
||||||
int fflg = 0; /* -f - set full name */
|
|
||||||
int rflg = 0; /* -r - set room number */
|
|
||||||
int wflg = 0; /* -w - set work phone number */
|
|
||||||
int hflg = 0; /* -h - set home phone number */
|
|
||||||
int oflg = 0; /* -o - set other information */
|
|
||||||
char *user;
|
|
||||||
|
|
||||||
#ifdef USE_PAM
|
|
||||||
pam_handle_t *pamh = NULL;
|
|
||||||
int retval;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sanitize_env ();
|
|
||||||
setlocale (LC_ALL, "");
|
|
||||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
|
||||||
textdomain (PACKAGE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This command behaves different for root and non-root
|
|
||||||
* users.
|
|
||||||
*/
|
|
||||||
amroot = (getuid () == 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the program name. The program name is used as a
|
|
||||||
* prefix to most error messages.
|
|
||||||
*/
|
|
||||||
Prog = Basename (argv[0]);
|
|
||||||
|
|
||||||
OPENLOG ("chfn");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The remaining arguments will be processed one by one and executed
|
* The remaining arguments will be processed one by one and executed
|
||||||
@ -309,52 +276,23 @@ int main (int argc, char **argv)
|
|||||||
usage ();
|
usage ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the name of the user to check. It is either the command line
|
* check_perms - check if the caller is allowed to add a group
|
||||||
* name, or the name getlogin() returns.
|
*
|
||||||
*/
|
* Non-root users are only allowed to change their gecos field.
|
||||||
if (optind < argc) {
|
* (see also may_change_field())
|
||||||
user = argv[optind];
|
*
|
||||||
pw = xgetpwnam (user);
|
* Non-root users must be authenticated.
|
||||||
if (!pw) {
|
*
|
||||||
fprintf (stderr, _("%s: unknown user %s\n"), Prog,
|
* It will not return if the user is not allowed.
|
||||||
user);
|
*/
|
||||||
exit (E_NOPERM);
|
static void check_perms (const struct passwd *pw)
|
||||||
}
|
{
|
||||||
} else {
|
#ifdef USE_PAM
|
||||||
pw = get_my_pwent ();
|
int retval;
|
||||||
if (!pw) {
|
struct passwd *pampw;
|
||||||
fprintf (stderr,
|
|
||||||
_
|
|
||||||
("%s: Cannot determine your user name.\n"),
|
|
||||||
Prog);
|
|
||||||
exit (E_NOPERM);
|
|
||||||
}
|
|
||||||
user = xstrdup (pw->pw_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_NIS
|
|
||||||
/*
|
|
||||||
* Now we make sure this is a LOCAL password entry for this user ...
|
|
||||||
*/
|
|
||||||
if (__ispwNIS ()) {
|
|
||||||
char *nis_domain;
|
|
||||||
char *nis_master;
|
|
||||||
|
|
||||||
fprintf (stderr,
|
|
||||||
_("%s: cannot change user '%s' on NIS client.\n"),
|
|
||||||
Prog, user);
|
|
||||||
|
|
||||||
if (!yp_get_default_domain (&nis_domain) &&
|
|
||||||
!yp_master (nis_domain, "passwd.byname", &nis_master)) {
|
|
||||||
fprintf (stderr,
|
|
||||||
_
|
|
||||||
("%s: '%s' is the NIS master for this client.\n"),
|
|
||||||
Prog, nis_master);
|
|
||||||
}
|
|
||||||
exit (E_NOPERM);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -393,17 +331,13 @@ int main (int argc, char **argv)
|
|||||||
#else /* !USE_PAM */
|
#else /* !USE_PAM */
|
||||||
retval = PAM_SUCCESS;
|
retval = PAM_SUCCESS;
|
||||||
|
|
||||||
{
|
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
||||||
struct passwd *pampw;
|
if (pampw == NULL) {
|
||||||
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
|
retval = PAM_USER_UNKNOWN;
|
||||||
if (pampw == NULL) {
|
}
|
||||||
retval = PAM_USER_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retval == PAM_SUCCESS) {
|
if (retval == PAM_SUCCESS) {
|
||||||
retval = pam_start ("chfn", pampw->pw_name,
|
retval = pam_start ("chfn", pampw->pw_name, &conv, &pamh);
|
||||||
&conv, &pamh);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval == PAM_SUCCESS) {
|
if (retval == PAM_SUCCESS) {
|
||||||
@ -425,98 +359,17 @@ int main (int argc, char **argv)
|
|||||||
exit (E_NOPERM);
|
exit (E_NOPERM);
|
||||||
}
|
}
|
||||||
#endif /* USE_PAM */
|
#endif /* USE_PAM */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now get the full name. It is the first comma separated field in
|
* update_gecos - update the gecos fields in the password database
|
||||||
* the GECOS field.
|
*
|
||||||
*/
|
* Commit the user's entry after changing her gecos field.
|
||||||
STRFCPY (old_gecos, pw->pw_gecos);
|
*/
|
||||||
cp = copy_field (old_gecos, fflg ? (char *) 0 : fullnm, slop);
|
static void update_gecos (const char *user, char *gecos)
|
||||||
|
{
|
||||||
/*
|
const struct passwd *pw; /* The user's password file entry */
|
||||||
* Now get the room number. It is the next comma separated field,
|
struct passwd pwent; /* modified password file entry */
|
||||||
* if there is indeed one.
|
|
||||||
*/
|
|
||||||
if (cp)
|
|
||||||
cp = copy_field (cp, rflg ? (char *) 0 : roomno, slop);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now get the work phone number. It is the third field.
|
|
||||||
*/
|
|
||||||
if (cp)
|
|
||||||
cp = copy_field (cp, wflg ? (char *) 0 : workph, slop);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now get the home phone number. It is the fourth field.
|
|
||||||
*/
|
|
||||||
if (cp)
|
|
||||||
cp = copy_field (cp, hflg ? (char *) 0 : homeph, slop);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Anything left over is "slop".
|
|
||||||
*/
|
|
||||||
if (cp && !oflg) {
|
|
||||||
if (slop[0])
|
|
||||||
strcat (slop, ",");
|
|
||||||
|
|
||||||
strcat (slop, cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If none of the fields were changed from the command line, let the
|
|
||||||
* user interactively change them.
|
|
||||||
*/
|
|
||||||
if (!fflg && !rflg && !wflg && !hflg && !oflg) {
|
|
||||||
printf (_("Changing the user information for %s\n"), user);
|
|
||||||
new_fields ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check all of the fields for valid information
|
|
||||||
*/
|
|
||||||
if (valid_field (fullnm, ":,=")) {
|
|
||||||
fprintf (stderr, _("%s: invalid name: '%s'\n"), Prog, fullnm);
|
|
||||||
closelog ();
|
|
||||||
exit (E_NOPERM);
|
|
||||||
}
|
|
||||||
if (valid_field (roomno, ":,=")) {
|
|
||||||
fprintf (stderr, _("%s: invalid room number: '%s'\n"),
|
|
||||||
Prog, roomno);
|
|
||||||
closelog ();
|
|
||||||
exit (E_NOPERM);
|
|
||||||
}
|
|
||||||
if (valid_field (workph, ":,=")) {
|
|
||||||
fprintf (stderr, _("%s: invalid work phone: '%s'\n"),
|
|
||||||
Prog, workph);
|
|
||||||
closelog ();
|
|
||||||
exit (E_NOPERM);
|
|
||||||
}
|
|
||||||
if (valid_field (homeph, ":,=")) {
|
|
||||||
fprintf (stderr, _("%s: invalid home phone: '%s'\n"),
|
|
||||||
Prog, homeph);
|
|
||||||
closelog ();
|
|
||||||
exit (E_NOPERM);
|
|
||||||
}
|
|
||||||
if (valid_field (slop, ":")) {
|
|
||||||
fprintf (stderr,
|
|
||||||
_("%s: '%s' contains illegal characters\n"),
|
|
||||||
Prog, slop);
|
|
||||||
closelog ();
|
|
||||||
exit (E_NOPERM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build the new GECOS field by plastering all the pieces together,
|
|
||||||
* if they will fit ...
|
|
||||||
*/
|
|
||||||
if (strlen (fullnm) + strlen (roomno) + strlen (workph) +
|
|
||||||
strlen (homeph) + strlen (slop) > (unsigned int) 80) {
|
|
||||||
fprintf (stderr, _("%s: fields too long\n"), Prog);
|
|
||||||
closelog ();
|
|
||||||
exit (E_NOPERM);
|
|
||||||
}
|
|
||||||
snprintf (new_gecos, sizeof new_gecos, "%s,%s,%s,%s%s%s",
|
|
||||||
fullnm, roomno, workph, homeph, slop[0] ? "," : "", slop);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before going any further, raise the ulimit to prevent colliding
|
* Before going any further, raise the ulimit to prevent colliding
|
||||||
@ -571,7 +424,7 @@ int main (int argc, char **argv)
|
|||||||
* fields remain unchanged.
|
* fields remain unchanged.
|
||||||
*/
|
*/
|
||||||
pwent = *pw;
|
pwent = *pw;
|
||||||
pwent.pw_gecos = new_gecos;
|
pwent.pw_gecos = gecos;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update the passwd file entry. If there is a DBM file, update that
|
* Update the passwd file entry. If there is a DBM file, update that
|
||||||
@ -601,13 +454,228 @@ int main (int argc, char **argv)
|
|||||||
closelog ();
|
closelog ();
|
||||||
exit (E_NOPERM);
|
exit (E_NOPERM);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_old_fields - parse the old gecos and use the old value for the fields
|
||||||
|
* which are not set on the command line
|
||||||
|
*/
|
||||||
|
static void get_old_fields (const char *gecos)
|
||||||
|
{
|
||||||
|
char *cp; /* temporary character pointer */
|
||||||
|
char old_gecos[BUFSIZ]; /* buffer for old GECOS fields */
|
||||||
|
STRFCPY (old_gecos, gecos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now get the full name. It is the first comma separated field in
|
||||||
|
* the GECOS field.
|
||||||
|
*/
|
||||||
|
cp = copy_field (old_gecos, fflg ? (char *) 0 : fullnm, slop);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now get the room number. It is the next comma separated field,
|
||||||
|
* if there is indeed one.
|
||||||
|
*/
|
||||||
|
if (cp)
|
||||||
|
cp = copy_field (cp, rflg ? (char *) 0 : roomno, slop);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now get the work phone number. It is the third field.
|
||||||
|
*/
|
||||||
|
if (cp)
|
||||||
|
cp = copy_field (cp, wflg ? (char *) 0 : workph, slop);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now get the home phone number. It is the fourth field.
|
||||||
|
*/
|
||||||
|
if (cp)
|
||||||
|
cp = copy_field (cp, hflg ? (char *) 0 : homeph, slop);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Anything left over is "slop".
|
||||||
|
*/
|
||||||
|
if (cp && !oflg) {
|
||||||
|
if (slop[0])
|
||||||
|
strcat (slop, ",");
|
||||||
|
|
||||||
|
strcat (slop, cp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check_fields - check all of the fields for valid information
|
||||||
|
*
|
||||||
|
* It will not return if a field is not valid.
|
||||||
|
*/
|
||||||
|
static void check_fields (void)
|
||||||
|
{
|
||||||
|
if (valid_field (fullnm, ":,=")) {
|
||||||
|
fprintf (stderr, _("%s: invalid name: '%s'\n"), Prog, fullnm);
|
||||||
|
closelog ();
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
if (valid_field (roomno, ":,=")) {
|
||||||
|
fprintf (stderr, _("%s: invalid room number: '%s'\n"),
|
||||||
|
Prog, roomno);
|
||||||
|
closelog ();
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
if (valid_field (workph, ":,=")) {
|
||||||
|
fprintf (stderr, _("%s: invalid work phone: '%s'\n"),
|
||||||
|
Prog, workph);
|
||||||
|
closelog ();
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
if (valid_field (homeph, ":,=")) {
|
||||||
|
fprintf (stderr, _("%s: invalid home phone: '%s'\n"),
|
||||||
|
Prog, homeph);
|
||||||
|
closelog ();
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
if (valid_field (slop, ":")) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: '%s' contains illegal characters\n"),
|
||||||
|
Prog, slop);
|
||||||
|
closelog ();
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* chfn - change a user's password file information
|
||||||
|
*
|
||||||
|
* This command controls the GECOS field information in the password
|
||||||
|
* file entry.
|
||||||
|
*
|
||||||
|
* The valid options are
|
||||||
|
*
|
||||||
|
* -f full name
|
||||||
|
* -r room number
|
||||||
|
* -w work phone number
|
||||||
|
* -h home phone number
|
||||||
|
* -o other information (*)
|
||||||
|
*
|
||||||
|
* (*) requires root permission to execute.
|
||||||
|
*/
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
const struct passwd *pw; /* password file entry */
|
||||||
|
char new_gecos[BUFSIZ]; /* buffer for new GECOS fields */
|
||||||
|
char *user;
|
||||||
|
|
||||||
|
sanitize_env ();
|
||||||
|
setlocale (LC_ALL, "");
|
||||||
|
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
|
textdomain (PACKAGE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This command behaves different for root and non-root
|
||||||
|
* users.
|
||||||
|
*/
|
||||||
|
amroot = (getuid () == 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the program name. The program name is used as a
|
||||||
|
* prefix to most error messages.
|
||||||
|
*/
|
||||||
|
Prog = Basename (argv[0]);
|
||||||
|
|
||||||
|
OPENLOG ("chfn");
|
||||||
|
|
||||||
|
/* parse the command line options */
|
||||||
|
process_flags (argc, argv);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the name of the user to check. It is either the command line
|
||||||
|
* name, or the name getlogin() returns.
|
||||||
|
*/
|
||||||
|
if (optind < argc) {
|
||||||
|
user = argv[optind];
|
||||||
|
pw = xgetpwnam (user);
|
||||||
|
if (!pw) {
|
||||||
|
fprintf (stderr, _("%s: unknown user %s\n"), Prog,
|
||||||
|
user);
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pw = get_my_pwent ();
|
||||||
|
if (!pw) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_
|
||||||
|
("%s: Cannot determine your user name.\n"),
|
||||||
|
Prog);
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
user = xstrdup (pw->pw_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_NIS
|
||||||
|
/*
|
||||||
|
* Now we make sure this is a LOCAL password entry for this user ...
|
||||||
|
*/
|
||||||
|
if (__ispwNIS ()) {
|
||||||
|
char *nis_domain;
|
||||||
|
char *nis_master;
|
||||||
|
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: cannot change user '%s' on NIS client.\n"),
|
||||||
|
Prog, user);
|
||||||
|
|
||||||
|
if (!yp_get_default_domain (&nis_domain) &&
|
||||||
|
!yp_master (nis_domain, "passwd.byname", &nis_master)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_
|
||||||
|
("%s: '%s' is the NIS master for this client.\n"),
|
||||||
|
Prog, nis_master);
|
||||||
|
}
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check that the caller is allowed to change the gecos of the
|
||||||
|
* specified user */
|
||||||
|
check_perms (pw);
|
||||||
|
|
||||||
|
/* If some fields were not set on the command line, load the value from
|
||||||
|
* the old gecos fields. */
|
||||||
|
get_old_fields (pw->pw_gecos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If none of the fields were changed from the command line, let the
|
||||||
|
* user interactively change them.
|
||||||
|
*/
|
||||||
|
if (!fflg && !rflg && !wflg && !hflg && !oflg) {
|
||||||
|
printf (_("Changing the user information for %s\n"), user);
|
||||||
|
new_fields ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check all of the fields for valid information
|
||||||
|
*/
|
||||||
|
check_fields ();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build the new GECOS field by plastering all the pieces together,
|
||||||
|
* if they will fit ...
|
||||||
|
*/
|
||||||
|
if (strlen (fullnm) + strlen (roomno) + strlen (workph) +
|
||||||
|
strlen (homeph) + strlen (slop) > (unsigned int) 80) {
|
||||||
|
fprintf (stderr, _("%s: fields too long\n"), Prog);
|
||||||
|
closelog ();
|
||||||
|
exit (E_NOPERM);
|
||||||
|
}
|
||||||
|
snprintf (new_gecos, sizeof new_gecos, "%s,%s,%s,%s%s%s",
|
||||||
|
fullnm, roomno, workph, homeph, slop[0] ? "," : "", slop);
|
||||||
|
|
||||||
|
/* Rewrite the user's gecos in the passwd file */
|
||||||
|
update_gecos (user, new_gecos);
|
||||||
|
|
||||||
SYSLOG ((LOG_INFO, "changed user `%s' information", user));
|
SYSLOG ((LOG_INFO, "changed user `%s' information", user));
|
||||||
|
|
||||||
nscd_flush_cache ("passwd");
|
nscd_flush_cache ("passwd");
|
||||||
|
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
if (retval == PAM_SUCCESS)
|
pam_end (pamh, PAM_SUCCESS);
|
||||||
pam_end (pamh, PAM_SUCCESS);
|
|
||||||
#endif /* USE_PAM */
|
#endif /* USE_PAM */
|
||||||
|
|
||||||
closelog ();
|
closelog ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user