summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2013-08-15 11:40:59 -0400
committerJakub Hrozek <jhrozek@redhat.com>2013-08-22 19:29:08 +0200
commit18dff5d8bb4081af4c94339db9342b8a5b7d121e (patch)
tree061ce379e06245dcae2e3a54d12b3971109aaab0
parent8340ca480e0fe823441633720d67efc9e4a4bc64 (diff)
downloadsssd-18dff5d8bb4081af4c94339db9342b8a5b7d121e.tar.gz
sssd-18dff5d8bb4081af4c94339db9342b8a5b7d121e.tar.xz
sssd-18dff5d8bb4081af4c94339db9342b8a5b7d121e.zip
KRB5: Refactor cc_*_check_existing
There was duplicated code in cc_file_check_existing() and in cc_dir_check_existing(). I pulled them into the same function. There are two changes made to the original code here: 1) Fixes a use-after-free bug in cc_file_check_existing(). In the original code, we called krb5_free_context() and then used that context immediately after that in krb5_cc_close(). This patch corrects the ordering 2) The krb5_cc_resolve() call handles KRB5_FCC_NOFILE for all cache types. Previously, this was only handled for DIR caches.
-rw-r--r--src/providers/krb5/krb5_utils.c120
1 files changed, 59 insertions, 61 deletions
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index 675a6b71a..55f05f895 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -704,6 +704,60 @@ done:
return ret;
}
+static errno_t
+check_cc_validity(const char *location,
+ const char *realm,
+ const char *princ,
+ bool *_valid)
+{
+ errno_t ret;
+ bool valid = false;
+ krb5_ccache ccache = NULL;
+ krb5_context context = NULL;
+ krb5_error_code krberr;
+
+ krberr = krb5_init_context(&context);
+ if (krberr) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to init kerberos context\n"));
+ return EIO;
+ }
+
+ krberr = krb5_cc_resolve(context, location, &ccache);
+ if (krberr == KRB5_FCC_NOFILE || ccache == NULL) {
+ /* KRB5_FCC_NOFILE would be returned if the directory components
+ * of the DIR cache do not exist, which is the case in /run
+ * after a reboot
+ */
+ DEBUG(SSSDBG_TRACE_FUNC,
+ ("ccache %s is missing or empty\n", location));
+ valid = false;
+ ret = EOK;
+ goto done;
+ } else if (krberr != 0) {
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
+ DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_resolve failed.\n"));
+ ret = EIO;
+ goto done;
+ }
+
+ krberr = check_for_valid_tgt(context, ccache, realm, princ, &valid);
+ if (krberr != EOK) {
+ KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Could not check if ccache contains a valid principal\n"));
+ ret = EIO;
+ goto done;
+ }
+
+ ret = EOK;
+ *_valid = valid;
+
+ done:
+ if (ccache) krb5_cc_close(context, ccache);
+ krb5_free_context(context);
+ return ret;
+}
+
/*======== ccache back end utilities ========*/
struct sss_krb5_cc_be *
get_cc_be_ops(enum sss_krb5_cc_type type)
@@ -852,9 +906,6 @@ cc_file_check_existing(const char *location, uid_t uid,
bool active;
bool valid;
const char *filename;
- krb5_ccache ccache = NULL;
- krb5_context context = NULL;
- krb5_error_code kerr;
filename = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_FILE);
if (!filename) {
@@ -878,28 +929,9 @@ cc_file_check_existing(const char *location, uid_t uid,
return ret;
}
- kerr = krb5_init_context(&context);
- if (kerr != 0) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to init kerberos context\n"));
- return EIO;
- }
-
- kerr = krb5_cc_resolve(context, location, &ccache);
- if (kerr != 0) {
- KRB5_DEBUG(SSSDBG_OP_FAILURE, context, kerr);
- krb5_free_context(context);
- DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_resolve failed.\n"));
- return EIO;
- }
-
- kerr = check_for_valid_tgt(context, ccache, realm, princ, &valid);
- krb5_free_context(context);
- krb5_cc_close(context, ccache);
- if (kerr != EOK) {
- KRB5_DEBUG(SSSDBG_OP_FAILURE, context, kerr);
- DEBUG(SSSDBG_CRIT_FAILURE,
- ("Could not check if ccache contains a valid principal\n"));
- return EIO;
+ ret = check_cc_validity(location, realm, princ, &valid);
+ if (ret != EOK) {
+ return ret;
}
*_active = active;
@@ -977,9 +1009,6 @@ cc_dir_check_existing(const char *location, uid_t uid,
bool active = false;
bool active_primary = false;
bool valid = false;
- krb5_ccache ccache = NULL;
- krb5_context context = NULL;
- krb5_error_code krberr;
enum sss_krb5_cc_type type;
const char *filename;
const char *dir;
@@ -1062,45 +1091,14 @@ cc_dir_check_existing(const char *location, uid_t uid,
goto done;
}
- krberr = krb5_init_context(&context);
- if (krberr) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to init kerberos context\n"));
- ret = EIO;
- goto done;
- }
-
- krberr = krb5_cc_resolve(context, location, &ccache);
- if (krberr == KRB5_FCC_NOFILE || ccache == NULL) {
- /* KRB5_FCC_NOFILE would be returned if the directory components
- * of the DIR cache do not exist, which is the case in /run
- * after a reboot
- */
- DEBUG(SSSDBG_TRACE_FUNC,
- ("ccache %s is missing or empty\n", location));
- valid = false;
- ret = EOK;
- goto done;
- } else if (krberr != 0) {
- KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
- DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_resolve failed.\n"));
- ret = EIO;
- goto done;
- }
-
- krberr = check_for_valid_tgt(context, ccache, realm, princ, &valid);
- if (krberr != EOK) {
- KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
- DEBUG(SSSDBG_CRIT_FAILURE,
- ("Could not check if ccache contains a valid principal\n"));
- ret = EIO;
+ ret = check_cc_validity(location, realm, princ, &valid);
+ if (ret != EOK) {
goto done;
}
ret = EOK;
done:
talloc_free(tmp_ctx);
- if (ccache) krb5_cc_close(context, ccache);
- krb5_free_context(context);
*_active = active;
*_valid = valid;
return ret;