@@ -121,6 +121,7 @@ struct krb5_req {
121121 struct cli_opts * cli_opts ;
122122};
123123
124+ static bool krb5_child_has_setid_cap = true;
124125static krb5_context krb5_error_ctx ;
125126
126127#define KRB5_CHILD_DEBUG_INT (level , errctx , krb5_error ) do { \
@@ -1845,6 +1846,10 @@ static errno_t k5c_attach_ccname_msg(struct krb5_req *kr)
18451846 char * msg = NULL ;
18461847 int ret ;
18471848
1849+ if (!krb5_child_has_setid_cap ) {
1850+ return EOK ;
1851+ }
1852+
18481853 if (kr -> ccname == NULL ) {
18491854 DEBUG (SSSDBG_CRIT_FAILURE , "Error obtaining ccname.\n" );
18501855 return ERR_INTERNAL ;
@@ -2523,6 +2528,12 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
25232528 goto done ;
25242529 }
25252530
2531+ if (!krb5_child_has_setid_cap ) {
2532+ /* no set-id capability => can't populate user ccache */
2533+ kerr = 0 ;
2534+ goto done ;
2535+ }
2536+
25262537 /* Make sure ccache is created and written as the user */
25272538 kerr = switch_to_user ();
25282539 if (kerr != EOK ) {
@@ -4085,32 +4096,43 @@ static krb5_error_code privileged_krb5_setup(struct krb5_req *kr,
40854096 int ret ;
40864097 char * mem_keytab ;
40874098
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 );
4099+ /* Make use of cap_set*id (if available) first to bootstrap process */
4100+ if (sss_set_cap_effective (CAP_SETGID , true) == EOK ) {
4101+ if (geteuid () != 0 ) {
4102+ ret = setgroups (0 , NULL );
4103+ if (ret != 0 ) {
4104+ ret = errno ;
4105+ DEBUG (SSSDBG_CRIT_FAILURE , "Failed to drop supplementary groups: %d\n" , ret );
4106+ return ret ;
4107+ }
4108+ } /* Otherwise keep supplementary groups to have access to DB_PATH to store FAST ccache */
4109+ ret = setresgid (kr -> gid , -1 , -1 );
40924110 if (ret != 0 ) {
40934111 ret = errno ;
4094- DEBUG (SSSDBG_CRIT_FAILURE , "Failed to drop supplementary groups : %d\n" , ret );
4112+ DEBUG (SSSDBG_CRIT_FAILURE , "Failed to set real GID : %d\n" , ret );
40954113 return ret ;
40964114 }
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 ;
4115+ } else {
4116+ krb5_child_has_setid_cap = false;
41034117 }
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 ;
4118+ if (krb5_child_has_setid_cap && (sss_set_cap_effective (CAP_SETUID , true) == EOK )) {
4119+ ret = setresuid (kr -> uid , -1 , -1 );
4120+ if (ret != 0 ) {
4121+ ret = errno ;
4122+ DEBUG (SSSDBG_CRIT_FAILURE , "Failed to set real UID: %d\n" , ret );
4123+ return ret ;
4124+ }
4125+ } else {
4126+ krb5_child_has_setid_cap = false;
41104127 }
41114128 sss_drop_cap (CAP_SETUID );
41124129 sss_drop_cap (CAP_SETGID );
41134130
4131+ if (!krb5_child_has_setid_cap ) {
4132+ DEBUG (SSSDBG_CONF_SETTINGS , "'krb5_child' doesn't have CAP_SETUID and/or "
4133+ "CAP_SETGID. User ccache won't be updated.\n" );
4134+ }
4135+
41144136 kr -> realm = kr -> cli_opts -> realm ;
41154137 if (kr -> realm == NULL ) {
41164138 DEBUG (SSSDBG_MINOR_FAILURE , "Realm not available.\n" );
@@ -4337,7 +4359,7 @@ int main(int argc, const char *argv[])
43374359 * is only allowed for authenticated users. Since PKINIT is part of
43384360 * the authentication and the user is not authenticated yet, we have
43394361 * 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
4362+ * received. IDs the backend (and thus 'krb5_child' ) is running with are
43414363 * either root or the 'sssd' user. Root is allowed by default and
43424364 * the 'sssd' user is allowed with the help of the sssd-pcsc.rules
43434365 * policy-kit rule. So those IDs are a suitable choice and needs to
@@ -4346,11 +4368,13 @@ int main(int argc, const char *argv[])
43464368 * to make sure the empty ccache is created with the expected
43474369 * ownership. */
43484370 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 ;
4371+ if (krb5_child_has_setid_cap ) {
4372+ ret = switch_to_user ();
4373+ if (ret != EOK ) {
4374+ DEBUG (SSSDBG_CRIT_FAILURE , "Failed to switch to user IDs: %d\n" , ret );
4375+ ret = EFAULT ;
4376+ goto done ;
4377+ }
43544378 }
43554379 }
43564380
@@ -4370,7 +4394,9 @@ int main(int argc, const char *argv[])
43704394 case SSS_PAM_AUTHENTICATE :
43714395 /* If we are offline, we need to create an empty ccache file */
43724396 if (offline ) {
4373- ret = create_empty_ccache (kr );
4397+ if (krb5_child_has_setid_cap ) {
4398+ ret = create_empty_ccache (kr );
4399+ }
43744400 } else {
43754401 DEBUG (SSSDBG_TRACE_FUNC , "Will perform online auth\n" );
43764402 ret = tgt_req_child (kr );
@@ -4391,6 +4417,10 @@ int main(int argc, const char *argv[])
43914417 ret = KRB5_KDC_UNREACH ;
43924418 goto done ;
43934419 }
4420+ if (!krb5_child_has_setid_cap ) {
4421+ ret = KRB5_CC_NOTFOUND ;
4422+ goto done ;
4423+ }
43944424 ret = renew_tgt_child (kr );
43954425 break ;
43964426 case SSS_PAM_PREAUTH :
0 commit comments