f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek/*
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek SSSD
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek IPA back end -- set SELinux context in a child module
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek Authors:
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek Copyright (C) 2014 Red Hat
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek This program is free software; you can redistribute it and/or modify
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek it under the terms of the GNU General Public License as published by
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek the Free Software Foundation; either version 3 of the License, or
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek (at your option) any later version.
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek This program is distributed in the hope that it will be useful,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek GNU General Public License for more details.
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek You should have received a copy of the GNU General Public License
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek*/
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek#include <sys/types.h>
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek#include <unistd.h>
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek#include <sys/stat.h>
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek#include <popt.h>
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek#include "util/util.h"
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek#include "util/child_common.h"
cc2d77d5218c188119fa954c856e858cbde76947Pavel Březina#include "providers/backend.h"
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozekstruct input_buffer {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek const char *seuser;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek const char *mls_range;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek const char *username;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek};
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozekstatic errno_t unpack_buffer(uint8_t *buf,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek size_t size,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek struct input_buffer *ibuf)
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek{
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek size_t p = 0;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek uint32_t len;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* seuser */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "seuser length: %d\n", len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (len == 0) {
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek ibuf->seuser = "";
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek "Empty SELinux user, will delete the mapping\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek } else {
9f0bffebd070115ab47a92eadc6890a721c7b78dMichal Židek if (len > size - p) return EINVAL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ibuf->seuser = talloc_strndup(ibuf, (char *)(buf + p), len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (ibuf->seuser == NULL) return ENOMEM;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "seuser: %s\n", ibuf->seuser);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek p += len;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* MLS range */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "mls_range length: %d\n", len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (len == 0) {
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek if (strcmp(ibuf->seuser, "") != 0) {
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "No MLS mapping!\n");
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek return EINVAL;
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek } else {
9f0bffebd070115ab47a92eadc6890a721c7b78dMichal Židek if (len > size - p) return EINVAL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ibuf->mls_range = talloc_strndup(ibuf, (char *)(buf + p), len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (ibuf->mls_range == NULL) return ENOMEM;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "mls_range: %s\n", ibuf->mls_range);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek p += len;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* username */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "username length: %d\n", len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (len == 0) {
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "No username set!\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return EINVAL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek } else {
9f0bffebd070115ab47a92eadc6890a721c7b78dMichal Židek if (len > size - p) return EINVAL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ibuf->username = talloc_strndup(ibuf, (char *)(buf + p), len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (ibuf->username == NULL) return ENOMEM;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "username: %s\n", ibuf->username);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek p += len;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return EOK;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek}
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozekstatic errno_t pack_buffer(struct response *r, int result)
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek{
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek size_t p = 0;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* A buffer with the following structure must be created:
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek * uint32_t status of the request (required)
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek r->size = sizeof(uint32_t);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek r->buf = talloc_array(r, uint8_t, r->size);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if(r->buf == NULL) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return ENOMEM;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "result [%d]\n", result);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* result */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek SAFEALIGN_SET_UINT32(&r->buf[p], result, &p);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return EOK;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek}
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozekstatic errno_t prepare_response(TALLOC_CTX *mem_ctx,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek int result,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek struct response **rsp)
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek{
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek int ret;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek struct response *r = NULL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek r = talloc_zero(mem_ctx, struct response);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (r == NULL) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return ENOMEM;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek r->buf = NULL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek r->size = 0;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ret = pack_buffer(r, result);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (ret != EOK) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "pack_buffer failed\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return ret;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek *rsp = r;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_ALL, "r->size: %zu\n", r->size);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return EOK;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek}
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozekstatic int sc_set_seuser(const char *login_name, const char *seuser_name,
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek const char *mls)
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek{
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek int ret;
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek mode_t old_mask;
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek /* This is a workaround for
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek * https://bugzilla.redhat.com/show_bug.cgi?id=1186422 to make sure
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek * the directories are created with the expected permissions
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek */
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek old_mask = umask(0);
01f78f755fde63997ccfded71fb8395569b11430Jakub Hrozek if (strcmp(seuser_name, "") == 0) {
01f78f755fde63997ccfded71fb8395569b11430Jakub Hrozek /* An empty SELinux user should cause SSSD to use the system
01f78f755fde63997ccfded71fb8395569b11430Jakub Hrozek * default. We need to remove the SELinux user from the DB
01f78f755fde63997ccfded71fb8395569b11430Jakub Hrozek * in that case
01f78f755fde63997ccfded71fb8395569b11430Jakub Hrozek */
6b9c38df5712b951e31800efea2df0802e333e08Michal Židek ret = sss_del_seuser(login_name);
01f78f755fde63997ccfded71fb8395569b11430Jakub Hrozek } else {
6b9c38df5712b951e31800efea2df0802e333e08Michal Židek ret = sss_set_seuser(login_name, seuser_name, mls);
01f78f755fde63997ccfded71fb8395569b11430Jakub Hrozek }
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek umask(old_mask);
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek return ret;
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek}
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozekstatic bool seuser_needs_update(struct input_buffer *ibuf)
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek{
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek bool needs_update = true;
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek char *db_seuser = NULL;
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek char *db_mls_range = NULL;
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek errno_t ret;
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek
450b472a68abf442479755c7916c757907b35ea5Michal Židek ret = sss_get_seuser(ibuf->username, &db_seuser, &db_mls_range);
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
cfe87ca0c4fded9cbf907697d08fa0e6c8f8ebceJustin Stephenson "getseuserbyname: ret: %d seuser: %s mls: %s\n",
cfe87ca0c4fded9cbf907697d08fa0e6c8f8ebceJustin Stephenson ret, db_seuser ? db_seuser : "unknown",
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek db_mls_range ? db_mls_range : "unknown");
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek if (ret == EOK && db_seuser && db_mls_range &&
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek strcmp(db_seuser, ibuf->seuser) == 0 &&
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek strcmp(db_mls_range, ibuf->mls_range) == 0) {
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek needs_update = false;
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek }
78a08d30b5fbf6e1e3b589e0cf67022e0c1faa33Michal Židek /* OR */
78a08d30b5fbf6e1e3b589e0cf67022e0c1faa33Michal Židek if (ret == ERR_SELINUX_NOT_MANAGED) {
78a08d30b5fbf6e1e3b589e0cf67022e0c1faa33Michal Židek needs_update = false;
78a08d30b5fbf6e1e3b589e0cf67022e0c1faa33Michal Židek }
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek
cfe87ca0c4fded9cbf907697d08fa0e6c8f8ebceJustin Stephenson free(db_seuser);
cfe87ca0c4fded9cbf907697d08fa0e6c8f8ebceJustin Stephenson free(db_mls_range);
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek return needs_update;
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek}
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozekint main(int argc, const char *argv[])
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek{
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek int opt;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek poptContext pc;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek int debug_fd = -1;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek errno_t ret;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek TALLOC_CTX *main_ctx = NULL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek uint8_t *buf = NULL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ssize_t len = 0;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek struct input_buffer *ibuf = NULL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek struct response *resp = NULL;
8e44ddfccebe61728d8a2c1dafce36dfa944bc90Jakub Hrozek ssize_t written;
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek bool needs_update;
a24954cc19285b197fb287bfa7aa01949c92b17dLukas Slebodnik const char *opt_logger = NULL;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek struct poptOption long_options[] = {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek POPT_AUTOHELP
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek _("Debug level"), NULL},
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek _("Add debug timestamps"), NULL},
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek _("Show timestamps with microseconds"), NULL},
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek _("An open file descriptor for the debug logs"), NULL},
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek &debug_to_stderr, 0,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek _("Send the debug output to stderr directly."), NULL },
cb75b275d15beedd1fdecc1f8ced657fba282218Lukas Slebodnik SSSD_LOGGER_OPTS
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek POPT_TABLEEND
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek };
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* Set debug level to invalid value so we can decide if -d 0 was used. */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek debug_level = SSSDBG_INVALID;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek pc = poptGetContext(argv[0], argc, argv, long_options, 0);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek while((opt = poptGetNextOpt(pc)) != -1) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek switch(opt) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek default:
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek fprintf(stderr, "\nInvalid option %s: %s\n\n",
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek poptBadOption(pc, 0), poptStrerror(opt));
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek poptPrintUsage(pc, stderr, 0);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek _exit(-1);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek poptFreeContext(pc);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG_INIT(debug_level);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek debug_prg_name = talloc_asprintf(NULL, "[sssd[selinux_child[%d]]]", getpid());
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (debug_prg_name == NULL) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek goto fail;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (debug_fd != -1) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ret = set_debug_file_from_fd(debug_fd);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (ret != EOK) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
a24954cc19285b197fb287bfa7aa01949c92b17dLukas Slebodnik opt_logger = sss_logger_str[FILES_LOGGER];
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
cb75b275d15beedd1fdecc1f8ced657fba282218Lukas Slebodnik sss_set_logger(opt_logger);
cb75b275d15beedd1fdecc1f8ced657fba282218Lukas Slebodnik
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "selinux_child started.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek "Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n",
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek geteuid(), getegid());
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek /* libsemanage calls access(2) which works with real IDs, not effective.
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek * We need to switch also the real ID to 0.
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek */
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek if (getuid() != 0) {
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek ret = setuid(0);
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek if (ret == -1) {
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek ret = errno;
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek "setuid failed: %d, selinux_child might not work!\n", ret);
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek }
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek }
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek if (getgid() != 0) {
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek ret = setgid(0);
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek if (ret == -1) {
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek ret = errno;
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek "setgid failed: %d, selinux_child might not work!\n", ret);
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek }
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek }
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek "Running with real IDs [%"SPRIuid"][%"SPRIgid"].\n",
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek getuid(), getgid());
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek main_ctx = talloc_new(NULL);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (main_ctx == NULL) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek talloc_free(discard_const(debug_prg_name));
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek goto fail;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek talloc_steal(main_ctx, debug_prg_name);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek buf = talloc_size(main_ctx, sizeof(uint8_t)*IN_BUF_SIZE);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (buf == NULL) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek goto fail;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ibuf = talloc_zero(main_ctx, struct input_buffer);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (ibuf == NULL) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek goto fail;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "context initialized\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek errno = 0;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (len == -1) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ret = errno;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret));
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek goto fail;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek close(STDIN_FILENO);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ret = unpack_buffer(buf, len, ibuf);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (ret != EOK) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek "unpack_buffer failed.[%d][%s].\n", ret, strerror(ret));
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek goto fail;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "performing selinux operations\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek needs_update = seuser_needs_update(ibuf);
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek if (needs_update == true) {
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek ret = sc_set_seuser(ibuf->username, ibuf->seuser, ibuf->mls_range);
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek if (ret != EOK) {
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set SELinux login context.\n");
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek goto fail;
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek }
013c01bd491b535e1705dbb3dbd8424cffc66b7aMichal Zidek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ret = prepare_response(main_ctx, ret, &resp);
013c01bd491b535e1705dbb3dbd8424cffc66b7aMichal Zidek if (ret != EOK) {
013c01bd491b535e1705dbb3dbd8424cffc66b7aMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Failed to prepare response buffer.\n");
013c01bd491b535e1705dbb3dbd8424cffc66b7aMichal Zidek goto fail;
013c01bd491b535e1705dbb3dbd8424cffc66b7aMichal Zidek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek errno = 0;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek written = sss_atomic_write_s(STDOUT_FILENO, resp->buf, resp->size);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (written == -1) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ret = errno;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek strerror(ret));
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek goto fail;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek if (written != resp->size) {
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Expected to write %zu bytes, wrote %zu\n",
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek resp->size, written);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek goto fail;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek }
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "selinux_child completed successfully\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek close(STDOUT_FILENO);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek talloc_free(main_ctx);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return EXIT_SUCCESS;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozekfail:
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "selinux_child failed!\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek close(STDOUT_FILENO);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek talloc_free(main_ctx);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek return EXIT_FAILURE;
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek}