Skip to content

Commit fbb3273

Browse files
KRB5_CHILD: don't check if FILE:/DIR: path accessible in advance
Inaccessible FILE:/DIR: path is a system configuration error that needs to be fixed anyway. It doesn't make much difference to fail before or after credentials check in this case.
1 parent 2f942bb commit fbb3273

File tree

4 files changed

+32
-213
lines changed

4 files changed

+32
-213
lines changed

src/providers/krb5/krb5_ccache.c

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -102,108 +102,6 @@ static errno_t switch_to_service(void)
102102
return EOK;
103103
}
104104

105-
static errno_t check_parent_stat(struct stat *parent_stat, uid_t uid)
106-
{
107-
if (parent_stat->st_uid != 0 && parent_stat->st_uid != uid) {
108-
DEBUG(SSSDBG_CRIT_FAILURE,
109-
"Private directory can only be created below a directory "
110-
"belonging to root or to [%"SPRIuid"].\n", uid);
111-
return EINVAL;
112-
}
113-
114-
if (parent_stat->st_uid == uid) {
115-
if ( (parent_stat->st_mode & (S_IXUSR|S_IRUSR|S_IWUSR)) !=
116-
(S_IXUSR|S_IRUSR|S_IWUSR) ) {
117-
DEBUG(SSSDBG_CRIT_FAILURE,
118-
"Parent directory is owned but not accessible by user?!\n");
119-
return EINVAL;
120-
}
121-
} else {
122-
if ( (parent_stat->st_mode & (S_IXOTH|S_IROTH|S_IWOTH)) !=
123-
(S_IXOTH|S_IROTH|S_IWOTH) ) {
124-
DEBUG(SSSDBG_CRIT_FAILURE,
125-
"Parent directory is owned by root and not accessible to "
126-
"user\n");
127-
return EINVAL;
128-
}
129-
}
130-
131-
return EOK;
132-
}
133-
134-
errno_t sss_krb5_precheck_ccache(const char *ccname, uid_t uid, gid_t gid)
135-
{
136-
TALLOC_CTX *tmp_ctx = NULL;
137-
const char *filename;
138-
char *ccdirname;
139-
char *end;
140-
struct stat parent_stat;
141-
errno_t ret;
142-
143-
if (ccname[0] == '/') {
144-
filename = ccname;
145-
} else if (strncmp(ccname, "FILE:", 5) == 0) {
146-
filename = ccname + 5;
147-
} else if (strncmp(ccname, "DIR:", 4) == 0) {
148-
filename = ccname + 4;
149-
} else {
150-
/* only FILE and DIR types need pre-checks, we ignore any
151-
* other type */
152-
DEBUG(SSSDBG_TRACE_ALL, "No checks needed for [%s]\n", ccname);
153-
return EOK;
154-
}
155-
156-
tmp_ctx = talloc_new(NULL);
157-
if (!tmp_ctx) return ENOMEM;
158-
159-
ccdirname = talloc_strdup(tmp_ctx, filename);
160-
if (ccdirname == NULL) {
161-
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
162-
ret = ENOMEM;
163-
goto done;
164-
}
165-
166-
/* Get parent directory of wanted ccache directory/file,
167-
* removing trailing slashes from the back
168-
*/
169-
do {
170-
end = strrchr(ccdirname, '/');
171-
if (end == NULL || end == ccdirname) {
172-
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find parent directory of [%s], "
173-
"/ is not allowed.\n", ccdirname);
174-
ret = EINVAL;
175-
goto done;
176-
}
177-
*end = '\0';
178-
} while (*(end+1) == '\0');
179-
180-
/* This function is currently called from `privileged_krb5_setup()` only
181-
* so 'krb5_child' runs under service user at this point.
182-
*/
183-
switch_to_user();
184-
ret = stat(ccdirname, &parent_stat);
185-
switch_to_service();
186-
if (ret != 0) {
187-
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot stat() [%s]\n", ccdirname);
188-
ret = EINVAL;
189-
goto done;
190-
}
191-
192-
ret = check_parent_stat(&parent_stat, uid);
193-
if (ret != EOK) {
194-
DEBUG(SSSDBG_FATAL_FAILURE,
195-
"Check the ownership and permissions of krb5_ccachedir: [%s].\n",
196-
ccdirname);
197-
goto done;
198-
}
199-
200-
ret = EOK;
201-
202-
done:
203-
talloc_free(tmp_ctx);
204-
return ret;
205-
}
206-
207105
struct sss_krb5_ccache {
208106
krb5_context context;
209107
krb5_ccache ccache;

src/providers/krb5/krb5_ccache.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ struct tgt_times {
3535
time_t renew_till;
3636
};
3737

38-
errno_t sss_krb5_precheck_ccache(const char *ccname, uid_t uid, gid_t gid);
39-
4038
errno_t sss_krb5_check_ccache_princ(krb5_context kctx,
4139
const char *ccname,
4240
krb5_principal user_princ);

src/providers/krb5/krb5_child.c

Lines changed: 32 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -3870,88 +3870,55 @@ static errno_t old_ccache_valid(struct krb5_req *kr, bool *_valid)
38703870
return EOK;
38713871
}
38723872

3873-
static int k5c_check_old_ccache(struct krb5_req *kr)
3873+
static void k5c_ccache_check(struct krb5_req *kr, uint32_t offline)
38743874
{
38753875
errno_t ret;
38763876

3877-
if (kr->old_ccname) {
3878-
ret = old_ccache_valid(kr, &kr->old_cc_valid);
3879-
if (ret != EOK) {
3880-
DEBUG(SSSDBG_OP_FAILURE, "old_ccache_valid() failed.\n");
3881-
return ret;
3882-
}
3877+
kr->old_cc_valid = false;
3878+
kr->old_cc_active = false;
3879+
3880+
if (kr->pd->cmd == SSS_PAM_ACCT_MGMT) {
3881+
return;
3882+
}
3883+
3884+
if (kr->old_ccname == NULL) {
3885+
return;
3886+
}
38833887

3888+
ret = old_ccache_valid(kr, &kr->old_cc_valid);
3889+
if (ret != EOK) {
3890+
DEBUG(SSSDBG_OP_FAILURE, "old_ccache_valid() failed.\n");
3891+
} else {
38843892
ret = check_if_uid_is_active(kr->uid, &kr->old_cc_active);
38853893
if (ret != EOK) {
38863894
DEBUG(SSSDBG_OP_FAILURE, "check_if_uid_is_active() failed.\n");
3887-
return ret;
3895+
kr->old_cc_valid = false;
38883896
}
3889-
3890-
DEBUG(SSSDBG_TRACE_ALL,
3891-
"Old ccache is [%s] and is %s active and TGT is %s valid.\n",
3892-
kr->old_ccname ? kr->old_ccname : "not set",
3893-
kr->old_cc_active ? "" : "not",
3894-
kr->old_cc_valid ? "" : "not");
38953897
}
38963898

3897-
return EOK;
3898-
}
3899-
3900-
static int k5c_precheck_ccache(struct krb5_req *kr, uint32_t offline)
3901-
{
3902-
errno_t ret;
3899+
DEBUG(SSSDBG_TRACE_ALL,
3900+
"Old ccache is [%s] and is %s active and TGT is %s valid.\n",
3901+
kr->old_ccname ? kr->old_ccname : "not set",
3902+
kr->old_cc_active ? "" : "not",
3903+
kr->old_cc_valid ? "" : "not");
39033904

3904-
/* The ccache path should be checked if one of the following conditions
3905+
/* Old ccache can't be used if one of the following conditions
39053906
* is true:
3906-
* - it doesn't exist (kr->old_ccname == NULL)
3907+
* - it doesn't exist (1)
3908+
* - the backend is offline and the current cache file not used and
3909+
* it does not contain a valid TGT (2)
39073910
* - the backend is online and the current ccache file is not used, i.e
39083911
* the related user is currently not logged in and it is not a renewal
3909-
* request
3910-
* (offline && !kr->old_cc_active && kr->pd->cmd != SSS_CMD_RENEW)
3911-
* - the backend is offline and the current cache file not used and
3912-
* it does not contain a valid TGT
3913-
* (offline && !kr->old_cc_active && !kr->valid_tgt)
3912+
* request (3)
39143913
*/
3915-
if (kr->old_ccname == NULL ||
3916-
(offline && !kr->old_cc_active && !kr->old_cc_valid) ||
3917-
(!offline && !kr->old_cc_active && kr->pd->cmd != SSS_CMD_RENEW)) {
3918-
DEBUG(SSSDBG_TRACE_ALL, "Pre-checking ccache [%s]\n", kr->ccname);
3919-
ret = sss_krb5_precheck_ccache(kr->ccname, kr->uid, kr->gid);
3920-
if (ret != EOK) {
3921-
DEBUG(SSSDBG_OP_FAILURE, "ccache check failed.\n");
3922-
return ret;
3923-
}
3914+
if (kr->old_ccname == NULL || /* (1) */
3915+
(offline && !kr->old_cc_active && !kr->old_cc_valid) || /* (2) */
3916+
(!offline && !kr->old_cc_active && kr->pd->cmd != SSS_CMD_RENEW)) /* (3) */ {
3917+
DEBUG(SSSDBG_TRACE_ALL, "Ignoring old ccache\n");
39243918
} else {
39253919
DEBUG(SSSDBG_TRACE_ALL, "Reusing old ccache [%s]\n", kr->old_ccname);
39263920
kr->ccname = kr->old_ccname;
39273921
}
3928-
3929-
return EOK;
3930-
}
3931-
3932-
static int k5c_ccache_check(struct krb5_req *kr, uint32_t offline)
3933-
{
3934-
errno_t ret;
3935-
3936-
if (kr->pd->cmd == SSS_PAM_ACCT_MGMT) {
3937-
return EOK;
3938-
}
3939-
3940-
ret = k5c_check_old_ccache(kr);
3941-
if (ret != 0) {
3942-
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot check old ccache [%s]: [%d][%s]. " \
3943-
"Assuming old cache is invalid " \
3944-
"and not used.\n",
3945-
kr->old_ccname, ret, sss_strerror(ret));
3946-
}
3947-
3948-
ret = k5c_precheck_ccache(kr, offline);
3949-
if (ret != 0) {
3950-
DEBUG(SSSDBG_OP_FAILURE, "ccache pre-check failed\n");
3951-
return ret;
3952-
}
3953-
3954-
return EOK;
39553922
}
39563923

39573924
static int k5c_setup(struct krb5_req *kr, uint32_t offline)
@@ -4160,15 +4127,9 @@ static krb5_error_code privileged_krb5_setup(struct krb5_req *kr,
41604127
return ret;
41614128
}
41624129

4163-
/* Determine if old FILE:/DIR: ccache needs to be re-used and if
4164-
* path is accessible.
4165-
*/
4130+
/* Determine if old ccache name can and needs to be re-used */
41664131
if (kr->krb5_child_has_setid_caps) {
4167-
ret = k5c_ccache_check(kr, offline);
4168-
if (ret != EOK) {
4169-
DEBUG(SSSDBG_CRIT_FAILURE, "k5c_ccache_check() failed.\n");
4170-
return ret;
4171-
}
4132+
k5c_ccache_check(kr, offline);
41724133
}
41734134

41744135
if (!(offline ||

src/tests/krb5_utils-tests.c

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -74,39 +74,6 @@ void teardown_create_dir(void)
7474
ck_assert_msg(ret == 0, "Cannot free talloc context.");
7575
}
7676

77-
START_TEST(test_private_ccache_dir_in_wrong_user_dir)
78-
{
79-
int ret;
80-
char *cwd;
81-
char *dirname;
82-
char *subdirname;
83-
char *filename;
84-
85-
ck_assert_msg(getuid() == 0, "This test must be run as root.");
86-
87-
cwd = getcwd(NULL, 0);
88-
ck_assert_msg(cwd != NULL, "getcwd failed.");
89-
90-
dirname = talloc_asprintf(tmp_ctx, "%s/%s/priv_ccdir", cwd, TESTS_PATH);
91-
free(cwd);
92-
ck_assert_msg(dirname != NULL, "talloc_asprintf failed.");
93-
ret = mkdir(dirname, 0700);
94-
ck_assert_msg(ret == EOK, "mkdir failed.\n");
95-
ret = chown(dirname, 12346, 12346);
96-
ck_assert_msg(ret == EOK, "chown failed.\n");
97-
subdirname = talloc_asprintf(tmp_ctx, "%s/subdir", dirname);
98-
ck_assert_msg(subdirname != NULL, "talloc_asprintf failed.");
99-
filename = talloc_asprintf(tmp_ctx, "%s/ccfile", subdirname);
100-
ck_assert_msg(filename != NULL, "talloc_asprintf failed.");
101-
102-
ret = sss_krb5_precheck_ccache(filename, 12345, 12345);
103-
ck_assert_msg(ret == EINVAL, "Creating private ccache dir in wrong user "
104-
"dir does not failed with EINVAL.");
105-
106-
RMDIR(dirname);
107-
}
108-
END_TEST
109-
11077
START_TEST(test_illegal_patterns)
11178
{
11279
char *cwd;
@@ -650,11 +617,6 @@ Suite *krb5_utils_suite (void)
650617
tcase_add_checked_fixture (tc_create_dir, setup_create_dir,
651618
teardown_create_dir);
652619
tcase_add_test (tc_create_dir, test_illegal_patterns);
653-
if (getuid() == 0) {
654-
tcase_add_test (tc_create_dir, test_private_ccache_dir_in_wrong_user_dir);
655-
} else {
656-
printf("Run as root to enable more tests.\n");
657-
}
658620
suite_add_tcase (s, tc_create_dir);
659621

660622
TCase *tc_krb5_helpers = tcase_create("Helper functions");

0 commit comments

Comments
 (0)