Copyright (c) 2002 Bruce Fields <bfields@UMICH.EDU>
+ Copyright (c) 2014, Intel Corporation.
+
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
#include <sys/param.h>
#include <sys/stat.h>
+#include <inttypes.h>
#include <pwd.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
-#include <netdb.h>
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
#include "svcgssd.h"
#include "gss_util.h"
uint32_t cr_remote;
uint32_t cr_usr_root;
uint32_t cr_usr_mds;
+ uint32_t cr_usr_oss;
uid_t cr_uid;
uid_t cr_mapped_uid;
uid_t cr_gid;
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_usr_oss);
qword_printint(f, cred->cr_mapped_uid);
qword_printint(f, cred->cr_uid);
qword_printint(f, cred->cr_gid);
printerr(pri, "\n");
for (i = 0; i < length; i += 0x10) {
- printerr(pri, " %04x: ", (u_int)i);
+ printerr(pri, " %04x: ", (unsigned 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]);
+ printerr(pri, "%02x ", (unsigned int)cp[i+j]);
else
- printerr(pri,"%02x", (u_int)cp[i+j]);
+ printerr(pri, "%02x", (unsigned int)cp[i+j]);
}
for (; j < 16; j++) {
if ((j % 2) == 1)
gss_OID name_type = GSS_C_NO_OID;
struct passwd *pw;
- cred->cr_remote = cred->cr_usr_root = cred->cr_usr_mds = 0;
+ cred->cr_remote = 0;
+ cred->cr_usr_root = cred->cr_usr_mds = cred->cr_usr_oss = 0;
cred->cr_uid = cred->cr_mapped_uid = cred->cr_gid = -1;
maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type);
}
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 "
+ printerr(0, "WARNING: get_ids: error allocating %zu bytes "
"for sname\n", name.length + 1);
gss_release_buffer(&min_stat, &name);
return -1;
}
memcpy(sname, name.value, name.length);
+ sname[name.length] = '\0';
gss_release_buffer(&min_stat, &name);
if (lustre_svc == LUSTRE_GSS_SVC_MDS)
if (host)
*host++ = '\0';
- if (strcmp(sname, GSSD_SERVICE_OSS) == 0) {
- printerr(0, "forbid "GSSD_SERVICE_OSS" as user name\n");
+ if (strcmp(sname, GSSD_SERVICE_MGS) == 0) {
+ printerr(0, "forbid %s as a user name\n", sname);
goto out_free;
}
goto out_free;
}
} else {
- if (!strcmp(sname, GSSD_SERVICE_MDS)) {
- printerr(0, "ERROR: "GSSD_SERVICE_MDS"@%s from %016llx "
- "doesn't bind with hostname\n", realm, nid);
+ if (!strcmp(sname, GSSD_SERVICE_MDS) ||
+ !strcmp(sname, GSSD_SERVICE_OSS)) {
+ printerr(0, "ERROR: %s@%s from %016llx doesn't "
+ "bind with hostname\n", sname, realm, nid);
goto out_free;
}
}
- /* 2. check realm */
- if (!mds_local_realm || strcasecmp(mds_local_realm, realm)) {
- cred->cr_remote = 1;
-
- /* Allow mapped user from remote realm */
- if (cred->cr_mapped_uid != -1)
- res = 0;
- /* Allow OSS auth using client machine credential */
- else if (lustre_svc == LUSTRE_GSS_SVC_OSS &&
- !strcmp(sname, LUSTRE_ROOT_NAME))
- res = 0;
- /* Invalid remote user */
- else
- printerr(0, "ERROR: %s%s%s@%s from %016llx is remote "
- "but without mapping\n", sname,
- host ? "/" : "", host ? host : "", realm, nid);
+ /* 2. check realm and user */
+ switch (lustre_svc) {
+ case LUSTRE_GSS_SVC_MDS:
+ if (strcasecmp(mds_local_realm, realm)) {
+ cred->cr_remote = 1;
+
+ /* only allow mapped user from remote realm */
+ if (cred->cr_mapped_uid == -1) {
+ printerr(0, "ERROR: %s%s%s@%s from %016llx "
+ "is remote but without mapping\n",
+ sname, host ? "/" : "",
+ host ? host : "", realm, nid);
+ break;
+ }
+ } else {
+ if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_root = 1;
+ } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_mds = 1;
+ } else if (!strcmp(sname, GSSD_SERVICE_OSS)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_oss = 1;
+ } else {
+ pw = getpwnam(sname);
+ if (pw != NULL) {
+ cred->cr_uid = pw->pw_uid;
+ printerr(2, "%s resolve to uid %u\n",
+ sname, cred->cr_uid);
+ } else if (cred->cr_mapped_uid != -1) {
+ printerr(2, "user %s from %016llx is "
+ "mapped to %u\n", sname, nid,
+ cred->cr_mapped_uid);
+ } else {
+ printerr(0, "ERROR: invalid user, "
+ "%s/%s@%s from %016llx\n",
+ sname, host, realm, nid);
+ break;
+ }
+ }
+ }
- /* skip local user check */
- goto out_free;
+ res = 0;
+ break;
+ case LUSTRE_GSS_SVC_MGS:
+ if (!strcmp(sname, GSSD_SERVICE_OSS)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_oss = 1;
+ }
+ /* fall through */
+ case LUSTRE_GSS_SVC_OSS:
+ if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_root = 1;
+ } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
+ cred->cr_uid = 0;
+ cred->cr_usr_mds = 1;
+ }
+ if (cred->cr_uid == -1) {
+ printerr(0, "ERROR: svc %d doesn't accept user %s "
+ "from %016llx\n", lustre_svc, sname, nid);
+ break;
+ }
+ res = 0;
+ break;
+ default:
+ assert(0);
}
- /* 3. check user */
- if (!(pw = getpwnam(sname))) {
- /* map lustre_root/lustre_mds to root user, which is subject
- * to further mapping by root-squash in kernel. */
- if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
- cred->cr_uid = 0;
- cred->cr_usr_root = 1;
- } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
- cred->cr_uid = 0;
- cred->cr_usr_mds = 1;
- } else {
- if (cred->cr_mapped_uid == -1) {
- printerr(0, "ERROR: invalid user, %s/%s@%s "
- "from %016llx\n", sname, host,
- realm, nid);
- goto out_free;
- }
- }
- printerr(2, "user %s from %016llx is mapped to %u\n",
- sname, nid, cred->cr_mapped_uid);
- } else {
- /* note: a mapped local user will go to here too */
- cred->cr_uid = pw->pw_uid;
- printerr(2, "%s resolve to uid %u\n", sname, cred->cr_uid);
- }
-
- res = 0;
out_free:
if (!res)
printerr(1, "%s: authenticated %s%s%s@%s from %016llx\n",
gss_cred_id_t svc_cred;
u_int32_t maj_stat = GSS_S_FAILURE, min_stat = 0;
u_int32_t ignore_min_stat;
+ int get_len;
struct svc_cred cred;
static char *lbuf = NULL;
static int lbuflen = 0;
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(2, "handling req: svc %u, nid %016llx, idx %llx\n",
+ printerr(2, "handling req: svc %u, nid %016llx, idx %"PRIx64"\n",
lustre_svc, nid, handle_seq);
- in_handle.length = (size_t) qword_get(&cp, in_handle.value,
- sizeof(in_handle_buf));
- printerr(3, "in_handle: \n");
- print_hexl(3, in_handle.value, in_handle.length);
+ get_len = qword_get(&cp, in_handle.value, sizeof(in_handle_buf));
+ if (get_len < 0) {
+ printerr(0, "WARNING: handle_nullreq: "
+ "failed parsing request\n");
+ goto out_err;
+ }
+ in_handle.length = (size_t)get_len;
- in_tok.length = (size_t) qword_get(&cp, in_tok.value,
- sizeof(in_tok_buf));
- printerr(3, "in_tok: \n");
- print_hexl(3, in_tok.value, in_tok.length);
+ printerr(3, "in_handle:\n");
+ print_hexl(3, in_handle.value, in_handle.length);
- if (in_tok.length < 0) {
+ get_len = qword_get(&cp, in_tok.value, sizeof(in_tok_buf));
+ if (get_len < 0) {
printerr(0, "WARNING: handle_nullreq: "
"failed parsing request\n");
goto out_err;
}
+ in_tok.length = (size_t)get_len;
+
+ printerr(3, "in_tok:\n");
+ print_hexl(3, in_tok.value, in_tok.length);
if (in_handle.length != 0) { /* CONTINUE_INIT case */
if (in_handle.length != sizeof(ctx)) {
printerr(0, "WARNING: handle_nullreq: "
- "input handle has unexpected length %d\n",
+ "input handle has unexpected length %zu\n",
in_handle.length);
goto out_err;
}