From 1c022b3556f442f57326c4a3f250128b1bd232ae Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 30 Aug 2013 17:25:01 -0400 Subject: [PATCH 09/14] krb5: Unify function to create ccache files Only 2 types (FILE and DIR) need to precreate files or directories on the file system, and the 2 functions were basically identical. Consolidate all in one common function and use that function directly where needed instead of using indirection. Resolves: https://fedorahosted.org/sssd/ticket/2061 --- src/providers/krb5/krb5_auth.c | 6 ++-- src/providers/krb5/krb5_utils.c | 71 ++++++++++------------------------------- src/providers/krb5/krb5_utils.h | 14 ++------ src/tests/krb5_child-test.c | 6 ++-- src/tests/krb5_utils-tests.c | 40 +++++++++++------------ 5 files changed, 43 insertions(+), 94 deletions(-) diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 1ea179be3af48b16129aeb4c2d850a66244f7d08..d2c53f98c04cda01c2a8e0efe038f5cd5fa82839 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -333,9 +333,9 @@ static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr, return EINVAL; } - ret = kr->cc_be->create(kr->ccname, - kr->krb5_ctx->illegal_path_re, - kr->uid, kr->gid, private_path); + ret = sss_krb5_precreate_ccache(kr->ccname, + kr->krb5_ctx->illegal_path_re, + kr->uid, kr->gid, private_path); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("ccache creation failed.\n")); return ret; diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c index c4849e74bd43b096b585398970f5b81e946212e9..83e61e14ecc116b9556231c5d8a0f55b63260c77 100644 --- a/src/providers/krb5/krb5_utils.c +++ b/src/providers/krb5/krb5_utils.c @@ -722,19 +722,31 @@ done: return EOK; } -static errno_t -create_ccache_dir_head(const char *parent, pcre *illegal_re, - uid_t uid, gid_t gid, bool private_path) +errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re, + uid_t uid, gid_t gid, bool private_path) { + TALLOC_CTX *tmp_ctx = NULL; + const char *filename; char *ccdirname; - TALLOC_CTX *tmp_ctx = NULL; char *end; errno_t ret; + if (ccname[0] == '/') { + filename = ccname; + } else if (strncmp(ccname, "FILE:", 5) == 0) { + filename = ccname + 5; + } else if (strncmp(ccname, "DIR:", 4) == 0) { + filename = ccname + 4; + } else { + /* only FILE and DIR types need precreation so far, we ignore any + * other type */ + return EOK; + } + tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; - ccdirname = talloc_strdup(tmp_ctx, parent); + ccdirname = talloc_strdup(tmp_ctx, filename); if (ccdirname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_strdup failed.\n")); ret = ENOMEM; @@ -1066,72 +1078,23 @@ get_cc_be_ops_ccache(const char *ccache) } /*======== Operations on the FILE: back end ========*/ -errno_t -cc_file_create(const char *location, pcre *illegal_re, - uid_t uid, gid_t gid, bool private_path) -{ - const char *filename; - - filename = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_FILE); - if (filename == NULL) { - DEBUG(SSSDBG_OP_FAILURE, ("Bad ccache type %s\n", location)); - return EINVAL; - } - - return create_ccache_dir_head(filename, illegal_re, uid, gid, private_path); -} struct sss_krb5_cc_be file_cc = { .type = SSS_KRB5_TYPE_FILE, - .create = cc_file_create, }; #ifdef HAVE_KRB5_CC_COLLECTION /*======== Operations on the DIR: back end ========*/ -errno_t -cc_dir_create(const char *location, pcre *illegal_re, - uid_t uid, gid_t gid, bool private_path) -{ - const char *dir_name; - - dir_name = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_DIR); - if (dir_name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Bad residual type\n")); - return EINVAL; - } - - return create_ccache_dir_head(dir_name, illegal_re, uid, gid, private_path); -} struct sss_krb5_cc_be dir_cc = { .type = SSS_KRB5_TYPE_DIR, - .create = cc_dir_create, }; /*======== Operations on the KEYRING: back end ========*/ -errno_t -cc_keyring_create(const char *location, pcre *illegal_re, - uid_t uid, gid_t gid, bool private_path) -{ - const char *residual; - - residual = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_KEYRING); - if (residual == NULL) { - DEBUG(SSSDBG_OP_FAILURE, ("Bad ccache type %s\n", location)); - return EINVAL; - } - - /* No special steps are needed to create a kernel keyring. - * Everything is handled in libkrb5. - */ - return EOK; -} - struct sss_krb5_cc_be keyring_cc = { .type = SSS_KRB5_TYPE_KEYRING, - .create = cc_keyring_create, }; #endif /* HAVE_KRB5_CC_COLLECTION */ diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h index b364f87aa6e6f0070e8acb5559ee92f2e001e0a5..5f720335aab1ac6e493843ac197c5af881a9b998 100644 --- a/src/providers/krb5/krb5_utils.h +++ b/src/providers/krb5/krb5_utils.h @@ -42,15 +42,9 @@ errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb, const char *user, const char *upn); -/* Operations on a credential cache */ -typedef errno_t (*cc_be_create_fn)(const char *location, pcre *illegal_re, - uid_t uid, gid_t gid, bool private_path); - /* A ccache back end */ struct sss_krb5_cc_be { enum sss_krb5_cc_type type; - - cc_be_create_fn create; }; extern struct sss_krb5_cc_be file_cc; @@ -58,9 +52,6 @@ extern struct sss_krb5_cc_be file_cc; errno_t create_ccache_dir(const char *dirname, pcre *illegal_re, uid_t uid, gid_t gid, bool private_path); -errno_t cc_file_create(const char *filename, pcre *illegal_re, - uid_t uid, gid_t gid, bool private_path); - struct sss_krb5_cc_be *get_cc_be_ops(enum sss_krb5_cc_type type); struct sss_krb5_cc_be *get_cc_be_ops_ccache(const char *ccache); @@ -76,6 +67,8 @@ errno_t switch_creds(TALLOC_CTX *mem_ctx, struct sss_creds **saved_creds); errno_t restore_creds(struct sss_creds *saved_creds); +errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re, + uid_t uid, gid_t gid, bool private_path); errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid); errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid, const char *ccname, const char *principal); @@ -90,9 +83,6 @@ errno_t get_ccache_file_data(const char *ccache_file, const char *client_name, extern struct sss_krb5_cc_be dir_cc; extern struct sss_krb5_cc_be keyring_cc; -errno_t cc_dir_create(const char *location, pcre *illegal_re, - uid_t uid, gid_t gid, bool private_path); - #endif /* HAVE_KRB5_CC_COLLECTION */ diff --git a/src/tests/krb5_child-test.c b/src/tests/krb5_child-test.c index dff62ab64dd1948d20da6b640a0570ee8ea6b11d..5ea30014f9c8f748e85506627b7f40d72b913b1b 100644 --- a/src/tests/krb5_child-test.c +++ b/src/tests/krb5_child-test.c @@ -287,9 +287,9 @@ create_dummy_req(TALLOC_CTX *mem_ctx, const char *user, DEBUG(SSSDBG_FUNC_DATA, ("ccname [%s] uid [%llu] gid [%llu]\n", kr->ccname, kr->uid, kr->gid)); - ret = kr->krb5_ctx->cc_be->create(kr->ccname, - kr->krb5_ctx->illegal_path_re, - kr->uid, kr->gid, private); + ret = sss_krb5_precreate_ccache(kr->ccname, + kr->krb5_ctx->illegal_path_re, + kr->uid, kr->gid, private); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("create_ccache_dir failed.\n")); goto fail; diff --git a/src/tests/krb5_utils-tests.c b/src/tests/krb5_utils-tests.c index 4715774ff189700bc1cbeb6c90f4438445a594b0..ea0292569135e0fc22a44251cfc4e8719a15837f 100644 --- a/src/tests/krb5_utils-tests.c +++ b/src/tests/krb5_utils-tests.c @@ -117,14 +117,14 @@ START_TEST(test_pub_ccache_dir) ret = chmod(testpath, 0754); fail_unless(ret == EOK, "chmod failed."); - ret = cc_file_create(filename, NULL, 12345, 12345, false); - fail_unless(ret == EINVAL, "cc_file_create does not return EINVAL " + ret = sss_krb5_precreate_ccache(filename, NULL, 12345, 12345, false); + fail_unless(ret == EINVAL, "sss_krb5_precreate_ccache does not return EINVAL " "while x-bit is missing."); ret = chmod(testpath, 0755); fail_unless(ret == EOK, "chmod failed."); - ret = cc_file_create(filename, NULL, 12345, 12345, false); - fail_unless(ret == EOK, "cc_file_create failed."); + ret = sss_krb5_precreate_ccache(filename, NULL, 12345, 12345, false); + fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed."); check_dir(subdirname, 0, 0, 01777); RMDIR(subdirname); @@ -158,7 +158,7 @@ START_TEST(test_pub_ccache_dir_in_user_dir) filename = talloc_asprintf(tmp_ctx, "%s/ccfile", subdirname); fail_unless(filename != NULL, "talloc_asprintf failed."); - ret = cc_file_create(filename, NULL, 12345, 12345, false); + ret = sss_krb5_precreate_ccache(filename, NULL, 12345, 12345, false); fail_unless(ret == EINVAL, "Creating public ccache dir in user dir " "does not failed with EINVAL."); @@ -193,14 +193,14 @@ START_TEST(test_priv_ccache_dir) ret = chmod(testpath, 0754); fail_unless(ret == EOK, "chmod failed."); - ret = cc_file_create(filename, NULL, uid, gid, true); - fail_unless(ret == EINVAL, "cc_file_create does not return EINVAL " + ret = sss_krb5_precreate_ccache(filename, NULL, uid, gid, true); + fail_unless(ret == EINVAL, "sss_krb5_precreate_ccache does not return EINVAL " "while x-bit is missing."); ret = chmod(testpath, 0755); fail_unless(ret == EOK, "chmod failed."); - ret = cc_file_create(filename, NULL, uid, gid, true); - fail_unless(ret == EOK, "cc_file_create failed."); + ret = sss_krb5_precreate_ccache(filename, NULL, uid, gid, true); + fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed."); check_dir(subdir, uid, gid, 0700); RMDIR(subdir); @@ -248,14 +248,14 @@ START_TEST(test_private_ccache_dir_in_user_dir) ret = chmod(user_dir, 0600); fail_unless(ret == EOK, "chmod failed."); - ret = cc_file_create(filename, NULL, uid, gid, true); - fail_unless(ret == EINVAL, "cc_file_create does not return EINVAL " + ret = sss_krb5_precreate_ccache(filename, NULL, uid, gid, true); + fail_unless(ret == EINVAL, "sss_krb5_precreate_ccache does not return EINVAL " "while x-bit is missing."); ret = chmod(user_dir, 0700); fail_unless(ret == EOK, "chmod failed."); - ret = cc_file_create(filename, NULL, uid, gid, true); - fail_unless(ret == EOK, "cc_file_create failed."); + ret = sss_krb5_precreate_ccache(filename, NULL, uid, gid, true); + fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed."); check_dir(dn3, uid, gid, 0700); RMDIR(dn3); @@ -292,7 +292,7 @@ START_TEST(test_private_ccache_dir_in_wrong_user_dir) filename = talloc_asprintf(tmp_ctx, "%s/ccfile", subdirname); fail_unless(filename != NULL, "talloc_asprintf failed."); - ret = cc_file_create(filename, NULL, 12345, 12345, true); + ret = sss_krb5_precreate_ccache(filename, NULL, 12345, 12345, true); fail_unless(ret == EINVAL, "Creating private ccache dir in wrong user " "dir does not failed with EINVAL."); @@ -357,7 +357,6 @@ START_TEST(test_illegal_patterns) } END_TEST -#ifdef HAVE_KRB5_CC_COLLECTION START_TEST(test_cc_dir_create) { char *residual; @@ -386,8 +385,8 @@ START_TEST(test_cc_dir_create) residual = talloc_asprintf(tmp_ctx, "DIR:%s/%s", dirname, "ccdir"); fail_unless(residual != NULL, "talloc_asprintf failed."); - ret = cc_dir_create(residual, illegal_re, uid, gid, true); - fail_unless(ret == EOK, "cc_dir_create failed\n"); + ret = sss_krb5_precreate_ccache(residual, illegal_re, uid, gid, true); + fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed\n"); ret = rmdir(dirname); if (ret < 0) ret = errno; fail_unless(ret == 0, "Cannot remove %s: %s\n", dirname, strerror(ret)); @@ -399,8 +398,8 @@ START_TEST(test_cc_dir_create) residual = talloc_asprintf(tmp_ctx, "DIR:%s/%s", dirname, "ccdir/"); fail_unless(residual != NULL, "talloc_asprintf failed."); - ret = cc_dir_create(residual, illegal_re, uid, gid, true); - fail_unless(ret == EOK, "cc_dir_create failed\n"); + ret = sss_krb5_precreate_ccache(residual, illegal_re, uid, gid, true); + fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed\n"); ret = rmdir(dirname); if (ret < 0) ret = errno; fail_unless(ret == 0, "Cannot remove %s: %s\n", dirname, strerror(ret)); @@ -408,7 +407,6 @@ START_TEST(test_cc_dir_create) free(cwd); } END_TEST -#endif /* HAVE_KRB5_CC_COLLECTION */ void setup_talloc_context(void) @@ -774,9 +772,7 @@ Suite *krb5_utils_suite (void) tcase_add_checked_fixture (tc_create_dir, setup_create_dir, teardown_create_dir); tcase_add_test (tc_create_dir, test_illegal_patterns); -#ifdef HAVE_KRB5_CC_COLLECTION tcase_add_test (tc_create_dir, test_cc_dir_create); -#endif /* HAVE_KRB5_CC_COLLECTION */ if (getuid() == 0) { tcase_add_test (tc_create_dir, test_priv_ccache_dir); tcase_add_test (tc_create_dir, test_private_ccache_dir_in_user_dir); -- 1.8.3.1