-diff -Nrup nfs-utils-1.0.11/utils/gssd/lsupport.c nfs-utils-1.0.11.lustre/utils/gssd/lsupport.c
---- nfs-utils-1.0.11/utils/gssd/lsupport.c 1969-12-31 17:00:00.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/lsupport.c 2007-06-29 12:32:43.000000000 -0600
-@@ -0,0 +1,787 @@
-+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
-+ * vim:expandtab:shiftwidth=8:tabstop=8:
-+ *
-+ * Copyright (c) 2005 Cluster File Systems, Inc.
-+ *
-+ * This file is part of Lustre, http://www.lustre.org.
-+ *
-+ * Lustre is free software; you can redistribute it and/or
-+ * modify it under the terms of version 2 of the GNU General Public
-+ * License as published by the Free Software Foundation.
-+ *
-+ * Lustre is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with Lustre; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#ifndef _GNU_SOURCE
-+#define _GNU_SOURCE
-+#endif
-+#include "config.h"
-+#include <sys/param.h>
-+#include <sys/utsname.h>
-+#include <sys/stat.h>
-+#include <sys/socket.h>
-+#include <arpa/inet.h>
-+#include <sys/types.h>
-+#include <sys/ipc.h>
-+#include <sys/sem.h>
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <pwd.h>
-+#include <grp.h>
-+#include <string.h>
-+#include <dirent.h>
-+#include <poll.h>
-+#include <fcntl.h>
-+#include <signal.h>
-+#include <unistd.h>
-+#include <errno.h>
-+#include <assert.h>
-+#ifdef HAVE_GETHOSTBYNAME
-+# include <netdb.h>
-+#endif
-+
-+#ifdef _NEW_BUILD_
-+# include "lgss_utils.h"
-+#else
-+# include "err_util.h"
-+# include "gssd.h"
-+#endif
-+#include "lsupport.h"
-+
-+/****************************************
-+ * exclusive startup *
-+ ****************************************/
-+
-+static struct __sem_s {
-+ char *name;
-+ key_t sem_key;
-+ int sem_id;
-+} sems[2] = {
-+ [GSSD_CLI] = { "client", 0x3a92d473, 0 },
-+ [GSSD_SVC] = { "server", 0x3b92d473, 0 },
-+};
-+
-+void gssd_init_unique(int type)
-+{
-+ struct __sem_s *sem = &sems[type];
-+ struct sembuf sembuf;
-+
-+ assert(type == GSSD_CLI || type == GSSD_SVC);
-+
-+again:
-+ sem->sem_id = semget(sem->sem_key, 1, IPC_CREAT | IPC_EXCL | 0700);
-+ if (sem->sem_id == -1) {
-+ if (errno != EEXIST) {
-+ printerr(0, "Create sem: %s\n", strerror(errno));
-+ exit(-1);
-+ }
-+
-+ /* already exist. Note there's still a small window racing
-+ * with other processes, due to the stupid semaphore semantics.
-+ */
-+ sem->sem_id = semget(sem->sem_key, 0, 0700);
-+ if (sem->sem_id == -1) {
-+ if (errno == ENOENT) {
-+ printerr(0, "another instance just exit, "
-+ "try again\n");
-+ goto again;
-+ }
-+
-+ printerr(0, "Obtain sem: %s\n", strerror(errno));
-+ exit(-1);
-+ }
-+ } else {
-+ int val = 1;
-+
-+ if (semctl(sem->sem_id, 0, SETVAL, val) == -1) {
-+ printerr(0, "Initialize sem: %s\n",
-+ strerror(errno));
-+ exit(-1);
-+ }
-+ }
-+
-+ sembuf.sem_num = 0;
-+ sembuf.sem_op = -1;
-+ sembuf.sem_flg = IPC_NOWAIT | SEM_UNDO;
-+
-+ if (semop(sem->sem_id, &sembuf, 1) != 0) {
-+ if (errno == EAGAIN) {
-+ printerr(0, "Another instance is running, exit\n");
-+ exit(0);
-+ }
-+ printerr(0, "Grab sem: %s\n", strerror(errno));
-+ exit(0);
-+ }
-+
-+ printerr(2, "Successfully created %s global identity\n", sem->name);
-+}
-+
-+void gssd_exit_unique(int type)
-+{
-+ assert(type == GSSD_CLI || type == GSSD_SVC);
-+
-+ /*
-+ * do nothing. we can't remove the sem here, otherwise the race
-+ * window would be much bigger. So it's sad we have to leave the
-+ * sem in the system forever.
-+ */
-+}
-+
-+/****************************************
-+ * client side resolvation: *
-+ * lnd/netid/nid => hostname *
-+ ****************************************/
-+
-+char gethostname_ex[PATH_MAX] = GSSD_DEFAULT_GETHOSTNAME_EX;
-+
-+typedef int lnd_nid2hostname_t(char *lnd, uint32_t net, uint32_t addr,
-+ char *buf, int buflen);
-+
-+/* FIXME what about IPv6? */
-+static
-+int ipv4_nid2hostname(char *lnd, uint32_t net, uint32_t addr,
-+ char *buf, int buflen)
-+{
-+ struct hostent *ent;
-+
-+ addr = htonl(addr);
-+ ent = gethostbyaddr(&addr, sizeof(addr), AF_INET);
-+ if (!ent) {
-+ 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", lnd, ent->h_name);
-+ return -1;
-+ }
-+ strcpy(buf, ent->h_name);
-+
-+ printerr(2, "%s: net 0x%x, addr 0x%x => %s\n",
-+ lnd, net, addr, buf);
-+ return 0;
-+}
-+
-+static
-+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", lnd, addr);
-+ return -1;
-+ }
-+
-+ if (uname(&uts)) {
-+ 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",
-+ lnd, uts.nodename);
-+ return -1;
-+ }
-+
-+ if (strlen(ent->h_name) >= buflen) {
-+ printerr(0, "%s: name too long: %s\n", lnd, ent->h_name);
-+ return -1;
-+ }
-+ strcpy(buf, ent->h_name);
-+
-+ printerr(3, "%s: addr 0x%x => %s\n", lnd, addr, buf);
-+ return 0;
-+}
-+
-+static int is_space(char c)
-+{
-+ return (c == ' ' || c == '\t' || c == '\n');
-+}
-+
-+static
-+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, lnd, net, addr);
-+ printerr(2, "cmd: %s\n", buf);
-+
-+ fghn = popen(buf, "r");
-+ if (fghn == NULL) {
-+ printerr(0, "failed to call %s\n", gethostname_ex);
-+ return -1;
-+ }
-+
-+ head = fgets(buf, bufsize, fghn);
-+ if (head == NULL) {
-+ printerr(0, "can't read from %s\n", gethostname_ex);
-+ return -1;
-+ }
-+ if (pclose(fghn) == -1)
-+ printerr(1, "pclose failed, continue\n");
-+
-+ /* trim head/tail space */
-+ while (is_space(*head))
-+ head++;
-+
-+ tail = head + strlen(head);
-+ if (tail <= head) {
-+ 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 from %s\n", gethostname_ex);
-+ return -1;
-+ }
-+ *tail = '\0';
-+
-+ /* start with '@' means error msg */
-+ if (head[0] == '@') {
-+ printerr(0, "error from %s: %s\n", gethostname_ex, &head[1]);
-+ return -1;
-+ }
-+
-+ if (tail - head > namebuflen) {
-+ printerr(0, "external hostname too long: %s\n", head);
-+ return -1;
-+ }
-+
-+ printerr(2, "%s: net 0x%x, addr 0x%x => %s\n",
-+ lnd, net, addr, head);
-+ strcpy(namebuf, head);
-+ return 0;
-+}
-+
-+static struct {
-+ char *name;
-+ lnd_nid2hostname_t *nid2name;
-+} converter[LND_ENUM_END_MARKER] = {
-+ {"UNUSED0", NULL},
-+ [QSWLND] = { "QSWLND", external_nid2hostname},
-+ [SOCKLND] = { "SOCKLND", ipv4_nid2hostname },
-+ [GMLND] = { "GMLND", external_nid2hostname},
-+ [PTLLND] = { "PTLLND", external_nid2hostname },
-+ [O2IBLND] = { "O2IBLND", ipv4_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 lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen)
-+{
-+ uint32_t lnd, net, addr;
-+
-+ addr = LNET_NIDADDR(nid);
-+ net = LNET_NIDNET(nid);
-+ lnd = LNET_NETTYP(net);
-+
-+ if (lnd >= LND_ENUM_END_MARKER) {
-+ printerr(0, "ERROR: Unrecognized LND %u\n", lnd);
-+ return -1;
-+ }
-+
-+ if (converter[lnd].nid2name == NULL) {
-+ printerr(0, "ERROR: %s converter not ready\n",
-+ converter[lnd].name);
-+ return -1;
-+ }
-+
-+ return converter[lnd].nid2name(converter[lnd].name, net, addr,
-+ buf, buflen);
-+}
-+
-+
-+/****************************************
-+ * lnet support routine *
-+ * (from lnet/libcfs/nidstrings.c *
-+ ****************************************/
-+
-+#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;
-+}
-+
-+static void
-+libcfs_ip_addr2str(uint32_t addr, char *str)
-+{
-+ 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 :) */
-+
-+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) {
-+ *addr = ((a<<24)|(b<<16)|(c<<8)|d);
-+ 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;
-+}
-+
-+static void
-+libcfs_decnum_addr2str(uint32_t addr, char *str)
-+{
-+ snprintf(str, LNET_NIDSTR_SIZE, "%u", addr);
-+}
-+
-+static void
-+libcfs_hexnum_addr2str(uint32_t addr, char *str)
-+{
-+ snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr);
-+}
-+
-+static int
-+libcfs_num_str2addr(char *str, int nob, uint32_t *addr)
-+{
-+ int n;
-+
-+ n = nob;
-+ if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob)
-+ return 1;
-+
-+ n = nob;
-+ if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob)
-+ return 1;
-+
-+ n = nob;
-+ if (sscanf(str, "%u%n", addr, &n) >= 1 && n == nob)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static struct netstrfns *
-+libcfs_lnd2netstrfns(int lnd)
-+{
-+ 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;
-+ }
-+
-+ 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;
-+ }
-+
-+ *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 *
-+ * (very rudiment) *
-+ ****************************************/
-+
-+#define MAPPING_GROW_SIZE 512
-+#define MAX_LINE_LEN 256
-+
-+struct user_map_item {
-+ char *principal; /* NULL means match all, will cause multi->single mapped, FORBID */
-+ lnet_nid_t nid;
-+ uid_t uid;
-+};
-+
-+struct user_mapping {
-+ int nitems;
-+ struct user_map_item *items;
-+};
-+
-+static struct user_mapping mapping = {0, NULL};
-+/* FIXME to be finished: monitor change of mapping database */
-+static int mapping_mtime = 0;
-+
-+void cleanup_mapping(void)
-+{
-+ if (mapping.items) {
-+ for (; mapping.nitems > 0; mapping.nitems--)
-+ free(mapping.items[mapping.nitems - 1].principal);
-+ free(mapping.items);
-+ mapping.items = NULL;
-+ }
-+}
-+
-+static int grow_mapping(int nitems)
-+{
-+ struct user_map_item *new;
-+ int oldsize, newsize;
-+
-+ oldsize = (mapping.nitems * sizeof(struct user_map_item) +
-+ MAPPING_GROW_SIZE - 1) / MAPPING_GROW_SIZE;
-+ newsize = (nitems * sizeof(struct user_map_item) +
-+ MAPPING_GROW_SIZE - 1) / MAPPING_GROW_SIZE;
-+ while (newsize <= oldsize)
-+ return 0;
-+
-+ newsize *= MAPPING_GROW_SIZE;
-+ new = malloc(newsize);
-+ if (!new) {
-+ printerr(0, "can't alloc mapping size %d\n", newsize);
-+ return -1;
-+ }
-+
-+ if (mapping.items) {
-+ memcpy(new, mapping.items, mapping.nitems * sizeof(struct user_map_item));
-+ free(mapping.items);
-+ }
-+ mapping.items = new;
-+ return 0;
-+}
-+
-+uid_t parse_uid(char *uidstr)
-+{
-+ struct passwd *pw;
-+ char *p = NULL;
-+ long uid;
-+
-+ pw = getpwnam(uidstr);
-+ if (pw)
-+ return pw->pw_uid;
-+
-+ uid = strtol(uidstr, &p, 0);
-+ if (*p == '\0')
-+ return (uid_t) uid;
-+
-+ return -1;
-+}
-+
-+static int read_mapping_db(void)
-+{
-+ char princ[MAX_LINE_LEN];
-+ char nid_str[MAX_LINE_LEN];
-+ char dest[MAX_LINE_LEN];
-+ char linebuf[MAX_LINE_LEN];
-+ char *line;
-+ lnet_nid_t nid;
-+ uid_t dest_uid;
-+ FILE *f;
-+
-+ /* cleanup old mappings */
-+ cleanup_mapping();
-+
-+ f = fopen(MAPPING_DATABASE_FILE, "r");
-+ if (!f) {
-+ printerr(0, "can't open mapping database: %s\n",
-+ MAPPING_DATABASE_FILE);
-+ return -1;
-+ }
-+
-+ while ((line = fgets(linebuf, MAX_LINE_LEN, f)) != NULL) {
-+ char *name;
-+
-+ if (strlen(line) >= MAX_LINE_LEN) {
-+ printerr(0, "invalid mapping db: line too long (%d)\n",
-+ strlen(line));
-+ continue;
-+ }
-+
-+ if (sscanf(line, "%s %s %s", princ, nid_str, dest) != 3) {
-+ printerr(0, "mapping db: syntax error\n");
-+ continue;
-+ }
-+
-+ if (!strcmp(princ, "*")) {
-+ printerr(0, "NOT permit \"*\" princ, it will cause multi->single mapped\n");
-+ continue;
-+ } else {
-+ name = strdup(princ);
-+ if (!name) {
-+ printerr(0, "fail to dup str %s\n", princ);
-+ continue;
-+ }
-+ }
-+
-+ 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);
-+ free(name);
-+ continue;
-+ }
-+ }
-+
-+ dest_uid = parse_uid(dest);
-+ if (dest_uid == -1) {
-+ printerr(0, "no valid user: %s\n", dest);
-+ free(name);
-+ continue;
-+ }
-+
-+ if (grow_mapping(mapping.nitems + 1)) {
-+ printerr(0, "fail to grow mapping to %d\n",
-+ mapping.nitems + 1);
-+ free(name);
-+ fclose(f);
-+ return -1;
-+ }
-+
-+ mapping.items[mapping.nitems].principal = name;
-+ 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, nid_str, nid, dest_uid);
-+ }
-+
-+ fclose(f);
-+ return 0;
-+}
-+
-+static inline int mapping_changed(void)
-+{
-+ struct stat st;
-+
-+ if (stat(MAPPING_DATABASE_FILE, &st) == -1) {
-+ /* stat failed, treat it like doesn't exist or be removed */
-+ if (mapping_mtime == 0) {
-+ return 0;
-+ } else {
-+ printerr(0, "Warning: stat %s failed: %s\n",
-+ MAPPING_DATABASE_FILE, strerror(errno));
-+
-+ mapping_mtime = 0;
-+ return 1;
-+ }
-+ }
-+
-+ if (st.st_mtime != mapping_mtime) {
-+ mapping_mtime = st.st_mtime;
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid)
-+{
-+ int n;
-+
-+ *uid = -1;
-+
-+ /* FIXME race condition here */
-+ if (mapping_changed()) {
-+ if (read_mapping_db())
-+ printerr(0, "all remote users will be denied\n");
-+ }
-+
-+ for (n = 0; n < mapping.nitems; n++) {
-+ struct user_map_item *entry = &mapping.items[n];
-+
-+ if (entry->nid != LNET_NID_ANY && entry->nid != nid)
-+ continue;
-+ if (!strcasecmp(entry->principal, princ)) {
-+ printerr(1, "found mapping: %s ==> %d\n",
-+ princ, entry->uid);
-+ *uid = entry->uid;
-+ return 0;
-+ }
-+ }
-+
-+ printerr(2, "no mapping for %s/%#Lx\n", princ, nid);
-+ return -1;
-+}
-diff -Nrup nfs-utils-1.0.11/utils/gssd/lsupport.h nfs-utils-1.0.11.lustre/utils/gssd/lsupport.h
---- nfs-utils-1.0.11/utils/gssd/lsupport.h 1969-12-31 17:00:00.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/lsupport.h 2007-06-29 12:32:43.000000000 -0600
-@@ -0,0 +1,89 @@
-+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
-+ * vim:expandtab:shiftwidth=8:tabstop=8:
-+ */
-+
-+#ifndef __LIBCFS_H__
-+#define __LIBCFS_H__
-+
-+#include <unistd.h>
-+#include <stdint.h>
-+
-+#define GSSD_CLI (0)
-+#define GSSD_SVC (1)
-+
-+void gssd_init_unique(int type);
-+void gssd_exit_unique(int type);
-+
-+/*
-+ * copied from lustre source
-+ */
-+
-+#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)
-+
-+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);
-+void cleanup_mapping(void);
-+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__ */
-diff -Nrup nfs-utils-1.0.11/utils/gssd/Makefile.am nfs-utils-1.0.11.lustre/utils/gssd/Makefile.am
---- nfs-utils-1.0.11/utils/gssd/Makefile.am 2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/Makefile.am 2007-06-29 12:29:20.000000000 -0600