summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2009-04-02 17:46:29 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2009-04-02 17:46:29 -0400
commit393a8f50cf181ae374bcaddc7eaa85dbfe73dee5 (patch)
treec839834d5d0f1a252b04850eb150fad16f1db3f0
parentb794f6ea5a49e42660702591b6e9acf3f16956fe (diff)
downloadcredmonger-393a8f50cf181ae374bcaddc7eaa85dbfe73dee5.tar.gz
credmonger-393a8f50cf181ae374bcaddc7eaa85dbfe73dee5.tar.xz
credmonger-393a8f50cf181ae374bcaddc7eaa85dbfe73dee5.zip
- drop privileges to the target user while obtaining creds
-rw-r--r--src/credmonger.c82
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) {