+ if (original) {
+ fclose(original);
+ original = NULL;
+ }
+
+ /* The we update the shadow database */
+ shadow_path = fix_root("/etc/shadow");
+ r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
+ if (r < 0)
+ goto finish;
+
+ original = fopen(shadow_path, "re");
+ if (original) {
+ struct spwd *sp;
+
+ r = sync_rights(original, shadow);
+ if (r < 0)
+ goto finish;
+
+ errno = 0;
+ while ((sp = fgetspent(original))) {
+
+ i = hashmap_get(users, sp->sp_namp);
+ if (i && i->todo_user) {
+ r = -EEXIST;
+ goto finish;
+ }
+
+ errno = 0;
+ if (putspent(sp, shadow) < 0) {
+ r = errno ? -errno : -EIO;
+ goto finish;
+ }
+
+ errno = 0;
+ }
+ if (!IN_SET(errno, 0, ENOENT)) {
+ r = -errno;
+ goto finish;
+ }
+ } else if (errno != ENOENT) {
+ r = -errno;
+ goto finish;
+ } else if (fchmod(fileno(shadow), 0000) < 0) {
+ r = -errno;
+ goto finish;
+ }
+
+ lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+ HASHMAP_FOREACH(i, todo_uids, iterator) {
+ struct spwd n = {
+ .sp_namp = i->name,
+ .sp_pwdp = (char*) "!!",
+ .sp_lstchg = lstchg,
+ .sp_min = -1,
+ .sp_max = -1,
+ .sp_warn = -1,
+ .sp_inact = -1,
+ .sp_expire = -1,
+ .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
+ };
+
+ errno = 0;
+ if (putspent(&n, shadow) != 0) {
+ r = errno ? -errno : -EIO;
+ goto finish;
+ }
+ }
+
+ r = fflush_and_check(shadow);