diff options
author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2009-04-02 17:46:29 -0400 |
---|---|---|
committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2009-04-02 17:46:29 -0400 |
commit | 393a8f50cf181ae374bcaddc7eaa85dbfe73dee5 (patch) | |
tree | c839834d5d0f1a252b04850eb150fad16f1db3f0 | |
parent | b794f6ea5a49e42660702591b6e9acf3f16956fe (diff) | |
download | credmonger-393a8f50cf181ae374bcaddc7eaa85dbfe73dee5.tar.gz credmonger-393a8f50cf181ae374bcaddc7eaa85dbfe73dee5.tar.xz credmonger-393a8f50cf181ae374bcaddc7eaa85dbfe73dee5.zip |
- drop privileges to the target user while obtaining creds
-rw-r--r-- | src/credmonger.c | 82 |
1 files changed, 72 insertions, 10 deletions
diff --git a/src/credmonger.c b/src/credmonger.c index c6a37a4..3eb0517 100644 --- a/src/credmonger.c +++ b/src/credmonger.c @@ -31,9 +31,11 @@ #endif #include <sys/types.h> +#include <sys/fsuid.h> #include <dirent.h> #include <errno.h> #include <pwd.h> +#include <grp.h> #include <signal.h> #include <stdarg.h> #include <stdio.h> @@ -50,6 +52,7 @@ /* A ccache that we need to maintain. */ static struct monger_entry { + char *user; /* name of ccache owner */ uid_t uid; /* UID of ccache owner. */ gid_t gid; /* GID of ccache owner. */ char *keytab; /* Name of keytab. */ @@ -59,6 +62,8 @@ static struct monger_entry { krb5_timestamp when; /* When the creds in the ccache expire. */ } **entries, **cleanup; +/* My own user name. */ +char *startup_user; /* Time to reload. */ static int reload = 0; /* Time to exit. */ @@ -89,7 +94,6 @@ entries_read(void) struct monger_entry **list, **tmp, *entry; struct passwd *pwd; uid_t uid; - gid_t gid; FILE *fp; int n_entries; DIR *dir; @@ -168,10 +172,7 @@ entries_read(void) /* Not a number, so treat it as a user * name. */ pwd = getpwnam(uids); - if (pwd != NULL) { - uid = pwd->pw_uid; - gid = pwd->pw_gid; - } else { + if (pwd == NULL) { log_err(LOG_ERR, "unknown user " "\"%s\"\n", uids); continue; @@ -179,9 +180,7 @@ entries_read(void) } else { /* Treat it as a number. */ pwd = getpwuid(uid); - if (pwd != NULL) { - gid = pwd->pw_gid; - } else { + if (pwd == NULL) { log_err(LOG_ERR, "unknown user %lu\n", (unsigned long) uid); @@ -235,8 +234,13 @@ entries_read(void) list[n_entries] = NULL; /* Initialize this entry. */ memset(entry, 0, sizeof(*entry)); - entry->uid = uid; - entry->gid = gid; + entry->user = strdup(pwd->pw_name); + if (entry->user == NULL) { + log_err(LOG_ERR, "out of memory\n"); + break; + } + entry->uid = pwd->pw_uid; + entry->gid = pwd->pw_gid; entry->keytab = strdup(keytab); if (entry->keytab == NULL) { log_err(LOG_ERR, "out of memory\n"); @@ -299,6 +303,19 @@ entries_poll(void) } /* Walk the list of entries. */ for (i = 0; (entries != NULL) && (entries[i] != NULL); i++) { + if (setfsuid(0) != 0) { + log_err(LOG_CRIT, "error resetting fsuid\n"); + _exit(1); + } + if (setfsgid(0) != 0) { + log_err(LOG_CRIT, "error resetting fsgid\n"); + _exit(1); + } + if (initgroups(startup_user, 0) != 0) { + log_err(LOG_CRIT, "error resetting " + "supplemental group list\n"); + _exit(1); + } log_err(LOG_DEBUG, "[uid=%ld, keytab=%s, client=%s, ccache=%s]\n", (unsigned long) entries[i]->uid, @@ -307,6 +324,26 @@ entries_poll(void) entries[i]->keytab : "<default>", entries[i]->principal_name, entries[i]->fccache_pattern); + /* Drop privileges to the target user. */ + if (initgroups(entries[i]->user, + entries[i]->gid) != 0) { + log_err(LOG_CRIT, "error resetting " + "supplemental group list for \"%s\"\n", + entries[i]->user); + break; + } + if (setfsgid(entries[i]->gid) != 0) { + log_err(LOG_CRIT, + "error resetting fsgid for \"%s\"\n", + entries[i]->user); + break; + } + if (setfsuid(entries[i]->uid) != 0) { + log_err(LOG_CRIT, + "error resetting fsuid for \"%s\"\n", + entries[i]->user); + break; + } /* Open the keytab. */ keytab = NULL; if ((entries[i]->keytab == NULL) || @@ -492,6 +529,19 @@ entries_poll(void) krb5_free_unparsed_name(ctx, principal_name); krb5_free_principal(ctx, client); } + if (setfsuid(0) != 0) { + log_err(LOG_CRIT, "error resetting fsuid\n"); + _exit(1); + } + if (setfsgid(0) != 0) { + log_err(LOG_CRIT, "error resetting fsgid\n"); + _exit(1); + } + if (initgroups(startup_user, 0) != 0) { + log_err(LOG_CRIT, "error resetting " + "supplemental group list\n"); + _exit(1); + } krb5_get_init_creds_opt_free(ctx, gic_opts); krb5_free_context(ctx); } @@ -588,6 +638,7 @@ main(int argc, char **argv) char *pidfile; int c, nofork; FILE *fp; + struct passwd *pwd; nofork = 0; pidfile = NULL; @@ -619,6 +670,17 @@ main(int argc, char **argv) return 1; } + /* Figure out our name. */ + if ((pwd = getpwuid(getuid())) == NULL) { + log_err(LOG_ERR, "unknown user\n"); + return 1; + } + startup_user = strdup(pwd->pw_name); + if (startup_user == NULL) { + log_err(LOG_ERR, "out of memory\n"); + return 1; + } + /* Go background. */ if (!nofork) { if (daemon(0, 0) != 0) { |