From afdad4de7aa8fecc5465f0b8992884e2b043313d Mon Sep 17 00:00:00 2001 From: ericm Date: Fri, 13 Oct 2006 23:57:13 +0000 Subject: [PATCH] branch: b_new_cmd from fanyong: re-enable mapping database lookup in lsvcgss. --- lustre/utils/gss/.cvsignore | 1 + lustre/utils/gss/Makefile.am | 9 +- lustre/utils/gss/gssd_proc.c | 2 +- lustre/utils/gss/l_idmap.c | 37 + lustre/utils/gss/lsupport.c | 464 ++- lustre/utils/gss/lsupport.h | 32 +- lustre/utils/gss/nfs-utils-1.0.10-lustre.diff | 4208 +++++++++++++------------ lustre/utils/gss/svcgssd_proc.c | 16 +- 8 files changed, 2593 insertions(+), 2176 deletions(-) create mode 100644 lustre/utils/gss/l_idmap.c diff --git a/lustre/utils/gss/.cvsignore b/lustre/utils/gss/.cvsignore index 65a8e0a..15f680f 100644 --- a/lustre/utils/gss/.cvsignore +++ b/lustre/utils/gss/.cvsignore @@ -6,5 +6,6 @@ tags TAGS lgssd lsvcgssd +l_idmap .*.cmd .*.d diff --git a/lustre/utils/gss/Makefile.am b/lustre/utils/gss/Makefile.am index 479e28d..34ccfaa 100644 --- a/lustre/utils/gss/Makefile.am +++ b/lustre/utils/gss/Makefile.am @@ -8,7 +8,7 @@ AM_LDFLAGS := -L$(top_builddir)/lnet/utils LIBPTLCTL := $(top_builddir)/lnet/utils/libptlctl.a -sbin_PROGRAMS = lgssd lsvcgssd +sbin_PROGRAMS = lgssd lsvcgssd l_idmap COMMON_SRCS = \ context.c \ @@ -56,4 +56,11 @@ lsvcgssd_LDADD = $(GSSAPI_LIBS) $(KRBLIBS) lsvcgssd_LDFLAGS = $(KRBLDFLAGS) lsvcgssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(KRBCFLAGS) +l_idmap_SOURCES = \ + l_idmap.c \ + lsupport.c \ + err_util.c \ + \ + lsupport.h + EXTRA_DIST = diff --git a/lustre/utils/gss/gssd_proc.c b/lustre/utils/gss/gssd_proc.c index 2aabf19..53150da 100644 --- a/lustre/utils/gss/gssd_proc.c +++ b/lustre/utils/gss/gssd_proc.c @@ -876,7 +876,7 @@ int construct_service_name(struct clnt_info *clp, clp->servicename = NULL; } - if (ptl_nid2hostname(ud->nid, name, buflen)) + if (lnet_nid2hostname(ud->nid, name, buflen)) return -1; clp->servicename = malloc(32 + strlen(name)); diff --git a/lustre/utils/gss/l_idmap.c b/lustre/utils/gss/l_idmap.c new file mode 100644 index 0000000..eada85c --- /dev/null +++ b/lustre/utils/gss/l_idmap.c @@ -0,0 +1,37 @@ +#include +#include +#include + +#include "lsupport.h" + +int main(int argc, char **argv) +{ + lnet_nid_t nid; + uid_t uid; + int rc; + + if (argc < 3) { + printf("Usage:\n" + "%s \n", + basename(argv[0])); + return 1; + } + + nid = libcfs_str2nid(argv[2]); + if (nid == LNET_NID_ANY) { + printf("parse nid %s failed\n", argv[2]); + return 1; + } + rc = lookup_mapping(argv[1], nid, &uid); + if (rc == -1) { + printf("lookup mapping failed\n"); + return 1; + } + + printf("principal: %s\n" + "nid: %#llx\n" + "uid: %u\n", + argv[1], nid, uid); + + return 0; +} diff --git a/lustre/utils/gss/lsupport.c b/lustre/utils/gss/lsupport.c index e6d86bf..b82d380 100644 --- a/lustre/utils/gss/lsupport.c +++ b/lustre/utils/gss/lsupport.c @@ -43,8 +43,10 @@ #include #include #include -#include #include +#ifdef HAVE_GETHOSTBYNAME +# include +#endif #include "err_util.h" #include "gssd.h" @@ -131,17 +133,17 @@ void gssd_exit_unique(int type) /**************************************** * client side resolvation: * - * nal/netid/nid => hostname * + * lnd/netid/nid => hostname * ****************************************/ char gethostname_ex[PATH_MAX] = GSSD_DEFAULT_GETHOSTNAME_EX; -typedef int ptl_nid2hostname_t(char *nal, uint32_t net, uint32_t addr, +typedef int lnd_nid2hostname_t(char *lnd, uint32_t net, uint32_t addr, char *buf, int buflen); /* FIXME what about IPv6? */ static -int socknal_nid2hostname(char *nal, uint32_t net, uint32_t addr, +int socklnd_nid2hostname(char *lnd, uint32_t net, uint32_t addr, char *buf, int buflen) { struct hostent *ent; @@ -149,51 +151,51 @@ int socknal_nid2hostname(char *nal, uint32_t net, uint32_t addr, addr = htonl(addr); ent = gethostbyaddr(&addr, sizeof(addr), AF_INET); if (!ent) { - printerr(0, "%s: can't resolve 0x%x\n", nal, addr); + printerr(0, "%s: can't resolve 0x%x\n", lnd, addr); return -1; } if (strlen(ent->h_name) >= buflen) { - printerr(0, "%s: name too long: %s\n", nal, ent->h_name); + printerr(0, "%s: name too long: %s\n", lnd, ent->h_name); return -1; } strcpy(buf, ent->h_name); printerr(2, "%s: net 0x%x, addr 0x%x => %s\n", - nal, net, addr, buf); + lnd, net, addr, buf); return 0; } static -int lonal_nid2hostname(char *nal, uint32_t net, uint32_t addr, +int lolnd_nid2hostname(char *lnd, uint32_t net, uint32_t addr, char *buf, int buflen) { struct utsname uts; struct hostent *ent; if (addr) { - printerr(0, "%s: addr is 0x%x, we expect 0\n", nal, addr); + printerr(0, "%s: addr is 0x%x, we expect 0\n", lnd, addr); return -1; } if (uname(&uts)) { - printerr(0, "%s: failed obtain local machine name\n", nal); + printerr(0, "%s: failed obtain local machine name\n", lnd); return -1; } ent = gethostbyname(uts.nodename); if (!ent) { printerr(0, "%s: failed obtain canonical name of %s\n", - nal, uts.nodename); + lnd, uts.nodename); return -1; } if (strlen(ent->h_name) >= buflen) { - printerr(0, "%s: name too long: %s\n", nal, ent->h_name); + printerr(0, "%s: name too long: %s\n", lnd, ent->h_name); return -1; } strcpy(buf, ent->h_name); - printerr(2, "%s: addr 0x%x => %s\n", nal, addr, buf); + printerr(2, "%s: addr 0x%x => %s\n", lnd, addr, buf); return 0; } @@ -203,14 +205,14 @@ static int is_space(char c) } static -int external_nid2hostname(char *nal, uint32_t net, uint32_t addr, - char *namebuf, int namebuflen) +int external_nid2hostname(char *lnd, uint32_t net, uint32_t addr, + char *namebuf, int namebuflen) { const int bufsize = PATH_MAX + 256; char buf[bufsize], *head, *tail; FILE *fghn; - sprintf(buf, "%s %s 0x%x 0x%x", gethostname_ex, nal, net, addr); + sprintf(buf, "%s %s 0x%x 0x%x", gethostname_ex, lnd, net, addr); printerr(2, "cmd: %s\n", buf); fghn = popen(buf, "r"); @@ -221,7 +223,7 @@ int external_nid2hostname(char *nal, uint32_t net, uint32_t addr, head = fgets(buf, bufsize, fghn); if (head == NULL) { - printerr(0, "can't read\n"); + printerr(0, "can't read from %s\n", gethostname_ex); return -1; } if (pclose(fghn) == -1) @@ -233,187 +235,337 @@ int external_nid2hostname(char *nal, uint32_t net, uint32_t addr, tail = head + strlen(head); if (tail <= head) { - printerr(0, "no output\n"); + printerr(0, "no output from %s\n", gethostname_ex); return -1; } while (is_space(*(tail - 1))) tail--; if (tail <= head) { - printerr(0, "output are all space\n"); + printerr(0, "output are all space from %s\n", gethostname_ex); return -1; } *tail = '\0'; /* start with '@' means error msg */ if (head[0] == '@') { - printerr(0, "%s\n", &head[1]); + printerr(0, "error from %s: %s\n", gethostname_ex, &head[1]); return -1; } if (tail - head > namebuflen) { - printerr(0, "hostname too long: %s\n", head); + printerr(0, "external hostname too long: %s\n", head); return -1; } printerr(2, "%s: net 0x%x, addr 0x%x => %s\n", - nal, net, addr, head); + lnd, net, addr, head); strcpy(namebuf, head); return 0; } -enum { - QSWNAL = 1, - SOCKNAL = 2, - GMNAL = 3, - /* 4 unused */ - TCPNAL = 5, - ROUTER = 6, - OPENIBNAL = 7, - IIBNAL = 8, - LONAL = 9, - RANAL = 10, - VIBNAL = 11, - NAL_ENUM_END_MARKER -}; - static struct { char *name; - ptl_nid2hostname_t *nid2name; -} converter[NAL_ENUM_END_MARKER] = { + lnd_nid2hostname_t *nid2name; +} converter[LND_ENUM_END_MARKER] = { {"UNUSED0", NULL}, - {"QSWNAL", external_nid2hostname}, - {"SOCKNAL", socknal_nid2hostname}, - {"GMNAL", external_nid2hostname}, - {"UNUSED4", NULL}, - {"TCPNAL", NULL}, - {"ROUTER", NULL}, - {"OPENIBNAL", external_nid2hostname}, - {"IIBNAL", external_nid2hostname}, - {"LONAL", lonal_nid2hostname}, - {"RANAL", NULL}, - {"VIBNAL", external_nid2hostname}, + [QSWLND] = { "QSWLND", external_nid2hostname}, + [SOCKLND] = { "SOCKLND", socklnd_nid2hostname}, + [GMLND] = { "GMLND", external_nid2hostname}, + [PTLLND] = { "PTLLND", external_nid2hostname }, + [O2IBLND] = { "O2IBLND", external_nid2hostname }, + [CIBLND] = { "CIBLND", external_nid2hostname }, + [OPENIBLND] = { "OPENIBLND",external_nid2hostname }, + [IIBLND] = { "IIBLND", external_nid2hostname }, + [LOLND] = { "LOLND", lolnd_nid2hostname }, + [RALND] = { "RALND", external_nid2hostname }, + [VIBLND] = { "VIBLND", external_nid2hostname }, }; -int ptl_nid2hostname(uint64_t nid, char *buf, int buflen) +int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen) { - uint32_t nal, net, addr; + uint32_t lnd, net, addr; addr = LNET_NIDADDR(nid); net = LNET_NIDNET(nid); - nal = LNET_NETTYP(net); + lnd = LNET_NETTYP(net); - if (nal >= NAL_ENUM_END_MARKER) { - printerr(0, "ERROR: Unrecognized NAL %u\n", nal); + if (lnd >= LND_ENUM_END_MARKER) { + printerr(0, "ERROR: Unrecognized LND %u\n", lnd); return -1; } - if (converter[nal].nid2name == NULL) { - printerr(0, "ERROR: NAL %s converter not ready\n", - converter[nal].name); + if (converter[lnd].nid2name == NULL) { + printerr(0, "ERROR: %s converter not ready\n", + converter[lnd].name); return -1; } - return converter[nal].nid2name(converter[nal].name, net, addr, + return converter[lnd].nid2name(converter[lnd].name, net, addr, buf, buflen); } /**************************************** - * portals support routine * + * lnet support routine * + * (from lnet/libcfs/nidstrings.c * ****************************************/ -static struct hostent * -ptl_gethostbyname(char * hname) { - struct hostent *he; - - he = gethostbyname(hname); - if (!he) { - switch(h_errno) { - case HOST_NOT_FOUND: - case NO_ADDRESS: - printerr(0, "Unable to resolve hostname: %s\n", - hname); - break; - default: - printerr(0, "gethostbyname %s: %s\n", - hname, strerror(h_errno)); - break; - } - return NULL; - } - return he; +#define LNET_NIDSTR_SIZE 32 /* size of each one (see below for usage) */ + +static int libcfs_lo_str2addr(char *str, int nob, uint32_t *addr); +static void libcfs_ip_addr2str(uint32_t addr, char *str); +static int libcfs_ip_str2addr(char *str, int nob, uint32_t *addr); +static void libcfs_decnum_addr2str(uint32_t addr, char *str); +static void libcfs_hexnum_addr2str(uint32_t addr, char *str); +static int libcfs_num_str2addr(char *str, int nob, uint32_t *addr); + +struct netstrfns { + int nf_type; + char *nf_name; + char *nf_modname; + void (*nf_addr2str)(uint32_t addr, char *str); + int (*nf_str2addr)(char *str, int nob, uint32_t *addr); +}; + +static struct netstrfns libcfs_netstrfns[] = { + {/* .nf_type */ LOLND, + /* .nf_name */ "lo", + /* .nf_modname */ "klolnd", + /* .nf_addr2str */ libcfs_decnum_addr2str, + /* .nf_str2addr */ libcfs_lo_str2addr}, + {/* .nf_type */ SOCKLND, + /* .nf_name */ "tcp", + /* .nf_modname */ "ksocklnd", + /* .nf_addr2str */ libcfs_ip_addr2str, + /* .nf_str2addr */ libcfs_ip_str2addr}, + {/* .nf_type */ O2IBLND, + /* .nf_name */ "o2ib", + /* .nf_modname */ "ko2iblnd", + /* .nf_addr2str */ libcfs_ip_addr2str, + /* .nf_str2addr */ libcfs_ip_str2addr}, + {/* .nf_type */ CIBLND, + /* .nf_name */ "cib", + /* .nf_modname */ "kciblnd", + /* .nf_addr2str */ libcfs_ip_addr2str, + /* .nf_str2addr */ libcfs_ip_str2addr}, + {/* .nf_type */ OPENIBLND, + /* .nf_name */ "openib", + /* .nf_modname */ "kopeniblnd", + /* .nf_addr2str */ libcfs_ip_addr2str, + /* .nf_str2addr */ libcfs_ip_str2addr}, + {/* .nf_type */ IIBLND, + /* .nf_name */ "iib", + /* .nf_modname */ "kiiblnd", + /* .nf_addr2str */ libcfs_ip_addr2str, + /* .nf_str2addr */ libcfs_ip_str2addr}, + {/* .nf_type */ VIBLND, + /* .nf_name */ "vib", + /* .nf_modname */ "kviblnd", + /* .nf_addr2str */ libcfs_ip_addr2str, + /* .nf_str2addr */ libcfs_ip_str2addr}, + {/* .nf_type */ RALND, + /* .nf_name */ "ra", + /* .nf_modname */ "kralnd", + /* .nf_addr2str */ libcfs_ip_addr2str, + /* .nf_str2addr */ libcfs_ip_str2addr}, + {/* .nf_type */ QSWLND, + /* .nf_name */ "elan", + /* .nf_modname */ "kqswlnd", + /* .nf_addr2str */ libcfs_decnum_addr2str, + /* .nf_str2addr */ libcfs_num_str2addr}, + {/* .nf_type */ GMLND, + /* .nf_name */ "gm", + /* .nf_modname */ "kgmlnd", + /* .nf_addr2str */ libcfs_hexnum_addr2str, + /* .nf_str2addr */ libcfs_num_str2addr}, + {/* .nf_type */ PTLLND, + /* .nf_name */ "ptl", + /* .nf_modname */ "kptllnd", + /* .nf_addr2str */ libcfs_decnum_addr2str, + /* .nf_str2addr */ libcfs_num_str2addr}, + /* placeholder for net0 alias. It MUST BE THE LAST ENTRY */ + {/* .nf_type */ -1}, +}; + +const int libcfs_nnetstrfns = sizeof(libcfs_netstrfns)/sizeof(libcfs_netstrfns[0]); + +static int +libcfs_lo_str2addr(char *str, int nob, uint32_t *addr) +{ + *addr = 0; + return 1; } -int -ptl_parse_ipquad (uint32_t *ipaddrp, char *str) +static void +libcfs_ip_addr2str(uint32_t addr, char *str) { - int a; - int b; - int c; - int d; + snprintf(str, LNET_NIDSTR_SIZE, "%u.%u.%u.%u", + (addr >> 24) & 0xff, (addr >> 16) & 0xff, + (addr >> 8) & 0xff, addr & 0xff); +} - if (sscanf(str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && +/* CAVEAT EMPTOR XscanfX + * I use "%n" at the end of a sscanf format to detect trailing junk. However + * sscanf may return immediately if it sees the terminating '0' in a string, so + * I initialise the %n variable to the expected length. If sscanf sets it; + * fine, if it doesn't, then the scan ended at the end of the string, which is + * fine too :) */ + +static int +libcfs_ip_str2addr(char *str, int nob, uint32_t *addr) +{ + int a; + int b; + int c; + int d; + int n = nob; /* XscanfX */ + + /* numeric IP? */ + if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 && + n == nob && (a & ~0xff) == 0 && (b & ~0xff) == 0 && - (c & ~0xff) == 0 && (d & ~0xff) == 0) - { - *ipaddrp = (a<<24)|(b<<16)|(c<<8)|d; - return (0); + (c & ~0xff) == 0 && (d & ~0xff) == 0) { + *addr = ((a<<24)|(b<<16)|(c<<8)|d); + return 1; } - return (-1); +#ifdef HAVE_GETHOSTBYNAME + /* known hostname? */ + if (('a' <= str[0] && str[0] <= 'z') || + ('A' <= str[0] && str[0] <= 'Z')) { + char *tmp; + + tmp = malloc(nob + 1); + if (tmp != NULL) { + struct hostent *he; + + memcpy(tmp, str, nob); + tmp[nob] = 0; + + he = gethostbyname(tmp); + + free(tmp); + tmp = NULL; + + if (he != NULL) { + uint32_t ip = *(uint32_t *)he->h_addr; + + *addr = ntohl(ip); + return 1; + } + } + } +#endif + return 0; } -int -ptl_parse_ipaddr (uint32_t *ipaddrp, char *str) +static void +libcfs_decnum_addr2str(uint32_t addr, char *str) { - struct hostent *he; + snprintf(str, LNET_NIDSTR_SIZE, "%u", addr); +} - if (!strcmp (str, "_all_")) { - *ipaddrp = 0; - return (0); - } +static void +libcfs_hexnum_addr2str(uint32_t addr, char *str) +{ + snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr); +} - if (ptl_parse_ipquad(ipaddrp, str) == 0) - return (0); +static int +libcfs_num_str2addr(char *str, int nob, uint32_t *addr) +{ + int n; - if ((('a' <= str[0] && str[0] <= 'z') || - ('A' <= str[0] && str[0] <= 'Z')) && - (he = ptl_gethostbyname (str)) != NULL) { - uint32_t addr = *(uint32_t *)he->h_addr; + n = nob; + if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob) + return 1; - *ipaddrp = ntohl(addr); /* HOST byte order */ - return (0); - } + n = nob; + if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob) + return 1; - return (-1); + n = nob; + if (sscanf(str, "%u%n", addr, &n) >= 1 && n == nob) + return 1; + + return 0; } -int -ptl_parse_nid (ptl_nid_t *nidp, char *str) +static struct netstrfns * +libcfs_lnd2netstrfns(int lnd) { - uint32_t ipaddr; - char *end; - unsigned long long ullval; - - if (ptl_parse_ipaddr (&ipaddr, str) == 0) { -#if !CRAY_PORTALS - *nidp = (ptl_nid_t)ipaddr; -#else - *nidp = (((ptl_nid_t)ipaddr & PNAL_HOSTID_MASK) << PNAL_VNODE_SHIFT); -#endif - return (0); + int i; + + if (lnd >= 0) + for (i = 0; i < libcfs_nnetstrfns; i++) + if (lnd == libcfs_netstrfns[i].nf_type) + return &libcfs_netstrfns[i]; + + return NULL; +} + +static struct netstrfns * +libcfs_str2net_internal(char *str, uint32_t *net) +{ + struct netstrfns *nf; + int nob; + int netnum; + int i; + + for (i = 0; i < libcfs_nnetstrfns; i++) { + nf = &libcfs_netstrfns[i]; + if (nf->nf_type >= 0 && + !strncmp(str, nf->nf_name, strlen(nf->nf_name))) + break; } - ullval = strtoull(str, &end, 0); - if (end != str && *end == 0) { - /* parsed whole non-empty string */ - *nidp = (ptl_nid_t)ullval; - return (0); + if (i == libcfs_nnetstrfns) + return NULL; + + nob = strlen(nf->nf_name); + + if (strlen(str) == (unsigned int)nob) { + netnum = 0; + } else { + if (nf->nf_type == LOLND) /* net number not allowed */ + return NULL; + + str += nob; + i = strlen(str); + if (sscanf(str, "%u%n", &netnum, &i) < 1 || + i != (int)strlen(str)) + return NULL; } - return (-1); + *net = LNET_MKNET(nf->nf_type, netnum); + return nf; } +lnet_nid_t +libcfs_str2nid(char *str) +{ + char *sep = strchr(str, '@'); + struct netstrfns *nf; + uint32_t net; + uint32_t addr; + + if (sep != NULL) { + nf = libcfs_str2net_internal(sep + 1, &net); + if (nf == NULL) + return LNET_NID_ANY; + } else { + sep = str + strlen(str); + net = LNET_MKNET(SOCKLND, 0); + nf = libcfs_lnd2netstrfns(SOCKLND); + if (!nf) + return LNET_NID_ANY; + } + + if (!nf->nf_str2addr(str, sep - str, &addr)) + return LNET_NID_ANY; + + return LNET_MKNID(net, addr); +} /**************************************** * user mapping database handling * @@ -425,8 +577,7 @@ ptl_parse_nid (ptl_nid_t *nidp, char *str) struct user_map_item { char *principal; /* NULL means match all */ - ptl_netid_t netid; - ptl_nid_t nid; + lnet_nid_t nid; uid_t uid; }; @@ -438,7 +589,7 @@ struct user_mapping { static struct user_mapping mapping = {0, 0, NULL}; /* FIXME to be finished: monitor change of mapping database */ -static int mapping_changed = 1; +static int mapping_mtime = 0; static void cleanup_mapping(void) @@ -446,8 +597,8 @@ void cleanup_mapping(void) int n; for (n = 0; n < mapping.nitems; n++) { - assert(mapping.items[n].principal); - free(mapping.items[n].principal); + if (mapping.items[n].principal) + free(mapping.items[n].principal); } mapping.nitems = 0; } @@ -500,7 +651,7 @@ int read_mapping_db(void) char princ[MAX_LINE_LEN]; char nid_str[MAX_LINE_LEN]; char dest[MAX_LINE_LEN]; - ptl_nid_t ptl_nid; + lnet_nid_t nid; uid_t dest_uid; FILE *f; char *line, linebuf[MAX_LINE_LEN]; @@ -547,10 +698,15 @@ int read_mapping_db(void) return -1; } } - if (ptl_parse_nid(&ptl_nid, nid_str)) { - printerr(0, "fail to parse nid %s\n", nid_str); - fclose(f); - return -1; + if (!strcmp(nid_str, "*")) { + nid = LNET_NID_ANY; + } else { + nid = libcfs_str2nid(nid_str); + if (nid == LNET_NID_ANY) { + printerr(0, "fail to parse nid %s\n", nid_str); + fclose(f); + return -1; + } } dest_uid = parse_uid(dest); if (dest_uid == -1) { @@ -561,33 +717,47 @@ int read_mapping_db(void) } mapping.items[mapping.nitems].principal = name; - mapping.items[mapping.nitems].netid = 0; - mapping.items[mapping.nitems].nid = ptl_nid; + mapping.items[mapping.nitems].nid = nid; mapping.items[mapping.nitems].uid = dest_uid; mapping.nitems++; printerr(1, "add mapping: %s(%s/0x%llx) ==> %d\n", - name ? name : "*", nid_str, ptl_nid, dest_uid); + name ? name : "*", nid_str, nid, dest_uid); + } + + return 0; +} + +static inline int mapping_changed(void) +{ + struct stat st; + + if (stat(MAPPING_DATABASE_FILE, &st) == -1) { + printerr(0, "stat %s failed\n"); + return 1; + } + + if (st.st_mtime != mapping_mtime) { + mapping_mtime = st.st_mtime; + return 1; } return 0; } -int lookup_mapping(char *princ, uint32_t nal, ptl_netid_t netid, - ptl_nid_t nid, uid_t *uid) +int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid) { int n; /* FIXME race condition here */ - if (mapping_changed) { + if (mapping_changed()) { if (read_mapping_db()) printerr(0, "all remote users will be denied\n"); - mapping_changed = 0; } for (n = 0; n < mapping.nitems; n++) { struct user_map_item *entry = &mapping.items[n]; - if (entry->netid != netid || entry->nid != nid) + if (entry->nid != LNET_NID_ANY && entry->nid != nid) continue; if (!entry->principal || !strcasecmp(entry->principal, princ)) { @@ -597,7 +767,7 @@ int lookup_mapping(char *princ, uint32_t nal, ptl_netid_t netid, return 0; } } - printerr(1, "no mapping for %s\n", princ); + printerr(1, "no mapping for %s/%#Lx\n", princ, nid); *uid = -1; return -1; } diff --git a/lustre/utils/gss/lsupport.h b/lustre/utils/gss/lsupport.h index 4945da8..1a15384 100644 --- a/lustre/utils/gss/lsupport.h +++ b/lustre/utils/gss/lsupport.h @@ -18,9 +18,6 @@ void gssd_exit_unique(int type); * copied from lustre source */ -typedef uint64_t ptl_nid_t; -typedef uint32_t ptl_netid_t; - #define LUSTRE_GSS_SVC_MDS 0 #define LUSTRE_GSS_SVC_OSS 1 @@ -52,9 +49,32 @@ struct lgssd_ioctl_param { #define GSSD_DEFAULT_GETHOSTNAME_EX "/etc/lustre/nid2hostname" #define MAPPING_DATABASE_FILE "/etc/lustre/idmap.conf" -int ptl_nid2hostname(uint64_t nid, char *buf, int buflen); -int lookup_mapping(char *princ, uint32_t nal, ptl_netid_t netid, - ptl_nid_t nid, uid_t *uid); +typedef uint64_t lnet_nid_t; +typedef uint32_t lnet_netid_t; + +#define LNET_NID_ANY ((lnet_nid_t) -1) +#define LNET_PID_ANY ((lnet_pid_t) -1) + +enum { + /* Only add to these values (i.e. don't ever change or redefine them): + * network addresses depend on them... */ + QSWLND = 1, + SOCKLND = 2, + GMLND = 3, + PTLLND = 4, + O2IBLND = 5, + CIBLND = 6, + OPENIBLND = 7, + IIBLND = 8, + LOLND = 9, + RALND = 10, + VIBLND = 11, + LND_ENUM_END_MARKER +}; + +int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen); +int lookup_mapping(char *princ, uint64_t nid, uid_t *uid); +lnet_nid_t libcfs_str2nid(char *str); /* how an LNET NID encodes net:address */ #define LNET_NIDADDR(nid) ((uint32_t)((nid) & 0xffffffff)) diff --git a/lustre/utils/gss/nfs-utils-1.0.10-lustre.diff b/lustre/utils/gss/nfs-utils-1.0.10-lustre.diff index 262a554..3892cbc 100644 --- a/lustre/utils/gss/nfs-utils-1.0.10-lustre.diff +++ b/lustre/utils/gss/nfs-utils-1.0.10-lustre.diff @@ -1,653 +1,317 @@ ---- nfs-utils-1.0.10/utils/gssd/context.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/context.c 2006-08-14 10:32:30.000000000 -0600 -@@ -33,8 +33,6 @@ - #include - #include - #include +--- nfs-utils-1.0.10/utils/gssd/gssd_proc.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/gssd_proc.c 2006-10-13 17:25:01.000000000 -0600 +@@ -43,7 +43,6 @@ + #endif + #include "config.h" + #include -#include --#include - #include "gss_util.h" + #include + #include + #include +@@ -68,6 +67,7 @@ #include "gss_oids.h" - #include "err_util.h" ---- nfs-utils-1.0.10/utils/gssd/context.h.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/context.h 2006-08-14 10:32:30.000000000 -0600 -@@ -31,8 +31,6 @@ - #ifndef _CONTEXT_H_ - #define _CONTEXT_H_ + #include "krb5_util.h" + #include "context.h" ++#include "lsupport.h" --#include + /* + * pollarray: +@@ -98,83 +98,6 @@ + + int pollsize; /* the size of pollaray (in pollfd's) */ + +-/* XXX buffer problems: */ +-static int +-read_service_info(char *info_file_name, char **servicename, char **servername, +- int *prog, int *vers, char **protocol) { +-#define INFOBUFLEN 256 +- char buf[INFOBUFLEN]; +- static char dummy[128]; +- int nbytes; +- static char service[128]; +- static char address[128]; +- char program[16]; +- char version[16]; +- char protoname[16]; +- in_addr_t inaddr; +- int fd = -1; +- struct hostent *ent = NULL; +- int numfields; - - int serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf, - gss_OID mech); - int serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf); ---- nfs-utils-1.0.10/utils/gssd/context_mit.c.lustre 2006-08-14 10:32:04.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/context_mit.c 2006-08-14 10:32:30.000000000 -0600 -@@ -34,8 +34,6 @@ - #include - #include - #include --#include --#include - #include "gss_util.h" - #include "gss_oids.h" - #include "err_util.h" -@@ -468,6 +466,7 @@ - else - keyptr = &lctx->cfx_kd.ctx_key; +- *servicename = *servername = *protocol = NULL; +- +- if ((fd = open(info_file_name, O_RDONLY)) == -1) { +- printerr(0, "ERROR: can't open %s: %s\n", info_file_name, +- strerror(errno)); +- goto fail; +- } +- if ((nbytes = read(fd, buf, INFOBUFLEN)) == -1) +- goto fail; +- close(fd); +- +- numfields = sscanf(buf,"RPC server: %127s\n" +- "service: %127s %15s version %15s\n" +- "address: %127s\n" +- "protocol: %15s\n", +- dummy, +- service, program, version, +- address, +- protoname); +- +- if (numfields == 5) { +- strcpy(protoname, "tcp"); +- } else if (numfields != 6) { +- goto fail; +- } +- +- /* check service, program, and version */ +- if(memcmp(service, "nfs", 3)) return -1; +- *prog = atoi(program + 1); /* skip open paren */ +- *vers = atoi(version); +- if((*prog != 100003) || ((*vers != 2) && (*vers != 3) && (*vers != 4))) +- goto fail; +- +- /* create service name */ +- inaddr = inet_addr(address); +- if (!(ent = gethostbyaddr(&inaddr, sizeof(inaddr), AF_INET))) { +- printerr(0, "ERROR: can't resolve server %s name\n", address); +- goto fail; +- } +- if (!(*servername = calloc(strlen(ent->h_name) + 1, 1))) +- goto fail; +- memcpy(*servername, ent->h_name, strlen(ent->h_name)); +- snprintf(buf, INFOBUFLEN, "%s@%s", service, ent->h_name); +- if (!(*servicename = calloc(strlen(buf) + 1, 1))) +- goto fail; +- memcpy(*servicename, buf, strlen(buf)); +- +- if (!(*protocol = strdup(protoname))) +- goto fail; +- return 0; +-fail: +- printerr(0, "ERROR: failed to read service info\n"); +- if (fd != -1) close(fd); +- if (*servername) free(*servername); +- if (*servicename) free(*servicename); +- if (*protocol) free(*protocol); +- return -1; +-} +- + static void + destroy_client(struct clnt_info *clp) + { +@@ -189,8 +112,6 @@ + if (clp->spkm3_fd != -1) close(clp->spkm3_fd); + if (clp->dirname) free(clp->dirname); + if (clp->servicename) free(clp->servicename); +- if (clp->servername) free(clp->servername); +- if (clp->protocol) free(clp->protocol); + free(clp); + } -+#if 0 - if (lctx->initiate == 1) { - sign_usage = KG_USAGE_INITIATOR_SIGN; - seal_usage = KG_USAGE_INITIATOR_SEAL; -@@ -475,6 +474,19 @@ - sign_usage = KG_USAGE_ACCEPTOR_SIGN; - seal_usage = KG_USAGE_ACCEPTOR_SEAL; +@@ -220,7 +141,6 @@ + { + char kname[32]; + char sname[32]; +- char info_file_name[32]; + + if (clp->krb5_fd == -1) { + snprintf(kname, sizeof(kname), "%s/krb5", clp->dirname); +@@ -232,13 +152,6 @@ + } + if((clp->krb5_fd == -1) && (clp->spkm3_fd == -1)) + return -1; +- snprintf(info_file_name, sizeof(info_file_name), "%s/info", +- clp->dirname); +- if ((clp->servicename == NULL) && +- read_service_info(info_file_name, &clp->servicename, +- &clp->servername, &clp->prog, &clp->vers, +- &clp->protocol)) +- return -1; + return 0; + } + +@@ -272,6 +185,8 @@ } -+#else -+ /* FIXME -+ * These are from rfc4142, but I don't understand: if we supply -+ * different 'usage' value for client & server, then the peers -+ * will have different derived keys. How could this work? -+ * -+ * Here we simply use old SIGN/SEAL values until we find the -+ * answer. --ericm -+ * FIXME -+ */ -+ sign_usage = KG_USAGE_SIGN; -+ seal_usage = KG_USAGE_SEAL; -+#endif + pollarray[clp->krb5_poll_index].fd = clp->krb5_fd; + pollarray[clp->krb5_poll_index].events |= POLLIN; ++ printerr(2, "monitoring krb5 channel under %s\n", ++ clp->dirname); + } - /* derive and send down: Ke, Ki, and Kc */ + if ((clp->spkm3_fd != -1) && (clp->spkm3_poll_index == -1)) { +@@ -385,7 +300,10 @@ + int + update_client_list(void) + { +- struct dirent **namelist; ++ char lustre_dir[PATH_MAX]; ++ struct dirent lustre_dirent = { .d_name = "lustre" }; ++ struct dirent *namelist[1]; ++ struct stat statbuf; + int i, j; -@@ -793,7 +805,10 @@ + if (chdir(pipefsdir) < 0) { +@@ -394,45 +312,76 @@ + return -1; + } - out_err: - printerr(0, "ERROR: failed serializing krb5 context for kernel\n"); -- if (buf->value) free(buf->value); -+ if (buf->value) { -+ free(buf->value); -+ buf->value = NULL; -+ } - buf->length = 0; - return -1; +- j = scandir(pipefsdir, &namelist, NULL, alphasort); +- if (j < 0) { +- printerr(0, "ERROR: can't scandir %s: %s\n", +- pipefsdir, strerror(errno)); +- return -1; ++ snprintf(lustre_dir, sizeof(lustre_dir), "%s/%s", pipefsdir, "lustre"); ++ if (stat(lustre_dir, &statbuf) == 0) { ++ namelist[0] = &lustre_dirent; ++ j = 1; ++ printerr(2, "re-processing lustre directory\n"); ++ } else { ++ namelist[0] = NULL; ++ j = 0; ++ printerr(2, "lustre directory not exist\n"); + } ++ + update_old_clients(namelist, j); + for (i=0; i < j; i++) { +- if (i < FD_ALLOC_BLOCK +- && !strncmp(namelist[i]->d_name, "clnt", 4) +- && !find_client(namelist[i]->d_name)) ++ if (i < FD_ALLOC_BLOCK && ++ !find_client(namelist[i]->d_name)) + process_clnt_dir(namelist[i]->d_name); +- free(namelist[i]); + } + +- free(namelist); ++ chdir("/"); + return 0; } ---- nfs-utils-1.0.10/utils/gssd/context_spkm3.c.lustre 2006-08-14 10:32:04.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/context_spkm3.c 2006-08-14 10:32:30.000000000 -0600 -@@ -33,8 +33,6 @@ - #include - #include - #include --#include --#include - #include "gss_util.h" - #include "gss_oids.h" - #include "err_util.h" ---- nfs-utils-1.0.10/utils/gssd/err_util.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/err_util.c 2006-08-14 10:32:30.000000000 -0600 -@@ -32,6 +32,8 @@ - #include - #include - #include -+#include -+#include - #include "err_util.h" - static int verbosity = 0; -@@ -91,3 +93,40 @@ - /* reset the buffer */ - memset(message_buf, 0, sizeof(message_buf)); - } -+ -+void print_hexl(int pri, unsigned char *cp, int length) -+{ -+ int i, j, jm; -+ unsigned char c; -+ -+ printerr(pri, "length %d\n",length); -+ printerr(pri, "\n"); ++/* Context creation response. */ ++struct lustre_gss_init_res { ++ gss_buffer_desc gr_ctx; /* context handle */ ++ u_int gr_major; /* major status */ ++ u_int gr_minor; /* minor status */ ++ u_int gr_win; /* sequence window */ ++ gss_buffer_desc gr_token; /* token */ ++}; + -+ for (i = 0; i < length; i += 0x10) { -+ printerr(pri, " %04x: ", (u_int)i); -+ jm = length - i; -+ jm = jm > 16 ? 16 : jm; ++struct lustre_gss_data { ++ int lgd_established; ++ int lgd_lustre_svc; /* mds/oss */ ++ int lgd_uid; /* uid */ ++ char *lgd_uuid; /* client device uuid */ ++ gss_name_t lgd_name; /* service name */ + -+ for (j = 0; j < jm; j++) { -+ if ((j % 2) == 1) -+ printerr(pri,"%02x ", (u_int)cp[i+j]); -+ else -+ printerr(pri,"%02x", (u_int)cp[i+j]); -+ } -+ for (; j < 16; j++) { -+ if ((j % 2) == 1) -+ printerr(pri," "); -+ else -+ printerr(pri," "); -+ } -+ printerr(pri," "); ++ gss_OID lgd_mech; /* mech OID */ ++ u_int lgd_req_flags; /* request flags */ ++ gss_cred_id_t lgd_cred; /* credential */ ++ gss_ctx_id_t lgd_ctx; /* session context */ ++ gss_buffer_desc lgd_rmt_ctx; /* remote handle of context */ ++ uint32_t lgd_seq_win; /* sequence window */ + -+ for (j = 0; j < jm; j++) { -+ c = cp[i+j]; -+ c = isprint(c) ? c : '.'; -+ printerr(pri,"%c", c); -+ } -+ printerr(pri,"\n"); -+ } -+} ++ int lgd_rpc_err; ++ int lgd_gss_err; ++}; + ---- nfs-utils-1.0.10/utils/gssd/err_util.h.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/err_util.h 2006-08-14 10:32:30.000000000 -0600 -@@ -33,5 +33,6 @@ - - void initerr(char *progname, int verbosity, int fg); - void printerr(int priority, char *format, ...); -+void print_hexl(int pri, unsigned char *cp, int length); + static int +-do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd, +- gss_buffer_desc *context_token) ++do_downcall(int k5_fd, struct lgssd_upcall_data *updata, ++ struct lustre_gss_data *lgd, gss_buffer_desc *context_token) + { + char *buf = NULL, *p = NULL, *end = NULL; + unsigned int timeout = 0; /* XXX decide on a reasonable value */ + unsigned int buf_size = 0; - #endif /* _ERR_UTIL_H_ */ ---- nfs-utils-1.0.10/utils/gssd/gss_clnt_send_err.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/gss_clnt_send_err.c 2006-08-14 10:32:30.000000000 -0600 -@@ -47,6 +47,7 @@ - #include "gssd.h" - #include "write_bytes.h" +- printerr(1, "doing downcall\n"); +- buf_size = sizeof(uid) + sizeof(timeout) + sizeof(pd->pd_seq_win) + +- sizeof(pd->pd_ctx_hndl.length) + pd->pd_ctx_hndl.length + ++ printerr(2, "doing downcall\n"); ++ buf_size = sizeof(updata->seq) + sizeof(timeout) + ++ sizeof(lgd->lgd_seq_win) + ++ sizeof(lgd->lgd_rmt_ctx.length) + lgd->lgd_rmt_ctx.length + + sizeof(context_token->length) + context_token->length; + p = buf = malloc(buf_size); + end = buf + buf_size; -+#if 0 - char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR; +- if (WRITE_BYTES(&p, end, uid)) goto out_err; ++ if (WRITE_BYTES(&p, end, updata->seq)) goto out_err; + /* Not setting any timeout for now: */ + if (WRITE_BYTES(&p, end, timeout)) goto out_err; +- if (WRITE_BYTES(&p, end, pd->pd_seq_win)) goto out_err; +- if (write_buffer(&p, end, &pd->pd_ctx_hndl)) goto out_err; ++ if (WRITE_BYTES(&p, end, lgd->lgd_seq_win)) goto out_err; ++ if (write_buffer(&p, end, &lgd->lgd_rmt_ctx)) goto out_err; + if (write_buffer(&p, end, context_token)) goto out_err; - static void -@@ -102,3 +103,4 @@ - } - exit(0); + if (write(k5_fd, buf, p - buf) < p - buf) goto out_err; +@@ -440,12 +389,13 @@ + return 0; + out_err: + if (buf) free(buf); +- printerr(0, "Failed to write downcall!\n"); ++ printerr(0, "ERROR: Failed to write downcall!\n"); + return -1; } -+#endif ---- nfs-utils-1.0.10/utils/gssd/gssd.c.lustre 2006-08-14 10:32:04.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/gssd.c 2006-08-14 10:32:30.000000000 -0600 -@@ -40,7 +40,6 @@ - - #include - #include --#include - - #include - #include -@@ -52,6 +51,7 @@ - #include "err_util.h" - #include "gss_util.h" - #include "krb5_util.h" -+#include "lsupport.h" - char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR; - char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE; -@@ -77,7 +77,7 @@ - static void - usage(char *progname) - { -- fprintf(stderr, "usage: %s [-f] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n", -+ fprintf(stderr, "usage: %s [-f] [-v] [-p pipefsdir] [-k keytab] [-d ccachedir]\n", - progname); - exit(1); - } -@@ -87,7 +87,6 @@ + static int +-do_error_downcall(int k5_fd, uid_t uid, int err) ++do_error_downcall(int k5_fd, struct lgssd_upcall_data *updata, ++ int rpc_err, int gss_err) { - int fg = 0; - int verbosity = 0; -- int rpc_verbosity = 0; - int opt; - extern char *optarg; - char *progname; -@@ -97,15 +96,9 @@ - case 'f': - fg = 1; - break; -- case 'm': -- /* Accept but ignore this. Now the default. */ -- break; - case 'v': - verbosity++; - break; -- case 'r': -- rpc_verbosity++; -- break; - case 'p': - strncpy(pipefsdir, optarg, sizeof(pipefsdir)); - if (pipefsdir[sizeof(pipefsdir)-1] != '\0') -@@ -126,10 +119,6 @@ - break; - } - } -- strncat(pipefsdir + strlen(pipefsdir), "/" GSSD_SERVICE_NAME, -- sizeof(pipefsdir)-strlen(pipefsdir)); -- if (pipefsdir[sizeof(pipefsdir)-1] != '\0') -- errx(1, "pipefs path name too long"); + char buf[1024]; + char *p = buf, *end = buf + 1024; +@@ -454,11 +404,12 @@ - if ((progname = strrchr(argv[0], '/'))) - progname++; -@@ -137,30 +126,34 @@ - progname = argv[0]; + printerr(1, "doing error downcall\n"); - initerr(progname, verbosity, fg); --#ifdef HAVE_AUTHGSS_SET_DEBUG_LEVEL -- authgss_set_debug_level(rpc_verbosity); --#else -- if (rpc_verbosity > 0) -- printerr(0, "Warning: rpcsec_gss library does not " -- "support setting debug level\n"); --#endif +- if (WRITE_BYTES(&p, end, uid)) goto out_err; ++ if (WRITE_BYTES(&p, end, updata->seq)) goto out_err; + if (WRITE_BYTES(&p, end, timeout)) goto out_err; + /* use seq_win = 0 to indicate an error: */ + if (WRITE_BYTES(&p, end, zero)) goto out_err; +- if (WRITE_BYTES(&p, end, err)) goto out_err; ++ if (WRITE_BYTES(&p, end, rpc_err)) goto out_err; ++ if (WRITE_BYTES(&p, end, gss_err)) goto out_err; - if (gssd_check_mechs() != 0) - errx(1, "Problem with gssapi library"); + if (write(k5_fd, buf, p - buf) < p - buf) goto out_err; + return 0; +@@ -467,6 +418,7 @@ + return -1; + } +#if 0 -+ /* Determine Kerberos information from the kernel */ -+ gssd_obtain_kernel_krb5_info(); + /* + * Create an RPC connection and establish an authenticated + * gss context with a server. +@@ -658,7 +610,287 @@ + + goto out; + } +#endif + - if (!fg && daemon(0, 0) < 0) - errx(1, "fork"); - -+ /* This should be checked _after_ daemon(), because we need to own -+ * the undo-able semaphore by this process -+ */ -+ gssd_init_unique(GSSD_CLI); ++static ++int do_negotiation(struct lustre_gss_data *lgd, ++ gss_buffer_desc *gss_token, ++ struct lustre_gss_init_res *gr, ++ int timeout) ++{ ++ char *file = "/proc/fs/lustre/sptlrpc/gss/init_channel"; ++ struct lgssd_ioctl_param param; ++ struct passwd *pw; ++ int fd, ret; ++ char outbuf[8192]; ++ unsigned int *p; ++ int res; + -+ /* Process keytab file and get machine credentials. This will modify -+ * disk status so do it after we are sure we are the only instance -+ */ -+ if (gssd_refresh_krb5_machine_creds()) ++ pw = getpwuid(lgd->lgd_uid); ++ if (!pw) { ++ printerr(0, "no uid %u in local user database\n", ++ lgd->lgd_uid); + return -1; -+ - signal(SIGINT, sig_die); - signal(SIGTERM, sig_die); - signal(SIGHUP, sig_hup); - -- /* Process keytab file and get machine credentials */ -- gssd_refresh_krb5_machine_creds(); -- /* Determine Kerberos information from the kernel */ -- gssd_obtain_kernel_krb5_info(); -- -- gssd_run(); -+ lgssd_run(); - printerr(0, "gssd_run returned!\n"); - abort(); - } ---- nfs-utils-1.0.10/utils/gssd/gssd.h.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/gssd.h 2006-08-14 10:32:30.000000000 -0600 -@@ -48,8 +48,13 @@ - #define GSSD_DEFAULT_CRED_PREFIX "krb5cc_" - #define GSSD_DEFAULT_MACHINE_CRED_SUFFIX "machine" - #define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab" --#define GSSD_SERVICE_NAME "nfs" --#define GSSD_SERVICE_NAME_LEN 3 -+#define GSSD_SERVICE_MDS "lustre_mds" -+#define GSSD_SERVICE_OSS "lustre_oss" -+#define GSSD_SERVICE_MDS_NAMELEN 10 -+#define GSSD_SERVICE_OSS_NAMELEN 10 -+ -+#define LUSTRE_ROOT_NAME "lustre_root" -+#define LUSTRE_ROOT_NAMELEN 11 - - /* - * The gss mechanisms that we can handle -@@ -61,6 +66,7 @@ - extern char pipefsdir[PATH_MAX]; - extern char keytabfile[PATH_MAX]; - extern char ccachedir[PATH_MAX]; -+extern char gethostname_ex[PATH_MAX]; - - TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list; - -@@ -69,10 +75,6 @@ - char *dirname; - int dir_fd; - char *servicename; -- char *servername; -- int prog; -- int vers; -- char *protocol; - int krb5_fd; - int krb5_poll_index; - int spkm3_fd; -@@ -83,8 +85,7 @@ - int update_client_list(void); - void handle_krb5_upcall(struct clnt_info *clp); - void handle_spkm3_upcall(struct clnt_info *clp); --int gssd_acquire_cred(char *server_name); --void gssd_run(void); -+void lgssd_run(void); - - - #endif /* _RPC_GSSD_H_ */ ---- nfs-utils-1.0.10/utils/gssd/gssd_main_loop.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/gssd_main_loop.c 2006-08-14 10:32:30.000000000 -0600 -@@ -94,7 +94,7 @@ - }; - - void --gssd_run() -+lgssd_run() - { - int ret; - struct sigaction dn_act; -@@ -118,6 +118,7 @@ - - while (1) { - while (dir_changed) { -+ printerr(2, "pipefs root dir changed\n"); - dir_changed = 0; - if (update_client_list()) { - printerr(0, "ERROR: couldn't update " ---- nfs-utils-1.0.10/utils/gssd/gssd_proc.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/gssd_proc.c 2006-08-14 10:32:30.000000000 -0600 -@@ -43,7 +43,6 @@ - #endif - #include "config.h" - #include --#include - #include - #include - #include -@@ -68,6 +67,7 @@ - #include "gss_oids.h" - #include "krb5_util.h" - #include "context.h" -+#include "lsupport.h" - - /* - * pollarray: -@@ -98,83 +98,6 @@ - - int pollsize; /* the size of pollaray (in pollfd's) */ - --/* XXX buffer problems: */ --static int --read_service_info(char *info_file_name, char **servicename, char **servername, -- int *prog, int *vers, char **protocol) { --#define INFOBUFLEN 256 -- char buf[INFOBUFLEN]; -- static char dummy[128]; -- int nbytes; -- static char service[128]; -- static char address[128]; -- char program[16]; -- char version[16]; -- char protoname[16]; -- in_addr_t inaddr; -- int fd = -1; -- struct hostent *ent = NULL; -- int numfields; -- -- *servicename = *servername = *protocol = NULL; -- -- if ((fd = open(info_file_name, O_RDONLY)) == -1) { -- printerr(0, "ERROR: can't open %s: %s\n", info_file_name, -- strerror(errno)); -- goto fail; -- } -- if ((nbytes = read(fd, buf, INFOBUFLEN)) == -1) -- goto fail; -- close(fd); -- -- numfields = sscanf(buf,"RPC server: %127s\n" -- "service: %127s %15s version %15s\n" -- "address: %127s\n" -- "protocol: %15s\n", -- dummy, -- service, program, version, -- address, -- protoname); -- -- if (numfields == 5) { -- strcpy(protoname, "tcp"); -- } else if (numfields != 6) { -- goto fail; -- } -- -- /* check service, program, and version */ -- if(memcmp(service, "nfs", 3)) return -1; -- *prog = atoi(program + 1); /* skip open paren */ -- *vers = atoi(version); -- if((*prog != 100003) || ((*vers != 2) && (*vers != 3) && (*vers != 4))) -- goto fail; -- -- /* create service name */ -- inaddr = inet_addr(address); -- if (!(ent = gethostbyaddr(&inaddr, sizeof(inaddr), AF_INET))) { -- printerr(0, "ERROR: can't resolve server %s name\n", address); -- goto fail; -- } -- if (!(*servername = calloc(strlen(ent->h_name) + 1, 1))) -- goto fail; -- memcpy(*servername, ent->h_name, strlen(ent->h_name)); -- snprintf(buf, INFOBUFLEN, "%s@%s", service, ent->h_name); -- if (!(*servicename = calloc(strlen(buf) + 1, 1))) -- goto fail; -- memcpy(*servicename, buf, strlen(buf)); -- -- if (!(*protocol = strdup(protoname))) -- goto fail; -- return 0; --fail: -- printerr(0, "ERROR: failed to read service info\n"); -- if (fd != -1) close(fd); -- if (*servername) free(*servername); -- if (*servicename) free(*servicename); -- if (*protocol) free(*protocol); -- return -1; --} -- - static void - destroy_client(struct clnt_info *clp) - { -@@ -189,8 +112,6 @@ - if (clp->spkm3_fd != -1) close(clp->spkm3_fd); - if (clp->dirname) free(clp->dirname); - if (clp->servicename) free(clp->servicename); -- if (clp->servername) free(clp->servername); -- if (clp->protocol) free(clp->protocol); - free(clp); - } - -@@ -220,7 +141,6 @@ - { - char kname[32]; - char sname[32]; -- char info_file_name[32]; - - if (clp->krb5_fd == -1) { - snprintf(kname, sizeof(kname), "%s/krb5", clp->dirname); -@@ -232,13 +152,6 @@ - } - if((clp->krb5_fd == -1) && (clp->spkm3_fd == -1)) - return -1; -- snprintf(info_file_name, sizeof(info_file_name), "%s/info", -- clp->dirname); -- if ((clp->servicename == NULL) && -- read_service_info(info_file_name, &clp->servicename, -- &clp->servername, &clp->prog, &clp->vers, -- &clp->protocol)) -- return -1; - return 0; - } - -@@ -272,6 +185,8 @@ - } - pollarray[clp->krb5_poll_index].fd = clp->krb5_fd; - pollarray[clp->krb5_poll_index].events |= POLLIN; -+ printerr(2, "monitoring krb5 channel under %s\n", -+ clp->dirname); - } - - if ((clp->spkm3_fd != -1) && (clp->spkm3_poll_index == -1)) { -@@ -385,7 +300,10 @@ - int - update_client_list(void) - { -- struct dirent **namelist; -+ char lustre_dir[PATH_MAX]; -+ struct dirent lustre_dirent = { .d_name = "lustre" }; -+ struct dirent *namelist[1]; -+ struct stat statbuf; - int i, j; - - if (chdir(pipefsdir) < 0) { -@@ -394,45 +312,76 @@ - return -1; - } - -- j = scandir(pipefsdir, &namelist, NULL, alphasort); -- if (j < 0) { -- printerr(0, "ERROR: can't scandir %s: %s\n", -- pipefsdir, strerror(errno)); -- return -1; -+ snprintf(lustre_dir, sizeof(lustre_dir), "%s/%s", pipefsdir, "lustre"); -+ if (stat(lustre_dir, &statbuf) == 0) { -+ namelist[0] = &lustre_dirent; -+ j = 1; -+ printerr(2, "re-processing lustre directory\n"); -+ } else { -+ namelist[0] = NULL; -+ j = 0; -+ printerr(2, "lustre directory not exist\n"); - } -+ - update_old_clients(namelist, j); - for (i=0; i < j; i++) { -- if (i < FD_ALLOC_BLOCK -- && !strncmp(namelist[i]->d_name, "clnt", 4) -- && !find_client(namelist[i]->d_name)) -+ if (i < FD_ALLOC_BLOCK && -+ !find_client(namelist[i]->d_name)) - process_clnt_dir(namelist[i]->d_name); -- free(namelist[i]); - } - -- free(namelist); -+ chdir("/"); - return 0; - } - -+/* Context creation response. */ -+struct lustre_gss_init_res { -+ gss_buffer_desc gr_ctx; /* context handle */ -+ u_int gr_major; /* major status */ -+ u_int gr_minor; /* minor status */ -+ u_int gr_win; /* sequence window */ -+ gss_buffer_desc gr_token; /* token */ -+}; -+ -+struct lustre_gss_data { -+ int lgd_established; -+ int lgd_lustre_svc; /* mds/oss */ -+ int lgd_uid; /* uid */ -+ char *lgd_uuid; /* client device uuid */ -+ gss_name_t lgd_name; /* service name */ -+ -+ gss_OID lgd_mech; /* mech OID */ -+ u_int lgd_req_flags; /* request flags */ -+ gss_cred_id_t lgd_cred; /* credential */ -+ gss_ctx_id_t lgd_ctx; /* session context */ -+ gss_buffer_desc lgd_rmt_ctx; /* remote handle of context */ -+ uint32_t lgd_seq_win; /* sequence window */ -+ -+ int lgd_rpc_err; -+ int lgd_gss_err; -+}; -+ - static int --do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd, -- gss_buffer_desc *context_token) -+do_downcall(int k5_fd, struct lgssd_upcall_data *updata, -+ struct lustre_gss_data *lgd, gss_buffer_desc *context_token) - { - char *buf = NULL, *p = NULL, *end = NULL; - unsigned int timeout = 0; /* XXX decide on a reasonable value */ - unsigned int buf_size = 0; - -- printerr(1, "doing downcall\n"); -- buf_size = sizeof(uid) + sizeof(timeout) + sizeof(pd->pd_seq_win) + -- sizeof(pd->pd_ctx_hndl.length) + pd->pd_ctx_hndl.length + -+ printerr(2, "doing downcall\n"); -+ buf_size = sizeof(updata->seq) + sizeof(timeout) + -+ sizeof(lgd->lgd_seq_win) + -+ sizeof(lgd->lgd_rmt_ctx.length) + lgd->lgd_rmt_ctx.length + - sizeof(context_token->length) + context_token->length; - p = buf = malloc(buf_size); - end = buf + buf_size; - -- if (WRITE_BYTES(&p, end, uid)) goto out_err; -+ if (WRITE_BYTES(&p, end, updata->seq)) goto out_err; - /* Not setting any timeout for now: */ - if (WRITE_BYTES(&p, end, timeout)) goto out_err; -- if (WRITE_BYTES(&p, end, pd->pd_seq_win)) goto out_err; -- if (write_buffer(&p, end, &pd->pd_ctx_hndl)) goto out_err; -+ if (WRITE_BYTES(&p, end, lgd->lgd_seq_win)) goto out_err; -+ if (write_buffer(&p, end, &lgd->lgd_rmt_ctx)) goto out_err; - if (write_buffer(&p, end, context_token)) goto out_err; - - if (write(k5_fd, buf, p - buf) < p - buf) goto out_err; -@@ -440,12 +389,13 @@ - return 0; - out_err: - if (buf) free(buf); -- printerr(0, "Failed to write downcall!\n"); -+ printerr(0, "ERROR: Failed to write downcall!\n"); - return -1; - } - - static int --do_error_downcall(int k5_fd, uid_t uid, int err) -+do_error_downcall(int k5_fd, struct lgssd_upcall_data *updata, -+ int rpc_err, int gss_err) - { - char buf[1024]; - char *p = buf, *end = buf + 1024; -@@ -454,11 +404,12 @@ - - printerr(1, "doing error downcall\n"); - -- if (WRITE_BYTES(&p, end, uid)) goto out_err; -+ if (WRITE_BYTES(&p, end, updata->seq)) goto out_err; - if (WRITE_BYTES(&p, end, timeout)) goto out_err; - /* use seq_win = 0 to indicate an error: */ - if (WRITE_BYTES(&p, end, zero)) goto out_err; -- if (WRITE_BYTES(&p, end, err)) goto out_err; -+ if (WRITE_BYTES(&p, end, rpc_err)) goto out_err; -+ if (WRITE_BYTES(&p, end, gss_err)) goto out_err; - - if (write(k5_fd, buf, p - buf) < p - buf) goto out_err; - return 0; -@@ -467,6 +418,7 @@ - return -1; - } - -+#if 0 - /* - * Create an RPC connection and establish an authenticated - * gss context with a server. -@@ -658,7 +610,287 @@ - - goto out; - } -+#endif -+ -+static -+int do_negotiation(struct lustre_gss_data *lgd, -+ gss_buffer_desc *gss_token, -+ struct lustre_gss_init_res *gr, -+ int timeout) -+{ -+ char *file = "/proc/fs/lustre/sptlrpc/gss/init_channel"; -+ struct lgssd_ioctl_param param; -+ struct passwd *pw; -+ int fd, ret; -+ char outbuf[8192]; -+ unsigned int *p; -+ int res; -+ -+ pw = getpwuid(lgd->lgd_uid); -+ if (!pw) { -+ printerr(0, "no uid %u in local user database\n", -+ lgd->lgd_uid); -+ return -1; -+ } ++ } + + param.version = GSSD_INTERFACE_VERSION; + param.uuid = lgd->lgd_uuid; @@ -892,7 +556,7 @@ + clp->servicename = NULL; + } + -+ if (ptl_nid2hostname(ud->nid, name, buflen)) ++ if (lnet_nid2hostname(ud->nid, name, buflen)) + return -1; + + clp->servicename = malloc(32 + strlen(name)); @@ -1076,1312 +740,1505 @@ goto out; +#endif } ---- nfs-utils-1.0.10/utils/gssd/gss_util.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/gss_util.c 2006-08-14 10:32:30.000000000 -0600 -@@ -87,9 +87,16 @@ - #ifdef HAVE_COM_ERR_H - #include - #endif -+#include "lsupport.h" +--- nfs-utils-1.0.10/utils/gssd/context_mit.c.lustre 2006-10-13 16:02:38.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/context_mit.c 2006-10-13 16:03:33.000000000 -0600 +@@ -34,8 +34,6 @@ + #include + #include + #include +-#include +-#include + #include "gss_util.h" + #include "gss_oids.h" + #include "err_util.h" +@@ -468,6 +466,7 @@ + else + keyptr = &lctx->cfx_kd.ctx_key; - /* Global gssd_credentials handle */ --gss_cred_id_t gssd_creds; -+gss_cred_id_t gssd_cred_mds; -+gss_cred_id_t gssd_cred_oss; -+int gssd_cred_mds_valid = 0; -+int gssd_cred_oss_valid = 0; -+ -+char *mds_local_realm = NULL; -+char *oss_local_realm = NULL; ++#if 0 + if (lctx->initiate == 1) { + sign_usage = KG_USAGE_INITIATOR_SIGN; + seal_usage = KG_USAGE_INITIATOR_SEAL; +@@ -475,6 +474,19 @@ + sign_usage = KG_USAGE_ACCEPTOR_SIGN; + seal_usage = KG_USAGE_ACCEPTOR_SEAL; + } ++#else ++ /* FIXME ++ * These are from rfc4142, but I don't understand: if we supply ++ * different 'usage' value for client & server, then the peers ++ * will have different derived keys. How could this work? ++ * ++ * Here we simply use old SIGN/SEAL values until we find the ++ * answer. --ericm ++ * FIXME ++ */ ++ sign_usage = KG_USAGE_SIGN; ++ seal_usage = KG_USAGE_SEAL; ++#endif - gss_OID g_mechOid = GSS_C_NULL_OID;; + /* derive and send down: Ke, Ki, and Kc */ -@@ -183,15 +190,51 @@ - display_status_2(msg, maj_stat, min_stat, mech); +@@ -793,7 +805,10 @@ + + out_err: + printerr(0, "ERROR: failed serializing krb5 context for kernel\n"); +- if (buf->value) free(buf->value); ++ if (buf->value) { ++ free(buf->value); ++ buf->value = NULL; ++ } + buf->length = 0; + return -1; } +--- nfs-utils-1.0.10/utils/gssd/context.h.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/context.h 2006-10-13 16:03:33.000000000 -0600 +@@ -31,8 +31,6 @@ + #ifndef _CONTEXT_H_ + #define _CONTEXT_H_ --int --gssd_acquire_cred(char *server_name) -+static -+int extract_realm_name(gss_buffer_desc *name, char **realm) -+{ -+ char *sname, *c; -+ -+ sname = malloc(name->length + 1); -+ if (!sname) { -+ printerr(0, "out of memory\n"); -+ return -ENOMEM; -+ } -+ -+ memcpy(sname, name->value, name->length); -+ sname[name->length] = '\0'; -+ printerr(1, "service principal: %s\n", sname); -+ -+ c = strchr(sname, '@'); -+ if (!realm) -+ *realm = NULL; -+ else { -+ c++; -+ *realm = malloc(strlen(c) + 1); -+ if (!*realm) { -+ printerr(0, "out of memory\n"); -+ return -ENOMEM; -+ } -+ strcpy(*realm, c); -+ } -+ free(sname); -+ -+ return 0; -+} -+ -+static -+int gssd_acquire_cred(char *server_name, gss_cred_id_t *cred, -+ char **local_realm, int *valid) +-#include +- + int serialize_context_for_kernel(gss_ctx_id_t ctx, gss_buffer_desc *buf, + gss_OID mech); + int serialize_spkm3_ctx(gss_ctx_id_t ctx, gss_buffer_desc *buf); +--- nfs-utils-1.0.10/utils/gssd/gssd_main_loop.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/gssd_main_loop.c 2006-10-13 16:03:33.000000000 -0600 +@@ -94,7 +94,7 @@ + }; + + void +-gssd_run() ++lgssd_run() { - gss_buffer_desc name; - gss_name_t target_name; - u_int32_t maj_stat, min_stat; - u_int32_t ignore_maj_stat, ignore_min_stat; -+ gss_OID name_type; - gss_buffer_desc pbuf; + int ret; + struct sigaction dn_act; +@@ -118,6 +118,7 @@ -+ *valid = 0; -+ - name.value = (void *)server_name; - name.length = strlen(server_name); + while (1) { + while (dir_changed) { ++ printerr(2, "pipefs root dir changed\n"); + dir_changed = 0; + if (update_client_list()) { + printerr(0, "ERROR: couldn't update " +--- nfs-utils-1.0.10/utils/gssd/svcgssd.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/svcgssd.c 2006-10-13 16:03:33.000000000 -0600 +@@ -43,7 +43,6 @@ + #include + #include + #include +-#include + #include + #include -@@ -201,12 +244,20 @@ +@@ -54,11 +53,33 @@ + #include + #include + #include +-#include "nfslib.h" ++#include + #include "svcgssd.h" + #include "gss_util.h" + #include "err_util.h" ++#include "lsupport.h" - if (maj_stat != GSS_S_COMPLETE) { - pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid); -- return (FALSE); -+ return -1; -+ } ++void ++closeall(int min) ++{ ++ DIR *dir = opendir("/proc/self/fd"); ++ if (dir != NULL) { ++ int dfd = dirfd(dir); ++ struct dirent *d; + -+ maj_stat = gss_display_name(&min_stat, target_name, &name, &name_type); -+ if (maj_stat != GSS_S_COMPLETE) { -+ pgsserr(0, maj_stat, min_stat, g_mechOid); -+ return -1; - } -+ if (extract_realm_name(&name, local_realm)) -+ return -1; ++ while ((d = readdir(dir)) != NULL) { ++ char *endp; ++ long n = strtol(d->d_name, &endp, 10); ++ if (*endp != '\0' && n >= min && n != dfd) ++ (void) close(n); ++ } ++ closedir(dir); ++ } else { ++ int fd = sysconf(_SC_OPEN_MAX); ++ while (--fd >= min) ++ (void) close(fd); ++ } ++} + /* + * mydaemon creates a pipe between the partent and child + * process. The parent process will wait until the +@@ -165,8 +186,8 @@ + int get_creds = 1; + int fg = 0; + int verbosity = 0; +- int rpc_verbosity = 0; + int opt; ++ int must_srv_mds = 0, must_srv_oss = 0; + extern char *optarg; + char *progname; - maj_stat = gss_acquire_cred(&min_stat, target_name, 0, - GSS_C_NULL_OID_SET, GSS_C_ACCEPT, -- &gssd_creds, NULL, NULL); -+ cred, NULL, NULL); +@@ -181,8 +202,13 @@ + case 'v': + verbosity++; + break; +- case 'r': +- rpc_verbosity++; ++ case 'm': ++ get_creds = 1; ++ must_srv_mds = 1; ++ break; ++ case 'o': ++ get_creds = 1; ++ must_srv_oss = 1; + break; + default: + usage(argv[0]); +@@ -196,27 +222,13 @@ + progname = argv[0]; - if (maj_stat != GSS_S_COMPLETE) { - pgsserr("gss_acquire_cred", maj_stat, min_stat, g_mechOid); -@@ -218,11 +269,65 @@ - ignore_maj_stat = gss_release_buffer(&ignore_min_stat, - &pbuf); - } -- } -+ } else -+ *valid = 1; + initerr(progname, verbosity, fg); +-#ifdef HAVE_AUTHGSS_SET_DEBUG_LEVEL +- authgss_set_debug_level(rpc_verbosity); +-#else +- if (rpc_verbosity > 0) +- printerr(0, "Warning: rpcsec_gss library does not " +- "support setting debug level\n"); +-#endif - ignore_maj_stat = gss_release_name(&ignore_min_stat, &target_name); + if (gssd_check_mechs() != 0) { + printerr(0, "ERROR: Problem with gssapi library\n"); + exit(1); + } + +- if (!fg) +- mydaemon(0, 0); +- +- signal(SIGINT, sig_die); +- signal(SIGTERM, sig_die); +- signal(SIGHUP, sig_hup); +- +- if (get_creds && !gssd_acquire_cred(GSSD_SERVICE_NAME)) { ++ if (get_creds && gssd_prepare_creds(must_srv_mds, must_srv_oss)) { + printerr(0, "unable to obtain root (machine) credentials\n"); + printerr(0, "do you have a keytab entry for " + "nfs/@ in " +@@ -225,9 +237,18 @@ + } -- return (maj_stat == GSS_S_COMPLETE); -+ if (maj_stat != GSS_S_COMPLETE) -+ return -1; -+ return 0; -+} -+ -+int gssd_prepare_creds(int must_srv_mds, int must_srv_oss) -+{ -+ if (gssd_acquire_cred(GSSD_SERVICE_MDS, &gssd_cred_mds, -+ &mds_local_realm, &gssd_cred_mds_valid)) { -+ if (must_srv_mds) -+ return -1; -+ } -+ -+ if (gssd_acquire_cred(GSSD_SERVICE_OSS, &gssd_cred_oss, -+ &oss_local_realm, &gssd_cred_oss_valid)) { -+ if (must_srv_oss) -+ return -1; -+ } -+ -+ if (!gssd_cred_mds_valid && !gssd_cred_oss_valid) { -+ printerr(0, "can't obtain both mds & oss creds, exit\n"); -+ return -1; -+ } -+ -+ printerr(0, "Ready to serve %s\n", -+ gssd_cred_mds_valid && !gssd_cred_oss_valid ? "Lustre MDS" : -+ (!gssd_cred_mds_valid && gssd_cred_oss_valid ? "Lustre OSS" : -+ "Lustre MDS and OSS")); + if (!fg) ++ mydaemon(0, 0); + -+ return 0; -+} ++ signal(SIGINT, sig_die); ++ signal(SIGTERM, sig_die); ++ signal(SIGHUP, sig_hup); + -+gss_cred_id_t gssd_select_svc_cred(int lustre_svc) -+{ -+ switch (lustre_svc) { -+ case LUSTRE_GSS_SVC_MDS: -+ if (!gssd_cred_mds_valid) { -+ printerr(0, "ERROR: service cred for mds not ready\n"); -+ return NULL; -+ } -+ printerr(2, "select mds service cred\n"); -+ return gssd_cred_mds; -+ case LUSTRE_GSS_SVC_OSS: -+ if (!gssd_cred_oss_valid) { -+ printerr(0, "ERROR: service cred for oss not ready\n"); -+ return NULL; -+ } -+ printerr(2, "select oss service cred\n"); -+ return gssd_cred_oss; -+ default: -+ printerr(0, "ERROR: invalid lustre svc id %d\n", lustre_svc); -+ } ++ if (!fg) + release_parent(); + +- gssd_run(); ++ gssd_init_unique(GSSD_SVC); + -+ return NULL; ++ svcgssd_run(); + printerr(0, "gssd_run returned!\n"); + abort(); } +--- nfs-utils-1.0.10/utils/gssd/svcgssd_proc.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/svcgssd_proc.c 2006-10-13 16:48:03.000000000 -0600 +@@ -35,7 +35,6 @@ - int gssd_check_mechs(void) ---- nfs-utils-1.0.10/utils/gssd/gss_util.h.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/gss_util.h 2006-08-14 10:32:30.000000000 -0600 -@@ -32,12 +32,10 @@ - #define _GSS_UTIL_H_ - - #include --#include - #include "write_bytes.h" - - extern gss_cred_id_t gssd_creds; - --int gssd_acquire_cred(char *server_name); - void pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat, - const gss_OID mech); - int gssd_check_mechs(void); ---- nfs-utils-1.0.10/utils/gssd/krb5_util.c.lustre 2006-08-14 10:32:04.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/krb5_util.c 2006-08-14 10:32:30.000000000 -0600 -@@ -99,12 +99,14 @@ - #include - #include + #include #include -+#include - #include - #include +-#include + #include #include - #include +@@ -44,25 +43,28 @@ #include -+#include - #include #include #include -@@ -114,7 +116,6 @@ - #include - #endif - #include --#include +-#include ++#include - #include "gssd.h" + #include "svcgssd.h" + #include "gss_util.h" #include "err_util.h" -@@ -129,6 +130,12 @@ - int num_krb5_enctypes = 0; - krb5_enctype *krb5_enctypes = NULL; + #include "context.h" + #include "cacheio.h" ++#include "lsupport.h" -+/* realm of this node */ -+char *this_realm = NULL; -+ -+/* credential expire time in advance */ -+unsigned long machine_cred_expire_advance = 300; /* 5 mins */ -+ - /*==========================*/ - /*=== Internal routines ===*/ - /*==========================*/ -@@ -137,11 +144,55 @@ - static int gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d); - static int gssd_get_single_krb5_cred(krb5_context context, - krb5_keytab kt, struct gssd_k5_kt_princ *ple); --static int gssd_have_realm_ple(void *realm); - static int gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, - char *kt_name); + extern char * mech2file(gss_OID mech); +-#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.rpcsec.context/channel" +-#define SVCGSSD_INIT_CHANNEL "/proc/net/rpc/auth.rpcsec.init/channel" ++#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.ptlrpcs.context/channel" ++#define SVCGSSD_INIT_CHANNEL "/proc/net/rpc/auth.ptlrpcs.init/channel" - /* -+ * convenient macros, these perhaps need further cleanup -+ */ -+#ifdef HAVE_KRB5 -+ -+#define KEYTAB_ENTRY_MATCH(kte, name) \ -+ ( \ -+ (kte).principal->data[0].length == (sizeof(name)-1) && \ -+ strncmp((kte).principal->data[0].data, (name), sizeof(name)-1) == 0 \ -+ ) -+#define KRB5_FREE_UNPARSED_NAME(ctx, name) \ -+ krb5_free_unparsed_name((ctx), (name)); -+#define KRB5_STRDUP(str) \ -+ strndup((str).data, (str).length) -+#define KRB5_STRCMP(str, name) \ -+ ( \ -+ (str)->length != strlen(name) || \ -+ strncmp((str)->data, (name), (str)->length) != 0 \ -+ ) -+#define KRB5_STRCASECMP(str, name) \ -+ ( \ -+ (str)->length != strlen(name) || \ -+ strncasecmp((str)->data, (name), (str)->length) != 0 \ -+ ) -+ -+#else /* !HAVE_KRB5 */ -+ -+#define KEYTAB_ENTRY_MATCH(kte, name) \ -+ ( \ -+ strlen((kte).principal->name.name_string.val[0]) == \ -+ (sizeof(name)-1) && \ -+ strncmp(kte.principal->name.name_string.val[0], (name), \ -+ sizeof(name)-1) == 0 \ -+ ) -+#define KRB5_FREE_UNPARSED_NAME(ctx, name) \ -+ free(pname); -+#define KRB5_STRDUP(str) \ -+ strdup(str) -+#define KRB5_STRCMP(str, name) \ -+ strcmp((str), (name)) -+#define KRB5_STRCASECMP(str, name) \ -+ strcmp((str), (name)) -+ -+#endif /* HAVE_KRB5 */ -+ -+/* - * Called from the scandir function to weed out potential krb5 - * credentials cache files - * -@@ -292,7 +343,7 @@ + #define TOKEN_BUF_SIZE 8192 - memset(&my_creds, 0, sizeof(my_creds)); + struct svc_cred { +- uid_t cr_uid; +- gid_t cr_gid; +- int cr_ngroups; +- gid_t cr_groups[NGROUPS]; ++ uint32_t cr_remote; ++ uint32_t cr_usr_root; ++ uint32_t cr_usr_mds; ++ uid_t cr_uid; ++ uid_t cr_mapped_uid; ++ uid_t cr_gid; + }; -- if (ple->ccname && ple->endtime > now) { -+ if (ple->ccname && ple->endtime > now + machine_cred_expire_advance) { - printerr(2, "INFO: Credentials in CC '%s' are good until %d\n", - ple->ccname, ple->endtime); - code = 0; -@@ -323,11 +374,7 @@ - "principal '%s' from keytab '%s'\n", - error_message(code), - pname ? pname : "", kt_name); --#ifdef HAVE_KRB5 -- if (pname) krb5_free_unparsed_name(context, pname); --#else -- if (pname) free(pname); --#endif -+ if (pname) KRB5_FREE_UNPARSED_NAME(context, pname); - goto out; - } + static int +@@ -70,10 +72,9 @@ + gss_OID mech, gss_buffer_desc *context_token) + { + FILE *f; +- int i; + char *fname = NULL; + +- printerr(1, "doing downcall\n"); ++ printerr(2, "doing downcall\n"); + if ((fname = mech2file(mech)) == NULL) + goto out_err; + f = fopen(SVCGSSD_CONTEXT_CHANNEL, "w"); +@@ -86,11 +87,12 @@ + qword_printhex(f, out_handle->value, out_handle->length); + /* XXX are types OK for the rest of this? */ + qword_printint(f, 0x7fffffff); /*XXX need a better timeout */ ++ qword_printint(f, cred->cr_remote); ++ qword_printint(f, cred->cr_usr_root); ++ qword_printint(f, cred->cr_usr_mds); ++ qword_printint(f, cred->cr_mapped_uid); + qword_printint(f, cred->cr_uid); + qword_printint(f, cred->cr_gid); +- qword_printint(f, cred->cr_ngroups); +- for (i=0; i < cred->cr_ngroups; i++) +- qword_printint(f, cred->cr_groups[i]); + qword_print(f, fname); + qword_printhex(f, context_token->value, context_token->length); + qword_eol(f); +@@ -119,7 +121,7 @@ + /* XXXARG: */ + int g; -@@ -371,15 +418,7 @@ - return (code); +- printerr(1, "sending null reply\n"); ++ printerr(2, "sending null reply\n"); + + qword_addhex(&bp, &blen, in_handle->value, in_handle->length); + qword_addhex(&bp, &blen, in_token->value, in_token->length); +@@ -159,6 +161,7 @@ + #define rpcsec_gsserr_credproblem 13 + #define rpcsec_gsserr_ctxproblem 14 + ++#if 0 + static void + add_supplementary_groups(char *secname, char *name, struct svc_cred *cred) + { +@@ -182,7 +185,9 @@ + } + } } ++#endif --/* -- * Determine if we already have a ple for the given realm -- * -- * Returns: -- * 0 => no ple found for given realm -- * 1 => found ple for given realm -- */ --static int --gssd_have_realm_ple(void *r) -+static struct gssd_k5_kt_princ * gssd_get_realm_ple(void *r) ++#if 0 + static int + get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred) { - struct gssd_k5_kt_princ *ple; - #ifdef HAVE_KRB5 -@@ -389,18 +428,76 @@ - #endif +@@ -248,7 +253,9 @@ + out: + return res; + } ++#endif - for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) { --#ifdef HAVE_KRB5 -- if ((realm->length == strlen(ple->realm)) && -- (strncmp(realm->data, ple->realm, realm->length) == 0)) { --#else -- if (strcmp(realm, ple->realm) == 0) { --#endif -- return 1; -- } -+ if (KRB5_STRCMP(realm, ple->realm) == 0) -+ return ple; -+ } -+ return NULL; -+} -+ -+static void gssd_free_ple(krb5_context kctx, struct gssd_k5_kt_princ *ple) -+{ -+ if (ple->princ) -+ krb5_free_principal(kctx, ple->princ); -+ if (ple->realm) -+ free(ple->realm); -+ if (ple->ccname) -+ free(ple->ccname); -+ free(ple); -+} -+ -+static int gssd_remove_ple(krb5_context kctx, struct gssd_k5_kt_princ *ple) -+{ -+ struct gssd_k5_kt_princ **prev = &gssd_k5_kt_princ_list; -+ struct gssd_k5_kt_princ *ent = gssd_k5_kt_princ_list; -+ -+ for (; ent; prev = &ent->next, ent = ent->next) { -+ if (ent != ple) -+ continue; -+ -+ *prev = ent->next; -+ gssd_free_ple(kctx, ent); -+ return 1; ++#if 0 + void + print_hexl(int pri, unsigned char *cp, int length) + { +@@ -285,12 +292,110 @@ + printerr(pri,"\n"); } - return 0; } - -+static -+struct gssd_k5_kt_princ *gssd_create_ple(krb5_context kctx, -+ krb5_principal principal) -+{ -+ struct gssd_k5_kt_princ *ple; -+ krb5_error_code code; ++#endif + -+ ple = malloc(sizeof(*ple)); -+ if (ple == NULL) { -+ printerr(0, "ERROR: could not allocate storage " -+ "for principal list entry\n"); -+ return NULL; -+ } ++static int ++get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred, ++ lnet_nid_t nid) ++{ ++ u_int32_t maj_stat, min_stat; ++ gss_buffer_desc name; ++ char *sname, *realm, *slash; ++ int res = -1; ++ gss_OID name_type = GSS_C_NO_OID; ++ struct passwd *pw; + -+ memset(ple, 0, sizeof(*ple)); ++ memset(cred, 0, sizeof(*cred)); + -+ ple->realm = KRB5_STRDUP(principal->realm); -+ if (ple->realm == NULL) { -+ printerr(0, "ERROR: not enough memory while copying realm to " -+ "principal list entry\n"); -+ goto err_free; ++ maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type); ++ if (maj_stat != GSS_S_COMPLETE) { ++ pgsserr("get_ids: gss_display_name", ++ maj_stat, min_stat, mech); ++ return -1; + } -+ -+ code = krb5_copy_principal(kctx, principal, &ple->princ); -+ if (code) { -+ printerr(0, "ERROR: %s while copying principal " -+ "to principal list entry\n", -+ error_message(code)); -+ goto err_free; ++ if (name.length >= 0xffff || /* be certain name.length+1 doesn't overflow */ ++ !(sname = calloc(name.length + 1, 1))) { ++ printerr(0, "WARNING: get_ids: error allocating %d bytes " ++ "for sname\n", name.length + 1); ++ gss_release_buffer(&min_stat, &name); ++ return -1; + } ++ memcpy(sname, name.value, name.length); ++ printerr(1, "authenticate user %s\n", sname); ++ gss_release_buffer(&min_stat, &name); + -+ return ple; -+err_free: -+ gssd_free_ple(kctx, ple); -+ return NULL; -+} -+ - /* - * Process the given keytab file and create a list of principals we - * might use to perform mount operations. -@@ -444,82 +541,106 @@ - } - printerr(2, "Processing keytab entry for principal '%s'\n", - pname); --#ifdef HAVE_KRB5 -- if ( (kte.principal->data[0].length == GSSD_SERVICE_NAME_LEN) && -- (strncmp(kte.principal->data[0].data, GSSD_SERVICE_NAME, -- GSSD_SERVICE_NAME_LEN) == 0) && --#else -- if ( (strlen(kte.principal->name.name_string.val[0]) == GSSD_SERVICE_NAME_LEN) && -- (strncmp(kte.principal->name.name_string.val[0], GSSD_SERVICE_NAME, -- GSSD_SERVICE_NAME_LEN) == 0) && -- --#endif -- (!gssd_have_realm_ple((void *)&kte.principal->realm)) ) { -- printerr(2, "We will use this entry (%s)\n", pname); -- ple = malloc(sizeof(struct gssd_k5_kt_princ)); -- if (ple == NULL) { -- printerr(0, "ERROR: could not allocate storage " -- "for principal list entry\n"); --#ifdef HAVE_KRB5 -- krb5_free_unparsed_name(context, pname); --#else -- free(pname); --#endif -- retval = ENOMEM; -- goto out; -+ -+ /* mds service entry: -+ * - hostname and realm should match this node -+ * - replace existing non-mds entry of this realm -+ */ -+ if (KEYTAB_ENTRY_MATCH(kte, GSSD_SERVICE_MDS)) { -+ krb5_principal princ = kte.principal; -+ krb5_data *princ_host; -+ struct utsname utsbuf; -+ struct hostent *host; -+ -+ if (KRB5_STRCASECMP(krb5_princ_realm(context, princ), -+ this_realm) != 0) { -+ printerr(2, "alien mds service entry, skip\n"); -+ goto next; - } -- /* These will be filled in later */ -- ple->next = NULL; -- ple->ccname = NULL; -- ple->endtime = 0; -- if ((ple->realm = --#ifdef HAVE_KRB5 -- strndup(kte.principal->realm.data, -- kte.principal->realm.length)) --#else -- strdup(kte.principal->realm)) --#endif -- == NULL) { -- printerr(0, "ERROR: %s while copying realm to " -- "principal list entry\n", -- "not enough memory"); --#ifdef HAVE_KRB5 -- krb5_free_unparsed_name(context, pname); --#else -- free(pname); --#endif -- retval = ENOMEM; -- goto out; -+ -+ princ_host = krb5_princ_component(context, princ, 1); -+ if (princ_host == NULL) { -+ printerr(2, "mds service entry: no hostname in " -+ "principal, skip\n"); -+ goto next; - } -- if ((code = krb5_copy_principal(context, -- kte.principal, &ple->princ))) { -- printerr(0, "ERROR: %s while copying principal " -- "to principal list entry\n", -- error_message(code)); --#ifdef HAVE_KRB5 -- krb5_free_unparsed_name(context, pname); --#else -- free(pname); --#endif -- retval = code; -- goto out; -+ -+ if (uname(&utsbuf)) { -+ printerr(2, "mds service entry: unable to get " -+ "UTS name, skip\n"); -+ goto next; - } -- if (gssd_k5_kt_princ_list == NULL) -- gssd_k5_kt_princ_list = ple; -- else { -- ple->next = gssd_k5_kt_princ_list; -- gssd_k5_kt_princ_list = ple; -+ host = gethostbyname(utsbuf.nodename); -+ if (host == NULL) { -+ printerr(2, "mds service entry: unable to get " -+ "local hostname, skip\n"); -+ goto next; - } -- } -- else { -+ -+ if (KRB5_STRCASECMP(princ_host, host->h_name) != 0) { -+ printerr(2, "mds service entry: hostname " -+ "doesn't match: %s - %.*s, skip\n", -+ host->h_name, -+ princ_host->length, princ_host->data); -+ goto next; -+ } ++ lookup_mapping(sname, nid, &cred->cr_mapped_uid); + -+ ple = gssd_get_realm_ple((void *)&kte.principal->realm); -+ if (ple) { -+ if (ple->fl_mds) { -+ printerr(2,"mds service entry: found a" -+ "duplicated one, it's like a " -+ "mis-configuration, skip\n"); -+ goto next; -+ } ++ realm = strchr(sname, '@'); ++ if (!realm) { ++ printerr(0, "WARNNING: principal %s contains no realm name\n", ++ sname); ++ cred->cr_remote = (mds_local_realm != NULL); ++ } else { ++ *realm++ = '\0'; ++ if (!mds_local_realm) ++ cred->cr_remote = 1; ++ else ++ cred->cr_remote = ++ (strcasecmp(mds_local_realm, realm) != 0); ++ } + -+ gssd_remove_ple(context, ple); -+ printerr(2, "mds service entry: replace an " -+ "existed non-mds one\n"); -+ } -+ } else if (KEYTAB_ENTRY_MATCH(kte, LUSTRE_ROOT_NAME)) { -+ ple = gssd_get_realm_ple((void *)&kte.principal->realm); -+ if (ple) { -+ if (ple->fl_mds || ple->fl_root) { -+ printerr(2, "root entry: found a " -+ "existed %s entry, skip\n", -+ ple->fl_mds ? "mds" : "root"); -+ goto next; -+ } ++ if (cred->cr_remote) { ++ if (cred->cr_mapped_uid != -1) ++ res = 0; ++ else ++ printerr(0, "principal %s is remote without mapping\n", ++ sname); ++ goto out_free; ++ } + -+ gssd_remove_ple(context, ple); -+ printerr(2, "root entry: replace an existed " -+ "non-mds non-root one\n"); -+ } -+ } else { - printerr(2, "We will NOT use this entry (%s)\n", - pname); -+ goto next; - } --#ifdef HAVE_KRB5 -- krb5_free_unparsed_name(context, pname); --#else -- free(pname); --#endif ++ slash = strchr(sname, '/'); ++ if (slash) ++ *slash = '\0'; + -+ /* construct ple */ -+ printerr(2, "We will use this entry (%s)\n", pname); -+ ple = gssd_create_ple(context, kte.principal); -+ if (ple == NULL) { -+ KRB5_FREE_UNPARSED_NAME(context, pname); -+ goto out; -+ } ++ if (!(pw = getpwnam(sname))) { ++ /* If client use machine credential, we map it to root, which ++ * will subject to further mapping by root-squash in kernel. ++ * ++ * MDS service keytab is treated as special user, also mapped ++ * to root. OSS service keytab can't be used as a user. ++ */ ++ if (!strcmp(sname, LUSTRE_ROOT_NAME)) { ++ printerr(2, "lustre_root principal, resolve to uid 0\n"); ++ cred->cr_uid = 0; ++ cred->cr_usr_root = 1; ++ } else if (!strcmp(sname, GSSD_SERVICE_MDS)) { ++ printerr(2, "mds service principal, resolve to uid 0\n"); ++ cred->cr_uid = 0; ++ cred->cr_usr_mds = 1; ++ } else { ++ cred->cr_uid = -1; ++ if (cred->cr_mapped_uid == -1) { ++ printerr(0, "invalid user %s\n", sname); ++ goto out_free; ++ } ++ printerr(2, "user %s mapped to %u\n", ++ sname, cred->cr_mapped_uid); ++ } ++ } else { ++ cred->cr_uid = pw->pw_uid; ++ printerr(2, "%s resolve to uid %u\n", sname, cred->cr_uid); ++ } + -+ /* add proper flags */ -+ if (KEYTAB_ENTRY_MATCH(kte, GSSD_SERVICE_MDS)) -+ ple->fl_mds = 1; -+ else if (KEYTAB_ENTRY_MATCH(kte, LUSTRE_ROOT_NAME)) -+ ple->fl_root = 1; ++ res = 0; ++out_free: ++ free(sname); ++ return res; ++} + -+ /* enqueue */ -+ if (gssd_k5_kt_princ_list == NULL) -+ gssd_k5_kt_princ_list = ple; -+ else { -+ ple->next = gssd_k5_kt_princ_list; -+ gssd_k5_kt_princ_list = ple; -+ } -+ next: -+ KRB5_FREE_UNPARSED_NAME(context, pname); - } ++typedef struct gss_union_ctx_id_t { ++ gss_OID mech_type; ++ gss_ctx_id_t internal_ctx_id; ++} gss_union_ctx_id_desc, *gss_union_ctx_id_t; - if ((code = krb5_kt_end_seq_get(context, kt, &cursor))) { -@@ -695,7 +816,18 @@ - goto out; + void + handle_nullreq(FILE *f) { +- /* XXX initialize to a random integer to reduce chances of unnecessary +- * invalidation of existing ctx's on restarting svcgssd. */ +- static u_int32_t handle_seq = 0; ++ uint64_t handle_seq; + char in_tok_buf[TOKEN_BUF_SIZE]; + char in_handle_buf[15]; + char out_handle_buf[15]; +@@ -302,10 +407,13 @@ + ignore_out_tok = {.value = NULL}, + /* XXX isn't there a define for this?: */ + null_token = {.value = NULL}; ++ uint32_t lustre_svc; ++ lnet_nid_t nid; + u_int32_t ret_flags; + gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; + gss_name_t client_name; + gss_OID mech = GSS_C_NO_OID; ++ gss_cred_id_t svc_cred; + u_int32_t maj_stat = GSS_S_FAILURE, min_stat = 0; + u_int32_t ignore_min_stat; + struct svc_cred cred; +@@ -313,7 +421,7 @@ + static int lbuflen = 0; + static char *cp; + +- printerr(1, "handling null request\n"); ++ printerr(2, "handling null request\n"); + + if (readline(fileno(f), &lbuf, &lbuflen) != 1) { + printerr(0, "WARNING: handle_nullreq: " +@@ -323,15 +431,21 @@ + + cp = lbuf; + ++ qword_get(&cp, (char *) &lustre_svc, sizeof(lustre_svc)); ++ qword_get(&cp, (char *) &nid, sizeof(nid)); ++ qword_get(&cp, (char *) &handle_seq, sizeof(handle_seq)); ++ printerr(1, "handling req: svc %u, nid %016llx, idx %llx\n", ++ lustre_svc, nid, handle_seq); ++ + in_handle.length = (size_t) qword_get(&cp, in_handle.value, + sizeof(in_handle_buf)); +- printerr(2, "in_handle: \n"); +- print_hexl(2, in_handle.value, in_handle.length); ++ printerr(3, "in_handle: \n"); ++ print_hexl(3, in_handle.value, in_handle.length); + + in_tok.length = (size_t) qword_get(&cp, in_tok.value, + sizeof(in_tok_buf)); +- printerr(2, "in_tok: \n"); +- print_hexl(2, in_tok.value, in_tok.length); ++ printerr(3, "in_tok: \n"); ++ print_hexl(3, in_tok.value, in_tok.length); + + if (in_tok.length < 0) { + printerr(0, "WARNING: handle_nullreq: " +@@ -351,7 +465,13 @@ + memcpy(&ctx, in_handle.value, in_handle.length); } -- printerr(1, "Using keytab file '%s'\n", keytabfile); -+ if (this_realm == NULL) { -+ code = krb5_get_default_realm(context, &this_realm); -+ if (code) { -+ printerr(0, "ERROR: get default realm: %s\n", -+ error_message(code)); -+ retval = code; -+ goto out; -+ } -+ printerr(1, "Local realm: %s\n", this_realm); +- maj_stat = gss_accept_sec_context(&min_stat, &ctx, gssd_creds, ++ svc_cred = gssd_select_svc_cred(lustre_svc); ++ if (!svc_cred) { ++ printerr(0, "no service credential for svc %u\n", lustre_svc); ++ goto out_err; + } + -+ printerr(2, "Using keytab file '%s'\n", keytabfile); ++ maj_stat = gss_accept_sec_context(&min_stat, &ctx, svc_cred, + &in_tok, GSS_C_NO_CHANNEL_BINDINGS, &client_name, + &mech, &out_tok, &ret_flags, NULL, NULL); - if ((code = krb5_kt_resolve(context, keytabfile, &kt))) { - printerr(0, "ERROR: %s while resolving keytab '%s'\n", -@@ -710,12 +842,12 @@ - if (gssd_k5_kt_princ_list == NULL) { - printerr(0, "ERROR: No usable keytab entries found in " - "keytab '%s'\n", keytabfile); -- printerr(0, "Do you have a valid keytab entry for " -- "%s/@ in " -+ printerr(0, "You must have a valid keytab entry for " -+ "%s/@ on MDT nodes, " -+ "and %s@ on client nodes, in " - "keytab file %s ?\n", -- GSSD_SERVICE_NAME, keytabfile); -- printerr(0, "Continuing without (machine) credentials " -- "- nfs4 mounts with Kerberos will fail\n"); -+ GSSD_SERVICE_MDS, LUSTRE_ROOT_NAME, -+ keytabfile); - } +@@ -369,7 +489,7 @@ + maj_stat, min_stat, mech); + goto out_err; + } +- if (get_ids(client_name, mech, &cred)) { ++ if (get_ids(client_name, mech, &cred, nid)) { + /* get_ids() prints error msg */ + maj_stat = GSS_S_BAD_NAME; /* XXX ? */ + gss_release_name(&ignore_min_stat, &client_name); +@@ -377,10 +497,8 @@ } + gss_release_name(&ignore_min_stat, &client_name); -@@ -865,6 +997,7 @@ - krb5_free_context(context); - } +- + /* Context complete. Pass handle_seq in out_handle to use + * for context lookup in the kernel. */ +- handle_seq++; + out_handle.length = sizeof(handle_seq); + memcpy(out_handle.value, &handle_seq, sizeof(handle_seq)); -+#if 0 - #ifdef HAVE_SET_ALLOWABLE_ENCTYPES - /* - * this routine obtains a credentials handle via gss_acquire_cred() -@@ -920,6 +1053,7 @@ - return 0; - } - #endif /* HAVE_SET_ALLOWABLE_ENCTYPES */ -+#endif +@@ -404,7 +522,6 @@ + free(ctx_token.value); + if (out_tok.value != NULL) + gss_release_buffer(&ignore_min_stat, &out_tok); +- printerr(1, "finished handling null request\n"); + return; + + out_err: +--- nfs-utils-1.0.10/utils/gssd/gss_util.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/gss_util.c 2006-10-13 16:03:33.000000000 -0600 +@@ -87,9 +87,16 @@ + #ifdef HAVE_COM_ERR_H + #include + #endif ++#include "lsupport.h" + + /* Global gssd_credentials handle */ +-gss_cred_id_t gssd_creds; ++gss_cred_id_t gssd_cred_mds; ++gss_cred_id_t gssd_cred_oss; ++int gssd_cred_mds_valid = 0; ++int gssd_cred_oss_valid = 0; ++ ++char *mds_local_realm = NULL; ++char *oss_local_realm = NULL; - /* - * Obtain supported enctypes from kernel. ---- nfs-utils-1.0.10/utils/gssd/krb5_util.h.lustre 2006-08-14 10:32:04.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/krb5_util.h 2006-08-14 10:32:30.000000000 -0600 -@@ -10,6 +10,8 @@ - struct gssd_k5_kt_princ { - struct gssd_k5_kt_princ *next; - krb5_principal princ; -+ unsigned int fl_root:1, -+ fl_mds:1; - char *ccname; - char *realm; - krb5_timestamp endtime; -@@ -25,8 +27,32 @@ - void gssd_obtain_kernel_krb5_info(void); + gss_OID g_mechOid = GSS_C_NULL_OID;; +@@ -183,15 +190,51 @@ + display_status_2(msg, maj_stat, min_stat, mech); + } --#ifdef HAVE_SET_ALLOWABLE_ENCTYPES --int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid); --#endif -+#endif /* KRB5_UTIL_H */ -+#ifndef KRB5_UTIL_H -+#define KRB5_UTIL_H +-int +-gssd_acquire_cred(char *server_name) ++static ++int extract_realm_name(gss_buffer_desc *name, char **realm) ++{ ++ char *sname, *c; + -+#include ++ sname = malloc(name->length + 1); ++ if (!sname) { ++ printerr(0, "out of memory\n"); ++ return -ENOMEM; ++ } + -+/* -+ * List of principals from our keytab that we -+ * may try to get credentials for -+ */ -+struct gssd_k5_kt_princ { -+ struct gssd_k5_kt_princ *next; -+ krb5_principal princ; -+ char *ccname; -+ char *realm; -+ krb5_timestamp endtime; -+}; ++ memcpy(sname, name->value, name->length); ++ sname[name->length] = '\0'; ++ printerr(1, "service principal: %s\n", sname); + ++ c = strchr(sname, '@'); ++ if (!realm) ++ *realm = NULL; ++ else { ++ c++; ++ *realm = malloc(strlen(c) + 1); ++ if (!*realm) { ++ printerr(0, "out of memory\n"); ++ return -ENOMEM; ++ } ++ strcpy(*realm, c); ++ } ++ free(sname); + -+void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername); -+int gssd_get_krb5_machine_cred_list(char ***list); -+int gssd_refresh_krb5_machine_creds(void); -+void gssd_free_krb5_machine_cred_list(char **list); -+void gssd_setup_krb5_machine_gss_ccache(char *servername); -+void gssd_destroy_krb5_machine_creds(void); -+void gssd_obtain_kernel_krb5_info(void); ++ return 0; ++} + ++static ++int gssd_acquire_cred(char *server_name, gss_cred_id_t *cred, ++ char **local_realm, int *valid) + { + gss_buffer_desc name; + gss_name_t target_name; + u_int32_t maj_stat, min_stat; + u_int32_t ignore_maj_stat, ignore_min_stat; ++ gss_OID name_type; + gss_buffer_desc pbuf; - #endif /* KRB5_UTIL_H */ ---- nfs-utils-1.0.10/utils/gssd/Makefile.am.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/Makefile.am 2006-08-14 10:32:30.000000000 -0600 -@@ -1,17 +1,11 @@ - ## Process this file with automake to produce Makefile.in ++ *valid = 0; ++ + name.value = (void *)server_name; + name.length = strlen(server_name); --man8_MANS = gssd.man svcgssd.man -- --RPCPREFIX = rpc. -+RPCPREFIX = - KPREFIX = @kprefix@ --sbin_PREFIXED = gssd svcgssd --sbin_PROGRAMS = $(sbin_PREFIXED) gss_clnt_send_err -+sbin_PREFIXED = lgssd lsvcgssd -+sbin_PROGRAMS = $(sbin_PREFIXED) - sbin_SCRIPTS = gss_destroy_creds +@@ -201,12 +244,20 @@ --EXTRA_DIST = \ -- gss_destroy_creds \ -- $(man8_MANS) -- - COMMON_SRCS = \ - context.c \ - context_mit.c \ -@@ -20,13 +14,15 @@ - gss_util.c \ - gss_oids.c \ - err_util.c \ -+ lsupport.c \ - \ - context.h \ - err_util.h \ - gss_oids.h \ -- gss_util.h -+ gss_util.h \ -+ lsupport.h + if (maj_stat != GSS_S_COMPLETE) { + pgsserr("gss_import_name", maj_stat, min_stat, g_mechOid); +- return (FALSE); ++ return -1; ++ } ++ ++ maj_stat = gss_display_name(&min_stat, target_name, &name, &name_type); ++ if (maj_stat != GSS_S_COMPLETE) { ++ pgsserr(0, maj_stat, min_stat, g_mechOid); ++ return -1; + } ++ if (extract_realm_name(&name, local_realm)) ++ return -1; --gssd_SOURCES = \ -+lgssd_SOURCES = \ - $(COMMON_SRCS) \ - gssd.c \ - gssd_main_loop.c \ -@@ -37,13 +33,12 @@ - krb5_util.h \ - write_bytes.h + maj_stat = gss_acquire_cred(&min_stat, target_name, 0, + GSS_C_NULL_OID_SET, GSS_C_ACCEPT, +- &gssd_creds, NULL, NULL); ++ cred, NULL, NULL); --gssd_LDADD = $(RPCSECGSS_LIBS) $(KRBLIBS) --gssd_LDFLAGS = $(KRBLDFLAGS) -+lgssd_LDADD = $(GSSAPI_LIBS) $(KRBLIBS) -+lgssd_LDFLAGS = $(KRBLDFLAGS) + if (maj_stat != GSS_S_COMPLETE) { + pgsserr("gss_acquire_cred", maj_stat, min_stat, g_mechOid); +@@ -218,11 +269,65 @@ + ignore_maj_stat = gss_release_buffer(&ignore_min_stat, + &pbuf); + } +- } ++ } else ++ *valid = 1; --gssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \ -- $(RPCSECGSS_CFLAGS) $(KRBCFLAGS) -+lgssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(GSSAPI_CFLAGS) $(KRBCFLAGS) + ignore_maj_stat = gss_release_name(&ignore_min_stat, &target_name); --svcgssd_SOURCES = \ -+lsvcgssd_SOURCES = \ - $(COMMON_SRCS) \ - cacheio.c \ - svcgssd.c \ -@@ -54,20 +49,11 @@ - cacheio.h \ - svcgssd.h +- return (maj_stat == GSS_S_COMPLETE); ++ if (maj_stat != GSS_S_COMPLETE) ++ return -1; ++ return 0; ++} ++ ++int gssd_prepare_creds(int must_srv_mds, int must_srv_oss) ++{ ++ if (gssd_acquire_cred(GSSD_SERVICE_MDS, &gssd_cred_mds, ++ &mds_local_realm, &gssd_cred_mds_valid)) { ++ if (must_srv_mds) ++ return -1; ++ } ++ ++ if (gssd_acquire_cred(GSSD_SERVICE_OSS, &gssd_cred_oss, ++ &oss_local_realm, &gssd_cred_oss_valid)) { ++ if (must_srv_oss) ++ return -1; ++ } ++ ++ if (!gssd_cred_mds_valid && !gssd_cred_oss_valid) { ++ printerr(0, "can't obtain both mds & oss creds, exit\n"); ++ return -1; ++ } ++ ++ printerr(0, "Ready to serve %s\n", ++ gssd_cred_mds_valid && !gssd_cred_oss_valid ? "Lustre MDS" : ++ (!gssd_cred_mds_valid && gssd_cred_oss_valid ? "Lustre OSS" : ++ "Lustre MDS and OSS")); ++ ++ return 0; ++} ++ ++gss_cred_id_t gssd_select_svc_cred(int lustre_svc) ++{ ++ switch (lustre_svc) { ++ case LUSTRE_GSS_SVC_MDS: ++ if (!gssd_cred_mds_valid) { ++ printerr(0, "ERROR: service cred for mds not ready\n"); ++ return NULL; ++ } ++ printerr(2, "select mds service cred\n"); ++ return gssd_cred_mds; ++ case LUSTRE_GSS_SVC_OSS: ++ if (!gssd_cred_oss_valid) { ++ printerr(0, "ERROR: service cred for oss not ready\n"); ++ return NULL; ++ } ++ printerr(2, "select oss service cred\n"); ++ return gssd_cred_oss; ++ default: ++ printerr(0, "ERROR: invalid lustre svc id %d\n", lustre_svc); ++ } ++ ++ return NULL; + } --svcgssd_LDADD = \ -- ../../support/nfs/libnfs.a \ -- $(RPCSECGSS_LIBS) -lnfsidmap \ -- $(KRBLIBS) -- --svcgssd_LDFLAGS = $(KRBLDFLAGS) -- --svcgssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \ -- $(RPCSECGSS_CFLAGS) $(KRBCFLAGS) -+lsvcgssd_LDADD = $(GSSAPI_LIBS) $(KRBLIBS) + int gssd_check_mechs(void) +--- nfs-utils-1.0.10/utils/gssd/gss_util.h.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/gss_util.h 2006-10-13 16:03:33.000000000 -0600 +@@ -32,12 +32,10 @@ + #define _GSS_UTIL_H_ --gss_clnt_send_err_SOURCES = gss_clnt_send_err.c -+lsvcgssd_LDFLAGS = $(KRBLDFLAGS) + #include +-#include + #include "write_bytes.h" --gss_clnt_send_err_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \ -- $(RPCSECGSS_CFLAGS) $(KRBCFLAGS) -+lsvcgssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(GSSAPI_CFLAGS) $(KRBCFLAGS) + extern gss_cred_id_t gssd_creds; - MAINTAINERCLEANFILES = Makefile.in +-int gssd_acquire_cred(char *server_name); + void pgsserr(char *msg, u_int32_t maj_stat, u_int32_t min_stat, + const gss_OID mech); + int gssd_check_mechs(void); +--- nfs-utils-1.0.10/utils/gssd/krb5_util.h.lustre 2006-10-13 16:02:38.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/krb5_util.h 2006-10-13 16:03:33.000000000 -0600 +@@ -10,6 +10,8 @@ + struct gssd_k5_kt_princ { + struct gssd_k5_kt_princ *next; + krb5_principal princ; ++ unsigned int fl_root:1, ++ fl_mds:1; + char *ccname; + char *realm; + krb5_timestamp endtime; +@@ -25,8 +27,32 @@ + void gssd_obtain_kernel_krb5_info(void); -@@ -91,23 +77,3 @@ - done) +-#ifdef HAVE_SET_ALLOWABLE_ENCTYPES +-int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid); +-#endif ++#endif /* KRB5_UTIL_H */ ++#ifndef KRB5_UTIL_H ++#define KRB5_UTIL_H ++ ++#include ++ ++/* ++ * List of principals from our keytab that we ++ * may try to get credentials for ++ */ ++struct gssd_k5_kt_princ { ++ struct gssd_k5_kt_princ *next; ++ krb5_principal princ; ++ char *ccname; ++ char *realm; ++ krb5_timestamp endtime; ++}; ++ ++ ++void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername); ++int gssd_get_krb5_machine_cred_list(char ***list); ++int gssd_refresh_krb5_machine_creds(void); ++void gssd_free_krb5_machine_cred_list(char **list); ++void gssd_setup_krb5_machine_gss_ccache(char *servername); ++void gssd_destroy_krb5_machine_creds(void); ++void gssd_obtain_kernel_krb5_info(void); ++ --# XXX This makes some assumptions about what automake does. --# XXX But there is no install-man-hook or install-man-local. --install-man: install-man8 install-man-links --uninstall-man: uninstall-man8 uninstall-man-links -- --install-man-links: -- (cd $(DESTDIR)$(man8dir) && \ -- for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \ -- inst=`echo $$m | sed -e 's/man$$/8/'`; \ -- rm -f $(RPCPREFIX)$$inst ; \ -- $(LN_S) $$inst $(RPCPREFIX)$$inst ; \ -- done) -- --uninstall-man-links: -- (cd $(DESTDIR)$(man8dir) && \ -- for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \ -- inst=`echo $$m | sed -e 's/man$$/8/'`; \ -- rm -f $(RPCPREFIX)$$inst ; \ -- done) -- ---- nfs-utils-1.0.10/utils/gssd/svcgssd.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/svcgssd.c 2006-08-14 10:32:45.000000000 -0600 -@@ -43,7 +43,6 @@ + #endif /* KRB5_UTIL_H */ +--- nfs-utils-1.0.10/utils/gssd/krb5_util.c.lustre 2006-10-13 16:02:38.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/krb5_util.c 2006-10-13 16:03:33.000000000 -0600 +@@ -99,12 +99,14 @@ + #include #include #include ++#include #include --#include - #include - #include + #include -@@ -54,11 +53,33 @@ + #include #include #include - #include --#include "nfslib.h" -+#include - #include "svcgssd.h" - #include "gss_util.h" ++#include + #include + #include + #include +@@ -114,7 +116,6 @@ + #include + #endif + #include +-#include + + #include "gssd.h" #include "err_util.h" -+#include "lsupport.h" +@@ -129,6 +130,12 @@ + int num_krb5_enctypes = 0; + krb5_enctype *krb5_enctypes = NULL; -+void -+closeall(int min) ++/* realm of this node */ ++char *this_realm = NULL; ++ ++/* credential expire time in advance */ ++unsigned long machine_cred_expire_advance = 300; /* 5 mins */ ++ + /*==========================*/ + /*=== Internal routines ===*/ + /*==========================*/ +@@ -137,11 +144,55 @@ + static int gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d); + static int gssd_get_single_krb5_cred(krb5_context context, + krb5_keytab kt, struct gssd_k5_kt_princ *ple); +-static int gssd_have_realm_ple(void *realm); + static int gssd_process_krb5_keytab(krb5_context context, krb5_keytab kt, + char *kt_name); + + /* ++ * convenient macros, these perhaps need further cleanup ++ */ ++#ifdef HAVE_KRB5 ++ ++#define KEYTAB_ENTRY_MATCH(kte, name) \ ++ ( \ ++ (kte).principal->data[0].length == (sizeof(name)-1) && \ ++ strncmp((kte).principal->data[0].data, (name), sizeof(name)-1) == 0 \ ++ ) ++#define KRB5_FREE_UNPARSED_NAME(ctx, name) \ ++ krb5_free_unparsed_name((ctx), (name)); ++#define KRB5_STRDUP(str) \ ++ strndup((str).data, (str).length) ++#define KRB5_STRCMP(str, name) \ ++ ( \ ++ (str)->length != strlen(name) || \ ++ strncmp((str)->data, (name), (str)->length) != 0 \ ++ ) ++#define KRB5_STRCASECMP(str, name) \ ++ ( \ ++ (str)->length != strlen(name) || \ ++ strncasecmp((str)->data, (name), (str)->length) != 0 \ ++ ) ++ ++#else /* !HAVE_KRB5 */ ++ ++#define KEYTAB_ENTRY_MATCH(kte, name) \ ++ ( \ ++ strlen((kte).principal->name.name_string.val[0]) == \ ++ (sizeof(name)-1) && \ ++ strncmp(kte.principal->name.name_string.val[0], (name), \ ++ sizeof(name)-1) == 0 \ ++ ) ++#define KRB5_FREE_UNPARSED_NAME(ctx, name) \ ++ free(pname); ++#define KRB5_STRDUP(str) \ ++ strdup(str) ++#define KRB5_STRCMP(str, name) \ ++ strcmp((str), (name)) ++#define KRB5_STRCASECMP(str, name) \ ++ strcmp((str), (name)) ++ ++#endif /* HAVE_KRB5 */ ++ ++/* + * Called from the scandir function to weed out potential krb5 + * credentials cache files + * +@@ -292,7 +343,7 @@ + + memset(&my_creds, 0, sizeof(my_creds)); + +- if (ple->ccname && ple->endtime > now) { ++ if (ple->ccname && ple->endtime > now + machine_cred_expire_advance) { + printerr(2, "INFO: Credentials in CC '%s' are good until %d\n", + ple->ccname, ple->endtime); + code = 0; +@@ -323,11 +374,7 @@ + "principal '%s' from keytab '%s'\n", + error_message(code), + pname ? pname : "", kt_name); +-#ifdef HAVE_KRB5 +- if (pname) krb5_free_unparsed_name(context, pname); +-#else +- if (pname) free(pname); +-#endif ++ if (pname) KRB5_FREE_UNPARSED_NAME(context, pname); + goto out; + } + +@@ -371,15 +418,7 @@ + return (code); + } + +-/* +- * Determine if we already have a ple for the given realm +- * +- * Returns: +- * 0 => no ple found for given realm +- * 1 => found ple for given realm +- */ +-static int +-gssd_have_realm_ple(void *r) ++static struct gssd_k5_kt_princ * gssd_get_realm_ple(void *r) + { + struct gssd_k5_kt_princ *ple; + #ifdef HAVE_KRB5 +@@ -389,18 +428,76 @@ + #endif + + for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) { +-#ifdef HAVE_KRB5 +- if ((realm->length == strlen(ple->realm)) && +- (strncmp(realm->data, ple->realm, realm->length) == 0)) { +-#else +- if (strcmp(realm, ple->realm) == 0) { +-#endif +- return 1; +- } ++ if (KRB5_STRCMP(realm, ple->realm) == 0) ++ return ple; ++ } ++ return NULL; ++} ++ ++static void gssd_free_ple(krb5_context kctx, struct gssd_k5_kt_princ *ple) +{ -+ DIR *dir = opendir("/proc/self/fd"); -+ if (dir != NULL) { -+ int dfd = dirfd(dir); -+ struct dirent *d; ++ if (ple->princ) ++ krb5_free_principal(kctx, ple->princ); ++ if (ple->realm) ++ free(ple->realm); ++ if (ple->ccname) ++ free(ple->ccname); ++ free(ple); ++} ++ ++static int gssd_remove_ple(krb5_context kctx, struct gssd_k5_kt_princ *ple) ++{ ++ struct gssd_k5_kt_princ **prev = &gssd_k5_kt_princ_list; ++ struct gssd_k5_kt_princ *ent = gssd_k5_kt_princ_list; ++ ++ for (; ent; prev = &ent->next, ent = ent->next) { ++ if (ent != ple) ++ continue; ++ ++ *prev = ent->next; ++ gssd_free_ple(kctx, ent); ++ return 1; + } + return 0; + } + ++static ++struct gssd_k5_kt_princ *gssd_create_ple(krb5_context kctx, ++ krb5_principal principal) ++{ ++ struct gssd_k5_kt_princ *ple; ++ krb5_error_code code; + -+ while ((d = readdir(dir)) != NULL) { -+ char *endp; -+ long n = strtol(d->d_name, &endp, 10); -+ if (*endp != '\0' && n >= min && n != dfd) -+ (void) close(n); -+ } -+ closedir(dir); -+ } else { -+ int fd = sysconf(_SC_OPEN_MAX); -+ while (--fd >= min) -+ (void) close(fd); ++ ple = malloc(sizeof(*ple)); ++ if (ple == NULL) { ++ printerr(0, "ERROR: could not allocate storage " ++ "for principal list entry\n"); ++ return NULL; ++ } ++ ++ memset(ple, 0, sizeof(*ple)); ++ ++ ple->realm = KRB5_STRDUP(principal->realm); ++ if (ple->realm == NULL) { ++ printerr(0, "ERROR: not enough memory while copying realm to " ++ "principal list entry\n"); ++ goto err_free; ++ } ++ ++ code = krb5_copy_principal(kctx, principal, &ple->princ); ++ if (code) { ++ printerr(0, "ERROR: %s while copying principal " ++ "to principal list entry\n", ++ error_message(code)); ++ goto err_free; + } ++ ++ return ple; ++err_free: ++ gssd_free_ple(kctx, ple); ++ return NULL; +} ++ /* - * mydaemon creates a pipe between the partent and child - * process. The parent process will wait until the -@@ -165,8 +186,8 @@ - int get_creds = 1; - int fg = 0; - int verbosity = 0; -- int rpc_verbosity = 0; - int opt; -+ int must_srv_mds = 0, must_srv_oss = 0; - extern char *optarg; - char *progname; - -@@ -181,8 +202,13 @@ - case 'v': - verbosity++; - break; -- case 'r': -- rpc_verbosity++; -+ case 'm': -+ get_creds = 1; -+ must_srv_mds = 1; -+ break; -+ case 'o': -+ get_creds = 1; -+ must_srv_oss = 1; - break; - default: - usage(argv[0]); -@@ -196,27 +222,13 @@ - progname = argv[0]; - - initerr(progname, verbosity, fg); --#ifdef HAVE_AUTHGSS_SET_DEBUG_LEVEL -- authgss_set_debug_level(rpc_verbosity); + * Process the given keytab file and create a list of principals we + * might use to perform mount operations. +@@ -444,82 +541,106 @@ + } + printerr(2, "Processing keytab entry for principal '%s'\n", + pname); +-#ifdef HAVE_KRB5 +- if ( (kte.principal->data[0].length == GSSD_SERVICE_NAME_LEN) && +- (strncmp(kte.principal->data[0].data, GSSD_SERVICE_NAME, +- GSSD_SERVICE_NAME_LEN) == 0) && -#else -- if (rpc_verbosity > 0) -- printerr(0, "Warning: rpcsec_gss library does not " -- "support setting debug level\n"); +- if ( (strlen(kte.principal->name.name_string.val[0]) == GSSD_SERVICE_NAME_LEN) && +- (strncmp(kte.principal->name.name_string.val[0], GSSD_SERVICE_NAME, +- GSSD_SERVICE_NAME_LEN) == 0) && +- -#endif - - if (gssd_check_mechs() != 0) { - printerr(0, "ERROR: Problem with gssapi library\n"); - exit(1); - } - -- if (!fg) -- mydaemon(0, 0); -- -- signal(SIGINT, sig_die); -- signal(SIGTERM, sig_die); -- signal(SIGHUP, sig_hup); -- -- if (get_creds && !gssd_acquire_cred(GSSD_SERVICE_NAME)) { -+ if (get_creds && gssd_prepare_creds(must_srv_mds, must_srv_oss)) { - printerr(0, "unable to obtain root (machine) credentials\n"); - printerr(0, "do you have a keytab entry for " - "nfs/@ in " -@@ -225,9 +237,18 @@ - } - - if (!fg) -+ mydaemon(0, 0); +- (!gssd_have_realm_ple((void *)&kte.principal->realm)) ) { +- printerr(2, "We will use this entry (%s)\n", pname); +- ple = malloc(sizeof(struct gssd_k5_kt_princ)); +- if (ple == NULL) { +- printerr(0, "ERROR: could not allocate storage " +- "for principal list entry\n"); +-#ifdef HAVE_KRB5 +- krb5_free_unparsed_name(context, pname); +-#else +- free(pname); +-#endif +- retval = ENOMEM; +- goto out; + -+ signal(SIGINT, sig_die); -+ signal(SIGTERM, sig_die); -+ signal(SIGHUP, sig_hup); ++ /* mds service entry: ++ * - hostname and realm should match this node ++ * - replace existing non-mds entry of this realm ++ */ ++ if (KEYTAB_ENTRY_MATCH(kte, GSSD_SERVICE_MDS)) { ++ krb5_principal princ = kte.principal; ++ krb5_data *princ_host; ++ struct utsname utsbuf; ++ struct hostent *host; + -+ if (!fg) - release_parent(); - -- gssd_run(); -+ gssd_init_unique(GSSD_SVC); ++ if (KRB5_STRCASECMP(krb5_princ_realm(context, princ), ++ this_realm) != 0) { ++ printerr(2, "alien mds service entry, skip\n"); ++ goto next; + } +- /* These will be filled in later */ +- ple->next = NULL; +- ple->ccname = NULL; +- ple->endtime = 0; +- if ((ple->realm = +-#ifdef HAVE_KRB5 +- strndup(kte.principal->realm.data, +- kte.principal->realm.length)) +-#else +- strdup(kte.principal->realm)) +-#endif +- == NULL) { +- printerr(0, "ERROR: %s while copying realm to " +- "principal list entry\n", +- "not enough memory"); +-#ifdef HAVE_KRB5 +- krb5_free_unparsed_name(context, pname); +-#else +- free(pname); +-#endif +- retval = ENOMEM; +- goto out; + -+ svcgssd_run(); - printerr(0, "gssd_run returned!\n"); - abort(); - } ---- nfs-utils-1.0.10/utils/gssd/svcgssd.h.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/svcgssd.h 2006-08-14 10:32:30.000000000 -0600 -@@ -36,8 +36,19 @@ - #include - - void handle_nullreq(FILE *f); --void gssd_run(void); -+void svcgssd_run(void); -+int gssd_prepare_creds(int must_srv_mds, int must_srv_oss); -+gss_cred_id_t gssd_select_svc_cred(int lustre_svc); - --#define GSSD_SERVICE_NAME "nfs" -+extern char *mds_local_realm; -+extern char *oss_local_realm; ++ princ_host = krb5_princ_component(context, princ, 1); ++ if (princ_host == NULL) { ++ printerr(2, "mds service entry: no hostname in " ++ "principal, skip\n"); ++ goto next; + } +- if ((code = krb5_copy_principal(context, +- kte.principal, &ple->princ))) { +- printerr(0, "ERROR: %s while copying principal " +- "to principal list entry\n", +- error_message(code)); +-#ifdef HAVE_KRB5 +- krb5_free_unparsed_name(context, pname); +-#else +- free(pname); +-#endif +- retval = code; +- goto out; ++ ++ if (uname(&utsbuf)) { ++ printerr(2, "mds service entry: unable to get " ++ "UTS name, skip\n"); ++ goto next; + } +- if (gssd_k5_kt_princ_list == NULL) +- gssd_k5_kt_princ_list = ple; +- else { +- ple->next = gssd_k5_kt_princ_list; +- gssd_k5_kt_princ_list = ple; ++ host = gethostbyname(utsbuf.nodename); ++ if (host == NULL) { ++ printerr(2, "mds service entry: unable to get " ++ "local hostname, skip\n"); ++ goto next; + } +- } +- else { ++ ++ if (KRB5_STRCASECMP(princ_host, host->h_name) != 0) { ++ printerr(2, "mds service entry: hostname " ++ "doesn't match: %s - %.*s, skip\n", ++ host->h_name, ++ princ_host->length, princ_host->data); ++ goto next; ++ } ++ ++ ple = gssd_get_realm_ple((void *)&kte.principal->realm); ++ if (ple) { ++ if (ple->fl_mds) { ++ printerr(2,"mds service entry: found a" ++ "duplicated one, it's like a " ++ "mis-configuration, skip\n"); ++ goto next; ++ } ++ ++ gssd_remove_ple(context, ple); ++ printerr(2, "mds service entry: replace an " ++ "existed non-mds one\n"); ++ } ++ } else if (KEYTAB_ENTRY_MATCH(kte, LUSTRE_ROOT_NAME)) { ++ ple = gssd_get_realm_ple((void *)&kte.principal->realm); ++ if (ple) { ++ if (ple->fl_mds || ple->fl_root) { ++ printerr(2, "root entry: found a " ++ "existed %s entry, skip\n", ++ ple->fl_mds ? "mds" : "root"); ++ goto next; ++ } + -+#define GSSD_SERVICE_NAME "lustre" ++ gssd_remove_ple(context, ple); ++ printerr(2, "root entry: replace an existed " ++ "non-mds non-root one\n"); ++ } ++ } else { + printerr(2, "We will NOT use this entry (%s)\n", + pname); ++ goto next; + } +-#ifdef HAVE_KRB5 +- krb5_free_unparsed_name(context, pname); +-#else +- free(pname); +-#endif + -+/* XXX */ -+#define GSSD_SERVICE_MDS "lustre_mds" -+#define GSSD_SERVICE_OSS "lustre_oss" -+#define LUSTRE_ROOT_NAME "lustre_root" -+#define LUSTRE_ROOT_NAMELEN 11 - - #endif /* _RPC_SVCGSSD_H_ */ ---- nfs-utils-1.0.10/utils/gssd/svcgssd_main_loop.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/svcgssd_main_loop.c 2006-08-14 10:32:30.000000000 -0600 -@@ -47,31 +47,31 @@ - #include "err_util.h" - - void --gssd_run() -+svcgssd_run() - { - int ret; - FILE *f; - struct pollfd pollfd; - --#define NULLRPC_FILE "/proc/net/rpc/auth.rpcsec.init/channel" -+#define NULLRPC_FILE "/proc/net/rpc/auth.ptlrpcs.init/channel" - -- f = fopen(NULLRPC_FILE, "rw"); -- -- if (!f) { -- printerr(0, "failed to open %s: %s\n", -- NULLRPC_FILE, strerror(errno)); -- exit(1); -- } -- pollfd.fd = fileno(f); -- pollfd.events = POLLIN; - while (1) { - int save_err; - -+ while ((f = fopen(NULLRPC_FILE, "rw")) == NULL) { -+ printerr(3, "failed to open %s: %s\n", -+ NULLRPC_FILE, strerror(errno)); -+ sleep(1); ++ /* construct ple */ ++ printerr(2, "We will use this entry (%s)\n", pname); ++ ple = gssd_create_ple(context, kte.principal); ++ if (ple == NULL) { ++ KRB5_FREE_UNPARSED_NAME(context, pname); ++ goto out; + } -+ pollfd.fd = fileno(f); -+ pollfd.events = POLLIN; + - pollfd.revents = 0; -- printerr(1, "entering poll\n"); -- ret = poll(&pollfd, 1, -1); -+ printerr(3, "entering poll\n"); -+ ret = poll(&pollfd, 1, 1000); - save_err = errno; -- printerr(1, "leaving poll\n"); -+ printerr(3, "leaving poll\n"); ++ /* add proper flags */ ++ if (KEYTAB_ENTRY_MATCH(kte, GSSD_SERVICE_MDS)) ++ ple->fl_mds = 1; ++ else if (KEYTAB_ENTRY_MATCH(kte, LUSTRE_ROOT_NAME)) ++ ple->fl_root = 1; + - if (ret < 0) { - if (save_err != EINTR) - printerr(0, "error return from poll: %s\n", -@@ -87,5 +87,6 @@ - if (pollfd.revents & POLLIN) - handle_nullreq(f); - } -+ fclose(f); ++ /* enqueue */ ++ if (gssd_k5_kt_princ_list == NULL) ++ gssd_k5_kt_princ_list = ple; ++ else { ++ ple->next = gssd_k5_kt_princ_list; ++ gssd_k5_kt_princ_list = ple; ++ } ++ next: ++ KRB5_FREE_UNPARSED_NAME(context, pname); } - } ---- nfs-utils-1.0.10/utils/gssd/svcgssd_proc.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/svcgssd_proc.c 2006-08-14 10:32:30.000000000 -0600 -@@ -35,7 +35,6 @@ - - #include - #include --#include - - #include - #include -@@ -44,25 +43,28 @@ - #include - #include - #include --#include -+#include - - #include "svcgssd.h" - #include "gss_util.h" - #include "err_util.h" - #include "context.h" - #include "cacheio.h" -+#include "lsupport.h" - - extern char * mech2file(gss_OID mech); --#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.rpcsec.context/channel" --#define SVCGSSD_INIT_CHANNEL "/proc/net/rpc/auth.rpcsec.init/channel" -+#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.ptlrpcs.context/channel" -+#define SVCGSSD_INIT_CHANNEL "/proc/net/rpc/auth.ptlrpcs.init/channel" - - #define TOKEN_BUF_SIZE 8192 - - struct svc_cred { -- uid_t cr_uid; -- gid_t cr_gid; -- int cr_ngroups; -- gid_t cr_groups[NGROUPS]; -+ uint32_t cr_remote; -+ uint32_t cr_usr_root; -+ uint32_t cr_usr_mds; -+ uid_t cr_uid; -+ uid_t cr_mapped_uid; -+ uid_t cr_gid; - }; - - static int -@@ -70,10 +72,9 @@ - gss_OID mech, gss_buffer_desc *context_token) - { - FILE *f; -- int i; - char *fname = NULL; - -- printerr(1, "doing downcall\n"); -+ printerr(2, "doing downcall\n"); - if ((fname = mech2file(mech)) == NULL) - goto out_err; - f = fopen(SVCGSSD_CONTEXT_CHANNEL, "w"); -@@ -86,11 +87,12 @@ - qword_printhex(f, out_handle->value, out_handle->length); - /* XXX are types OK for the rest of this? */ - qword_printint(f, 0x7fffffff); /*XXX need a better timeout */ -+ qword_printint(f, cred->cr_remote); -+ qword_printint(f, cred->cr_usr_root); -+ qword_printint(f, cred->cr_usr_mds); -+ qword_printint(f, cred->cr_mapped_uid); - qword_printint(f, cred->cr_uid); - qword_printint(f, cred->cr_gid); -- qword_printint(f, cred->cr_ngroups); -- for (i=0; i < cred->cr_ngroups; i++) -- qword_printint(f, cred->cr_groups[i]); - qword_print(f, fname); - qword_printhex(f, context_token->value, context_token->length); - qword_eol(f); -@@ -119,7 +121,7 @@ - /* XXXARG: */ - int g; -- printerr(1, "sending null reply\n"); -+ printerr(2, "sending null reply\n"); + if ((code = krb5_kt_end_seq_get(context, kt, &cursor))) { +@@ -695,7 +816,18 @@ + goto out; + } - qword_addhex(&bp, &blen, in_handle->value, in_handle->length); - qword_addhex(&bp, &blen, in_token->value, in_token->length); -@@ -159,6 +161,7 @@ - #define rpcsec_gsserr_credproblem 13 - #define rpcsec_gsserr_ctxproblem 14 +- printerr(1, "Using keytab file '%s'\n", keytabfile); ++ if (this_realm == NULL) { ++ code = krb5_get_default_realm(context, &this_realm); ++ if (code) { ++ printerr(0, "ERROR: get default realm: %s\n", ++ error_message(code)); ++ retval = code; ++ goto out; ++ } ++ printerr(1, "Local realm: %s\n", this_realm); ++ } ++ ++ printerr(2, "Using keytab file '%s'\n", keytabfile); -+#if 0 - static void - add_supplementary_groups(char *secname, char *name, struct svc_cred *cred) - { -@@ -182,7 +185,9 @@ + if ((code = krb5_kt_resolve(context, keytabfile, &kt))) { + printerr(0, "ERROR: %s while resolving keytab '%s'\n", +@@ -710,12 +842,12 @@ + if (gssd_k5_kt_princ_list == NULL) { + printerr(0, "ERROR: No usable keytab entries found in " + "keytab '%s'\n", keytabfile); +- printerr(0, "Do you have a valid keytab entry for " +- "%s/@ in " ++ printerr(0, "You must have a valid keytab entry for " ++ "%s/@ on MDT nodes, " ++ "and %s@ on client nodes, in " + "keytab file %s ?\n", +- GSSD_SERVICE_NAME, keytabfile); +- printerr(0, "Continuing without (machine) credentials " +- "- nfs4 mounts with Kerberos will fail\n"); ++ GSSD_SERVICE_MDS, LUSTRE_ROOT_NAME, ++ keytabfile); } } + +@@ -865,6 +997,7 @@ + krb5_free_context(context); } -+#endif +#if 0 - static int - get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred) - { -@@ -248,7 +253,9 @@ - out: - return res; + #ifdef HAVE_SET_ALLOWABLE_ENCTYPES + /* + * this routine obtains a credentials handle via gss_acquire_cred() +@@ -920,6 +1053,7 @@ + return 0; } + #endif /* HAVE_SET_ALLOWABLE_ENCTYPES */ +#endif + /* + * Obtain supported enctypes from kernel. +--- nfs-utils-1.0.10/utils/gssd/gss_clnt_send_err.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/gss_clnt_send_err.c 2006-10-13 16:03:33.000000000 -0600 +@@ -47,6 +47,7 @@ + #include "gssd.h" + #include "write_bytes.h" + +#if 0 - void - print_hexl(int pri, unsigned char *cp, int length) - { -@@ -285,12 +292,114 @@ - printerr(pri,"\n"); + char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR; + + static void +@@ -102,3 +103,4 @@ } + exit(0); } +#endif +--- nfs-utils-1.0.10/utils/gssd/context.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/context.c 2006-10-13 16:03:33.000000000 -0600 +@@ -33,8 +33,6 @@ + #include + #include + #include +-#include +-#include + #include "gss_util.h" + #include "gss_oids.h" + #include "err_util.h" +--- nfs-utils-1.0.10/utils/gssd/lsupport.h.lustre 2006-10-13 16:03:33.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/lsupport.h 2006-10-13 17:24:45.000000000 -0600 +@@ -0,0 +1,88 @@ ++/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- ++ * vim:expandtab:shiftwidth=8:tabstop=8: ++ */ + -+static int -+get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred, -+ ptl_nid_t ptl_nid) -+{ -+ u_int32_t maj_stat, min_stat; -+ gss_buffer_desc name; -+ char *sname, *realm, *slash; -+ int res = -1; -+ gss_OID name_type = GSS_C_NO_OID; -+ struct passwd *pw; ++#ifndef __LIBCFS_H__ ++#define __LIBCFS_H__ + -+ memset(cred, 0, sizeof(*cred)); ++#include ++#include + -+ maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type); -+ if (maj_stat != GSS_S_COMPLETE) { -+ pgsserr("get_ids: gss_display_name", -+ maj_stat, min_stat, mech); -+ return -1; -+ } -+ if (name.length >= 0xffff || /* be certain name.length+1 doesn't overflow */ -+ !(sname = calloc(name.length + 1, 1))) { -+ printerr(0, "WARNING: get_ids: error allocating %d bytes " -+ "for sname\n", name.length + 1); -+ gss_release_buffer(&min_stat, &name); -+ return -1; -+ } -+ memcpy(sname, name.value, name.length); -+ printerr(1, "authenticate user %s\n", sname); -+ gss_release_buffer(&min_stat, &name); ++#define GSSD_CLI (0) ++#define GSSD_SVC (1) + -+#if 0 -+ lookup_mapping(sname, ptl_nal, ptl_netid, ptl_nid, &cred->cr_mapped_uid); -+#else -+ cred->cr_mapped_uid = -1; -+#endif ++void gssd_init_unique(int type); ++void gssd_exit_unique(int type); + -+ realm = strchr(sname, '@'); -+ if (!realm) { -+ printerr(0, "WARNNING: principal %s contains no realm name\n", -+ sname); -+ cred->cr_remote = (mds_local_realm != NULL); -+ } else { -+ *realm++ = '\0'; -+ if (!mds_local_realm) -+ cred->cr_remote = 1; -+ else -+ cred->cr_remote = -+ (strcasecmp(mds_local_realm, realm) != 0); -+ } ++/* ++ * copied from lustre source ++ */ + -+ if (cred->cr_remote) { -+ if (cred->cr_mapped_uid != -1) -+ res = 0; -+ else -+ printerr(0, "principal %s is remote without mapping\n", -+ sname); -+ goto out_free; -+ } ++#define LUSTRE_GSS_SVC_MDS 0 ++#define LUSTRE_GSS_SVC_OSS 1 + -+ slash = strchr(sname, '/'); -+ if (slash) -+ *slash = '\0'; ++struct lgssd_upcall_data { ++ uint32_t seq; ++ uint32_t uid; ++ uint32_t gid; ++ uint32_t svc; ++ uint64_t nid; ++ char obd[64]; ++}; + -+ if (!(pw = getpwnam(sname))) { -+ /* If client use machine credential, we map it to root, which -+ * will subject to further mapping by root-squash in kernel. -+ * -+ * MDS service keytab is treated as special user, also mapped -+ * to root. OSS service keytab can't be used as a user. -+ */ -+ if (!strcmp(sname, LUSTRE_ROOT_NAME)) { -+ printerr(2, "lustre_root principal, resolve to uid 0\n"); -+ cred->cr_uid = 0; -+ cred->cr_usr_root = 1; -+ } else if (!strcmp(sname, GSSD_SERVICE_MDS)) { -+ printerr(2, "mds service principal, resolve to uid 0\n"); -+ cred->cr_uid = 0; -+ cred->cr_usr_mds = 1; -+ } else { -+ cred->cr_uid = -1; -+ if (cred->cr_mapped_uid == -1) { -+ printerr(0, "invalid user %s\n", sname); -+ goto out_free; -+ } -+ printerr(2, "user %s mapped to %u\n", -+ sname, cred->cr_mapped_uid); -+ } -+ } else { -+ cred->cr_uid = pw->pw_uid; -+ printerr(2, "%s resolve to uid %u\n", sname, cred->cr_uid); -+ } ++#define GSSD_INTERFACE_VERSION (1) + -+ res = 0; -+out_free: -+ free(sname); -+ return res; ++struct lgssd_ioctl_param { ++ int version; /* in */ ++ char *uuid; /* in */ ++ int lustre_svc; /* in */ ++ uid_t uid; /* in */ ++ gid_t gid; /* in */ ++ long send_token_size;/* in */ ++ char *send_token; /* in */ ++ long reply_buf_size; /* in */ ++ char *reply_buf; /* in */ ++ long status; /* out */ ++ long reply_length; /* out */ ++}; ++ ++#define GSSD_DEFAULT_GETHOSTNAME_EX "/etc/lustre/nid2hostname" ++#define MAPPING_DATABASE_FILE "/etc/lustre/idmap.conf" ++ ++typedef uint64_t lnet_nid_t; ++typedef uint32_t lnet_netid_t; ++ ++#define LNET_NID_ANY ((lnet_nid_t) -1) ++#define LNET_PID_ANY ((lnet_pid_t) -1) ++ ++enum { ++ /* Only add to these values (i.e. don't ever change or redefine them): ++ * network addresses depend on them... */ ++ QSWLND = 1, ++ SOCKLND = 2, ++ GMLND = 3, ++ PTLLND = 4, ++ O2IBLND = 5, ++ CIBLND = 6, ++ OPENIBLND = 7, ++ IIBLND = 8, ++ LOLND = 9, ++ RALND = 10, ++ VIBLND = 11, ++ LND_ENUM_END_MARKER ++}; ++ ++int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen); ++int lookup_mapping(char *princ, uint64_t nid, uid_t *uid); ++lnet_nid_t libcfs_str2nid(char *str); ++ ++/* how an LNET NID encodes net:address */ ++#define LNET_NIDADDR(nid) ((uint32_t)((nid) & 0xffffffff)) ++#define LNET_NIDNET(nid) ((uint32_t)(((nid) >> 32)) & 0xffffffff) ++#define LNET_MKNID(net,addr) ((((uint64_t)(net))<<32)|((uint64_t)(addr))) ++/* how net encodes type:number */ ++#define LNET_NETNUM(net) ((net) & 0xffff) ++#define LNET_NETTYP(net) (((net) >> 16) & 0xffff) ++#define LNET_MKNET(typ,num) ((((uint32_t)(typ))<<16)|((uint32_t)(num))) ++ ++#endif /* __LIBCFS_H__ */ +--- nfs-utils-1.0.10/utils/gssd/err_util.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/err_util.c 2006-10-13 16:03:33.000000000 -0600 +@@ -32,6 +32,8 @@ + #include + #include + #include ++#include ++#include + #include "err_util.h" + + static int verbosity = 0; +@@ -91,3 +93,40 @@ + /* reset the buffer */ + memset(message_buf, 0, sizeof(message_buf)); + } ++ ++void print_hexl(int pri, unsigned char *cp, int length) ++{ ++ int i, j, jm; ++ unsigned char c; ++ ++ printerr(pri, "length %d\n",length); ++ printerr(pri, "\n"); ++ ++ for (i = 0; i < length; i += 0x10) { ++ printerr(pri, " %04x: ", (u_int)i); ++ jm = length - i; ++ jm = jm > 16 ? 16 : jm; ++ ++ for (j = 0; j < jm; j++) { ++ if ((j % 2) == 1) ++ printerr(pri,"%02x ", (u_int)cp[i+j]); ++ else ++ printerr(pri,"%02x", (u_int)cp[i+j]); ++ } ++ for (; j < 16; j++) { ++ if ((j % 2) == 1) ++ printerr(pri," "); ++ else ++ printerr(pri," "); ++ } ++ printerr(pri," "); ++ ++ for (j = 0; j < jm; j++) { ++ c = cp[i+j]; ++ c = isprint(c) ? c : '.'; ++ printerr(pri,"%c", c); ++ } ++ printerr(pri,"\n"); ++ } +} + -+typedef struct gss_union_ctx_id_t { -+ gss_OID mech_type; -+ gss_ctx_id_t internal_ctx_id; -+} gss_union_ctx_id_desc, *gss_union_ctx_id_t; +--- nfs-utils-1.0.10/utils/gssd/context_spkm3.c.lustre 2006-10-13 16:02:38.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/context_spkm3.c 2006-10-13 16:03:33.000000000 -0600 +@@ -33,8 +33,6 @@ + #include + #include + #include +-#include +-#include + #include "gss_util.h" + #include "gss_oids.h" + #include "err_util.h" +--- nfs-utils-1.0.10/utils/gssd/gssd.c.lustre 2006-10-13 16:02:38.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/gssd.c 2006-10-13 16:03:33.000000000 -0600 +@@ -40,7 +40,6 @@ - void - handle_nullreq(FILE *f) { -- /* XXX initialize to a random integer to reduce chances of unnecessary -- * invalidation of existing ctx's on restarting svcgssd. */ -- static u_int32_t handle_seq = 0; -+ uint64_t handle_seq; - char in_tok_buf[TOKEN_BUF_SIZE]; - char in_handle_buf[15]; - char out_handle_buf[15]; -@@ -302,10 +411,13 @@ - ignore_out_tok = {.value = NULL}, - /* XXX isn't there a define for this?: */ - null_token = {.value = NULL}; -+ uint32_t lustre_svc; -+ uint64_t ptl_nid; - u_int32_t ret_flags; - gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; - gss_name_t client_name; - gss_OID mech = GSS_C_NO_OID; -+ gss_cred_id_t svc_cred; - u_int32_t maj_stat = GSS_S_FAILURE, min_stat = 0; - u_int32_t ignore_min_stat; - struct svc_cred cred; -@@ -313,7 +425,7 @@ - static int lbuflen = 0; - static char *cp; + #include + #include +-#include + + #include + #include +@@ -52,6 +51,7 @@ + #include "err_util.h" + #include "gss_util.h" + #include "krb5_util.h" ++#include "lsupport.h" + + char pipefsdir[PATH_MAX] = GSSD_PIPEFS_DIR; + char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE; +@@ -77,7 +77,7 @@ + static void + usage(char *progname) + { +- fprintf(stderr, "usage: %s [-f] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n", ++ fprintf(stderr, "usage: %s [-f] [-v] [-p pipefsdir] [-k keytab] [-d ccachedir]\n", + progname); + exit(1); + } +@@ -87,7 +87,6 @@ + { + int fg = 0; + int verbosity = 0; +- int rpc_verbosity = 0; + int opt; + extern char *optarg; + char *progname; +@@ -97,15 +96,9 @@ + case 'f': + fg = 1; + break; +- case 'm': +- /* Accept but ignore this. Now the default. */ +- break; + case 'v': + verbosity++; + break; +- case 'r': +- rpc_verbosity++; +- break; + case 'p': + strncpy(pipefsdir, optarg, sizeof(pipefsdir)); + if (pipefsdir[sizeof(pipefsdir)-1] != '\0') +@@ -126,10 +119,6 @@ + break; + } + } +- strncat(pipefsdir + strlen(pipefsdir), "/" GSSD_SERVICE_NAME, +- sizeof(pipefsdir)-strlen(pipefsdir)); +- if (pipefsdir[sizeof(pipefsdir)-1] != '\0') +- errx(1, "pipefs path name too long"); -- printerr(1, "handling null request\n"); -+ printerr(2, "handling null request\n"); + if ((progname = strrchr(argv[0], '/'))) + progname++; +@@ -137,30 +126,34 @@ + progname = argv[0]; - if (readline(fileno(f), &lbuf, &lbuflen) != 1) { - printerr(0, "WARNING: handle_nullreq: " -@@ -323,15 +435,21 @@ + initerr(progname, verbosity, fg); +-#ifdef HAVE_AUTHGSS_SET_DEBUG_LEVEL +- authgss_set_debug_level(rpc_verbosity); +-#else +- if (rpc_verbosity > 0) +- printerr(0, "Warning: rpcsec_gss library does not " +- "support setting debug level\n"); +-#endif - cp = lbuf; + if (gssd_check_mechs() != 0) + errx(1, "Problem with gssapi library"); -+ qword_get(&cp, (char *) &lustre_svc, sizeof(lustre_svc)); -+ qword_get(&cp, (char *) &ptl_nid, sizeof(ptl_nid)); -+ qword_get(&cp, (char *) &handle_seq, sizeof(handle_seq)); -+ printerr(1, "handling req: svc %u, nid %016llx, idx %llx\n", -+ lustre_svc, ptl_nid, handle_seq); ++#if 0 ++ /* Determine Kerberos information from the kernel */ ++ gssd_obtain_kernel_krb5_info(); ++#endif + - in_handle.length = (size_t) qword_get(&cp, in_handle.value, - sizeof(in_handle_buf)); -- printerr(2, "in_handle: \n"); -- print_hexl(2, in_handle.value, in_handle.length); -+ printerr(3, "in_handle: \n"); -+ print_hexl(3, in_handle.value, in_handle.length); - - in_tok.length = (size_t) qword_get(&cp, in_tok.value, - sizeof(in_tok_buf)); -- printerr(2, "in_tok: \n"); -- print_hexl(2, in_tok.value, in_tok.length); -+ printerr(3, "in_tok: \n"); -+ print_hexl(3, in_tok.value, in_tok.length); - - if (in_tok.length < 0) { - printerr(0, "WARNING: handle_nullreq: " -@@ -351,7 +469,13 @@ - memcpy(&ctx, in_handle.value, in_handle.length); - } + if (!fg && daemon(0, 0) < 0) + errx(1, "fork"); -- maj_stat = gss_accept_sec_context(&min_stat, &ctx, gssd_creds, -+ svc_cred = gssd_select_svc_cred(lustre_svc); -+ if (!svc_cred) { -+ printerr(0, "no service credential for svc %u\n", lustre_svc); -+ goto out_err; -+ } ++ /* This should be checked _after_ daemon(), because we need to own ++ * the undo-able semaphore by this process ++ */ ++ gssd_init_unique(GSSD_CLI); + -+ maj_stat = gss_accept_sec_context(&min_stat, &ctx, svc_cred, - &in_tok, GSS_C_NO_CHANNEL_BINDINGS, &client_name, - &mech, &out_tok, &ret_flags, NULL, NULL); - -@@ -369,7 +493,7 @@ - maj_stat, min_stat, mech); - goto out_err; - } -- if (get_ids(client_name, mech, &cred)) { -+ if (get_ids(client_name, mech, &cred, ptl_nid)) { - /* get_ids() prints error msg */ - maj_stat = GSS_S_BAD_NAME; /* XXX ? */ - gss_release_name(&ignore_min_stat, &client_name); -@@ -377,10 +501,8 @@ - } - gss_release_name(&ignore_min_stat, &client_name); ++ /* Process keytab file and get machine credentials. This will modify ++ * disk status so do it after we are sure we are the only instance ++ */ ++ if (gssd_refresh_krb5_machine_creds()) ++ return -1; ++ + signal(SIGINT, sig_die); + signal(SIGTERM, sig_die); + signal(SIGHUP, sig_hup); +- /* Process keytab file and get machine credentials */ +- gssd_refresh_krb5_machine_creds(); +- /* Determine Kerberos information from the kernel */ +- gssd_obtain_kernel_krb5_info(); - - /* Context complete. Pass handle_seq in out_handle to use - * for context lookup in the kernel. */ -- handle_seq++; - out_handle.length = sizeof(handle_seq); - memcpy(out_handle.value, &handle_seq, sizeof(handle_seq)); - -@@ -404,7 +526,6 @@ - free(ctx_token.value); - if (out_tok.value != NULL) - gss_release_buffer(&ignore_min_stat, &out_tok); -- printerr(1, "finished handling null request\n"); - return; +- gssd_run(); ++ lgssd_run(); + printerr(0, "gssd_run returned!\n"); + abort(); + } +--- nfs-utils-1.0.10/utils/gssd/cacheio.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/cacheio.c 2006-10-13 16:03:33.000000000 -0600 +@@ -227,7 +227,8 @@ + return -1; + while (*bp == ' ') bp++; + *bpp = bp; +- *dest = '\0'; ++// why should we clear *dest??? ++// *dest = '\0'; + return len; + } - out_err: ---- nfs-utils-1.0.10/utils/gssd/lsupport.c.lustre 2006-08-14 10:32:30.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/lsupport.c 2006-08-14 10:32:30.000000000 -0600 -@@ -0,0 +1,604 @@ +--- nfs-utils-1.0.10/utils/gssd/lsupport.c.lustre 2006-10-13 16:03:33.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/lsupport.c 2006-10-13 17:40:51.000000000 -0600 +@@ -0,0 +1,774 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * @@ -2427,8 +2284,10 @@ +#include +#include +#include -+#include +#include ++#ifdef HAVE_GETHOSTBYNAME ++# include ++#endif + +#include "err_util.h" +#include "gssd.h" @@ -2515,17 +2374,17 @@ + +/**************************************** + * client side resolvation: * -+ * nal/netid/nid => hostname * ++ * lnd/netid/nid => hostname * + ****************************************/ + +char gethostname_ex[PATH_MAX] = GSSD_DEFAULT_GETHOSTNAME_EX; + -+typedef int ptl_nid2hostname_t(char *nal, uint32_t net, uint32_t addr, ++typedef int lnd_nid2hostname_t(char *lnd, uint32_t net, uint32_t addr, + char *buf, int buflen); + +/* FIXME what about IPv6? */ +static -+int socknal_nid2hostname(char *nal, uint32_t net, uint32_t addr, ++int socklnd_nid2hostname(char *lnd, uint32_t net, uint32_t addr, + char *buf, int buflen) +{ + struct hostent *ent; @@ -2533,51 +2392,51 @@ + addr = htonl(addr); + ent = gethostbyaddr(&addr, sizeof(addr), AF_INET); + if (!ent) { -+ printerr(0, "%s: can't resolve 0x%x\n", nal, addr); ++ printerr(0, "%s: can't resolve 0x%x\n", lnd, addr); + return -1; + } + if (strlen(ent->h_name) >= buflen) { -+ printerr(0, "%s: name too long: %s\n", nal, ent->h_name); ++ printerr(0, "%s: name too long: %s\n", lnd, ent->h_name); + return -1; + } + strcpy(buf, ent->h_name); + + printerr(2, "%s: net 0x%x, addr 0x%x => %s\n", -+ nal, net, addr, buf); ++ lnd, net, addr, buf); + return 0; +} + +static -+int lonal_nid2hostname(char *nal, uint32_t net, uint32_t addr, ++int lolnd_nid2hostname(char *lnd, uint32_t net, uint32_t addr, + char *buf, int buflen) +{ + struct utsname uts; + struct hostent *ent; + + if (addr) { -+ printerr(0, "%s: addr is 0x%x, we expect 0\n", nal, addr); ++ printerr(0, "%s: addr is 0x%x, we expect 0\n", lnd, addr); + return -1; + } + + if (uname(&uts)) { -+ printerr(0, "%s: failed obtain local machine name\n", nal); ++ printerr(0, "%s: failed obtain local machine name\n", lnd); + return -1; + } + + ent = gethostbyname(uts.nodename); + if (!ent) { + printerr(0, "%s: failed obtain canonical name of %s\n", -+ nal, uts.nodename); ++ lnd, uts.nodename); + return -1; + } + + if (strlen(ent->h_name) >= buflen) { -+ printerr(0, "%s: name too long: %s\n", nal, ent->h_name); ++ printerr(0, "%s: name too long: %s\n", lnd, ent->h_name); + return -1; + } + strcpy(buf, ent->h_name); + -+ printerr(2, "%s: addr 0x%x => %s\n", nal, addr, buf); ++ printerr(2, "%s: addr 0x%x => %s\n", lnd, addr, buf); + return 0; +} + @@ -2587,14 +2446,14 @@ +} + +static -+int external_nid2hostname(char *nal, uint32_t net, uint32_t addr, -+ char *namebuf, int namebuflen) ++int external_nid2hostname(char *lnd, uint32_t net, uint32_t addr, ++ char *namebuf, int namebuflen) +{ + const int bufsize = PATH_MAX + 256; + char buf[bufsize], *head, *tail; + FILE *fghn; + -+ sprintf(buf, "%s %s 0x%x 0x%x", gethostname_ex, nal, net, addr); ++ sprintf(buf, "%s %s 0x%x 0x%x", gethostname_ex, lnd, net, addr); + printerr(2, "cmd: %s\n", buf); + + fghn = popen(buf, "r"); @@ -2605,7 +2464,7 @@ + + head = fgets(buf, bufsize, fghn); + if (head == NULL) { -+ printerr(0, "can't read\n"); ++ printerr(0, "can't read from %s\n", gethostname_ex); + return -1; + } + if (pclose(fghn) == -1) @@ -2617,187 +2476,337 @@ + + tail = head + strlen(head); + if (tail <= head) { -+ printerr(0, "no output\n"); ++ printerr(0, "no output from %s\n", gethostname_ex); + return -1; + } + while (is_space(*(tail - 1))) + tail--; + if (tail <= head) { -+ printerr(0, "output are all space\n"); ++ printerr(0, "output are all space from %s\n", gethostname_ex); + return -1; + } + *tail = '\0'; + + /* start with '@' means error msg */ + if (head[0] == '@') { -+ printerr(0, "%s\n", &head[1]); ++ printerr(0, "error from %s: %s\n", gethostname_ex, &head[1]); + return -1; + } + + if (tail - head > namebuflen) { -+ printerr(0, "hostname too long: %s\n", head); ++ printerr(0, "external hostname too long: %s\n", head); + return -1; + } + + printerr(2, "%s: net 0x%x, addr 0x%x => %s\n", -+ nal, net, addr, head); ++ lnd, net, addr, head); + strcpy(namebuf, head); + return 0; +} + -+enum { -+ QSWNAL = 1, -+ SOCKNAL = 2, -+ GMNAL = 3, -+ /* 4 unused */ -+ TCPNAL = 5, -+ ROUTER = 6, -+ OPENIBNAL = 7, -+ IIBNAL = 8, -+ LONAL = 9, -+ RANAL = 10, -+ VIBNAL = 11, -+ NAL_ENUM_END_MARKER -+}; -+ +static struct { + char *name; -+ ptl_nid2hostname_t *nid2name; -+} converter[NAL_ENUM_END_MARKER] = { ++ lnd_nid2hostname_t *nid2name; ++} converter[LND_ENUM_END_MARKER] = { + {"UNUSED0", NULL}, -+ {"QSWNAL", external_nid2hostname}, -+ {"SOCKNAL", socknal_nid2hostname}, -+ {"GMNAL", external_nid2hostname}, -+ {"UNUSED4", NULL}, -+ {"TCPNAL", NULL}, -+ {"ROUTER", NULL}, -+ {"OPENIBNAL", external_nid2hostname}, -+ {"IIBNAL", external_nid2hostname}, -+ {"LONAL", lonal_nid2hostname}, -+ {"RANAL", NULL}, -+ {"VIBNAL", external_nid2hostname}, ++ [QSWLND] = { "QSWLND", external_nid2hostname}, ++ [SOCKLND] = { "SOCKLND", socklnd_nid2hostname}, ++ [GMLND] = { "GMLND", external_nid2hostname}, ++ [PTLLND] = { "PTLLND", external_nid2hostname }, ++ [O2IBLND] = { "O2IBLND", external_nid2hostname }, ++ [CIBLND] = { "CIBLND", external_nid2hostname }, ++ [OPENIBLND] = { "OPENIBLND",external_nid2hostname }, ++ [IIBLND] = { "IIBLND", external_nid2hostname }, ++ [LOLND] = { "LOLND", lolnd_nid2hostname }, ++ [RALND] = { "RALND", external_nid2hostname }, ++ [VIBLND] = { "VIBLND", external_nid2hostname }, +}; + -+int ptl_nid2hostname(uint64_t nid, char *buf, int buflen) ++int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen) +{ -+ uint32_t nal, net, addr; ++ uint32_t lnd, net, addr; + + addr = LNET_NIDADDR(nid); + net = LNET_NIDNET(nid); -+ nal = LNET_NETTYP(net); ++ lnd = LNET_NETTYP(net); + -+ if (nal >= NAL_ENUM_END_MARKER) { -+ printerr(0, "ERROR: Unrecognized NAL %u\n", nal); ++ if (lnd >= LND_ENUM_END_MARKER) { ++ printerr(0, "ERROR: Unrecognized LND %u\n", lnd); + return -1; + } + -+ if (converter[nal].nid2name == NULL) { -+ printerr(0, "ERROR: NAL %s converter not ready\n", -+ converter[nal].name); ++ if (converter[lnd].nid2name == NULL) { ++ printerr(0, "ERROR: %s converter not ready\n", ++ converter[lnd].name); + return -1; + } + -+ return converter[nal].nid2name(converter[nal].name, net, addr, ++ return converter[lnd].nid2name(converter[lnd].name, net, addr, + buf, buflen); +} + + +/**************************************** -+ * portals support routine * ++ * lnet support routine * ++ * (from lnet/libcfs/nidstrings.c * + ****************************************/ + -+static struct hostent * -+ptl_gethostbyname(char * hname) { -+ struct hostent *he; -+ -+ he = gethostbyname(hname); -+ if (!he) { -+ switch(h_errno) { -+ case HOST_NOT_FOUND: -+ case NO_ADDRESS: -+ printerr(0, "Unable to resolve hostname: %s\n", -+ hname); -+ break; -+ default: -+ printerr(0, "gethostbyname %s: %s\n", -+ hname, strerror(h_errno)); -+ break; -+ } -+ return NULL; -+ } -+ return he; ++#define LNET_NIDSTR_SIZE 32 /* size of each one (see below for usage) */ ++ ++static int libcfs_lo_str2addr(char *str, int nob, uint32_t *addr); ++static void libcfs_ip_addr2str(uint32_t addr, char *str); ++static int libcfs_ip_str2addr(char *str, int nob, uint32_t *addr); ++static void libcfs_decnum_addr2str(uint32_t addr, char *str); ++static void libcfs_hexnum_addr2str(uint32_t addr, char *str); ++static int libcfs_num_str2addr(char *str, int nob, uint32_t *addr); ++ ++struct netstrfns { ++ int nf_type; ++ char *nf_name; ++ char *nf_modname; ++ void (*nf_addr2str)(uint32_t addr, char *str); ++ int (*nf_str2addr)(char *str, int nob, uint32_t *addr); ++}; ++ ++static struct netstrfns libcfs_netstrfns[] = { ++ {/* .nf_type */ LOLND, ++ /* .nf_name */ "lo", ++ /* .nf_modname */ "klolnd", ++ /* .nf_addr2str */ libcfs_decnum_addr2str, ++ /* .nf_str2addr */ libcfs_lo_str2addr}, ++ {/* .nf_type */ SOCKLND, ++ /* .nf_name */ "tcp", ++ /* .nf_modname */ "ksocklnd", ++ /* .nf_addr2str */ libcfs_ip_addr2str, ++ /* .nf_str2addr */ libcfs_ip_str2addr}, ++ {/* .nf_type */ O2IBLND, ++ /* .nf_name */ "o2ib", ++ /* .nf_modname */ "ko2iblnd", ++ /* .nf_addr2str */ libcfs_ip_addr2str, ++ /* .nf_str2addr */ libcfs_ip_str2addr}, ++ {/* .nf_type */ CIBLND, ++ /* .nf_name */ "cib", ++ /* .nf_modname */ "kciblnd", ++ /* .nf_addr2str */ libcfs_ip_addr2str, ++ /* .nf_str2addr */ libcfs_ip_str2addr}, ++ {/* .nf_type */ OPENIBLND, ++ /* .nf_name */ "openib", ++ /* .nf_modname */ "kopeniblnd", ++ /* .nf_addr2str */ libcfs_ip_addr2str, ++ /* .nf_str2addr */ libcfs_ip_str2addr}, ++ {/* .nf_type */ IIBLND, ++ /* .nf_name */ "iib", ++ /* .nf_modname */ "kiiblnd", ++ /* .nf_addr2str */ libcfs_ip_addr2str, ++ /* .nf_str2addr */ libcfs_ip_str2addr}, ++ {/* .nf_type */ VIBLND, ++ /* .nf_name */ "vib", ++ /* .nf_modname */ "kviblnd", ++ /* .nf_addr2str */ libcfs_ip_addr2str, ++ /* .nf_str2addr */ libcfs_ip_str2addr}, ++ {/* .nf_type */ RALND, ++ /* .nf_name */ "ra", ++ /* .nf_modname */ "kralnd", ++ /* .nf_addr2str */ libcfs_ip_addr2str, ++ /* .nf_str2addr */ libcfs_ip_str2addr}, ++ {/* .nf_type */ QSWLND, ++ /* .nf_name */ "elan", ++ /* .nf_modname */ "kqswlnd", ++ /* .nf_addr2str */ libcfs_decnum_addr2str, ++ /* .nf_str2addr */ libcfs_num_str2addr}, ++ {/* .nf_type */ GMLND, ++ /* .nf_name */ "gm", ++ /* .nf_modname */ "kgmlnd", ++ /* .nf_addr2str */ libcfs_hexnum_addr2str, ++ /* .nf_str2addr */ libcfs_num_str2addr}, ++ {/* .nf_type */ PTLLND, ++ /* .nf_name */ "ptl", ++ /* .nf_modname */ "kptllnd", ++ /* .nf_addr2str */ libcfs_decnum_addr2str, ++ /* .nf_str2addr */ libcfs_num_str2addr}, ++ /* placeholder for net0 alias. It MUST BE THE LAST ENTRY */ ++ {/* .nf_type */ -1}, ++}; ++ ++const int libcfs_nnetstrfns = sizeof(libcfs_netstrfns)/sizeof(libcfs_netstrfns[0]); ++ ++static int ++libcfs_lo_str2addr(char *str, int nob, uint32_t *addr) ++{ ++ *addr = 0; ++ return 1; +} + -+int -+ptl_parse_ipquad (uint32_t *ipaddrp, char *str) ++static void ++libcfs_ip_addr2str(uint32_t addr, char *str) +{ -+ int a; -+ int b; -+ int c; -+ int d; ++ snprintf(str, LNET_NIDSTR_SIZE, "%u.%u.%u.%u", ++ (addr >> 24) & 0xff, (addr >> 16) & 0xff, ++ (addr >> 8) & 0xff, addr & 0xff); ++} ++ ++/* CAVEAT EMPTOR XscanfX ++ * I use "%n" at the end of a sscanf format to detect trailing junk. However ++ * sscanf may return immediately if it sees the terminating '0' in a string, so ++ * I initialise the %n variable to the expected length. If sscanf sets it; ++ * fine, if it doesn't, then the scan ended at the end of the string, which is ++ * fine too :) */ + -+ if (sscanf(str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && ++static int ++libcfs_ip_str2addr(char *str, int nob, uint32_t *addr) ++{ ++ int a; ++ int b; ++ int c; ++ int d; ++ int n = nob; /* XscanfX */ ++ ++ /* numeric IP? */ ++ if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 && ++ n == nob && + (a & ~0xff) == 0 && (b & ~0xff) == 0 && -+ (c & ~0xff) == 0 && (d & ~0xff) == 0) -+ { -+ *ipaddrp = (a<<24)|(b<<16)|(c<<8)|d; -+ return (0); ++ (c & ~0xff) == 0 && (d & ~0xff) == 0) { ++ *addr = ((a<<24)|(b<<16)|(c<<8)|d); ++ return 1; + } + -+ return (-1); ++#ifdef HAVE_GETHOSTBYNAME ++ /* known hostname? */ ++ if (('a' <= str[0] && str[0] <= 'z') || ++ ('A' <= str[0] && str[0] <= 'Z')) { ++ char *tmp; ++ ++ tmp = malloc(nob + 1); ++ if (tmp != NULL) { ++ struct hostent *he; ++ ++ memcpy(tmp, str, nob); ++ tmp[nob] = 0; ++ ++ he = gethostbyname(tmp); ++ ++ free(tmp); ++ tmp = NULL; ++ ++ if (he != NULL) { ++ uint32_t ip = *(uint32_t *)he->h_addr; ++ ++ *addr = ntohl(ip); ++ return 1; ++ } ++ } ++ } ++#endif ++ return 0; +} + -+int -+ptl_parse_ipaddr (uint32_t *ipaddrp, char *str) ++static void ++libcfs_decnum_addr2str(uint32_t addr, char *str) +{ -+ struct hostent *he; ++ snprintf(str, LNET_NIDSTR_SIZE, "%u", addr); ++} + -+ if (!strcmp (str, "_all_")) { -+ *ipaddrp = 0; -+ return (0); -+ } ++static void ++libcfs_hexnum_addr2str(uint32_t addr, char *str) ++{ ++ snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr); ++} + -+ if (ptl_parse_ipquad(ipaddrp, str) == 0) -+ return (0); ++static int ++libcfs_num_str2addr(char *str, int nob, uint32_t *addr) ++{ ++ int n; + -+ if ((('a' <= str[0] && str[0] <= 'z') || -+ ('A' <= str[0] && str[0] <= 'Z')) && -+ (he = ptl_gethostbyname (str)) != NULL) { -+ uint32_t addr = *(uint32_t *)he->h_addr; ++ n = nob; ++ if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob) ++ return 1; + -+ *ipaddrp = ntohl(addr); /* HOST byte order */ -+ return (0); -+ } ++ n = nob; ++ if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob) ++ return 1; + -+ return (-1); ++ n = nob; ++ if (sscanf(str, "%u%n", addr, &n) >= 1 && n == nob) ++ return 1; ++ ++ return 0; +} + -+int -+ptl_parse_nid (ptl_nid_t *nidp, char *str) ++static struct netstrfns * ++libcfs_lnd2netstrfns(int lnd) +{ -+ uint32_t ipaddr; -+ char *end; -+ unsigned long long ullval; ++ int i; + -+ if (ptl_parse_ipaddr (&ipaddr, str) == 0) { -+#if !CRAY_PORTALS -+ *nidp = (ptl_nid_t)ipaddr; -+#else -+ *nidp = (((ptl_nid_t)ipaddr & PNAL_HOSTID_MASK) << PNAL_VNODE_SHIFT); -+#endif -+ return (0); ++ if (lnd >= 0) ++ for (i = 0; i < libcfs_nnetstrfns; i++) ++ if (lnd == libcfs_netstrfns[i].nf_type) ++ return &libcfs_netstrfns[i]; ++ ++ return NULL; ++} ++ ++static struct netstrfns * ++libcfs_str2net_internal(char *str, uint32_t *net) ++{ ++ struct netstrfns *nf; ++ int nob; ++ int netnum; ++ int i; ++ ++ for (i = 0; i < libcfs_nnetstrfns; i++) { ++ nf = &libcfs_netstrfns[i]; ++ if (nf->nf_type >= 0 && ++ !strncmp(str, nf->nf_name, strlen(nf->nf_name))) ++ break; + } + -+ ullval = strtoull(str, &end, 0); -+ if (end != str && *end == 0) { -+ /* parsed whole non-empty string */ -+ *nidp = (ptl_nid_t)ullval; -+ return (0); ++ if (i == libcfs_nnetstrfns) ++ return NULL; ++ ++ nob = strlen(nf->nf_name); ++ ++ if (strlen(str) == (unsigned int)nob) { ++ netnum = 0; ++ } else { ++ if (nf->nf_type == LOLND) /* net number not allowed */ ++ return NULL; ++ ++ str += nob; ++ i = strlen(str); ++ if (sscanf(str, "%u%n", &netnum, &i) < 1 || ++ i != (int)strlen(str)) ++ return NULL; + } + -+ return (-1); ++ *net = LNET_MKNET(nf->nf_type, netnum); ++ return nf; +} + ++lnet_nid_t ++libcfs_str2nid(char *str) ++{ ++ char *sep = strchr(str, '@'); ++ struct netstrfns *nf; ++ uint32_t net; ++ uint32_t addr; ++ ++ if (sep != NULL) { ++ nf = libcfs_str2net_internal(sep + 1, &net); ++ if (nf == NULL) ++ return LNET_NID_ANY; ++ } else { ++ sep = str + strlen(str); ++ net = LNET_MKNET(SOCKLND, 0); ++ nf = libcfs_lnd2netstrfns(SOCKLND); ++ if (!nf) ++ return LNET_NID_ANY; ++ } ++ ++ if (!nf->nf_str2addr(str, sep - str, &addr)) ++ return LNET_NID_ANY; ++ ++ return LNET_MKNID(net, addr); ++} + +/**************************************** + * user mapping database handling * @@ -2809,8 +2818,7 @@ + +struct user_map_item { + char *principal; /* NULL means match all */ -+ ptl_netid_t netid; -+ ptl_nid_t nid; ++ lnet_nid_t nid; + uid_t uid; +}; + @@ -2822,7 +2830,7 @@ + +static struct user_mapping mapping = {0, 0, NULL}; +/* FIXME to be finished: monitor change of mapping database */ -+static int mapping_changed = 1; ++static int mapping_mtime = 0; + +static +void cleanup_mapping(void) @@ -2830,8 +2838,8 @@ + int n; + + for (n = 0; n < mapping.nitems; n++) { -+ assert(mapping.items[n].principal); -+ free(mapping.items[n].principal); ++ if (mapping.items[n].principal) ++ free(mapping.items[n].principal); + } + mapping.nitems = 0; +} @@ -2884,7 +2892,7 @@ + char princ[MAX_LINE_LEN]; + char nid_str[MAX_LINE_LEN]; + char dest[MAX_LINE_LEN]; -+ ptl_nid_t ptl_nid; ++ lnet_nid_t nid; + uid_t dest_uid; + FILE *f; + char *line, linebuf[MAX_LINE_LEN]; @@ -2931,10 +2939,15 @@ + return -1; + } + } -+ if (ptl_parse_nid(&ptl_nid, nid_str)) { -+ printerr(0, "fail to parse nid %s\n", nid_str); -+ fclose(f); -+ return -1; ++ if (!strcmp(nid_str, "*")) { ++ nid = LNET_NID_ANY; ++ } else { ++ nid = libcfs_str2nid(nid_str); ++ if (nid == LNET_NID_ANY) { ++ printerr(0, "fail to parse nid %s\n", nid_str); ++ fclose(f); ++ return -1; ++ } + } + dest_uid = parse_uid(dest); + if (dest_uid == -1) { @@ -2945,33 +2958,47 @@ + } + + mapping.items[mapping.nitems].principal = name; -+ mapping.items[mapping.nitems].netid = 0; -+ mapping.items[mapping.nitems].nid = ptl_nid; ++ mapping.items[mapping.nitems].nid = nid; + mapping.items[mapping.nitems].uid = dest_uid; + mapping.nitems++; + printerr(1, "add mapping: %s(%s/0x%llx) ==> %d\n", -+ name ? name : "*", nid_str, ptl_nid, dest_uid); ++ name ? name : "*", nid_str, nid, dest_uid); ++ } ++ ++ return 0; ++} ++ ++static inline int mapping_changed(void) ++{ ++ struct stat st; ++ ++ if (stat(MAPPING_DATABASE_FILE, &st) == -1) { ++ printerr(0, "stat %s failed\n"); ++ return 1; ++ } ++ ++ if (st.st_mtime != mapping_mtime) { ++ mapping_mtime = st.st_mtime; ++ return 1; + } + + return 0; +} + -+int lookup_mapping(char *princ, uint32_t nal, ptl_netid_t netid, -+ ptl_nid_t nid, uid_t *uid) ++int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid) +{ + int n; + + /* FIXME race condition here */ -+ if (mapping_changed) { ++ if (mapping_changed()) { + if (read_mapping_db()) + printerr(0, "all remote users will be denied\n"); -+ mapping_changed = 0; + } + + for (n = 0; n < mapping.nitems; n++) { + struct user_map_item *entry = &mapping.items[n]; + -+ if (entry->netid != netid || entry->nid != nid) ++ if (entry->nid != LNET_NID_ANY && entry->nid != nid) + continue; + if (!entry->principal || + !strcasecmp(entry->principal, princ)) { @@ -2981,96 +3008,255 @@ + return 0; + } + } -+ printerr(1, "no mapping for %s\n", princ); ++ printerr(1, "no mapping for %s/%#Lx\n", princ, nid); + *uid = -1; + return -1; +} + ---- nfs-utils-1.0.10/utils/gssd/lsupport.h.lustre 2006-08-14 10:32:30.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/lsupport.h 2006-08-14 10:32:30.000000000 -0600 -@@ -0,0 +1,68 @@ -+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- -+ * vim:expandtab:shiftwidth=8:tabstop=8: -+ */ -+ -+#ifndef __LIBCFS_H__ -+#define __LIBCFS_H__ -+ -+#include -+#include -+ -+#define GSSD_CLI (0) -+#define GSSD_SVC (1) -+ -+void gssd_init_unique(int type); -+void gssd_exit_unique(int type); -+ -+/* -+ * copied from lustre source -+ */ -+ -+typedef uint64_t ptl_nid_t; -+typedef uint32_t ptl_netid_t; -+ -+#define LUSTRE_GSS_SVC_MDS 0 -+#define LUSTRE_GSS_SVC_OSS 1 -+ -+struct lgssd_upcall_data { -+ uint32_t seq; -+ uint32_t uid; -+ uint32_t gid; -+ uint32_t svc; -+ uint64_t nid; -+ char obd[64]; -+}; -+ -+#define GSSD_INTERFACE_VERSION (1) +--- nfs-utils-1.0.10/utils/gssd/err_util.h.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/err_util.h 2006-10-13 16:03:33.000000000 -0600 +@@ -33,5 +33,6 @@ + + void initerr(char *progname, int verbosity, int fg); + void printerr(int priority, char *format, ...); ++void print_hexl(int pri, unsigned char *cp, int length); + + #endif /* _ERR_UTIL_H_ */ +--- nfs-utils-1.0.10/utils/gssd/svcgssd_main_loop.c.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/svcgssd_main_loop.c 2006-10-13 16:03:33.000000000 -0600 +@@ -47,31 +47,31 @@ + #include "err_util.h" + + void +-gssd_run() ++svcgssd_run() + { + int ret; + FILE *f; + struct pollfd pollfd; + +-#define NULLRPC_FILE "/proc/net/rpc/auth.rpcsec.init/channel" ++#define NULLRPC_FILE "/proc/net/rpc/auth.ptlrpcs.init/channel" + +- f = fopen(NULLRPC_FILE, "rw"); +- +- if (!f) { +- printerr(0, "failed to open %s: %s\n", +- NULLRPC_FILE, strerror(errno)); +- exit(1); +- } +- pollfd.fd = fileno(f); +- pollfd.events = POLLIN; + while (1) { + int save_err; + ++ while ((f = fopen(NULLRPC_FILE, "rw")) == NULL) { ++ printerr(3, "failed to open %s: %s\n", ++ NULLRPC_FILE, strerror(errno)); ++ sleep(1); ++ } ++ pollfd.fd = fileno(f); ++ pollfd.events = POLLIN; + -+struct lgssd_ioctl_param { -+ int version; /* in */ -+ char *uuid; /* in */ -+ int lustre_svc; /* in */ -+ uid_t uid; /* in */ -+ gid_t gid; /* in */ -+ long send_token_size;/* in */ -+ char *send_token; /* in */ -+ long reply_buf_size; /* in */ -+ char *reply_buf; /* in */ -+ long status; /* out */ -+ long reply_length; /* out */ -+}; + pollfd.revents = 0; +- printerr(1, "entering poll\n"); +- ret = poll(&pollfd, 1, -1); ++ printerr(3, "entering poll\n"); ++ ret = poll(&pollfd, 1, 1000); + save_err = errno; +- printerr(1, "leaving poll\n"); ++ printerr(3, "leaving poll\n"); + -+#define GSSD_DEFAULT_GETHOSTNAME_EX "/etc/lustre/nid2hostname" -+#define MAPPING_DATABASE_FILE "/etc/lustre/idmap.conf" + if (ret < 0) { + if (save_err != EINTR) + printerr(0, "error return from poll: %s\n", +@@ -87,5 +87,6 @@ + if (pollfd.revents & POLLIN) + handle_nullreq(f); + } ++ fclose(f); + } + } +--- nfs-utils-1.0.10/utils/gssd/Makefile.am.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/Makefile.am 2006-10-13 16:03:33.000000000 -0600 +@@ -1,17 +1,11 @@ + ## Process this file with automake to produce Makefile.in + +-man8_MANS = gssd.man svcgssd.man +- +-RPCPREFIX = rpc. ++RPCPREFIX = + KPREFIX = @kprefix@ +-sbin_PREFIXED = gssd svcgssd +-sbin_PROGRAMS = $(sbin_PREFIXED) gss_clnt_send_err ++sbin_PREFIXED = lgssd lsvcgssd ++sbin_PROGRAMS = $(sbin_PREFIXED) + sbin_SCRIPTS = gss_destroy_creds + +-EXTRA_DIST = \ +- gss_destroy_creds \ +- $(man8_MANS) +- + COMMON_SRCS = \ + context.c \ + context_mit.c \ +@@ -20,13 +14,15 @@ + gss_util.c \ + gss_oids.c \ + err_util.c \ ++ lsupport.c \ + \ + context.h \ + err_util.h \ + gss_oids.h \ +- gss_util.h ++ gss_util.h \ ++ lsupport.h + +-gssd_SOURCES = \ ++lgssd_SOURCES = \ + $(COMMON_SRCS) \ + gssd.c \ + gssd_main_loop.c \ +@@ -37,13 +33,12 @@ + krb5_util.h \ + write_bytes.h + +-gssd_LDADD = $(RPCSECGSS_LIBS) $(KRBLIBS) +-gssd_LDFLAGS = $(KRBLDFLAGS) ++lgssd_LDADD = $(GSSAPI_LIBS) $(KRBLIBS) ++lgssd_LDFLAGS = $(KRBLDFLAGS) + +-gssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \ +- $(RPCSECGSS_CFLAGS) $(KRBCFLAGS) ++lgssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(GSSAPI_CFLAGS) $(KRBCFLAGS) + +-svcgssd_SOURCES = \ ++lsvcgssd_SOURCES = \ + $(COMMON_SRCS) \ + cacheio.c \ + svcgssd.c \ +@@ -54,20 +49,11 @@ + cacheio.h \ + svcgssd.h + +-svcgssd_LDADD = \ +- ../../support/nfs/libnfs.a \ +- $(RPCSECGSS_LIBS) -lnfsidmap \ +- $(KRBLIBS) +- +-svcgssd_LDFLAGS = $(KRBLDFLAGS) +- +-svcgssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \ +- $(RPCSECGSS_CFLAGS) $(KRBCFLAGS) ++lsvcgssd_LDADD = $(GSSAPI_LIBS) $(KRBLIBS) + +-gss_clnt_send_err_SOURCES = gss_clnt_send_err.c ++lsvcgssd_LDFLAGS = $(KRBLDFLAGS) + +-gss_clnt_send_err_CFLAGS = $(AM_CFLAGS) $(CFLAGS) \ +- $(RPCSECGSS_CFLAGS) $(KRBCFLAGS) ++lsvcgssd_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(GSSAPI_CFLAGS) $(KRBCFLAGS) + + MAINTAINERCLEANFILES = Makefile.in + +@@ -91,23 +77,3 @@ + done) + + +-# XXX This makes some assumptions about what automake does. +-# XXX But there is no install-man-hook or install-man-local. +-install-man: install-man8 install-man-links +-uninstall-man: uninstall-man8 uninstall-man-links +- +-install-man-links: +- (cd $(DESTDIR)$(man8dir) && \ +- for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \ +- inst=`echo $$m | sed -e 's/man$$/8/'`; \ +- rm -f $(RPCPREFIX)$$inst ; \ +- $(LN_S) $$inst $(RPCPREFIX)$$inst ; \ +- done) +- +-uninstall-man-links: +- (cd $(DESTDIR)$(man8dir) && \ +- for m in $(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS); do \ +- inst=`echo $$m | sed -e 's/man$$/8/'`; \ +- rm -f $(RPCPREFIX)$$inst ; \ +- done) +- +--- nfs-utils-1.0.10/utils/gssd/gssd.h.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/gssd.h 2006-10-13 16:03:33.000000000 -0600 +@@ -48,8 +48,13 @@ + #define GSSD_DEFAULT_CRED_PREFIX "krb5cc_" + #define GSSD_DEFAULT_MACHINE_CRED_SUFFIX "machine" + #define GSSD_DEFAULT_KEYTAB_FILE "/etc/krb5.keytab" +-#define GSSD_SERVICE_NAME "nfs" +-#define GSSD_SERVICE_NAME_LEN 3 ++#define GSSD_SERVICE_MDS "lustre_mds" ++#define GSSD_SERVICE_OSS "lustre_oss" ++#define GSSD_SERVICE_MDS_NAMELEN 10 ++#define GSSD_SERVICE_OSS_NAMELEN 10 + -+int ptl_nid2hostname(uint64_t nid, char *buf, int buflen); -+int lookup_mapping(char *princ, uint32_t nal, ptl_netid_t netid, -+ ptl_nid_t nid, uid_t *uid); ++#define LUSTRE_ROOT_NAME "lustre_root" ++#define LUSTRE_ROOT_NAMELEN 11 + + /* + * The gss mechanisms that we can handle +@@ -61,6 +66,7 @@ + extern char pipefsdir[PATH_MAX]; + extern char keytabfile[PATH_MAX]; + extern char ccachedir[PATH_MAX]; ++extern char gethostname_ex[PATH_MAX]; + + TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list; + +@@ -69,10 +75,6 @@ + char *dirname; + int dir_fd; + char *servicename; +- char *servername; +- int prog; +- int vers; +- char *protocol; + int krb5_fd; + int krb5_poll_index; + int spkm3_fd; +@@ -83,8 +85,7 @@ + int update_client_list(void); + void handle_krb5_upcall(struct clnt_info *clp); + void handle_spkm3_upcall(struct clnt_info *clp); +-int gssd_acquire_cred(char *server_name); +-void gssd_run(void); ++void lgssd_run(void); + + + #endif /* _RPC_GSSD_H_ */ +--- nfs-utils-1.0.10/utils/gssd/svcgssd.h.lustre 2006-08-07 00:40:50.000000000 -0600 ++++ nfs-utils-1.0.10/utils/gssd/svcgssd.h 2006-10-13 16:03:33.000000000 -0600 +@@ -36,8 +36,19 @@ + #include + + void handle_nullreq(FILE *f); +-void gssd_run(void); ++void svcgssd_run(void); ++int gssd_prepare_creds(int must_srv_mds, int must_srv_oss); ++gss_cred_id_t gssd_select_svc_cred(int lustre_svc); + +-#define GSSD_SERVICE_NAME "nfs" ++extern char *mds_local_realm; ++extern char *oss_local_realm; + -+/* how an LNET NID encodes net:address */ -+#define LNET_NIDADDR(nid) ((uint32_t)((nid) & 0xffffffff)) -+#define LNET_NIDNET(nid) ((uint32_t)(((nid) >> 32)) & 0xffffffff) -+#define LNET_MKNID(net,addr) ((((uint64_t)(net))<<32)|((uint64_t)(addr))) -+/* how net encodes type:number */ -+#define LNET_NETNUM(net) ((net) & 0xffff) -+#define LNET_NETTYP(net) (((net) >> 16) & 0xffff) -+#define LNET_MKNET(typ,num) ((((uint32_t)(typ))<<16)|((uint32_t)(num))) ++#define GSSD_SERVICE_NAME "lustre" + -+#endif /* __LIBCFS_H__ */ ---- nfs-utils-1.0.10/utils/gssd/cacheio.c.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/gssd/cacheio.c 2006-08-14 10:32:30.000000000 -0600 -@@ -227,7 +227,8 @@ - return -1; - while (*bp == ' ') bp++; - *bpp = bp; -- *dest = '\0'; -+// why should we clear *dest??? -+// *dest = '\0'; - return len; - } ++/* XXX */ ++#define GSSD_SERVICE_MDS "lustre_mds" ++#define GSSD_SERVICE_OSS "lustre_oss" ++#define LUSTRE_ROOT_NAME "lustre_root" ++#define LUSTRE_ROOT_NAMELEN 11 + #endif /* _RPC_SVCGSSD_H_ */ --- nfs-utils-1.0.10/utils/Makefile.am.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/utils/Makefile.am 2006-08-14 10:32:30.000000000 -0600 ++++ nfs-utils-1.0.10/utils/Makefile.am 2006-10-13 16:03:33.000000000 -0600 @@ -2,31 +2,6 @@ OPTDIRS = @@ -3105,7 +3291,7 @@ MAINTAINERCLEANFILES = Makefile.in --- nfs-utils-1.0.10/configure.in.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/configure.in 2006-08-14 10:32:30.000000000 -0600 ++++ nfs-utils-1.0.10/configure.in 2006-10-13 16:03:33.000000000 -0600 @@ -17,61 +17,14 @@ RELEASE=$withval, RELEASE=1) @@ -3298,7 +3484,7 @@ AC_OUTPUT --- nfs-utils-1.0.10/Makefile.am.lustre 2006-08-07 00:40:50.000000000 -0600 -+++ nfs-utils-1.0.10/Makefile.am 2006-08-14 10:32:30.000000000 -0600 ++++ nfs-utils-1.0.10/Makefile.am 2006-10-13 16:03:33.000000000 -0600 @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in diff --git a/lustre/utils/gss/svcgssd_proc.c b/lustre/utils/gss/svcgssd_proc.c index e799f82..3b17dca 100644 --- a/lustre/utils/gss/svcgssd_proc.c +++ b/lustre/utils/gss/svcgssd_proc.c @@ -296,7 +296,7 @@ print_hexl(int pri, unsigned char *cp, int length) static int get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred, - ptl_nid_t ptl_nid) + lnet_nid_t nid) { u_int32_t maj_stat, min_stat; gss_buffer_desc name; @@ -324,11 +324,7 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred, printerr(1, "authenticate user %s\n", sname); gss_release_buffer(&min_stat, &name); -#if 0 - lookup_mapping(sname, ptl_nal, ptl_netid, ptl_nid, &cred->cr_mapped_uid); -#else - cred->cr_mapped_uid = -1; -#endif + lookup_mapping(sname, nid, &cred->cr_mapped_uid); realm = strchr(sname, '@'); if (!realm) { @@ -412,7 +408,7 @@ handle_nullreq(FILE *f) { /* XXX isn't there a define for this?: */ null_token = {.value = NULL}; uint32_t lustre_svc; - uint64_t ptl_nid; + lnet_nid_t nid; u_int32_t ret_flags; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; gss_name_t client_name; @@ -436,10 +432,10 @@ handle_nullreq(FILE *f) { cp = lbuf; qword_get(&cp, (char *) &lustre_svc, sizeof(lustre_svc)); - qword_get(&cp, (char *) &ptl_nid, sizeof(ptl_nid)); + qword_get(&cp, (char *) &nid, sizeof(nid)); qword_get(&cp, (char *) &handle_seq, sizeof(handle_seq)); printerr(1, "handling req: svc %u, nid %016llx, idx %llx\n", - lustre_svc, ptl_nid, handle_seq); + lustre_svc, nid, handle_seq); in_handle.length = (size_t) qword_get(&cp, in_handle.value, sizeof(in_handle_buf)); @@ -493,7 +489,7 @@ handle_nullreq(FILE *f) { maj_stat, min_stat, mech); goto out_err; } - if (get_ids(client_name, mech, &cred, ptl_nid)) { + if (get_ids(client_name, mech, &cred, nid)) { /* get_ids() prints error msg */ maj_stat = GSS_S_BAD_NAME; /* XXX ? */ gss_release_name(&ignore_min_stat, &client_name); -- 1.8.3.1