@@ -82,6 +82,8 @@ struct cli_opts {
8282};
8383
8484struct krb5_req {
85+ bool krb5_child_has_setid_caps ;
86+
8587 krb5_context ctx ;
8688 krb5_principal princ ;
8789 krb5_principal princ_orig ;
@@ -1845,6 +1847,10 @@ static errno_t k5c_attach_ccname_msg(struct krb5_req *kr)
18451847 char * msg = NULL ;
18461848 int ret ;
18471849
1850+ if (!kr -> krb5_child_has_setid_caps ) {
1851+ return EOK ;
1852+ }
1853+
18481854 if (kr -> ccname == NULL ) {
18491855 DEBUG (SSSDBG_CRIT_FAILURE , "Error obtaining ccname.\n" );
18501856 return ERR_INTERNAL ;
@@ -2523,6 +2529,12 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
25232529 goto done ;
25242530 }
25252531
2532+ if (!kr -> krb5_child_has_setid_caps ) {
2533+ /* no set-id capability => can't populate user ccache */
2534+ kerr = 0 ;
2535+ goto done ;
2536+ }
2537+
25262538 /* Make sure ccache is created and written as the user */
25272539 kerr = switch_to_user ();
25282540 if (kerr != EOK ) {
@@ -4085,29 +4097,37 @@ static krb5_error_code privileged_krb5_setup(struct krb5_req *kr,
40854097 int ret ;
40864098 char * mem_keytab ;
40874099
4088- /* Make use of cap_set*id first to bootstap process */
4089- sss_set_cap_effective (CAP_SETGID , true);
4090- if (geteuid () != 0 ) {
4091- ret = setgroups (0 , NULL );
4100+ /* Make use of cap_set*id (if available) first to bootstrap process */
4101+ kr -> krb5_child_has_setid_caps =
4102+ ((sss_set_cap_effective (CAP_SETGID , true) == EOK ) &&
4103+ (sss_set_cap_effective (CAP_SETUID , true) == EOK ));
4104+
4105+ if (kr -> krb5_child_has_setid_caps ) {
4106+ if (geteuid () != 0 ) {
4107+ ret = setgroups (0 , NULL );
4108+ if (ret != 0 ) {
4109+ ret = errno ;
4110+ DEBUG (SSSDBG_CRIT_FAILURE , "Failed to drop supplementary groups: %d\n" , ret );
4111+ return ret ;
4112+ }
4113+ } /* Otherwise keep supplementary groups to have access to DB_PATH to store FAST ccache */
4114+ ret = setresgid (kr -> gid , -1 , -1 );
40924115 if (ret != 0 ) {
40934116 ret = errno ;
4094- DEBUG (SSSDBG_CRIT_FAILURE , "Failed to drop supplementary groups : %d\n" , ret );
4117+ DEBUG (SSSDBG_CRIT_FAILURE , "Failed to set real GID : %d\n" , ret );
40954118 return ret ;
40964119 }
4097- } /* Otherwise keep supplementary groups to have access to DB_PATH to store FAST ccache */
4098- ret = setresgid (kr -> gid , -1 , -1 );
4099- if (ret != 0 ) {
4100- ret = errno ;
4101- DEBUG (SSSDBG_CRIT_FAILURE , "Failed to set real GID: %d\n" , ret );
4102- return ret ;
4103- }
4104- sss_set_cap_effective (CAP_SETUID , true);
4105- ret = setresuid (kr -> uid , -1 , -1 );
4106- if (ret != 0 ) {
4107- ret = errno ;
4108- DEBUG (SSSDBG_CRIT_FAILURE , "Failed to set real UID: %d\n" , ret );
4109- return ret ;
4120+ ret = setresuid (kr -> uid , -1 , -1 );
4121+ if (ret != 0 ) {
4122+ ret = errno ;
4123+ DEBUG (SSSDBG_CRIT_FAILURE , "Failed to set real UID: %d\n" , ret );
4124+ return ret ;
4125+ }
4126+ } else {
4127+ DEBUG (SSSDBG_CONF_SETTINGS , "'krb5_child' doesn't have CAP_SETUID and/or "
4128+ "CAP_SETGID. User ccache won't be updated.\n" );
41104129 }
4130+
41114131 sss_drop_cap (CAP_SETUID );
41124132 sss_drop_cap (CAP_SETGID );
41134133
@@ -4337,7 +4357,7 @@ int main(int argc, const char *argv[])
43374357 * is only allowed for authenticated users. Since PKINIT is part of
43384358 * the authentication and the user is not authenticated yet, we have
43394359 * to use different privileges and can only drop it after the TGT is
4340- * received. IDs the backend (and thus 'krb5_child) is running with are
4360+ * received. IDs the backend (and thus 'krb5_child' ) is running with are
43414361 * either root or the 'sssd' user. Root is allowed by default and
43424362 * the 'sssd' user is allowed with the help of the sssd-pcsc.rules
43434363 * policy-kit rule. So those IDs are a suitable choice and needs to
@@ -4346,11 +4366,13 @@ int main(int argc, const char *argv[])
43464366 * to make sure the empty ccache is created with the expected
43474367 * ownership. */
43484368 if (!IS_SC_AUTHTOK (kr -> pd -> authtok ) || offline ) {
4349- ret = switch_to_user ();
4350- if (ret != EOK ) {
4351- DEBUG (SSSDBG_CRIT_FAILURE , "Failed to switch to user IDs: %d\n" , ret );
4352- ret = EFAULT ;
4353- goto done ;
4369+ if (kr -> krb5_child_has_setid_caps ) {
4370+ ret = switch_to_user ();
4371+ if (ret != EOK ) {
4372+ DEBUG (SSSDBG_CRIT_FAILURE , "Failed to switch to user IDs: %d\n" , ret );
4373+ ret = EFAULT ;
4374+ goto done ;
4375+ }
43544376 }
43554377 }
43564378
@@ -4370,7 +4392,9 @@ int main(int argc, const char *argv[])
43704392 case SSS_PAM_AUTHENTICATE :
43714393 /* If we are offline, we need to create an empty ccache file */
43724394 if (offline ) {
4373- ret = create_empty_ccache (kr );
4395+ if (kr -> krb5_child_has_setid_caps ) {
4396+ ret = create_empty_ccache (kr );
4397+ }
43744398 } else {
43754399 DEBUG (SSSDBG_TRACE_FUNC , "Will perform online auth\n" );
43764400 ret = tgt_req_child (kr );
@@ -4391,6 +4415,10 @@ int main(int argc, const char *argv[])
43914415 ret = KRB5_KDC_UNREACH ;
43924416 goto done ;
43934417 }
4418+ if (!kr -> krb5_child_has_setid_caps ) {
4419+ ret = KRB5_CC_NOTFOUND ;
4420+ goto done ;
4421+ }
43944422 ret = renew_tgt_child (kr );
43954423 break ;
43964424 case SSS_PAM_PREAUTH :
0 commit comments