diff options
Diffstat (limited to 'src/usermod.c')
-rw-r--r-- | src/usermod.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/usermod.c b/src/usermod.c index e571426f..c3718864 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -57,6 +57,7 @@ #include "getdef.h" #include "groupio.h" #include "nscd.h" +#include "sssd.h" #include "prototypes.h" #include "pwauth.h" #include "pwio.h" @@ -1251,11 +1252,13 @@ static void process_flags (int argc, char **argv) prefix_user_home = xmalloc(len); wlen = snprintf(prefix_user_home, len, "%s/%s", prefix, user_home); assert (wlen == (int) len -1); + if (user_newhome) { + len = strlen(prefix) + strlen(user_newhome) + 2; + prefix_user_newhome = xmalloc(len); + wlen = snprintf(prefix_user_newhome, len, "%s/%s", prefix, user_newhome); + assert (wlen == (int) len -1); + } - len = strlen(prefix) + strlen(user_newhome) + 2; - prefix_user_newhome = xmalloc(len); - wlen = snprintf(prefix_user_newhome, len, "%s/%s", prefix, user_newhome); - assert (wlen == (int) len -1); } else { prefix_user_home = user_home; @@ -1365,7 +1368,7 @@ static void process_flags (int argc, char **argv) || Zflg #endif /* WITH_SELINUX */ )) { - fprintf (stderr, _("%s: no changes\n"), Prog); + fprintf (stdout, _("%s: no changes\n"), Prog); exit (E_SUCCESS); } @@ -1816,6 +1819,15 @@ static void move_home (void) return; } else { if (EXDEV == errno) { +#ifdef WITH_BTRFS + if (btrfs_is_subvolume (prefix_user_home) > 0) { + fprintf (stderr, + _("%s: error: cannot move subvolume from %s to %s - different device\n"), + Prog, prefix_user_home, prefix_user_newhome); + fail_exit (E_HOMEDIR); + } +#endif + if (copy_tree (prefix_user_home, prefix_user_newhome, true, true, user_id, @@ -1861,11 +1873,18 @@ static void update_lastlog (void) int fd; off_t off_uid = (off_t) user_id * sizeof ll; off_t off_newuid = (off_t) user_newid * sizeof ll; + uid_t max_uid; if (access (LASTLOG_FILE, F_OK) != 0) { return; } + max_uid = (uid_t) getdef_ulong ("LASTLOG_MAX_UID", 0xFFFFFFFFUL); + if (user_newid > max_uid) { + /* do not touch lastlog for large uids */ + return; + } + fd = open (LASTLOG_FILE, O_RDWR); if (-1 == fd) { @@ -2253,6 +2272,7 @@ int main (int argc, char **argv) nscd_flush_cache ("passwd"); nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); #ifdef WITH_SELINUX if (Zflg) { @@ -2302,7 +2322,10 @@ int main (int argc, char **argv) } if (!mflg && (uflg || gflg)) { - if (access (dflg ? prefix_user_newhome : prefix_user_home, F_OK) == 0) { + struct stat sb; + + if (stat (dflg ? prefix_user_newhome : prefix_user_home, &sb) == 0 && + ((uflg && sb.st_uid == user_newid) || sb.st_uid == user_id)) { /* * Change the UID on all of the files owned by * `user_id' to `user_newid' in the user's home |