target->cr_principal = kstrdup(source->cr_principal, GFP_KERNEL);
target->cr_raw_principal = kstrdup(source->cr_raw_principal,
GFP_KERNEL);
- if ((source->cr_principal && ! target->cr_principal) ||
- (source->cr_raw_principal && ! target->cr_raw_principal))
+ target->cr_targ_princ = kstrdup(source->cr_targ_princ, GFP_KERNEL);
+ if ((source->cr_principal && !target->cr_principal) ||
+ (source->cr_raw_principal && !target->cr_raw_principal) ||
+ (source->cr_targ_princ && !target->cr_targ_princ))
return -ENOMEM;
target->cr_flavor = source->cr_flavor;
|| (!gid_eq(cr1->cr_gid, cr2->cr_gid))
|| !groups_equal(cr1->cr_group_info, cr2->cr_group_info))
return false;
+ /* XXX: check that cr_targ_princ fields match ? */
if (cr1->cr_principal == cr2->cr_principal)
return true;
if (!cr1->cr_principal || !cr2->cr_principal)
/* name of form servicetype@hostname, passed down by
* rpc.svcgssd, or computed from the above: */
char *cr_principal;
+ char *cr_targ_princ;
struct gss_api_mech *cr_gss_mech;
};
cred->cr_group_info = NULL;
cred->cr_raw_principal = NULL;
cred->cr_principal = NULL;
+ cred->cr_targ_princ = NULL;
cred->cr_gss_mech = NULL;
}
put_group_info(cred->cr_group_info);
kfree(cred->cr_raw_principal);
kfree(cred->cr_principal);
+ kfree(cred->cr_targ_princ);
gss_mech_put(cred->cr_gss_mech);
init_svc_cred(cred);
}
return 0;
}
+static char *gssp_stringify(struct xdr_netobj *netobj)
+{
+ return kstrndup(netobj->data, netobj->len, GFP_KERNEL);
+}
+
+static void gssp_hostbased_service(char **principal)
+{
+ char *c;
+
+ if (!*principal)
+ return;
+
+ /* terminate and remove realm part */
+ c = strchr(*principal, '@');
+ if (c) {
+ *c = '\0';
+
+ /* change service-hostname delimiter */
+ c = strchr(*principal, '/');
+ if (c)
+ *c = '@';
+ }
+ if (!c) {
+ /* not a service principal */
+ kfree(*principal);
+ *principal = NULL;
+ }
+}
+
/*
* Public functions
*/
*/
.exported_context_token.len = GSSX_max_output_handle_sz,
.mech.len = GSS_OID_MAX_LEN,
+ .targ_name.display_name.len = GSSX_max_princ_sz,
.src_name.display_name.len = GSSX_max_princ_sz
};
struct gssx_res_accept_sec_context res = {
.rpc_cred = NULL, /* FIXME ? */
};
struct xdr_netobj client_name = { 0 , NULL };
+ struct xdr_netobj target_name = { 0, NULL };
int ret;
if (data->in_handle.len != 0)
if (ret)
return ret;
- /* use nfs/ for targ_name ? */
-
ret = gssp_call(net, &msg);
gssp_free_receive_pages(&arg);
kfree(rctxh.mech.data);
}
client_name = rctxh.src_name.display_name;
+ target_name = rctxh.targ_name.display_name;
}
if (res.options.count == 1) {
}
/* convert to GSS_NT_HOSTBASED_SERVICE form and set into creds */
- if (data->found_creds && client_name.data != NULL) {
- char *c;
-
- data->creds.cr_raw_principal = kstrndup(client_name.data,
- client_name.len, GFP_KERNEL);
-
- data->creds.cr_principal = kstrndup(client_name.data,
- client_name.len, GFP_KERNEL);
- if (data->creds.cr_principal) {
- /* terminate and remove realm part */
- c = strchr(data->creds.cr_principal, '@');
- if (c) {
- *c = '\0';
-
- /* change service-hostname delimiter */
- c = strchr(data->creds.cr_principal, '/');
- if (c) *c = '@';
- }
- if (!c) {
- /* not a service principal */
- kfree(data->creds.cr_principal);
- data->creds.cr_principal = NULL;
- }
+ if (data->found_creds) {
+ if (client_name.data) {
+ data->creds.cr_raw_principal =
+ gssp_stringify(&client_name);
+ data->creds.cr_principal =
+ gssp_stringify(&client_name);
+ gssp_hostbased_service(&data->creds.cr_principal);
+ }
+ if (target_name.data) {
+ data->creds.cr_targ_princ =
+ gssp_stringify(&target_name);
+ gssp_hostbased_service(&data->creds.cr_targ_princ);
}
}
kfree(client_name.data);
+ kfree(target_name.data);
return ret;
}