static void list_fields (void);
static void process_flags (int argc, char **argv, struct option_flags *flags);
static void check_flags (int argc, int opt_index);
-static void check_perms (void);
-static void open_files (bool readonly);
+static void check_perms (struct option_flags *flags);
+static void open_files (bool readonly, struct option_flags *flags);
static void close_files (struct option_flags *flags);
-NORETURN static void fail_exit (int code);
+NORETURN static void fail_exit (int code, bool process_selinux);
/*
* fail_exit - do some cleanup and exit with the given error code
*/
NORETURN
static void
-fail_exit (int code)
+fail_exit (int code, bool process_selinux)
{
if (spw_locked) {
- if (spw_unlock (true) == 0) {
+ if (spw_unlock (process_selinux) == 0) {
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
/* continue */
}
}
if (pw_locked) {
- if (pw_unlock (true) == 0) {
+ if (pw_unlock (process_selinux) == 0) {
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
/* continue */
*
* It will not return if the user is not allowed.
*/
-static void check_perms (void)
+static void check_perms (struct option_flags *flags)
{
+ bool process_selinux;
+
+ process_selinux = !flags->chroot && !flags->prefix;
+
/*
* An unprivileged user can ask for their own aging information, but
* only root can change it, or list another user's aging
if (!amroot && !lflg) {
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
}
* In read-only mode, the databases are not locked and are opened
* only for reading.
*/
-static void open_files (bool readonly)
+static void open_files (bool readonly, struct option_flags *flags)
{
+ bool process_selinux;
+
+ process_selinux = !flags->chroot && !flags->prefix;
+
/*
* Lock and open the password file. This loads all of the password
* file entries into memory. Then we get a pointer to the password
fprintf (stderr,
_("%s: cannot lock %s; try again later.\n"),
Prog, pw_dbname ());
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
pw_locked = true;
}
if (pw_open (readonly ? O_RDONLY: O_CREAT | O_RDWR) == 0) {
fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
SYSLOG ((LOG_WARN, "cannot open %s", pw_dbname ()));
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
/*
fprintf (stderr,
_("%s: cannot lock %s; try again later.\n"),
Prog, spw_dbname ());
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
spw_locked = true;
}
fprintf (stderr,
_("%s: cannot open %s\n"), Prog, spw_dbname ());
SYSLOG ((LOG_WARN, "cannot open %s", spw_dbname ()));
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
}
fprintf (stderr,
_("%s: failure while writing changes to %s\n"), Prog, spw_dbname ());
SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname ()));
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
/*
if (pw_close (process_selinux) == 0) {
fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, pw_dbname ());
SYSLOG ((LOG_ERR, "failure while writing changes to %s", pw_dbname ()));
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
if (spw_unlock (process_selinux) == 0) {
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
* It will not return in case of error
*/
static void update_age (/*@null@*/const struct spwd *sp,
- /*@notnull@*/const struct passwd *pw)
+ /*@notnull@*/const struct passwd *pw,
+ bool process_selinux)
{
struct spwd spwent;
if (pw_update (&pwent) == 0) {
fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"), Prog, pw_dbname (), pwent.pw_name);
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
} else {
spwent.sp_namp = xstrdup (sp->sp_namp);
if (spw_update (&spwent) == 0) {
fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"), Prog, spw_dbname (), spwent.sp_namp);
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
}
gid_t rgid;
const struct passwd *pw;
struct option_flags flags;
+ bool process_selinux;
sanitize_env ();
check_fds ();
#endif
process_flags (argc, argv, &flags);
+ process_selinux = !flags.chroot && !flags.prefix;
- check_perms ();
+ check_perms (&flags);
if (!spw_file_present ()) {
fprintf (stderr,
exit (E_SHADOW_NOTFOUND);
}
- open_files (lflg);
+ open_files (lflg, &flags);
/* Drop privileges */
if (lflg && ( (setregid (rgid, rgid) != 0)
|| (setreuid (ruid, ruid) != 0))) {
fprintf (stderr, _("%s: failed to drop privileges (%s)\n"),
Prog, strerror (errno));
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
pw = pw_locate (argv[optind]);
fprintf (stderr, _("%s: user '%s' does not exist in %s\n"),
Prog, argv[optind], pw_dbname ());
closelog ();
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
STRTCPY(user_name, pw->pw_name);
#ifdef WITH_TCB
if (shadowtcb_set_user (pw->pw_name) == SHADOWTCB_FAILURE) {
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
#endif
user_uid = pw->pw_uid;
if (lflg) {
if (!amroot && (ruid != user_uid)) {
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
/* Displaying fields is not of interest to audit */
list_fields ();
- fail_exit (E_SUCCESS);
+ fail_exit (E_SUCCESS, process_selinux);
}
/*
if (new_fields () == 0) {
fprintf (stderr, _("%s: error changing fields\n"),
Prog);
- fail_exit (E_NOPERM);
+ fail_exit (E_NOPERM, process_selinux);
}
#ifdef WITH_AUDIT
else {
#endif
}
- update_age (sp, pw);
+ update_age (sp, pw, process_selinux);
close_files (&flags);