/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <thread.h>
#include <synch.h>
#include <syslog.h>
#include <deflt.h>
#include <mechglueP.h>
static int uid_map_opt = 0;
extern int _getgroupsbymember(const char *, gid_t[], int, int);
/* local function used to call a mechanisms pname_to_uid */
/*
* The gsscred functions will first attempt to call the
* mechanism'm pname_to_uid function. In case this function
* returns an error or if it is not provided by a mechanism
* then the functions will attempt to look up the principal
* in the gsscred table.
* It is envisioned that the pname_to_uid function will be
* provided by only a few mechanism, which may have the principal
* name to unix credential mapping inherently present.
*/
/*
* Fetch gsscred options from conf file.
*/
static void
{
int flags;
char *ptr;
void *defp;
*uid_map = 0;
/* ignore case */
*uid_map = 1;
}
}
}
void
{
int u;
get_conf_options(&u);
(void) mutex_lock(&uid_map_lock);
uid_map_opt = u;
(void) mutex_unlock(&uid_map_lock);
}
static int
{
int u;
(void) mutex_lock(&uid_map_lock);
u = uid_map_opt;
(void) mutex_unlock(&uid_map_lock);
return (u);
}
/*
* This routine accepts a name in export name format and retrieves
* unix credentials associated with it.
*/
const gss_buffer_t expName,
int *gidsLen,
int try_mech)
{
return (GSS_S_CALL_INACCESSIBLE_WRITE);
return (GSS_S_CALL_INACCESSIBLE_READ);
/* first check the mechanism for the mapping */
&intName) == GSS_S_COMPLETE) {
if (debug) {
if (major == GSS_S_COMPLETE) {
}
}
if (try_mech) {
if (major == GSS_S_COMPLETE) {
if (debug) {
"%s: mech provided local name"
" mapping (%s, %s, %d)", whoami,
*uidOut);
}
return (gss_get_group_info(*uidOut,
return (GSS_S_COMPLETE);
}
}
}
/*
* we fall back onto the gsscred table to provide the mapping
* start by making sure that the expName is an export name buffer
*/
"%s: gsscred tbl provided"
" local name mapping (%s, %s, %d)",
*uidOut);
} else if (debug) {
"%s: gsscred tbl could NOT"
" provide local name mapping (%s, %s)",
}
return (major);
} /* gsscred_expname_to_unix_cred */
const gss_buffer_t expName,
int *gidsLen)
{
gidsLen, 1));
}
/*
* private routine added to be called from gsscred_name_to_unix_cred
* and gsscred_expName_to_unix_cred.
*/
static OM_uint32
const gss_buffer_t expName;
int *gidsLen;
{
return (GSS_S_DEFECTIVE_TOKEN);
return (GSS_S_FAILURE);
/* did caller request group info also ? */
return (GSS_S_COMPLETE);
}
/*
* Return a string of the authenticated name.
* It's a bit of hack/workaround/longroad but the current intName
* passed to gss_display_name insists on returning an empty string.
*
* Caller must free string memory.
*/
static
char *make_name_str(
const gss_name_t intName,
{
return (NULL);
if (major)
return (NULL);
&iName) == GSS_S_COMPLETE) {
if (major == GSS_S_COMPLETE) {
char *s;
return (s);
}
}
return (NULL);
}
/*
* This routine accepts a name in gss internal name format together with
* a mechanim OID and retrieves a unix credentials for that entity.
*/
const gss_name_t intName,
int *gidsLen,
int try_mech)
{
const char *mechStr;
return (GSS_S_CALL_INACCESSIBLE_READ);
return (GSS_S_CALL_INACCESSIBLE_WRITE);
/* first try the mechanism provided mapping */
== GSS_S_COMPLETE) {
if (debug) {
"%s: mech provided local name"
" mapping (%s, %s, %d)", whoami,
s ? s : "<null>",
*uidOut);
free(s);
}
gidsLen));
return (GSS_S_COMPLETE);
}
/*
* falling back onto the gsscred table to provide the mapping
* start by canonicalizing the passed in name and then export it
*/
return (major);
if (major)
return (major);
if (debug) {
NULL);
if (maj == GSS_S_COMPLETE) {
}
}
if (major == GSS_S_COMPLETE)
"%s: gsscred tbl provided"
" local name mapping (%s, %s, %d)",
*uidOut);
else
"%s: gsscred tbl could NOT"
" provide local name mapping (%s, %s)",
}
return (major);
} /* gsscred_name_to_unix_cred */
const gss_name_t intName,
int *gidsLen)
{
}
/*
* This routine accepts a unix uid, and retrieves the group id
* and supplamentery group ids for that uid.
* Callers should be aware that the supplamentary group ids
* array may be empty even when this function returns success.
*/
int *gidsLen;
{
int maxgroups;
/* check for output parameters */
return (GSS_S_CALL_INACCESSIBLE_WRITE);
*gidsLen = 0;
/* determine maximum number of groups possible */
if (maxgroups < 1)
maxgroups = 16;
return (GSS_S_FAILURE);
/*
* we allocate for the maximum number of groups
* we do not reclaim the space when the actual number
* is lower, just set the size approprately.
*/
return (GSS_S_FAILURE);
/*
* we will try to remove the duplicate entry from the groups
* array. This can cause the group array to be empty.
*/
if (*gidsLen < 1)
{
return (GSS_S_FAILURE);
} else if (*gidsLen == 1) {
*gidsLen = 0;
} else {
/* length is atleast 2 */
}
return (GSS_S_COMPLETE);
} /* gss_get_group_info */
static OM_uint32
const gss_name_t name;
{
if (!minor)
return (GSS_S_CALL_INACCESSIBLE_WRITE);
*minor = 0;
return (GSS_S_CALL_INACCESSIBLE_WRITE);
return (GSS_S_CALL_INACCESSIBLE_READ);
else {
/*
* if this is a MN, then try using the mech
* from the name; otherwise ask for default
*/
}
return (GSS_S_UNAVAILABLE);
/* may need to import the name if this is not MN */
&mechName);
if (major != GSS_S_COMPLETE)
return (major);
} else
/* now call the mechanism's pname function to do the work */
&mechName);
return (major);
} /* gss_pname_to_uid */