f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek IPA back end -- set SELinux context in a child module
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek Jakub Hrozek <jhrozek@redhat.com>
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek Copyright (C) 2014 Red Hat
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 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 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 /* seuser */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "seuser length: %d\n", len);
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek "Empty SELinux user, will delete the mapping\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ibuf->seuser = talloc_strndup(ibuf, (char *)(buf + p), len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "seuser: %s\n", ibuf->seuser);
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);
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "No MLS mapping!\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ibuf->mls_range = talloc_strndup(ibuf, (char *)(buf + p), len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "mls_range: %s\n", ibuf->mls_range);
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);
3e6dac8e14f8a3da6d359ee013453dbd8a38dd99Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "No username set!\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ibuf->username = talloc_strndup(ibuf, (char *)(buf + p), len);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "username: %s\n", ibuf->username);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozekstatic errno_t pack_buffer(struct response *r, int result)
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* A buffer with the following structure must be created:
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek * uint32_t status of the request (required)
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "result [%d]\n", result);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* result */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozekstatic errno_t prepare_response(TALLOC_CTX *mem_ctx,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "pack_buffer failed\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_ALL, "r->size: %zu\n", r->size);
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozekstatic int sc_set_seuser(const char *login_name, const char *seuser_name,
8f78b6442f3176ee43aa06704a3adb9f4ac625d6Jakub Hrozek const char *mls)
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
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
6b9c38df5712b951e31800efea2df0802e333e08Michal Židek ret = sss_set_seuser(login_name, seuser_name, mls);
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozekstatic bool seuser_needs_update(struct input_buffer *ibuf)
450b472a68abf442479755c7916c757907b35ea5Michal Židek ret = sss_get_seuser(ibuf->username, &db_seuser, &db_mls_range);
cfe87ca0c4fded9cbf907697d08fa0e6c8f8ebceJustin Stephenson "getseuserbyname: ret: %d seuser: %s mls: %s\n",
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 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 _("Send the debug output to stderr directly."), NULL },
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek /* Set debug level to invalid value so we can decide if -d 0 was used. */
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek pc = poptGetContext(argv[0], argc, argv, long_options, 0);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek debug_prg_name = talloc_asprintf(NULL, "[sssd[selinux_child[%d]]]", getpid());
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "selinux_child started.\n");
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek "Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n",
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 if (getuid() != 0) {
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek "setuid failed: %d, selinux_child might not work!\n", ret);
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek if (getgid() != 0) {
b0f46a3019e0ff4f375ef07682ceb9418751707fJakub Hrozek "setgid failed: %d, selinux_child might not work!\n", ret);
486f0d5227a9b81815aaaf7d9a2c39aafcbfdf6aJakub Hrozek "Running with real IDs [%"SPRIuid"][%"SPRIgid"].\n",
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek buf = talloc_size(main_ctx, sizeof(uint8_t)*IN_BUF_SIZE);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek ibuf = talloc_zero(main_ctx, struct input_buffer);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "context initialized\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret));
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek "unpack_buffer failed.[%d][%s].\n", ret, strerror(ret));
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "performing selinux operations\n");
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek if (needs_update == true) {
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek ret = sc_set_seuser(ibuf->username, ibuf->seuser, ibuf->mls_range);
1e0fa55fb377db788e065de917ba8e149eb56161Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set SELinux login context.\n");
013c01bd491b535e1705dbb3dbd8424cffc66b7aMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Failed to prepare response buffer.\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek written = sss_atomic_write_s(STDOUT_FILENO, resp->buf, resp->size);
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret,
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Expected to write %zu bytes, wrote %zu\n",
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "selinux_child completed successfully\n");
f3a25949de81f80c136bb073e4a8f504b080c20cJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "selinux_child failed!\n");