Skip to content

Commit

Permalink
Fleet commander: store deskprofiles under user running SSSD
Browse files Browse the repository at this point in the history
Integrated feature was never oficially released, but the latest
development status was:
```
org.freedesktop.FleetCommanderClient is run as root
```
and can read profiles doesn't matter files ownership
( https://lists.fedorahosted.org/archives/list/[email protected]/message/IG3MIET5MILWJZRS3JQWMTVOPGNY6XWI/ )

Actual status is that 'FleetCommanderClient' isn't really maintained.

Storing profiles under user that runs SSSD doesn't break anything
but removes the need for CAP_SET_?ID and CAP_CHOWN (in this code).

Resolves: #4659

Reviewed-by: Justin Stephenson <[email protected]>
Reviewed-by: Pavel Březina <[email protected]>
Reviewed-by: Sumit Bose <[email protected]>
  • Loading branch information
alexey-tikhonov committed Jan 30, 2024
1 parent 1bacf49 commit c11734e
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 228 deletions.
5 changes: 0 additions & 5 deletions src/man/sssd.conf.5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3433,11 +3433,6 @@ pam_gssapi_indicators_map = sudo:pkinit, sudo-i:pkinit
Default: <quote>id_provider</quote> is used if it
is set and can perform session related tasks.
</para>
<para>
<emphasis>NOTE:</emphasis> In order to have this feature
working as expected SSSD must be running as "root" and
not as the unprivileged user.
</para>
</listitem>
</varlistentry>

Expand Down
160 changes: 5 additions & 155 deletions src/providers/ipa/ipa_deskprofile_rules_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,7 @@ ipa_deskprofile_get_filename_path(TALLOC_CTX *mem_ctx,
}

errno_t
ipa_deskprofile_rules_create_user_dir(
const char *username, /* fully-qualified */
uid_t uid,
gid_t gid)
ipa_deskprofile_rules_create_user_dir(const char *username /* fully-qualified */)
{
TALLOC_CTX *tmp_ctx;
char *shortname;
Expand All @@ -245,8 +242,7 @@ ipa_deskprofile_rules_create_user_dir(
}

old_umask = umask(0026);
ret = sss_create_dir(IPA_DESKPROFILE_RULES_USER_DIR, domain, 0751,
getuid(), getgid());
ret = sss_create_dir(IPA_DESKPROFILE_RULES_USER_DIR, domain, 0751);
umask(old_umask);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
Expand All @@ -267,7 +263,7 @@ ipa_deskprofile_rules_create_user_dir(
/* In order to read, create and traverse the directory, we need to have its
* permissions set as 'rwx------' (700). */
old_umask = umask(0077);
ret = sss_create_dir(domain_dir, shortname, 0700, uid, gid);
ret = sss_create_dir(domain_dir, shortname, 0700);
umask(old_umask);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
Expand Down Expand Up @@ -684,9 +680,7 @@ ipa_deskprofile_rules_save_rule_to_disk(
struct sysdb_attrs *rule,
struct sss_domain_info *domain,
const char *hostname,
const char *username, /* fully-qualified */
uid_t uid,
gid_t gid)
const char *username /* fully-qualified */)
{
TALLOC_CTX *tmp_ctx;
const char *rule_name;
Expand All @@ -706,18 +700,13 @@ ipa_deskprofile_rules_save_rule_to_disk(
const char *extension = "json";
uint32_t prio;
int fd = -1;
gid_t orig_gid;
uid_t orig_uid;
errno_t ret;

tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
return ENOMEM;
}

orig_gid = getegid();
orig_uid = geteuid();

ret = sysdb_attrs_get_string(rule, IPA_CN, &rule_name);
if (ret != EOK) {
DEBUG(SSSDBG_TRACE_FUNC,
Expand Down Expand Up @@ -880,26 +869,6 @@ ipa_deskprofile_rules_save_rule_to_disk(
goto done;
}

ret = setegid(gid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Unable to set effective group id (%"PRIu32") of the domain's "
"process [%d]: %s\n",
gid, ret, sss_strerror(ret));
goto done;
}

ret = seteuid(uid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Unable to set effective user id (%"PRIu32") of the domain's "
"process [%d]: %s\n",
uid, ret, sss_strerror(ret));
goto done;
}

fd = open(filename_path, O_WRONLY | O_CREAT | O_TRUNC, 0400);
if (fd == -1) {
ret = errno;
Expand All @@ -920,94 +889,21 @@ ipa_deskprofile_rules_save_rule_to_disk(
goto done;
}

ret = seteuid(orig_uid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Failed to set the effect user id (%"PRIu32") of the domain's "
"process [%d]: %s\n",
orig_uid, ret, sss_strerror(ret));
goto done;
}

ret = setegid(orig_gid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Failed to set the effect group id (%"PRIu32") of the domain's "
"process [%d]: %s\n",
orig_gid, ret, sss_strerror(ret));
goto done;
}

ret = EOK;

done:
if (fd != -1) {
close(fd);
}
if (geteuid() != orig_uid) {
ret = seteuid(orig_uid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Unable to set effective user id (%"PRIu32") of the "
"domain's process [%d]: %s\n",
orig_uid, ret, sss_strerror(ret));
DEBUG(SSSDBG_CRIT_FAILURE,
"Sending SIGUSR2 to the process: %d\n", getpid());
kill(getpid(), SIGUSR2);
}
}
if (getegid() != orig_gid) {
ret = setegid(orig_gid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Unable to set effective group id (%"PRIu32") of the "
"domain's process. Let's have the process restarted!\n",
orig_gid);
DEBUG(SSSDBG_CRIT_FAILURE,
"Sending SIGUSR2 to the process: %d\n", getpid());
kill(getpid(), SIGUSR2);
}
}
talloc_free(tmp_ctx);
return ret;
}

errno_t
ipa_deskprofile_rules_remove_user_dir(const char *user_dir,
uid_t uid,
gid_t gid)
ipa_deskprofile_rules_remove_user_dir(const char *user_dir)
{
gid_t orig_gid;
uid_t orig_uid;
errno_t ret;

orig_gid = getegid();
orig_uid = geteuid();

ret = setegid(gid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Unable to set effective group id (%"PRIu32") of the domain's "
"process [%d]: %s\n",
gid, ret, sss_strerror(ret));
goto done;
}

ret = seteuid(uid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Unable to set effective user id (%"PRIu32") of the domain's "
"process [%d]: %s\n",
uid, ret, sss_strerror(ret));
goto done;
}

ret = sss_remove_subtree(user_dir);
if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_CRIT_FAILURE,
Expand All @@ -1016,26 +912,6 @@ ipa_deskprofile_rules_remove_user_dir(const char *user_dir,
goto done;
}

ret = seteuid(orig_uid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Failed to set the effect user id (%"PRIu32") of the domain's "
"process [%d]: %s\n",
orig_uid, ret, sss_strerror(ret));
goto done;
}

ret = setegid(orig_gid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Failed to set the effect group id (%"PRIu32") of the domain's "
"process [%d]: %s\n",
orig_gid, ret, sss_strerror(ret));
goto done;
}

ret = sss_remove_tree(user_dir);
if ((ret != EOK) && (ret != ENOENT)) {
DEBUG(SSSDBG_CRIT_FAILURE,
Expand All @@ -1047,32 +923,6 @@ ipa_deskprofile_rules_remove_user_dir(const char *user_dir,
ret = EOK;

done:
if (geteuid() != orig_uid) {
ret = seteuid(orig_uid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"unable to set effective user id (%"PRIu32") of the "
"domain's process [%d]: %s\n",
orig_uid, ret, sss_strerror(ret));
DEBUG(SSSDBG_CRIT_FAILURE,
"Sending SIGUSR2 to the process: %d\n", getpid());
kill(getpid(), SIGUSR2);
}
}
if (getegid() != orig_gid) {
ret = setegid(orig_gid);
if (ret == -1) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
"Unable to set effective user id (%"PRIu32") of the "
"domain's process [%d]: %s\n",
orig_uid, ret, sss_strerror(ret));
DEBUG(SSSDBG_CRIT_FAILURE,
"Sending SIGUSR2 to the process: %d\n", getpid());
kill(getpid(), SIGUSR2);
}
}
return ret;
}

Expand Down
13 changes: 3 additions & 10 deletions src/providers/ipa/ipa_deskprofile_rules_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,17 @@ ipa_deskprofile_get_filename_path(TALLOC_CTX *mem_ctx,
char **_filename_path);

errno_t
ipa_deskprofile_rules_create_user_dir(
const char *username, /* fully-qualified */
uid_t uid,
gid_t gid);
ipa_deskprofile_rules_create_user_dir(const char *username /* fully-qualified */);
errno_t
ipa_deskprofile_rules_save_rule_to_disk(
TALLOC_CTX *mem_ctx,
uint16_t priority,
struct sysdb_attrs *rule,
struct sss_domain_info *domain,
const char *hostname,
const char *username, /* fully-qualified */
uid_t uid,
gid_t gid);
const char *username /* fully-qualified */);
errno_t
ipa_deskprofile_rules_remove_user_dir(const char *user_dir,
uid_t uid,
gid_t gid);
ipa_deskprofile_rules_remove_user_dir(const char *user_dir);

errno_t
deskprofile_get_cached_priority(struct sss_domain_info *domain,
Expand Down
32 changes: 10 additions & 22 deletions src/providers/ipa/ipa_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ struct ipa_pam_session_handler_state {
char *domain;
char *user_dir;
uid_t uid;
gid_t gid;
};

static errno_t
Expand All @@ -460,8 +459,7 @@ ipa_pam_session_handler_get_deskprofile_user_info(
char **_shortname,
char **_domain,
char **_user_dir,
uid_t *uid,
gid_t *gid);
uid_t *uid);
static void ipa_pam_session_handler_done(struct tevent_req *subreq);
static errno_t
ipa_pam_session_handler_save_deskprofile_rules(
Expand All @@ -470,8 +468,7 @@ ipa_pam_session_handler_save_deskprofile_rules(
const char *username, /* fully-qualified */
const char *user_dir,
const char *hostname,
uid_t uid,
gid_t gid);
uid_t uid);
static errno_t
ipa_pam_session_handler_notify_deskprofile_client(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
Expand Down Expand Up @@ -515,8 +512,7 @@ ipa_pam_session_handler_send(TALLOC_CTX *mem_ctx,
&state->shortname,
&state->domain,
&state->user_dir,
&state->uid,
&state->gid);
&state->uid);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"ipa_deskprofile_get_user_info() failed [%d]: %s\n",
Expand All @@ -528,9 +524,7 @@ ipa_pam_session_handler_send(TALLOC_CTX *mem_ctx,
/* As no proper merging mechanism has been implemented yet ...
* let's just remove the user directory stored in the disk as it's
* going to be created again in case there's any rule fetched. */
ret = ipa_deskprofile_rules_remove_user_dir(state->user_dir,
state->uid,
state->gid);
ret = ipa_deskprofile_rules_remove_user_dir(state->user_dir);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"ipa_deskprofile_rules_remove_user_dir() failed.\n");
Expand Down Expand Up @@ -593,8 +587,7 @@ ipa_pam_session_handler_done(struct tevent_req *subreq)
state->pd->user,
state->user_dir,
hostname,
state->uid,
state->gid);
state->uid);

if (ret == EOK || ret == ENOENT) {
state->pd->pam_status = PAM_SUCCESS;
Expand Down Expand Up @@ -630,8 +623,7 @@ ipa_pam_session_handler_get_deskprofile_user_info(TALLOC_CTX *mem_ctx,
char **_shortname,
char **_domain,
char **_user_dir,
uid_t *_uid,
gid_t *_gid)
uid_t *_uid)
{
TALLOC_CTX *tmp_ctx;
struct ldb_result *res = NULL;
Expand Down Expand Up @@ -681,7 +673,7 @@ ipa_pam_session_handler_get_deskprofile_user_info(TALLOC_CTX *mem_ctx,
uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0);
gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0);
if (uid == 0 || gid == 0) {
/* As IPA doesn't handle root users ou groups, we know for sure that's
/* As IPA doesn't handle root users or groups, we know for sure that's
* something wrong in case we get uid = 0 or gid = 0.
*/
ret = EINVAL;
Expand All @@ -694,7 +686,6 @@ ipa_pam_session_handler_get_deskprofile_user_info(TALLOC_CTX *mem_ctx,
*_domain = talloc_steal(mem_ctx, domain_name);
*_user_dir = talloc_steal(mem_ctx, user_dir);
*_uid = uid;
*_gid = gid;

done:
talloc_free(tmp_ctx);
Expand All @@ -708,8 +699,7 @@ ipa_pam_session_handler_save_deskprofile_rules(
const char *username, /* fully-qualified */
const char *user_dir,
const char *hostname,
uid_t uid,
gid_t gid)
uid_t uid)
{
TALLOC_CTX *tmp_ctx;
const char **attrs_get_cached_rules;
Expand Down Expand Up @@ -764,7 +754,7 @@ ipa_pam_session_handler_save_deskprofile_rules(
}

/* Create the user directory where the rules are going to be stored */
ret = ipa_deskprofile_rules_create_user_dir(username, uid, gid);
ret = ipa_deskprofile_rules_create_user_dir(username);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Cannot create the user directory [%d]: %s\n",
Expand All @@ -779,9 +769,7 @@ ipa_pam_session_handler_save_deskprofile_rules(
rules[i],
domain,
hostname,
username,
uid,
gid);
username);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Failed to save a Desktop Profile Rule to disk [%d]: %s\n",
Expand Down
Loading

0 comments on commit c11734e

Please sign in to comment.