* src/usermod.c: Split update_files() into update_lastlog() and
update_faillog(). Report errors (but don't fail) if the file exist, but open(), lseek(), read(), write(), or close() fails. * src/usermod.c: Add brackets and parenthesis. * src/usermod.c: Ignore the return value of pam_end() before exiting. * src/usermod.c: Ignore the return value of strftime(), snprintf(), and puts(). * src/usermod.c: Check the return value of gmtime() and asctime(), and output the raw time_t on failures.
This commit is contained in:
parent
e4e3bd5175
commit
62c8e79676
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
2008-07-11 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
* src/usermod.c: Split update_files() into update_lastlog() and
|
||||||
|
update_faillog(). Report errors (but don't fail) if the file
|
||||||
|
exist, but open(), lseek(), read(), write(), or close() fails.
|
||||||
|
* src/usermod.c: Add brackets and parenthesis.
|
||||||
|
* src/usermod.c: Ignore the return value of pam_end() before
|
||||||
|
exiting.
|
||||||
|
* src/usermod.c: Ignore the return value of strftime(),
|
||||||
|
snprintf(), and puts().
|
||||||
|
* src/usermod.c: Check the return value of gmtime() and asctime(),
|
||||||
|
and output the raw time_t on failures.
|
||||||
|
|
||||||
2008-07-11 Nicolas François <nicolas.francois@centraliens.net>
|
2008-07-11 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
* libmisc/setugid.c: Add brackets.
|
* libmisc/setugid.c: Add brackets.
|
||||||
|
147
src/usermod.c
147
src/usermod.c
@ -158,7 +158,8 @@ static void close_files (void);
|
|||||||
static void open_files (void);
|
static void open_files (void);
|
||||||
static void usr_update (void);
|
static void usr_update (void);
|
||||||
static void move_home (void);
|
static void move_home (void);
|
||||||
static void update_files (void);
|
static void update_lastlog (void);
|
||||||
|
static void update_faillog (void);
|
||||||
|
|
||||||
#ifndef NO_MOVE_MAILBOX
|
#ifndef NO_MOVE_MAILBOX
|
||||||
static void move_mailbox (void);
|
static void move_mailbox (void);
|
||||||
@ -611,8 +612,9 @@ static void update_group (void)
|
|||||||
SYSLOG ((LOG_INFO, "add `%s' to group `%s'",
|
SYSLOG ((LOG_INFO, "add `%s' to group `%s'",
|
||||||
user_newname, ngrp->gr_name));
|
user_newname, ngrp->gr_name));
|
||||||
}
|
}
|
||||||
if (!changed)
|
if (!changed) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
changed = false;
|
changed = false;
|
||||||
if (gr_update (ngrp) == 0) {
|
if (gr_update (ngrp) == 0) {
|
||||||
@ -1040,8 +1042,9 @@ static void process_flags (int argc, char **argv)
|
|||||||
exit (E_USAGE);
|
exit (E_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind != argc - 1)
|
if (optind != argc - 1) {
|
||||||
usage ();
|
usage ();
|
||||||
|
}
|
||||||
|
|
||||||
if (aflg && (!Gflg)) {
|
if (aflg && (!Gflg)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@ -1296,8 +1299,9 @@ static void move_home (void)
|
|||||||
* Don't try to move it if it is not a directory
|
* Don't try to move it if it is not a directory
|
||||||
* (but /dev/null for example). --marekm
|
* (but /dev/null for example). --marekm
|
||||||
*/
|
*/
|
||||||
if (!S_ISDIR (sb.st_mode))
|
if (!S_ISDIR (sb.st_mode)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (access (user_newhome, F_OK) == 0) {
|
if (access (user_newhome, F_OK) == 0) {
|
||||||
fprintf (stderr, _("%s: directory %s exists\n"),
|
fprintf (stderr, _("%s: directory %s exists\n"),
|
||||||
@ -1367,40 +1371,120 @@ static void move_home (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* update_files - update the lastlog and faillog files
|
* update_lastlog - update the lastlog file
|
||||||
|
*
|
||||||
|
* Relocate the "lastlog" entries for the user. The old entry is
|
||||||
|
* left alone in case the UID was shared. It doesn't hurt anything
|
||||||
|
* to just leave it be.
|
||||||
*/
|
*/
|
||||||
static void update_files (void)
|
static void update_lastlog (void)
|
||||||
{
|
{
|
||||||
struct lastlog ll;
|
struct lastlog ll;
|
||||||
struct faillog fl;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
off_t off_uid = (off_t) user_id * sizeof ll;
|
||||||
|
off_t off_newuid = (off_t) user_newid * sizeof ll;
|
||||||
|
|
||||||
/*
|
if (access (LASTLOG_FILE, F_OK) != 0) {
|
||||||
* Relocate the "lastlog" entries for the user. The old entry is
|
return;
|
||||||
* left alone in case the UID was shared. It doesn't hurt anything
|
|
||||||
* to just leave it be.
|
|
||||||
*/
|
|
||||||
fd = open (LASTLOG_FILE, O_RDWR);
|
|
||||||
if (-1 != fd) {
|
|
||||||
lseek (fd, (off_t) user_id * sizeof ll, SEEK_SET);
|
|
||||||
if (read (fd, (char *) &ll, sizeof ll) == (ssize_t) sizeof ll) {
|
|
||||||
lseek (fd, (off_t) user_newid * sizeof ll, SEEK_SET);
|
|
||||||
write (fd, (char *) &ll, sizeof ll);
|
|
||||||
}
|
|
||||||
close (fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
fd = open (LASTLOG_FILE, O_RDWR);
|
||||||
* Relocate the "faillog" entries in the same manner.
|
|
||||||
*/
|
if (-1 == fd) {
|
||||||
fd = open (FAILLOG_FILE, O_RDWR);
|
fprintf (stderr,
|
||||||
if (-1 != fd) {
|
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
|
||||||
lseek (fd, (off_t) user_id * sizeof fl, SEEK_SET);
|
Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
|
||||||
if (read (fd, (char *) &fl, sizeof fl) == (ssize_t) sizeof fl) {
|
return;
|
||||||
lseek (fd, (off_t) user_newid * sizeof fl, SEEK_SET);
|
}
|
||||||
write (fd, (char *) &fl, sizeof fl);
|
|
||||||
|
if ( (lseek (fd, off_uid, SEEK_SET) == off_uid)
|
||||||
|
&& (read (fd, &ll, sizeof ll) == (ssize_t) sizeof ll)) {
|
||||||
|
/* Copy the old entry to its new location */
|
||||||
|
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|
||||||
|
|| (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
|
||||||
|
|| (close (fd) != 0)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
|
||||||
|
Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Assume lseek or read failed because there is
|
||||||
|
* no entry for the old UID */
|
||||||
|
|
||||||
|
/* Check if the new UID already has an entry */
|
||||||
|
if ( (lseek (fd, off_newuid, SEEK_SET) == off_newuid)
|
||||||
|
&& (read (fd, &ll, sizeof ll) == (ssize_t) sizeof ll)) {
|
||||||
|
/* Reset the new uid's lastlog entry */
|
||||||
|
memzero (&ll, sizeof (ll));
|
||||||
|
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|
||||||
|
|| (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
|
||||||
|
|| (close (fd) != 0)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
|
||||||
|
Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(void) close (fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* update_faillog - update the faillog file
|
||||||
|
*
|
||||||
|
* Relocate the "faillog" entries for the user. The old entry is
|
||||||
|
* left alone in case the UID was shared. It doesn't hurt anything
|
||||||
|
* to just leave it be.
|
||||||
|
*/
|
||||||
|
static void update_faillog (void)
|
||||||
|
{
|
||||||
|
struct faillog fl;
|
||||||
|
int fd;
|
||||||
|
off_t off_uid = (off_t) user_id * sizeof fl;
|
||||||
|
off_t off_newuid = (off_t) user_newid * sizeof fl;
|
||||||
|
|
||||||
|
if (access (FAILLOG_FILE, F_OK) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open (FAILLOG_FILE, O_RDWR);
|
||||||
|
|
||||||
|
if (-1 == fd) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
|
||||||
|
Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (lseek (fd, off_uid, SEEK_SET) == off_uid)
|
||||||
|
&& (read (fd, (char *) &fl, sizeof fl) == (ssize_t) sizeof fl)) {
|
||||||
|
/* Copy the old entry to its new location */
|
||||||
|
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|
||||||
|
|| (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)
|
||||||
|
|| (close (fd) != 0)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
|
||||||
|
Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Assume lseek or read failed because there is
|
||||||
|
* no entry for the old UID */
|
||||||
|
|
||||||
|
/* Check if the new UID already has an entry */
|
||||||
|
if ( (lseek (fd, off_newuid, SEEK_SET) == off_newuid)
|
||||||
|
&& (read (fd, &fl, sizeof fl) == (ssize_t) sizeof fl)) {
|
||||||
|
/* Reset the new uid's lastlog entry */
|
||||||
|
memzero (&fl, sizeof (fl));
|
||||||
|
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|
||||||
|
|| (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)
|
||||||
|
|| (close (fd) != 0)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
|
||||||
|
Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(void) close (fd);
|
||||||
}
|
}
|
||||||
close (fd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1585,7 +1669,8 @@ int main (int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (uflg) {
|
if (uflg) {
|
||||||
update_files ();
|
update_lastlog ();
|
||||||
|
update_faillog ();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change the UID on all of the files owned by `user_id' to
|
* Change the UID on all of the files owned by `user_id' to
|
||||||
|
Loading…
Reference in New Issue
Block a user