Re: apropos freebsd / heimdal / gssapi questions
Harry Coin <[email protected]>
| Newsgroups | gmane.comp.encryption.kerberos.heimdal.general |
|---|---|
| Message-ID | <[email protected]> |
Re: questions about the flexibility in principal naming / gss / heimdal
in freebsd. Here's some relevant code. Note this is not NFS specific.
\usr\src\lib\librpcsec_gss\svc_rpcsec_gss.c
...
bool_t
rpc_gss_get_principal_name(rpc_gss_principal_t *principal,
const char *mech, const char *name, const char *node, const char
*domain)
{
OM_uint32 maj_stat, min_stat;
gss_OID mech_oid;
size_t namelen;
gss_buffer_desc buf;
gss_name_t gss_name, gss_mech_name;
rpc_gss_principal_t result;
svc_rpc_gss_init();
if (!rpc_gss_mech_to_oid(mech, &mech_oid))
return (FALSE);
/*
* Construct a gss_buffer containing the full name formatted
* as "name/node@domain" where node and domain are optional.
*/
namelen = strlen(name);
if (node) {
namelen += strlen(node) + 1;
}
if (domain) {
namelen += strlen(domain) + 1;
}
buf.value = mem_alloc(namelen);
buf.length = namelen;
strcpy((char *) buf.value, name);
if (node) {
strcat((char *) buf.value, "/");
strcat((char *) buf.value, node);
}
if (domain) {
strcat((char *) buf.value, "@");
strcat((char *) buf.value, domain);
}
/*
* Convert that to a gss_name_t and then convert that to a
* mechanism name in the selected mechanism.
*/
maj_stat = gss_import_name(&min_stat, &buf,
GSS_C_NT_USER_NAME, &gss_name);
mem_free(buf.value, buf.length);
if (maj_stat != GSS_S_COMPLETE) {
log_status("gss_import_name", mech_oid, maj_stat, min_stat);
return (FALSE);
}
maj_stat = gss_canonicalize_name(&min_stat, gss_name, mech_oid,
&gss_mech_name);
if (maj_stat != GSS_S_COMPLETE) {
log_status("gss_canonicalize_name", mech_oid, maj_stat,
min_stat);
gss_release_name(&min_stat, &gss_name);
return (FALSE);
}
gss_release_name(&min_stat, &gss_name);
/*
* Export the mechanism name and use that to construct the
* rpc_gss_principal_t result.
*/
maj_stat = gss_export_name(&min_stat, gss_mech_name, &buf);
if (maj_stat != GSS_S_COMPLETE) {
log_status("gss_export_name", mech_oid, maj_stat, min_stat);
gss_release_name(&min_stat, &gss_mech_name);
return (FALSE);
}
gss_release_name(&min_stat, &gss_mech_name);
result = mem_alloc(sizeof(int) + buf.length);
if (!result) {
gss_release_buffer(&min_stat, &buf);
return (FALSE);
}
result->len = buf.length;
memcpy(result->name, buf.value, buf.length);
gss_release_buffer(&min_stat, &buf);
*principal = result;
return (TRUE);
}
...
static void
svc_rpc_gss_build_ucred(struct svc_rpc_gss_client *client,
const gss_name_t name)
{
OM_uint32 maj_stat, min_stat;
char buf[128]; <-- bug that gets a normal user things
like files owned by root:nonpriv should be 1024.
uid_t uid;
struct passwd pwd, *pw;
rpc_gss_ucred_t *uc = &client->cl_ucred;
uc->uid = 65534;
uc->gid = 65534;
uc->gidlen = 0;
uc->gidlist = client->cl_gid_storage;
maj_stat = gss_pname_to_uid(&min_stat, name, client->cl_mech, &uid);
if (maj_stat != GSS_S_COMPLETE)
return;
getpwuid_r(uid, &pwd, buf, sizeof(buf), &pw);
if (pw) {
int len = NGRPS;
uc->uid = pw->pw_uid;
uc->gid = pw->pw_gid;
uc->gidlist = client->cl_gid_storage;
getgrouplist(pw->pw_name, pw->pw_gid, uc->gidlist, &len);
uc->gidlen = len;
}
}