idmap_kapi.c revision be47d14853d0e04809e26e9ff241631dfbd15d94
/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Windows to Solaris Identity Mapping kernel API
* This module provides an API to map Windows SIDs to
* Solaris UID and GIDs.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <rpc/rpc_sztypes.h>
#ifdef DEBUG
#endif /* DEBUG */
#include <sys/sysmacros.h>
#include "idmap_prot.h"
#include "kidmap_priv.h"
static kmutex_t idmap_lock;
static idmap_cache_t idmap_cache;
/*
* Used to hold RPC header, in particular the XID (not that XID matters
* in doors RPC)
*/
typedef struct idmap_get_res {
int *is_user;
const char **sid_prefix;
/* Batch mapping handle structure */
struct idmap_get_handle {
int mapping_num;
int mapping_size;
};
static kmutex_t idmap_mutex;
static int idmap_stopped = 0;
struct idmap_reg {
int idmap_invalid;
int idmap_invalidated;
int idmap_ref;
};
static idmap_reg_t *idmap_ptr;
static int
static void
{
door_ki_rele(p->idmap_door);
if (idmap_ptr == p)
kmem_free(p, sizeof (*p));
}
void
{
return;
}
}
void
{
/*
* Note we may decrement idmap_ref twice; if we do it's because
* we had EBADF, and rather than decrement the ref count where
* that happens we do it here to make sure that we do both
* decrements while holding idmap_mutex.
*/
return;
}
}
}
int
{
if (idmap_stopped) {
/*
* We're unloading the module. Calling idmap_reg(2)
* again once we're done unloading should cause the
* module to be loaded again, so we return EAGAIN.
*/
return (EAGAIN);
}
}
idmp->idmap_invalid = 0;
idmp->idmap_invalidated = 0;
return (0);
}
int
{
return (EINVAL);
}
if (idmap_ptr->idmap_invalid) {
return (EINVAL);
}
return (0);
}
static int
{
int status = 0;
return (-1);
}
#ifdef DEBUG
if (status != 0)
#endif /* DEBUG */
}
return (status);
}
int
kidmap_start(void)
{
idmap_stopped = 0;
return (0);
}
int
kidmap_stop(void)
{
return (EBUSY);
}
idmap_stopped = 1;
return (0);
}
/*
* Given Domain SID and RID, get UID
*
* Input:
* sid_prefix - Domain SID in canonical form
* rid - RID
*
* Output:
* uid - POSIX UID if return == IDMAP_SUCCESS
*
* Return:
* Success return IDMAP_SUCCESS else IDMAP error
*/
{
int is_user;
const char *new_sid_prefix;
return (IDMAP_ERR_ARG);
return (IDMAP_SUCCESS);
}
/* Door call succeded */
if (status == IDMAP_SUCCESS) {
}
} else {
*uid = UID_NOBODY;
}
} else {
/* Door call failed */
*uid = UID_NOBODY;
}
return (status);
}
/*
* Given Domain SID and RID, get GID
*
* Input:
* sid_prefix - Domain SID in canonical form
* rid - RID
*
* Output:
* gid - POSIX UID if return == IDMAP_SUCCESS
*
* Return:
* Success return IDMAP_SUCCESS else IDMAP error
*/
{
int is_user;
const char *new_sid_prefix;
return (IDMAP_ERR_ARG);
return (IDMAP_SUCCESS);
}
/* Door call succeded */
if (status == IDMAP_SUCCESS) {
}
} else {
*gid = GID_NOBODY;
}
} else {
/* Door call failed */
*gid = GID_NOBODY;
}
return (status);
}
/*
* Given Domain SID and RID, get Posix ID
*
* Input:
* sid_prefix - Domain SID in canonical form
* rid - RID
*
* Output:
* pid - POSIX ID if return == IDMAP_SUCCESS
* is_user - 1 == UID, 0 == GID if return == IDMAP_SUCCESS
*
* Return:
* Success return IDMAP_SUCCESS else IDMAP error
*/
int *is_user)
{
const char *new_sid_prefix;
return (IDMAP_ERR_ARG);
is_user) == IDMAP_SUCCESS) {
return (IDMAP_SUCCESS);
}
/* Door call succeded */
*is_user = 1;
} else {
*is_user = 0;
}
if (status == IDMAP_SUCCESS) {
}
} else {
*is_user = 1;
*pid = UID_NOBODY;
}
} else {
/* Door call failed */
*is_user = 1;
*pid = UID_NOBODY;
}
return (status);
}
/*
* Given UID, get Domain SID and RID
*
* Input:
* uid - Posix UID
*
* Output:
* sid_prefix - Domain SID if return == IDMAP_SUCCESS
* rid - RID if return == IDMAP_SUCCESS
*
* Return:
* Success return IDMAP_SUCCESS else IDMAP error
*/
{
return (IDMAP_ERR_ARG);
== IDMAP_SUCCESS) {
return (IDMAP_SUCCESS);
}
/* Door call succeded */
if (status == IDMAP_SUCCESS) {
1, entry_ttl);
}
} else {
*rid = 0;
*sid_prefix = NULL;
}
} else {
/* Door call failed */
*rid = 0;
*sid_prefix = NULL;
}
return (status);
}
/*
* Given GID, get Domain SID and RID
*
* Input:
* gid - Posix GID
*
* Output:
* sid_prefix - Domain SID if return == IDMAP_SUCCESS
* rid - RID if return == IDMAP_SUCCESS
*
* Return:
* Success return IDMAP_SUCCESS else IDMAP error
*/
{
return (IDMAP_ERR_ARG);
== IDMAP_SUCCESS) {
return (IDMAP_SUCCESS);
}
/* Door call succeded */
if (status == IDMAP_SUCCESS) {
0, entry_ttl);
}
} else {
*rid = 0;
*sid_prefix = NULL;
}
} else {
/* Door call failed */
*rid = 0;
*sid_prefix = NULL;
}
return (status);
}
/*
*
* Input:
* none
* Return:
* get_handle
*
*/
kidmap_get_create(void)
{
#define INIT_MAPPING_SIZE 6
return (handle);
}
/*
* Internal routine to extend a "get_handle"
*/
static void
{
}
/*
* Given Domain SID and RID, get UID
*
* Input:
* sid_prefix - Domain SID in canonical form
* rid - RID
*
* Output:
* stat - status of the get request
* uid - POSIX UID if stat == IDMAP_SUCCESS
*
* Note: The output parameters will be set by idmap_get_mappings()
*/
{
int is_user;
return (IDMAP_ERR_ARG);
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
}
return (IDMAP_SUCCESS);
}
/*
* Given Domain SID and RID, get GID
*
* Input:
* sid_prefix - Domain SID in canonical form
* rid - RID
*
* Output:
* stat - status of the get request
* gid - POSIX GID if stat == IDMAP_SUCCESS
*
* Note: The output parameters will be set by idmap_get_mappings()
*/
{
int is_user;
return (IDMAP_ERR_ARG);
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
}
return (IDMAP_SUCCESS);
}
/*
* Given Domain SID and RID, get Posix ID
*
* Input:
* sid_prefix - Domain SID in canonical form
* rid - RID
*
* Output:
* stat - status of the get request
* is_user - user or group
* pid - POSIX UID if stat == IDMAP_SUCCESS and is_user == 1
* POSIX GID if stat == IDMAP_SUCCESS and is_user == 0
*
* Note: The output parameters will be set by idmap_get_mappings()
*/
{
return (IDMAP_ERR_ARG);
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
}
return (IDMAP_SUCCESS);
}
/*
* Given UID, get SID and RID
*
* Input:
* uid - POSIX UID
*
* Output:
* stat - status of the get request
* sid - SID in canonical form (if stat == IDMAP_SUCCESS)
* rid - RID (if stat == IDMAP_SUCCESS)
*
* Note: The output parameters will be set by idmap_get_mappings()
*/
{
return (IDMAP_ERR_ARG);
== IDMAP_SUCCESS) {
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
}
return (IDMAP_SUCCESS);
}
/*
* Given GID, get SID and RID
*
* Input:
* gid - POSIX GID
*
* Output:
* stat - status of the get request
* sid - SID in canonical form (if stat == IDMAP_SUCCESS)
* rid - RID (if stat == IDMAP_SUCCESS)
*
* Note: The output parameters will be set by idmap_get_mappings()
*/
{
return (IDMAP_ERR_ARG);
== IDMAP_SUCCESS) {
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
}
return (IDMAP_SUCCESS);
}
/*
* Process the batched "get mapping" requests. The results (i.e.
* status and identity) will be available in the data areas
* provided by individual requests.
*
* If the door call fails the status IDMAP_ERR_NOMAPPING is
* return and the UID or UID result is set to "nobody"
*/
{
int status;
int i;
const char *sid_prefix;
int is_user;
if (get_handle == NULL)
return (IDMAP_ERR_ARG);
if (get_handle->mapping_num == 0)
return (IDMAP_SUCCESS);
/* Door call succeded */
for (i = 0; i < get_handle->mapping_num; i++) {
if (result->sid_prefix)
continue;
}
case IDMAP_UID:
1, entry_ttl);
}
break;
case IDMAP_GID:
0, entry_ttl);
}
break;
case IDMAP_SID:
}
is_user = 1;
else
is_user = 0;
}
break;
default:
if (result->sid_prefix)
break;
}
}
} else {
/* Door call failed */
for (i = 0; i < get_handle->mapping_num; i++) {
if (result->sid_prefix)
}
}
/* Reset get_handle for new resquests */
get_handle->mapping_num = 0;
return (status);
}
/*
* Destroy the "get mapping" handle
*/
void
{
if (get_handle == NULL)
return;
}
static int
{
char *outbuf_ptr = NULL;
int status = 0;
int retry = 0;
#ifdef DEBUG
#endif /* DEBUG */
status = -1;
goto exit;
}
/* Auth none */
/* RPC args */
#ifdef DEBUG
#endif /* DEBUG */
if (retry > 2) {
status = -1;
goto exit;
}
retry++;
if (inbuf_ptr) {
}
if (outbuf_ptr) {
outbuf_ptr = NULL;
}
#ifdef DEBUG
#endif /* DEBUG */
status = -1;
goto exit;
}
goto retry;
}
if (kidmap_call_door(¶ms) != 0) {
status = -1;
goto exit;
}
status = -1;
goto exit;
}
} else {
#ifdef DEBUG
#endif /* DEBUG */
status = -1;
}
exit:
if (inbuf_ptr)
if (outbuf_ptr)
return (status);
}