---- 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 <syslog.h>
- #include <string.h>
- #include <gssapi/gssapi.h>
+--- 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 <sys/param.h>
-#include <rpc/rpc.h>
--#include <rpc/auth_gss.h>
- #include "gss_util.h"
+ #include <sys/stat.h>
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+@@ -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 <rpc/rpc.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;
-
- 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 <string.h>
- #include <errno.h>
- #include <gssapi/gssapi.h>
--#include <rpc/rpc.h>
--#include <rpc/auth_gss.h>
- #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 <syslog.h>
- #include <string.h>
- #include <gssapi/gssapi.h>
--#include <rpc/rpc.h>
--#include <rpc/auth_gss.h>
- #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 <stdarg.h>
- #include <syslog.h>
- #include <string.h>
-+#include <fcntl.h>
-+#include <ctype.h>
- #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 <sys/param.h>
- #include <sys/socket.h>
--#include <rpc/rpc.h>
-
- #include <unistd.h>
- #include <err.h>
-@@ -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 <sys/param.h>
--#include <rpc/rpc.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
-@@ -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;
+ 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));
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 <com_err.h>
- #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 <string.h>
+ #include <errno.h>
+ #include <gssapi/gssapi.h>
+-#include <rpc/rpc.h>
+-#include <rpc/auth_gss.h>
+ #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 <rpc/rpc.h>
+-
+ 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 <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/socket.h>
+-#include <rpc/rpc.h>
+ #include <fcntl.h>
+ #include <errno.h>
-@@ -201,12 +244,20 @@
+@@ -54,11 +53,33 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <signal.h>
+-#include "nfslib.h"
++#include <dirent.h>
+ #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/<your.host>@<YOUR.REALM> 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 <stdlib.h>
--#include <rpc/rpc.h>
- #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 <rpc/rpc.h>
- #include <sys/types.h>
+ #include <sys/param.h>
#include <sys/stat.h>
-+#include <sys/utsname.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
+-#include <rpc/rpc.h>
+ #include <pwd.h>
#include <stdio.h>
- #include <stdlib.h>
+@@ -44,25 +43,28 @@
#include <string.h>
-+#include <netdb.h>
- #include <dirent.h>
#include <fcntl.h>
#include <errno.h>
-@@ -114,7 +116,6 @@
- #include <gssapi/gssapi_krb5.h>
- #endif
- #include <krb5.h>
--#include <rpc/auth_gss.h>
+-#include <nfsidmap.h>
++#include <netdb.h>
- #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 : "<unparsable>", 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/<your.host>@<YOUR.REALM> in "
-+ printerr(0, "You must have a valid keytab entry for "
-+ "%s/<your.host>@<YOUR.REALM> on MDT nodes, "
-+ "and %s@<YOUR.REALM> 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 <com_err.h>
+ #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 <krb5.h>
++ 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 <stdlib.h>
+-#include <rpc/rpc.h>
+ #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 <krb5.h>
++
++/*
++ * 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 <rpc/rpc.h>
#include <sys/types.h>
#include <sys/stat.h>
++#include <sys/utsname.h>
#include <sys/socket.h>
--#include <rpc/rpc.h>
- #include <fcntl.h>
- #include <errno.h>
+ #include <arpa/inet.h>
-@@ -54,11 +53,33 @@
+ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
- #include <signal.h>
--#include "nfslib.h"
-+#include <dirent.h>
- #include "svcgssd.h"
- #include "gss_util.h"
++#include <netdb.h>
+ #include <dirent.h>
+ #include <fcntl.h>
+ #include <errno.h>
+@@ -114,7 +116,6 @@
+ #include <gssapi/gssapi_krb5.h>
+ #endif
+ #include <krb5.h>
+-#include <rpc/auth_gss.h>
+
+ #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 : "<unparsable>", 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/<your.host>@<YOUR.REALM> 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 <gssapi/gssapi.h>
-
- 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 <sys/param.h>
- #include <sys/stat.h>
--#include <rpc/rpc.h>
-
- #include <pwd.h>
- #include <stdio.h>
-@@ -44,25 +43,28 @@
- #include <string.h>
- #include <fcntl.h>
- #include <errno.h>
--#include <nfsidmap.h>
-+#include <netdb.h>
-
- #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/<your.host>@<YOUR.REALM> in "
++ printerr(0, "You must have a valid keytab entry for "
++ "%s/<your.host>@<YOUR.REALM> on MDT nodes, "
++ "and %s@<YOUR.REALM> 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 <syslog.h>
+ #include <string.h>
+ #include <gssapi/gssapi.h>
+-#include <rpc/rpc.h>
+-#include <rpc/auth_gss.h>
+ #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 <unistd.h>
++#include <stdint.h>
+
-+ 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 <stdarg.h>
+ #include <syslog.h>
+ #include <string.h>
++#include <fcntl.h>
++#include <ctype.h>
+ #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 <syslog.h>
+ #include <string.h>
+ #include <gssapi/gssapi.h>
+-#include <rpc/rpc.h>
+-#include <rpc/auth_gss.h>
+ #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 <sys/param.h>
+ #include <sys/socket.h>
+-#include <rpc/rpc.h>
+
+ #include <unistd.h>
+ #include <err.h>
+@@ -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:
+ *
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
-+#include <netdb.h>
+#include <assert.h>
++#ifdef HAVE_GETHOSTBYNAME
++# include <netdb.h>
++#endif
+
+#include "err_util.h"
+#include "gssd.h"
+
+/****************************************
+ * 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;
+ 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;
+}
+
+}
+
+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");
+
+ 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)
+
+ 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 *
+
+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;
+};
+
+
+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)
+ 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;
+}
+ 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];
+ 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) {
+ }
+
+ 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)) {
+ 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 <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
-+ */
-+
-+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 <gssapi/gssapi.h>
+
+ 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 =
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)
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