X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Fgss%2Flgss_keyring.c;h=bf936de51f89e9b8b0940edba56deca9909abcd2;hb=2ffbcc9f9ad930fee2df53238b3244b7c3e6bb91;hp=f4d74358a9fbf2988d8f444b924ccc3ca501271b;hpb=72057a3af19ee02d9a686bd7e7d074917e381310;p=fs%2Flustre-release.git diff --git a/lustre/utils/gss/lgss_keyring.c b/lustre/utils/gss/lgss_keyring.c index f4d7435..bf936de 100644 --- a/lustre/utils/gss/lgss_keyring.c +++ b/lustre/utils/gss/lgss_keyring.c @@ -36,6 +36,9 @@ * Author: Eric Mei */ +#include +#include +#include #include #include #include @@ -95,21 +98,22 @@ struct lgss_init_res { }; struct keyring_upcall_param { - uint32_t kup_ver; - uint32_t kup_secid; - uint32_t kup_uid; - uint32_t kup_fsuid; - uint32_t kup_gid; - uint32_t kup_fsgid; - uint32_t kup_svc; - uint64_t kup_nid; - uint64_t kup_selfnid; + uint32_t kup_ver; + uint32_t kup_secid; + uint32_t kup_uid; + uint32_t kup_fsuid; + uint32_t kup_gid; + uint32_t kup_fsgid; + uint32_t kup_svc; + uint64_t kup_nid; + uint64_t kup_selfnid; char kup_svc_type; - char kup_tgt[64]; - char kup_mech[16]; - unsigned int kup_is_root:1, + char kup_tgt[64]; + char kup_mech[16]; + unsigned int kup_is_root:1, kup_is_mdt:1, kup_is_ost:1; + uint32_t kup_pid; }; /**************************************** @@ -719,11 +723,12 @@ static int lgssc_kr_negotiate(key_serial_t keyid, struct lgss_cred *cred, * [7]: target_nid (uint64) * [8]: target_uuid (string) * [9]: self_nid (uint64) + * [10]: pid (uint) */ static int parse_callout_info(const char *coinfo, struct keyring_upcall_param *uparam) { - const int nargs = 10; + const int nargs = 11; char buf[1024]; char *string = buf; int length, i; @@ -750,9 +755,9 @@ static int parse_callout_info(const char *coinfo, } data[i] = string; - logmsg(LL_TRACE, "components: %s,%s,%s,%s,%s,%c,%s,%s,%s,%s\n", + logmsg(LL_TRACE, "components: %s,%s,%s,%s,%s,%c,%s,%s,%s,%s,%s\n", data[0], data[1], data[2], data[3], data[4], data[5][0], - data[6], data[7], data[8], data[9]); + data[6], data[7], data[8], data[9], data[10]); uparam->kup_secid = strtol(data[0], NULL, 0); strlcpy(uparam->kup_mech, data[1], sizeof(uparam->kup_mech)); @@ -769,15 +774,16 @@ static int parse_callout_info(const char *coinfo, uparam->kup_nid = strtoll(data[7], NULL, 0); strlcpy(uparam->kup_tgt, data[8], sizeof(uparam->kup_tgt)); uparam->kup_selfnid = strtoll(data[9], NULL, 0); + uparam->kup_pid = strtol(data[10], NULL, 0); logmsg(LL_DEBUG, "parse call out info: secid %d, mech %s, ugid %u:%u, " "is_root %d, is_mdt %d, is_ost %d, svc type %c, svc %d, " - "nid 0x%"PRIx64", tgt %s, self nid 0x%"PRIx64"\n", + "nid 0x%"PRIx64", tgt %s, self nid 0x%"PRIx64", pid %d\n", uparam->kup_secid, uparam->kup_mech, uparam->kup_uid, uparam->kup_gid, uparam->kup_is_root, uparam->kup_is_mdt, uparam->kup_is_ost, uparam->kup_svc_type, uparam->kup_svc, uparam->kup_nid, - uparam->kup_tgt, uparam->kup_selfnid); + uparam->kup_tgt, uparam->kup_selfnid, uparam->kup_pid); return 0; } @@ -808,6 +814,21 @@ out: fclose(file); } +#ifdef HAVE_SETNS +static int associate_with_ns(char *path) +{ + int fd, rc = -1; + + fd = open(path, O_RDONLY); + if (fd != -1) { + rc = setns(fd, 0); + close(fd); + } + + return rc; +} +#endif + /**************************************** * main process * ****************************************/ @@ -821,6 +842,10 @@ int main(int argc, char *argv[]) pid_t child; struct lgss_mech_type *mech; struct lgss_cred *cred; +#ifdef HAVE_SETNS + char path[PATH_MAX]; + struct stat parent_ns = { .st_ino = 0 }, caller_ns = { .st_ino = 0 }; +#endif set_log_level(); @@ -914,11 +939,35 @@ int main(int argc, char *argv[]) cred->lc_svc_type = uparam.kup_svc_type; cred->lc_self_nid = uparam.kup_selfnid; - if (lgss_prepare_cred(cred)) { - logmsg(LL_ERR, "key %08x: failed to prepare credentials " - "for user %d\n", keyid, uparam.kup_uid); - return 1; - } +#ifdef HAVE_SETNS + /* Is caller in different namespace? */ + snprintf(path, sizeof(path), "/proc/%d/ns/mnt", getpid()); + if (stat(path, &parent_ns)) + logmsg(LL_ERR, "cannot stat %s: %s\n", path, strerror(errno)); + snprintf(path, sizeof(path), "/proc/%d/ns/mnt", uparam.kup_pid); + if (stat(path, &caller_ns)) + logmsg(LL_ERR, "cannot stat %s: %s\n", path, strerror(errno)); + if (caller_ns.st_ino != parent_ns.st_ino) { + /* + * do credentials preparation in caller's namespace + */ + if (associate_with_ns(path) != 0) { + logmsg(LL_ERR, "failed to attach to pid %d namespace: " + "%s\n", uparam.kup_pid, strerror(errno)); + return 1; + } + logmsg(LL_TRACE, "working in namespace of pid %d\n", + uparam.kup_pid); + } else { + logmsg(LL_TRACE, "caller's namespace is the same\n"); + } +#endif /* HAVE_SETNS */ + + if (lgss_prepare_cred(cred)) { + logmsg(LL_ERR, "key %08x: failed to prepare credentials " + "for user %d\n", keyid, uparam.kup_uid); + return 1; + } /* pre initialize the key. note the keyring linked to is actually of the * original requesting process, not _this_ upcall process. if it's for