else
keyptr = &lctx->cfx_kd.ctx_key;
-#if 0
- if (lctx->initiate == 1) {
- sign_usage = KG_USAGE_INITIATOR_SIGN;
- seal_usage = KG_USAGE_INITIATOR_SEAL;
- } else {
- 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?
+ * 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
+ * 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
/* derive and send down: Ke, Ki, and Kc */
signal(SIGTERM, sig_die);
signal(SIGHUP, sig_hup);
-#if 0
- /* Determine Kerberos information from the kernel */
- gssd_obtain_kernel_krb5_info();
-#endif
-
lgssd_init_mutexs();
printerr(0, "lgssd initialized and ready to serve\n");
void init_client_list(void);
int update_client_list(void);
void handle_krb5_upcall(struct clnt_info *clp);
-void handle_spkm3_upcall(struct clnt_info *clp);
void lgssd_run(void);
if (i >= 0 && pollarray[i].revents) {
if (pollarray[i].revents & POLLHUP)
dir_changed = 1;
- if (pollarray[i].revents & POLLIN)
- handle_spkm3_upcall(clp);
pollarray[clp->spkm3_poll_index].revents = 0;
ret--;
if (!ret)
return -1;
}
-#if 0
-/*
- * Create an RPC connection and establish an authenticated
- * gss context with a server.
- */
-int create_auth_rpc_client(struct clnt_info *clp,
- CLIENT **clnt_return,
- AUTH **auth_return,
- uid_t uid,
- int authtype)
-{
- CLIENT *rpc_clnt = NULL;
- struct rpc_gss_sec sec;
- AUTH *auth = NULL;
- uid_t save_uid = -1;
- int retval = -1;
- int errcode;
- OM_uint32 min_stat;
- char rpc_errmsg[1024];
- int sockp = RPC_ANYSOCK;
- int sendsz = 32768, recvsz = 32768;
- struct addrinfo ai_hints, *a = NULL;
- char service[64];
- char *at_sign;
-
- /* Create the context as the user (not as root) */
- save_uid = geteuid();
- if (setfsuid(uid) != 0) {
- printerr(0, "WARNING: Failed to setfsuid for "
- "user with uid %d\n", uid);
- goto out_fail;
- }
- printerr(2, "creating context using fsuid %d (save_uid %d)\n",
- uid, save_uid);
-
- sec.qop = GSS_C_QOP_DEFAULT;
- sec.svc = RPCSEC_GSS_SVC_NONE;
- sec.cred = GSS_C_NO_CREDENTIAL;
- sec.req_flags = 0;
- if (authtype == AUTHTYPE_KRB5) {
- sec.mech = (gss_OID)&krb5oid;
- sec.req_flags = GSS_C_MUTUAL_FLAG;
- }
- else if (authtype == AUTHTYPE_SPKM3) {
- sec.mech = (gss_OID)&spkm3oid;
- /* XXX sec.req_flags = GSS_C_ANON_FLAG;
- * Need a way to switch....
- */
- sec.req_flags = GSS_C_MUTUAL_FLAG;
- }
- else {
- printerr(0, "ERROR: Invalid authentication type (%d) "
- "in create_auth_rpc_client\n", authtype);
- goto out_fail;
- }
-
-
- if (authtype == AUTHTYPE_KRB5) {
-#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
- /*
- * Do this before creating rpc connection since we won't need
- * rpc connection if it fails!
- */
- if (limit_krb5_enctypes(&sec, uid)) {
- printerr(1, "WARNING: Failed while limiting krb5 "
- "encryption types for user with uid %d\n",
- uid);
- goto out_fail;
- }
-#endif
- }
-
- /* create an rpc connection to the nfs server */
-
- printerr(2, "creating %s client for server %s\n", clp->protocol,
- clp->servername);
-
- memset(&ai_hints, '\0', sizeof(ai_hints));
- ai_hints.ai_family = PF_INET;
- ai_hints.ai_flags |= AI_CANONNAME;
- if ((strcmp(clp->protocol, "tcp")) == 0) {
- ai_hints.ai_socktype = SOCK_STREAM;
- ai_hints.ai_protocol = IPPROTO_TCP;
- } else if ((strcmp(clp->protocol, "udp")) == 0) {
- ai_hints.ai_socktype = SOCK_DGRAM;
- ai_hints.ai_protocol = IPPROTO_UDP;
- } else {
- printerr(0, "WARNING: unrecognized protocol, '%s', requested "
- "for connection to server %s for user with uid %d",
- clp->protocol, clp->servername, uid);
- goto out_fail;
- }
-
- /* extract the service name from clp->servicename */
- if ((at_sign = strchr(clp->servicename, '@')) == NULL) {
- printerr(0, "WARNING: servicename (%s) not formatted as "
- "expected with service@host", clp->servicename);
- goto out_fail;
- }
- if ((at_sign - clp->servicename) >= sizeof(service)) {
- printerr(0, "WARNING: service portion of servicename (%s) "
- "is too long!", clp->servicename);
- goto out_fail;
- }
- strncpy(service, clp->servicename, at_sign - clp->servicename);
- service[at_sign - clp->servicename] = '\0';
-
- errcode = getaddrinfo(clp->servername, service, &ai_hints, &a);
- if (errcode) {
- printerr(0, "WARNING: Error from getaddrinfo for server "
- "'%s': %s", clp->servername, gai_strerror(errcode));
- goto out_fail;
- }
-
- if (a == NULL) {
- printerr(0, "WARNING: No address information found for "
- "connection to server %s for user with uid %d",
- clp->servername, uid);
- goto out_fail;
- }
- if (a->ai_protocol == IPPROTO_TCP) {
- if ((rpc_clnt = clnttcp_create(
- (struct sockaddr_in *) a->ai_addr,
- clp->prog, clp->vers, &sockp,
- sendsz, recvsz)) == NULL) {
- snprintf(rpc_errmsg, sizeof(rpc_errmsg),
- "WARNING: can't create tcp rpc_clnt "
- "for server %s for user with uid %d",
- clp->servername, uid);
- printerr(0, "%s\n",
- clnt_spcreateerror(rpc_errmsg));
- goto out_fail;
- }
- } else if (a->ai_protocol == IPPROTO_UDP) {
- const struct timeval timeout = {5, 0};
- if ((rpc_clnt = clntudp_bufcreate(
- (struct sockaddr_in *) a->ai_addr,
- clp->prog, clp->vers, timeout,
- &sockp, sendsz, recvsz)) == NULL) {
- snprintf(rpc_errmsg, sizeof(rpc_errmsg),
- "WARNING: can't create udp rpc_clnt "
- "for server %s for user with uid %d",
- clp->servername, uid);
- printerr(0, "%s\n",
- clnt_spcreateerror(rpc_errmsg));
- goto out_fail;
- }
- } else {
- /* Shouldn't happen! */
- printerr(0, "ERROR: requested protocol '%s', but "
- "got addrinfo with protocol %d",
- clp->protocol, a->ai_protocol);
- goto out_fail;
- }
- /* We're done with this */
- freeaddrinfo(a);
- a = NULL;
-
- printerr(2, "creating context with server %s\n", clp->servicename);
- auth = authgss_create_default(rpc_clnt, clp->servicename, &sec);
- if (!auth) {
- /* Our caller should print appropriate message */
- printerr(2, "WARNING: Failed to create %s context for "
- "user with uid %d for server %s\n",
- (authtype == AUTHTYPE_KRB5 ? "krb5":"spkm3"),
- uid, clp->servername);
- goto out_fail;
- }
-
- /* Success !!! */
- rpc_clnt->cl_auth = auth;
- *clnt_return = rpc_clnt;
- *auth_return = auth;
- retval = 0;
-
- out:
- if (sec.cred != GSS_C_NO_CREDENTIAL)
- gss_release_cred(&min_stat, &sec.cred);
- if (a != NULL) freeaddrinfo(a);
- /* Restore euid to original value */
- if ((save_uid != -1) && (setfsuid(save_uid) != uid)) {
- printerr(0, "WARNING: Failed to restore fsuid"
- " to uid %d from %d\n", save_uid, uid);
- }
- return retval;
-
- out_fail:
- /* Only destroy here if failure. Otherwise, caller is responsible */
- if (rpc_clnt) clnt_destroy(rpc_clnt);
-
- goto out;
-}
-#endif
-
static
int do_negotiation(struct lustre_gss_data *lgd,
gss_buffer_desc *gss_token,
goto out;
}
-/*
- * this code uses the userland rpcsec gss library to create an spkm3
- * context on behalf of the kernel
- */
-void
-handle_spkm3_upcall(struct clnt_info *clp)
-{
-#if 0
- uid_t uid;
- CLIENT *rpc_clnt = NULL;
- AUTH *auth = NULL;
- struct authgss_private_data pd;
- gss_buffer_desc token;
-
- printerr(2, "handling spkm3 upcall\n");
-
- token.length = 0;
- token.value = NULL;
-
- if (read(clp->spkm3_fd, &uid, sizeof(uid)) < sizeof(uid)) {
- printerr(0, "WARNING: failed reading uid from spkm3 "
- "upcall pipe: %s\n", strerror(errno));
- goto out;
- }
-
- if (create_auth_rpc_client(clp, &rpc_clnt, &auth, uid, AUTHTYPE_SPKM3)) {
- printerr(0, "WARNING: Failed to create spkm3 context for "
- "user with uid %d\n", uid);
- goto out_return_error;
- }
-
- if (!authgss_get_private_data(auth, &pd)) {
- printerr(0, "WARNING: Failed to obtain authentication "
- "data for user with uid %d for server %s\n",
- uid, clp->servername);
- goto out_return_error;
- }
-
- if (serialize_context_for_kernel(pd.pd_ctx, &token, &spkm3oid)) {
- printerr(0, "WARNING: Failed to serialize spkm3 context for "
- "user with uid %d for server\n",
- uid, clp->servername);
- goto out_return_error;
- }
-
- do_downcall(clp->spkm3_fd, uid, &pd, &token);
-
-out:
- if (token.value)
- free(token.value);
- if (auth)
- AUTH_DESTROY(auth);
- if (rpc_clnt)
- clnt_destroy(rpc_clnt);
- return;
-
-out_return_error:
- do_error_downcall(clp->spkm3_fd, uid, -1);
- goto out;
-#endif
-}
krb5_free_context(context);
}
-#if 0
-#ifdef HAVE_SET_ALLOWABLE_ENCTYPES
-/*
- * this routine obtains a credentials handle via gss_acquire_cred()
- * then calls gss_krb5_set_allowable_enctypes() to limit the encryption
- * types negotiated.
- *
- * Returns:
- * 0 => all went well
- * -1 => there was an error
- */
-
-int
-limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
-{
- unsigned int maj_stat, min_stat;
- gss_cred_id_t credh;
- gss_OID_set_desc desired_mechs;
- krb5_enctype enctypes[] = {ENCTYPE_DES_CBC_CRC};
- int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
-
- /* We only care about getting a krb5 cred */
- desired_mechs.count = 1;
- desired_mechs.elements = &krb5oid;
-
- maj_stat = gss_acquire_cred(&min_stat, NULL, 0,
- &desired_mechs, GSS_C_INITIATE,
- &credh, NULL, NULL);
-
- if (maj_stat != GSS_S_COMPLETE) {
- pgsserr("gss_acquire_cred",
- maj_stat, min_stat, &krb5oid);
- return -1;
- }
-
- /*
- * If we failed for any reason to produce global
- * list of supported enctypes, use local default here.
- */
- if (krb5_enctypes == NULL)
- maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
- &krb5oid, num_enctypes, &enctypes);
- else
- maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
- &krb5oid, num_krb5_enctypes,
- krb5_enctypes);
- if (maj_stat != GSS_S_COMPLETE) {
- pgsserr("gss_set_allowable_enctypes",
- maj_stat, min_stat, &krb5oid);
- return -1;
- }
- sec->cred = credh;
- return 0;
-}
-#endif /* HAVE_SET_ALLOWABLE_ENCTYPES */
-#endif
-
-#if 0
-/*
- * Obtain supported enctypes from kernel.
- * Set defaults if info is not available.
- */
-void
-gssd_obtain_kernel_krb5_info(void)
-{
- char enctype_file_name[128];
- char buf[1024];
- char enctypes[128];
- int nscanned;
- int fd;
- int use_default_enctypes = 0;
- int nbytes, numfields;
- char default_enctypes[] = "1,3,2";
- int code;
-
- snprintf(enctype_file_name, sizeof(enctype_file_name),
- "%s/%s", pipefs_dir, "krb5_info");
-
- if ((fd = open(enctype_file_name, O_RDONLY)) == -1) {
- printerr(1, "WARNING: gssd_obtain_kernel_krb5_info: "
- "Unable to open '%s'. Unable to determine "
- "Kerberos encryption types supported by the "
- "kernel; using defaults (%s).\n",
- enctype_file_name, default_enctypes);
- use_default_enctypes = 1;
- goto do_the_parse;
- }
- memset(buf, 0, sizeof(buf));
- if ((nbytes = read(fd, buf, sizeof(buf)-1)) == -1) {
- printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
- "Error reading Kerberos encryption type "
- "information file '%s'; using defaults (%s).\n",
- enctype_file_name, default_enctypes);
- use_default_enctypes = 1;
- close(fd);
- goto do_the_parse;
- }
- close(fd);
- numfields = sscanf(buf, "enctypes: %s\n%n", enctypes, &nscanned);
- if (numfields < 1) {
- printerr(0, "WARNING: gssd_obtain_kernel_krb5_info: "
- "error parsing Kerberos encryption type "
- "information from file '%s'; using defaults (%s).\n",
- enctype_file_name, default_enctypes);
- use_default_enctypes = 1;
- goto do_the_parse;
- }
- if (nbytes > nscanned) {
- printerr(2, "gssd_obtain_kernel_krb5_info: "
- "Ignoring extra information, '%s', from '%s'\n",
- buf+nscanned, enctype_file_name);
- goto do_the_parse;
- }
- do_the_parse:
- if (use_default_enctypes)
- strcpy(enctypes, default_enctypes);
-
- if ((code = parse_enctypes(enctypes)) != 0) {
- printerr(0, "ERROR: gssd_obtain_kernel_krb5_info: "
- "parse_enctypes%s failed with code %d\n",
- use_default_enctypes ? " (with default enctypes)" : "",
- code);
- }
-}
-#endif
#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)
-{
- int ret;
- static gid_t *groups = NULL;
-
- cred->cr_ngroups = NGROUPS;
- ret = nfs4_gss_princ_to_grouplist(secname, name,
- cred->cr_groups, &cred->cr_ngroups);
- if (ret < 0) {
- groups = realloc(groups, cred->cr_ngroups*sizeof(gid_t));
- ret = nfs4_gss_princ_to_grouplist(secname, name,
- groups, &cred->cr_ngroups);
- if (ret < 0)
- cred->cr_ngroups = 0;
- else {
- if (cred->cr_ngroups > NGROUPS)
- cred->cr_ngroups = NGROUPS;
- memcpy(cred->cr_groups, groups,
- cred->cr_ngroups*sizeof(gid_t));
- }
- }
-}
-#endif
-
-#if 0
-static int
-get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred)
-{
- u_int32_t maj_stat, min_stat;
- gss_buffer_desc name;
- char *sname;
- int res = -1;
- uid_t uid, gid;
- gss_OID name_type = GSS_C_NO_OID;
- char *secname;
-
- 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);
- goto out;
- }
- 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);
- goto out;
- }
- memcpy(sname, name.value, name.length);
- printerr(1, "sname = %s\n", sname);
- gss_release_buffer(&min_stat, &name);
-
- res = -EINVAL;
- if ((secname = mech2file(mech)) == NULL) {
- printerr(0, "WARNING: get_ids: error mapping mech to "
- "file for name '%s'\n", sname);
- goto out_free;
- }
- nfs4_init_name_mapping(NULL); /* XXX: should only do this once */
- res = nfs4_gss_princ_to_ids(secname, sname, &uid, &gid);
- if (res < 0) {
- /*
- * -ENOENT means there was no mapping, any other error
- * value means there was an error trying to do the
- * mapping.
- * If there was no mapping, we send down the value -1
- * to indicate that the anonuid/anongid for the export
- * should be used.
- */
- if (res == -ENOENT) {
- cred->cr_uid = -1;
- cred->cr_gid = -1;
- cred->cr_ngroups = 0;
- res = 0;
- goto out_free;
- }
- printerr(0, "WARNING: get_ids: failed to map name '%s' "
- "to uid/gid: %s\n", sname, strerror(-res));
- goto out_free;
- }
- cred->cr_uid = uid;
- cred->cr_gid = gid;
- add_supplementary_groups(secname, sname, cred);
- res = 0;
-out_free:
- free(sname);
-out:
- return res;
-}
-#endif
-
-#if 0
-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: ", (unsigned int)i);
- jm = length - i;
- jm = jm > 16 ? 16 : jm;
-
- for (j = 0; j < jm; j++) {
- if ((j % 2) == 1)
- printerr(pri, "%02x ", (unsigned int)cp[i+j]);
- else
- printerr(pri, "%02x", (unsigned 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");
- }
-}
-#endif
-
static int
get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
lnet_nid_t nid, uint32_t lustre_svc)