Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5524,7 +5524,7 @@ if SSSD_USER
-$(SETCAP) cap_dac_read_search=p $(DESTDIR)$(sssdlibexecdir)/ldap_child
-chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/krb5_child
chmod 750 $(DESTDIR)$(sssdlibexecdir)/krb5_child
-$(SETCAP) cap_dac_read_search,cap_setuid,cap_setgid=p $(DESTDIR)$(sssdlibexecdir)/krb5_child
-$(SETCAP) cap_dac_read_search=p $(DESTDIR)$(sssdlibexecdir)/krb5_child
-chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/proxy_child
chmod 750 $(DESTDIR)$(sssdlibexecdir)/proxy_child
-chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/sssd_pam
Expand Down
2 changes: 1 addition & 1 deletion contrib/sssd.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ install -D -p -m 0644 %{SOURCE1} %{buildroot}%{_sysusersdir}/sssd.conf
%license COPYING
%attr(775,sssd,sssd) %dir %{pubconfpath}/krb5.include.d
%attr(0750,root,sssd) %caps(cap_dac_read_search=p) %{_libexecdir}/%{servicename}/ldap_child
%attr(0750,root,sssd) %caps(cap_dac_read_search,cap_setuid,cap_setgid=p) %{_libexecdir}/%{servicename}/krb5_child
%attr(0750,root,sssd) %caps(cap_dac_read_search=p) %{_libexecdir}/%{servicename}/krb5_child
%config(noreplace) %{_sysconfdir}/krb5.conf.d/enable_sssd_conf_dir
%dir %{_datadir}/sssd/krb5-snippets
%{_datadir}/sssd/krb5-snippets/enable_sssd_conf_dir
Expand Down
6 changes: 5 additions & 1 deletion src/providers/krb5/krb5_ccache.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@
#include "util/util.h"


/* real id == user id; set id == service id */
/* `switch_to_()` functions expect that
* real id == user id; set id == service id.
* This is prepared (set) in `privileged_krb5_setup()`
* if process has corresponding capabilities.
*/
errno_t switch_to_user(void)
{
int ret;
Expand Down
78 changes: 54 additions & 24 deletions src/providers/krb5/krb5_child.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ struct krb5_req {
struct cli_opts *cli_opts;
};

static bool krb5_child_has_setid_cap = true;
static krb5_context krb5_error_ctx;

#define KRB5_CHILD_DEBUG_INT(level, errctx, krb5_error) do { \
Expand Down Expand Up @@ -1845,6 +1846,10 @@ static errno_t k5c_attach_ccname_msg(struct krb5_req *kr)
char *msg = NULL;
int ret;

if (!krb5_child_has_setid_cap) {
return EOK;
}

if (kr->ccname == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Error obtaining ccname.\n");
return ERR_INTERNAL;
Expand Down Expand Up @@ -2523,6 +2528,12 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
goto done;
}

if (!krb5_child_has_setid_cap) {
/* no set-id capability => can't populate user ccache */
kerr = 0;
goto done;
}

/* Make sure ccache is created and written as the user */
kerr = switch_to_user();
if (kerr != EOK) {
Expand Down Expand Up @@ -4085,32 +4096,43 @@ static krb5_error_code privileged_krb5_setup(struct krb5_req *kr,
int ret;
char *mem_keytab;

/* Make use of cap_set*id first to bootstap process */
sss_set_cap_effective(CAP_SETGID, true);
if (geteuid() != 0) {
ret = setgroups(0, NULL);
/* Make use of cap_set*id (if available) first to bootstrap process */
if (sss_set_cap_effective(CAP_SETGID, true) == EOK) {
if (geteuid() != 0) {
ret = setgroups(0, NULL);
if (ret != 0) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to drop supplementary groups: %d\n", ret);
return ret;
}
} /* Otherwise keep supplementary groups to have access to DB_PATH to store FAST ccache */
ret = setresgid(kr->gid, -1, -1);
if (ret != 0) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to drop supplementary groups: %d\n", ret);
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set real GID: %d\n", ret);
return ret;
}
} /* Otherwise keep supplementary groups to have access to DB_PATH to store FAST ccache */
ret = setresgid(kr->gid, -1, -1);
if (ret != 0) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set real GID: %d\n", ret);
return ret;
} else {
krb5_child_has_setid_cap = false;
}
sss_set_cap_effective(CAP_SETUID, true);
ret = setresuid(kr->uid, -1, -1);
if (ret != 0) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set real UID: %d\n", ret);
return ret;
if (krb5_child_has_setid_cap && (sss_set_cap_effective(CAP_SETUID, true) == EOK)) {
ret = setresuid(kr->uid, -1, -1);
if (ret != 0) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set real UID: %d\n", ret);
return ret;
}
} else {
krb5_child_has_setid_cap = false;
}
sss_drop_cap(CAP_SETUID);
sss_drop_cap(CAP_SETGID);

if (!krb5_child_has_setid_cap) {
DEBUG(SSSDBG_CONF_SETTINGS, "'krb5_child' doesn't have CAP_SETUID and/or "
"CAP_SETGID. User ccache won't be updated.\n");
}

kr->realm = kr->cli_opts->realm;
if (kr->realm == NULL) {
DEBUG(SSSDBG_MINOR_FAILURE, "Realm not available.\n");
Expand Down Expand Up @@ -4337,7 +4359,7 @@ int main(int argc, const char *argv[])
* is only allowed for authenticated users. Since PKINIT is part of
* the authentication and the user is not authenticated yet, we have
* to use different privileges and can only drop it after the TGT is
* received. IDs the backend (and thus 'krb5_child) is running with are
* received. IDs the backend (and thus 'krb5_child') is running with are
* either root or the 'sssd' user. Root is allowed by default and
* the 'sssd' user is allowed with the help of the sssd-pcsc.rules
* policy-kit rule. So those IDs are a suitable choice and needs to
Expand All @@ -4346,11 +4368,13 @@ int main(int argc, const char *argv[])
* to make sure the empty ccache is created with the expected
* ownership. */
if (!IS_SC_AUTHTOK(kr->pd->authtok) || offline) {
ret = switch_to_user();
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to switch to user IDs: %d\n", ret);
ret = EFAULT;
goto done;
if (krb5_child_has_setid_cap) {
ret = switch_to_user();
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to switch to user IDs: %d\n", ret);
ret = EFAULT;
goto done;
}
}
}

Expand All @@ -4370,7 +4394,9 @@ int main(int argc, const char *argv[])
case SSS_PAM_AUTHENTICATE:
/* If we are offline, we need to create an empty ccache file */
if (offline) {
ret = create_empty_ccache(kr);
if (krb5_child_has_setid_cap) {
ret = create_empty_ccache(kr);
}
} else {
DEBUG(SSSDBG_TRACE_FUNC, "Will perform online auth\n");
ret = tgt_req_child(kr);
Expand All @@ -4391,6 +4417,10 @@ int main(int argc, const char *argv[])
ret = KRB5_KDC_UNREACH;
goto done;
}
if (!krb5_child_has_setid_cap) {
ret = KRB5_CC_NOTFOUND;
goto done;
}
ret = renew_tgt_child(kr);
break;
case SSS_PAM_PREAUTH:
Expand Down
Loading