/* Indicate if shadow groups are enabled on the system
* (/etc/gshadow present) */
static int is_shadowgrp;
+static int gshadow_locked = 0;
#endif
+static int group_locked = 0;
/* Flags set by options */
static int
/* local function prototypes */
static void usage (void);
static RETSIGTYPE catch_signals (int killed);
+static void fail_exit (int status);
static int check_list (const char *users);
static void process_flags (int argc, char **argv);
static void check_flags (int argc, int opt_index);
if (killed) {
putchar ('\n');
fflush (stdout);
- exit (killed);
+ fail_exit (killed);
}
}
+/*
+ * fail_exit - undo as much as possible
+ */
+static void fail_exit (int status)
+{
+ if (group_locked) {
+ gr_unlock ();
+ }
+ if (gshadow_locked) {
+ sgr_unlock ();
+ }
+
+ exit (status);
+}
+
/*
* check_list - check a comma-separated list of user names for validity
*
static void failure (void)
{
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
- exit (1);
+ fail_exit (1);
}
/*
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"adding to group", user, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
aflg++;
break;
_
("%s: shadow group passwords required for -A\n"),
Prog);
- exit (2);
+ fail_exit (2);
}
admins = optarg;
if (check_list (admins) != 0) {
- exit (1);
+ fail_exit (1);
}
Aflg++;
break;
}
members = optarg;
if (check_list (members) != 0) {
- exit (1);
+ fail_exit (1);
}
Mflg++;
break;
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"locking /etc/group", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
+ group_locked++;
#ifdef SHADOWGRP
- if (is_shadowgrp && (sgr_lock () == 0)) {
- fprintf (stderr, _("%s: can't get shadow lock\n"), Prog);
- SYSLOG ((LOG_WARN, "failed to get lock for /etc/gshadow"));
+ if (is_shadowgrp) {
+ if (sgr_lock () == 0) {
+ fprintf (stderr,
+ _("%s: can't get shadow lock\n"), Prog);
+ SYSLOG ((LOG_WARN, "failed to get lock for /etc/gshadow"));
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "locking /etc/gshadow", group, -1, 0);
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ "locking /etc/gshadow", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
+ }
+ gshadow_locked++;
}
#endif
if (gr_open (O_RDWR) == 0) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"opening /etc/group", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
#ifdef SHADOWGRP
if (is_shadowgrp && (sgr_open (O_RDWR) == 0)) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"opening /etc/gshadow", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
#endif
}
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"rewriting /etc/group", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
#ifdef SHADOWGRP
if (is_shadowgrp && (sgr_close () == 0)) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"rewriting /etc/gshadow", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
if (is_shadowgrp) {
/* TODO: same logging as in open_files & for /etc/group */
sgr_unlock ();
+ gshadow_locked--;
}
#endif
if (gr_unlock () == 0) {
#endif
exit (1);
}
+ group_locked--;
}
/*
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"updating /etc/group", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
#ifdef SHADOWGRP
if (is_shadowgrp && (sgr_update (sg) == 0)) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"updating /etc/gshadow", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
#endif
}
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"opening /etc/group", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
tmpgr = gr_locate (group);
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"closing /etc/group", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
#ifdef SHADOWGRP
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"opening /etc/gshadow", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
tmpsg = sgr_locate (group);
if (NULL != tmpsg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"closing /etc/gshadow", group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
}
#endif /* SHADOWGRP */
for (retries = 0; retries < RETRIES; retries++) {
cp = getpass (_("New Password: "));
if (NULL == cp) {
- exit (1);
+ fail_exit (1);
}
STRFCPY (pass, cp);
strzero (cp);
cp = getpass (_("Re-enter new password: "));
if (NULL == cp) {
- exit (1);
+ fail_exit (1);
}
if (strcmp (pass, cp) == 0) {
if (retries == RETRIES) {
fprintf (stderr, _("%s: Try again later\n"), Prog);
- exit (1);
+ fail_exit (1);
}
cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL));
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"deleting member", user, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting member",
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing password",
group, -1, 0);
#endif
- exit (1);
+ fail_exit (1);
}
catch_signals (0); /* save tty modes */
group, -1, 0);
#endif
closelog ();
- exit (1);
+ fail_exit (1);
}
pwd_init ();