summaryrefslogtreecommitdiffstats
path: root/src/providers/krb5
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-07-26 12:46:26 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-10 13:55:54 +0200
commit9df7cddb68c61ef4e0397c196604999c68f4be0d (patch)
tree0ef6135e302370a8a604fc8a1120d5459a96b27e /src/providers/krb5
parent5ecc36322d9ccc9a9266263fcea8598ca89f4426 (diff)
downloadsssd-9df7cddb68c61ef4e0397c196604999c68f4be0d.tar.gz
sssd-9df7cddb68c61ef4e0397c196604999c68f4be0d.tar.xz
sssd-9df7cddb68c61ef4e0397c196604999c68f4be0d.zip
UTIL: Move become_user outside krb5 tree
In order for several other SSSD processes to run as a non-root user, we need to move the functions to become another user to a shared space in our source tree. Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Diffstat (limited to 'src/providers/krb5')
-rw-r--r--src/providers/krb5/krb5_become_user.c199
-rw-r--r--src/providers/krb5/krb5_utils.h8
2 files changed, 0 insertions, 207 deletions
diff --git a/src/providers/krb5/krb5_become_user.c b/src/providers/krb5/krb5_become_user.c
deleted file mode 100644
index 6ddb35a56..000000000
--- a/src/providers/krb5/krb5_become_user.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- SSSD
-
- Kerberos 5 Backend Module -- Utilities
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "util/util.h"
-#include "providers/krb5/krb5_utils.h"
-#include <grp.h>
-
-errno_t become_user(uid_t uid, gid_t gid)
-{
- uid_t cuid;
- int ret;
-
- DEBUG(SSSDBG_FUNC_DATA,
- "Trying to become user [%"SPRIuid"][%"SPRIgid"].\n", uid, gid);
-
- /* skip call if we already are the requested user */
- cuid = geteuid();
- if (uid == cuid) {
- DEBUG(SSSDBG_FUNC_DATA, "Already user [%"SPRIuid"].\n", uid);
- return EOK;
- }
-
- /* drop supplmentary groups first */
- ret = setgroups(0, NULL);
- if (ret == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE,
- "setgroups failed [%d][%s].\n", ret, strerror(ret));
- return ret;
- }
-
- /* change gid so that root cannot be regained (changes saved gid too) */
- ret = setresgid(gid, gid, gid);
- if (ret == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE,
- "setresgid failed [%d][%s].\n", ret, strerror(ret));
- return ret;
- }
-
- /* change uid so that root cannot be regained (changes saved uid too) */
- /* this call also takes care of dropping CAP_SETUID, so this is a PNR */
- ret = setresuid(uid, uid, uid);
- if (ret == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE,
- "setresuid failed [%d][%s].\n", ret, strerror(ret));
- return ret;
- }
-
- return EOK;
-}
-
-struct sss_creds {
- uid_t uid;
- gid_t gid;
- int num_gids;
- gid_t gids[];
-};
-
-errno_t restore_creds(struct sss_creds *saved_creds);
-
-/* This is a reversible version of become_user, and returns the saved
- * credentials so that creds can be switched back calling restore_creds */
-errno_t switch_creds(TALLOC_CTX *mem_ctx,
- uid_t uid, gid_t gid,
- int num_gids, gid_t *gids,
- struct sss_creds **saved_creds)
-{
- struct sss_creds *ssc = NULL;
- int size;
- int ret;
-
- DEBUG(SSSDBG_FUNC_DATA, "Switch user to [%d][%d].\n", uid, gid);
-
- if (saved_creds) {
- /* save current user credentials */
- size = getgroups(0, NULL);
- if (size == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE, "Getgroups failed! (%d, %s)\n",
- ret, strerror(ret));
- goto done;
- }
-
- ssc = talloc_size(mem_ctx,
- (sizeof(struct sss_creds) + size * sizeof(gid_t)));
- if (!ssc) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Allocation failed!\n");
- ret = ENOMEM;
- goto done;
- }
- ssc->num_gids = size;
-
- size = getgroups(ssc->num_gids, ssc->gids);
- if (size == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE, "Getgroups failed! (%d, %s)\n",
- ret, strerror(ret));
- /* free ssc immediately otherwise the code will try to restore
- * wrong creds */
- talloc_zfree(ssc);
- goto done;
- }
-
- /* we care only about effective ids */
- ssc->uid = geteuid();
- ssc->gid = getegid();
- }
-
- /* if we are regaining root set euid first so that we have CAP_SETUID back,
- * ane the other calls work too, otherwise call it last so that we can
- * change groups before we loose CAP_SETUID */
- if (uid == 0) {
- ret = setresuid(0, 0, 0);
- if (ret == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE,
- "setresuid failed [%d][%s].\n", ret, strerror(ret));
- goto done;
- }
- }
-
- /* TODO: use prctl to get/set capabilities too ? */
-
- /* try to setgroups first should always work if CAP_SETUID is set,
- * otherwise it will always fail, failure is not critical though as
- * generally we only really care about uid and at mot primary gid */
- ret = setgroups(num_gids, gids);
- if (ret == -1) {
- ret = errno;
- DEBUG(SSSDBG_TRACE_FUNC,
- "setgroups failed [%d][%s].\n", ret, strerror(ret));
- }
-
- /* change gid now, (leaves saved gid to current, so we can restore) */
- ret = setresgid(-1, gid, -1);
- if (ret == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE,
- "setresgid failed [%d][%s].\n", ret, strerror(ret));
- goto done;
- }
-
- if (uid != 0) {
- /* change uid, (leaves saved uid to current, so we can restore) */
- ret = setresuid(-1, uid, -1);
- if (ret == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE,
- "setresuid failed [%d][%s].\n", ret, strerror(ret));
- goto done;
- }
- }
-
- ret = 0;
-
-done:
- if (ret) {
- if (ssc) {
- /* attempt to restore creds first */
- restore_creds(ssc);
- talloc_free(ssc);
- }
- } else if (saved_creds) {
- *saved_creds = ssc;
- }
- return ret;
-}
-
-errno_t restore_creds(struct sss_creds *saved_creds)
-{
- return switch_creds(saved_creds,
- saved_creds->uid,
- saved_creds->gid,
- saved_creds->num_gids,
- saved_creds->gids, NULL);
-}
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
index 4b1ebb0bb..f54a07f79 100644
--- a/src/providers/krb5/krb5_utils.h
+++ b/src/providers/krb5/krb5_utils.h
@@ -49,14 +49,6 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
const char *template, bool file_mode,
bool case_sensitive);
-errno_t become_user(uid_t uid, gid_t gid);
-struct sss_creds;
-errno_t switch_creds(TALLOC_CTX *mem_ctx,
- uid_t uid, gid_t gid,
- int num_gids, gid_t *gids,
- struct sss_creds **saved_creds);
-errno_t restore_creds(struct sss_creds *saved_creds);
-
errno_t sss_krb5_precreate_ccache(const char *ccname, pcre *illegal_re,
uid_t uid, gid_t gid);
errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid);