This allows us to open (and close) the PAM session from sudoers.
#define PAM_DATA_SILENT 0
#endif
-static pam_handle_t *pamh; /* global due to pam_prep_user() */
+static pam_handle_t *pamh;
int
pam_init(pw, promptp, auth)
{
int *pam_status = (int *) auth->data;
- /* If successful, we can't close the session until pam_prep_user() */
+ /* If successful, we can't close the session until pam_end_session() */
if (auth->status == AUTH_SUCCESS)
return(AUTH_SUCCESS);
}
int
-pam_prep_user(pw)
+pam_begin_session(pw, auth)
struct passwd *pw;
+ sudo_auth *auth;
{
- int eval;
+ int status;
if (pamh == NULL)
pam_init(pw, NULL, NULL);
* can at least cause pam_limits to be run by opening and then
* immediately closing the session.
*/
- if ((eval = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
- (void) pam_end(pamh, eval | PAM_DATA_SILENT);
- return(AUTH_FAILURE);
- }
+ status = pam_open_session(pamh, 0);
+ if (status != PAM_SUCCESS)
+ (void) pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
+#endif
+ return(status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
+}
+
+int
+pam_end_session(auth)
+ sudo_auth *auth;
+{
+ int status;
+
+#ifndef NO_PAM_SESSION
(void) pam_close_session(pamh, 0);
#endif
- if (pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT) == PAM_SUCCESS)
- return(AUTH_SUCCESS);
- else
- return(AUTH_FAILURE);
+ status = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
+ return(status == PAM_SUCCESS ? AUTH_SUCCESS : AUTH_FAILURE);
}
/*
AUTH_STANDALONE
#else
# ifndef WITHOUT_PASSWD
- AUTH_ENTRY(0, "passwd", passwd_init, NULL, passwd_verify, NULL)
+ AUTH_ENTRY(0, "passwd", passwd_init, NULL, passwd_verify, NULL, NULL, NULL)
# endif
# if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD)
- AUTH_ENTRY(0, "secureware", secureware_init, NULL, secureware_verify, NULL)
+ AUTH_ENTRY(0, "secureware", secureware_init, NULL, secureware_verify, NULL, NULL, NULL)
# endif
# ifdef HAVE_AFS
- AUTH_ENTRY(0, "afs", NULL, NULL, afs_verify, NULL)
+ AUTH_ENTRY(0, "afs", NULL, NULL, afs_verify, NULL, NULL, NULL)
# endif
# ifdef HAVE_DCE
- AUTH_ENTRY(0, "dce", NULL, NULL, dce_verify, NULL)
+ AUTH_ENTRY(0, "dce", NULL, NULL, dce_verify, NULL, NULL, NULL)
# endif
# ifdef HAVE_KERB4
- AUTH_ENTRY(0, "kerb4", kerb4_init, NULL, kerb4_verify, NULL)
+ AUTH_ENTRY(0, "kerb4", kerb4_init, NULL, kerb4_verify, NULL, NULL, NULL)
# endif
# ifdef HAVE_KERB5
- AUTH_ENTRY(0, "kerb5", kerb5_init, NULL, kerb5_verify, kerb5_cleanup)
+ AUTH_ENTRY(0, "kerb5", kerb5_init, NULL, kerb5_verify, kerb5_cleanup, NULL, NULL)
# endif
# ifdef HAVE_SKEY
- AUTH_ENTRY(0, "S/Key", NULL, rfc1938_setup, rfc1938_verify, NULL)
+ AUTH_ENTRY(0, "S/Key", NULL, rfc1938_setup, rfc1938_verify, NULL, NULL, NULL)
# endif
# ifdef HAVE_OPIE
- AUTH_ENTRY(0, "OPIE", NULL, rfc1938_setup, rfc1938_verify, NULL)
+ AUTH_ENTRY(0, "OPIE", NULL, rfc1938_setup, rfc1938_verify, NULL, NULL, NULL)
# endif
#endif /* AUTH_STANDALONE */
- AUTH_ENTRY(0, NULL, NULL, NULL, NULL, NULL)
+ AUTH_ENTRY(0, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
};
+extern char **NewArgv; /* XXX - for auditing */
+
+static void pass_warn(void);
+
int
verify_user(struct passwd *pw, char *prompt)
{
char *p;
sudo_auth *auth;
sigaction_t sa, osa;
- extern char **NewArgv; /* XXX */
/* Enable suspend during password entry. */
sigemptyset(&sa.sa_mask);
if (p)
zero_bytes(p, strlen(p));
#endif
- /* XXX - need way to know if askpass was used */
- //if (!ISSET(tgetpass_flags, TGP_ASKPASS))
- pass_warn();
+ pass_warn();
}
cleanup:
return rval;
}
-void
+int begin_session(struct passwd *pw)
+{
+ sudo_auth *auth;
+ int status;
+
+ for (auth = auth_switch; auth->name; auth++) {
+ if (auth->begin_session && IS_CONFIGURED(auth)) {
+ status = (auth->begin_session)(pw, auth);
+ if (status == AUTH_FATAL) { /* XXX log */
+ audit_failure(NewArgv, "authentication failure");
+ return -1; /* assume error msg already printed */
+ }
+ }
+ }
+ return TRUE;
+}
+
+int end_session(void)
+{
+ sudo_auth *auth;
+ int status;
+
+ for (auth = auth_switch; auth->name; auth++) {
+ if (auth->end_session && IS_CONFIGURED(auth)) {
+ status = (auth->end_session)(auth);
+ if (status == AUTH_FATAL) { /* XXX log */
+ return -1; /* assume error msg already printed */
+ }
+ }
+ }
+ return TRUE;
+}
+
+static void
pass_warn(void)
{
struct sudo_conv_message msg[2];
int (*setup)(struct passwd *pw, char **prompt, struct sudo_auth *auth);
int (*verify)(struct passwd *pw, char *p, struct sudo_auth *auth);
int (*cleanup)(struct passwd *pw, struct sudo_auth *auth);
+ int (*begin_session)(struct passwd *pw, struct sudo_auth *auth);
+ int (*end_session)(struct sudo_auth *auth);
} sudo_auth;
/* Values for sudo_auth.flags. */
int pam_init(struct passwd *pw, char **prompt, sudo_auth *auth);
int pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
int pam_cleanup(struct passwd *pw, sudo_auth *auth);
+int pam_begin_session(struct passwd *pw, sudo_auth *auth);
+int pam_end_session(sudo_auth *auth);
int sia_setup(struct passwd *pw, char **prompt, sudo_auth *auth);
int sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth);
int sia_cleanup(struct passwd *pw, sudo_auth *auth);
int securid_verify(struct passwd *pw, char *pass, sudo_auth *auth);
/* Fields: need_root, name, init, setup, verify, cleanup */
-#define AUTH_ENTRY(r, n, i, s, v, c) \
- { (r|FLAG_CONFIGURED), AUTH_FAILURE, n, NULL, i, s, v, c },
+#define AUTH_ENTRY(r, n, i, s, v, c, b, e) \
+ { (r|FLAG_CONFIGURED), AUTH_FAILURE, n, NULL, i, s, v, c , b, e },
-/* Some methods cannots (or should not) interoperate with any others */
+/* Some methods cannot (or should not) interoperate with any others */
#if defined(HAVE_PAM)
# define AUTH_STANDALONE \
AUTH_ENTRY(0, "pam", \
- pam_init, NULL, pam_verify, pam_cleanup)
+ pam_init, NULL, pam_verify, pam_cleanup, pam_begin_session, pam_end_session)
#elif defined(HAVE_SECURID)
# define AUTH_STANDALONE \
AUTH_ENTRY(0, "SecurId", \
- securid_init, securid_setup, securid_verify, NULL)
+ securid_init, securid_setup, securid_verify, NULL, NULL, NULL)
#elif defined(HAVE_SIA_SES_INIT)
# define AUTH_STANDALONE \
AUTH_ENTRY(0, "sia", \
- NULL, sia_setup, sia_verify, sia_cleanup)
+ NULL, sia_setup, sia_verify, sia_cleanup, NULL, NULL)
#elif defined(HAVE_AIXAUTH)
# define AUTH_STANDALONE \
AUTH_ENTRY(0, "aixauth", \
- NULL, NULL, aixauth_verify, aixauth_cleanup)
+ NULL, NULL, aixauth_verify, aixauth_cleanup, NULL, NULL)
#elif defined(HAVE_FWTK)
# define AUTH_STANDALONE \
AUTH_ENTRY(0, "fwtk", \
- fwtk_init, NULL, fwtk_verify, fwtk_cleanup)
+ fwtk_init, NULL, fwtk_verify, fwtk_cleanup, NULL, NULL)
#elif defined(HAVE_BSD_AUTH_H)
# define AUTH_STANDALONE \
AUTH_ENTRY(0, "bsdauth", \
- bsdauth_init, NULL, bsdauth_verify, bsdauth_cleanup)
+ bsdauth_init, NULL, bsdauth_verify, bsdauth_cleanup, NULL, NULL)
#endif
#endif /* SUDO_AUTH_H */
/*
* Prototypes
*/
-#if 0
-static void runas_setup(void);
-#endif
static void runas_setgroups(void);
/*
}
#endif /* HAVE_INITGROUPS */
-
-#if 0
-static void
-runas_setup()
-{
- gid_t gid;
-#ifdef HAVE_LOGIN_CAP_H
- int flags;
- extern login_cap_t *lc;
-#endif
-
- if (runas_pw->pw_name != NULL) {
- gid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
-#ifdef HAVE_GETUSERATTR
- aix_setlimits(runas_pw->pw_name);
-#endif
-#ifdef HAVE_PAM
- /* XXX - move this */
- pam_prep_user(runas_pw);
-#endif /* HAVE_PAM */
-
-#ifdef HAVE_LOGIN_CAP_H
- if (def_use_loginclass) {
- /*
- * We only use setusercontext() to set the nice value and rlimits.
- */
- flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
- if (setusercontext(lc, runas_pw, runas_pw->pw_uid, flags)) {
- if (runas_pw->pw_uid != ROOT_UID)
- error(1, "unable to set user context");
- else
- warning("unable to set user context");
- }
- }
-#endif /* HAVE_LOGIN_CAP_H */
- /*
- * Initialize group vector
- */
- runas_setgroups();
-#ifdef HAVE_SETEUID
- if (setegid(gid))
- warning("cannot set egid to runas gid");
-#endif
- if (setgid(gid))
- warning("cannot set gid to runas gid");
- }
-}
-#endif
/* We do not currently log the exit status. */
if (error_code)
warningx("unable to execute %s: %s", safe_cmnd, strerror(error_code));
+ end_session();
}
static int
restore_perms();
+ /*
+ * Ideally we would like to do session setup (currently only PAM)
+ * from inside sudo itself, but this should be close enough.
+ */
+ if (ISSET(sudo_mode, MODE_RUN))
+ rval = begin_session(runas_pw);
+ if (ISSET(sudo_mode, MODE_EDIT))
+ rval = begin_session(sudo_user.pw);
+
done:
return rval;
}
/* sudo_auth.c */
int verify_user(struct passwd *, char *);
-void pass_warn(void);
+int begin_session(struct passwd *);
+int end_session();
#ifdef HAVE_LDAP
/* ldap.c */