pam_krb5/pam_krb5-2.2.11-1-refresh-drop-restore-priv.dif

142 lines
3.7 KiB
Plaintext

--- src/auth.c
+++ src/auth.c 2007/03/15 10:55:36
@@ -418,9 +418,13 @@
return pam_sm_open_session(pamh, flags, argc, argv);
}
if (flags & (PAM_REINITIALIZE_CRED | PAM_REFRESH_CRED)) {
- if (_pam_krb5_sly_looks_unsafe() == 0) {
+ int unsave = _pam_krb5_sly_looks_unsafe();
+
+ /* unsave == 2 or 3 can be fixed inside of
+ _pam_krb5_sly_maybe_refresh */
+ if (unsave == 0 || unsave == 2 || unsave == 3) {
return _pam_krb5_sly_maybe_refresh(pamh, flags,
- argc, argv);
+ argc, argv);
} else {
return PAM_IGNORE;
}
--- src/sly.c
+++ src/sly.c 2007/03/15 10:46:36
@@ -146,6 +146,21 @@
return 0;
}
+/* restore dropped privileges */
+int
+_restore_privs(uid_t save_euid, gid_t save_egid)
+{
+ int retuid = 0, retgid = 0;
+
+ retuid = setresuid(getuid(), save_euid, getuid());
+ retgid = setresgid(getgid(), save_egid, getgid());
+
+ debug("restore privileges: UID = %u, EUID = %u\n", getuid(), geteuid());
+ debug("restore privileges: GID = %u, EGID = %u\n", getgid(), getegid());
+
+ return (retuid == -1 || retgid == -1)?-1:0;
+}
+
int
_pam_krb5_sly_maybe_refresh(pam_handle_t *pamh, int flags,
int argc, PAM_KRB5_MAYBE_CONST char **argv)
@@ -159,6 +174,20 @@
int i, retval, stored;
char *v5ccname, *v4tktfile;
+ uid_t save_euid = geteuid();
+ gid_t save_egid = getegid();
+
+
+ if(_pam_krb5_sly_looks_unsafe() == 2 || _pam_krb5_sly_looks_unsafe() == 3)
+ {
+ /* drop privileges temporarily; restore them on every return from this function */
+ setresuid(getuid(), getuid(), geteuid());
+ setresgid(getgid(), getgid(), getegid());
+
+ debug("drop privileges temporarily: UID = %u, EUID = %u\n", getuid(), geteuid());
+ debug("drop privileges temporarily: GID = %u, EGID = %u\n", getgid(), getegid());
+ }
+
/* Inexpensive checks. */
switch (_pam_krb5_sly_looks_unsafe()) {
case 0:
@@ -166,18 +195,22 @@
break;
case 1:
warn("won't refresh credentials while running under sudo");
+ _restore_privs(save_euid, save_egid);
return PAM_SERVICE_ERR;
break;
case 2:
warn("won't refresh credentials while running setuid");
+ _restore_privs(save_euid, save_egid);
return PAM_SERVICE_ERR;
break;
case 3:
warn("won't refresh credentials while running setgid");
+ _restore_privs(save_euid, save_egid);
return PAM_SERVICE_ERR;
break;
default:
warn("not safe to refresh credentials");
+ _restore_privs(save_euid, save_egid);
return PAM_SERVICE_ERR;
break;
}
@@ -185,6 +218,7 @@
/* Initialize Kerberos. */
if (_pam_krb5_init_ctx(&ctx, argc, argv) != 0) {
warn("error initializing Kerberos");
+ _restore_privs(save_euid, save_egid);
return PAM_SERVICE_ERR;
}
@@ -193,6 +227,7 @@
if (i != PAM_SUCCESS) {
warn("could not identify user name");
krb5_free_context(ctx);
+ _restore_privs(save_euid, save_egid);
return i;
}
@@ -201,6 +236,7 @@
if (options == NULL) {
warn("error parsing options (shouldn't happen)");
krb5_free_context(ctx);
+ _restore_privs(save_euid, save_egid);
return PAM_SERVICE_ERR;
}
if (options->debug) {
@@ -222,6 +258,7 @@
}
_pam_krb5_options_free(pamh, ctx, options);
krb5_free_context(ctx);
+ _restore_privs(save_euid, save_egid);
return retval;
}
@@ -233,6 +270,7 @@
_pam_krb5_user_info_free(ctx, userinfo);
_pam_krb5_options_free(pamh, ctx, options);
krb5_free_context(ctx);
+ _restore_privs(save_euid, save_egid);
return PAM_IGNORE;
}
@@ -244,6 +282,7 @@
_pam_krb5_user_info_free(ctx, userinfo);
_pam_krb5_options_free(pamh, ctx, options);
krb5_free_context(ctx);
+ _restore_privs(save_euid, save_egid);
return PAM_SERVICE_ERR;
}
@@ -331,5 +370,6 @@
pam_strerror(pamh, retval));
}
+ _restore_privs(save_euid, save_egid);
return retval;
}