/*
* 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
* or http://www.opensolaris.org/os/licensing.
* 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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
%#if defined(_KERNEL)
%#include <sys/nvpair.h>
%#else
%#include <libnvpair.h>
%#endif
/*
* XDR support for nvlist_t. libnvpair includes support for serializing
* an nvlist, but does not include any direct XDR plug-in support. Support
* is made trickier by the fact that on read xdr_pointer() wants to allocate
* structures on its own, even when there's a custom xdr_*() function for
* the structure. nvlist_unpack *also* wants to allocate the nvlist_t,
* and it seems wrong to burn sizeof(nvlist_t) into the program binary.
*
* Another possibility is to use opaque<> in this declaration, but that
* requires moving part of the encoding (the interaction with nvlist_pack
* and nvlist_unpack) out into the application, instead of keeping it
* all encapsulated in this layer.
*
* The resolution here is to put an nvlist_t * into a new typedef, and have
* *that* typedef have a custom xdr_*() function. xdr allocates space for
* the pointer, but leaves all initialization of it nvlist_t *) to the
* custom function.
*/
#if defined(RPC_HDR)
%typedef nvlist_t *nvlist_t_ptr;
#endif
#if defined(RPC_XDR)
%#if !defined(_KERNEL)
%#include <string.h>
%#include <stdio.h>
%#endif
%
%bool_t
%xdr_nvlist_t_ptr(XDR *xdrs, nvlist_t_ptr *n)
%{
% char *buf;
% u_int len;
% bool_t ret;
% int err;
% size_t sz;
% bool_t present;
%
% switch (xdrs->x_op) {
% case XDR_DECODE:
% if (!xdr_bool(xdrs, &present))
% return (FALSE);
% if (!present) {
% *n = NULL;
% return (TRUE);
% }
% buf = NULL;
% if (!xdr_bytes(xdrs, &buf, &len, ~0))
% return (FALSE);
%
% err = nvlist_unpack(buf, (size_t)len, n, 0);
%#if defined(_KERNEL)
% kmem_free(buf, len);
%#else
% free(buf);
%#endif
%
% if (err != 0) {
%#if !defined(_KERNEL)
% fprintf(stderr, "xdr_nvlist_t unpack: %s\n",
% strerror(err));
%#endif
% return (FALSE);
% }
% return (TRUE);
%
% case XDR_ENCODE:
% present = (*n != NULL);
% if (!xdr_bool(xdrs, &present))
% return (FALSE);
% if (!present)
% return (TRUE);
% buf = NULL;
% err = nvlist_pack(*n, &buf, &sz, NV_ENCODE_XDR, 0);
% if (err != 0) {
%#if !defined(_KERNEL)
% fprintf(stderr, "xdr_nvlist_t pack: %s\n",
% strerror(err));
%#endif
% return (FALSE);
% }
%
% /* nvlist_pack() and xdr_bytes() want different types */
% len = (u_int) sz;
%
% ret = xdr_bytes(xdrs, &buf, &len, ~0);
%#if defined(_KERNEL)
% kmem_free(buf, len);
%#else
% free(buf);
%#endif
%
% return (ret);
%
% case XDR_FREE:
% if (*n != NULL) {
% nvlist_free(*n);
% *n = NULL;
% }
% return (TRUE);
%
% default:
% return (FALSE);
% }
%}
#endif
/* opaque type to support non-ASCII strings */
typedef string idmap_utf8str<>;
typedef idmap_utf8str idmap_utf8str_list<>;
/* Return status */
typedef int idmap_retcode;
/* Identity types */
enum idmap_id_type {
IDMAP_NONE = 0,
IDMAP_UID = 1,
IDMAP_GID,
IDMAP_SID,
IDMAP_USID,
IDMAP_GSID,
IDMAP_POSIXID
};
/* The type of ID mapping */
enum idmap_map_type {
IDMAP_MAP_TYPE_UNKNOWN = 0,
IDMAP_MAP_TYPE_DS_AD,
IDMAP_MAP_TYPE_DS_NLDAP,
IDMAP_MAP_TYPE_RULE_BASED,
IDMAP_MAP_TYPE_EPHEMERAL,
IDMAP_MAP_TYPE_LOCAL_SID,
IDMAP_MAP_TYPE_KNOWN_SID,
IDMAP_MAP_TYPE_IDMU
};
/* Source of ID mapping */
enum idmap_map_src {
IDMAP_MAP_SRC_UNKNOWN = 0,
IDMAP_MAP_SRC_NEW,
IDMAP_MAP_SRC_CACHE,
IDMAP_MAP_SRC_HARD_CODED,
IDMAP_MAP_SRC_ALGORITHMIC
};
/* SID */
struct idmap_sid {
string prefix<>;
uint32_t rid;
};
/* Identity (sid-posix) */
union idmap_id switch(idmap_id_type idtype) {
case IDMAP_UID: uint32_t uid;
case IDMAP_GID: uint32_t gid;
case IDMAP_SID: idmap_sid sid;
case IDMAP_USID: idmap_sid usid;
case IDMAP_GSID: idmap_sid gsid;
case IDMAP_NONE: void;
case IDMAP_POSIXID: void;
};
/* Name-based mapping rules */
struct idmap_namerule {
bool is_user;
bool is_wuser;
int direction;
idmap_utf8str windomain;
idmap_utf8str winname;
idmap_utf8str unixname;
bool is_nt4;
};
struct idmap_namerules_res {
idmap_retcode retcode;
uint64_t lastrowid;
idmap_namerule rules<>;
};
/* How ID is mapped */
struct idmap_how_ds_based {
idmap_utf8str dn;
idmap_utf8str attr;
idmap_utf8str value;
};
union idmap_how switch(idmap_map_type map_type) {
case IDMAP_MAP_TYPE_UNKNOWN: void;
case IDMAP_MAP_TYPE_DS_AD: idmap_how_ds_based ad;
case IDMAP_MAP_TYPE_DS_NLDAP: idmap_how_ds_based nldap;
case IDMAP_MAP_TYPE_RULE_BASED: idmap_namerule rule;
case IDMAP_MAP_TYPE_EPHEMERAL: void;
case IDMAP_MAP_TYPE_LOCAL_SID: void;
case IDMAP_MAP_TYPE_KNOWN_SID: void;
case IDMAP_MAP_TYPE_IDMU: idmap_how_ds_based idmu;
};
struct idmap_info {
idmap_map_src src;
idmap_how how;
nvlist_t_ptr trace;
};
/* Id result */
struct idmap_id_res {
idmap_retcode retcode;
idmap_id id;
int direction;
idmap_info info;
};
struct idmap_ids_res {
idmap_retcode retcode;
idmap_id_res ids<>;
};
/*
* Flag supported by mapping requests
*/
/* Don't allocate a new value for the mapping */
const IDMAP_REQ_FLG_NO_NEW_ID_ALLOC = 0x00000001;
/* Validate the given identity before mapping */
const IDMAP_REQ_FLG_VALIDATE = 0x00000002;
/* Avoid name service lookups to prevent looping */
const IDMAP_REQ_FLG_NO_NAMESERVICE = 0x00000004;
/* Request how a mapping was formed */
const IDMAP_REQ_FLG_MAPPING_INFO = 0x00000008;
/*
* This libidmap only flag is defined in idmap.h
* It enables use of the libidmap cache
* const IDMAP_REQ_FLG_USE_CACHE = 0x00000010;
*/
/* Request mapping for well-known or local SIDs only */
const IDMAP_REQ_FLG_WK_OR_LOCAL_SIDS_ONLY = 0x00000020;
/* Request trace of mapping process */
const IDMAP_REQ_FLG_TRACE = 0x00000040;
/*
* Mapping direction definitions
*/
const IDMAP_DIRECTION_UNDEF = -1; /* not defined */
const IDMAP_DIRECTION_BI = 0; /* bi-directional */
const IDMAP_DIRECTION_W2U = 1; /* windows to unix only */
const IDMAP_DIRECTION_U2W = 2; /* unix to windows only */
/* Identity mappings (sid-posix) */
struct idmap_mapping {
int32_t flag;
int direction;
idmap_id id1;
idmap_utf8str id1domain;
idmap_utf8str id1name;
idmap_id id2;
idmap_utf8str id2domain;
idmap_utf8str id2name;
idmap_info info;
};
typedef idmap_mapping idmap_mapping_batch<>;
#ifndef IDMAP_XDR_MAPPING_ONLY
struct idmap_mappings_res {
idmap_retcode retcode;
uint64_t lastrowid;
idmap_mapping mappings<>;
};
/* Update result */
struct idmap_update_res {
idmap_retcode retcode;
int64_t error_index;
idmap_namerule error_rule;
idmap_namerule conflict_rule;
};
/* Update requests */
enum idmap_opnum {
OP_NONE = 0,
OP_ADD_NAMERULE = 1,
OP_RM_NAMERULE = 2,
OP_FLUSH_NAMERULES = 3
};
union idmap_update_op switch(idmap_opnum opnum) {
case OP_ADD_NAMERULE:
case OP_RM_NAMERULE:
idmap_namerule rule;
default:
void;
};
typedef idmap_update_op idmap_update_batch<>;
const AD_DISC_MAXHOSTNAME = 256;
struct idmap_ad_disc_ds_t {
int port;
int priority;
int weight;
char host[AD_DISC_MAXHOSTNAME];
};
/* get-prop, set-prop */
enum idmap_prop_type {
PROP_UNKNOWN = 0,
PROP_LIST_SIZE_LIMIT = 1,
PROP_DEFAULT_DOMAIN = 2, /* default domain name */
PROP_DOMAIN_NAME = 3, /* AD domain name */
PROP_MACHINE_SID = 4, /* machine sid */
PROP_DOMAIN_CONTROLLER = 5, /* domain controller hosts */
PROP_FOREST_NAME = 6, /* forest name */
PROP_SITE_NAME = 7, /* site name */
PROP_GLOBAL_CATALOG = 8, /* global catalog hosts */
PROP_AD_UNIXUSER_ATTR = 9,
PROP_AD_UNIXGROUP_ATTR = 10,
PROP_NLDAP_WINNAME_ATTR = 11,
PROP_DIRECTORY_BASED_MAPPING = 12
};
union idmap_prop_val switch(idmap_prop_type prop) {
case PROP_LIST_SIZE_LIMIT:
uint64_t intval;
case PROP_DEFAULT_DOMAIN:
case PROP_DOMAIN_NAME:
case PROP_MACHINE_SID:
case PROP_FOREST_NAME:
case PROP_SITE_NAME:
case PROP_AD_UNIXUSER_ATTR:
case PROP_AD_UNIXGROUP_ATTR:
case PROP_NLDAP_WINNAME_ATTR:
case PROP_DIRECTORY_BASED_MAPPING:
idmap_utf8str utf8val;
case PROP_DOMAIN_CONTROLLER:
case PROP_GLOBAL_CATALOG:
idmap_ad_disc_ds_t dsval;
default:
void;
};
struct idmap_prop_res {
idmap_retcode retcode;
idmap_prop_val value;
bool auto_discovered;
};
enum idmap_flush_op {
IDMAP_FLUSH_EXPIRE = 0,
IDMAP_FLUSH_DELETE = 1
};
/*
* Represents an error from the directory lookup service.
*
* code is an ASCII string that is a key for the error. It is not
* localized.
*
* fmt is a format string with %n markers for where to include
* params[n-1]. It should be, but NEEDSWORK is not localized to
* the caller's locale.
*
* params is a list of parameters for the error - e.g. the name that
* encountered a failure, the server that reported the failure, et cetera.
* The values are to be used both as marked in fmt and for machine
* interpretation of the error.
*/
struct directory_error_rpc {
idmap_utf8str code;
idmap_utf8str fmt;
idmap_utf8str params<>;
};
/*
* One value of a multivalued attribute.
*/
typedef opaque directory_value_rpc<>;
/*
* The value of an attribute, if found. Note that this is a list
* of directory_value_rpc objects, to support multivalued attributes.
*/
union directory_values_rpc switch (bool found) {
case TRUE:
directory_value_rpc values<>;
case FALSE:
void;
};
/*
* The status of the lookup for any particular identifier.
*/
enum directory_lookup_status_rpc {
DIRECTORY_NOT_FOUND = 0,
DIRECTORY_FOUND = 1,
DIRECTORY_ERROR = 2
};
/*
* This is the data returned for a particular identifier, either a
* list of attribute values or an error.
*/
union directory_entry_rpc switch (directory_lookup_status_rpc status) {
case DIRECTORY_NOT_FOUND:
void;
case DIRECTORY_FOUND:
directory_values_rpc attrs<>;
case DIRECTORY_ERROR:
directory_error_rpc err;
};
/*
* This is the result from a request, either a list of the entries for
* the identifiers specified, or an error.
*/
union directory_results_rpc switch (bool failed) {
case TRUE:
directory_error_rpc err;
case FALSE:
directory_entry_rpc entries<>;
};
#endif /* IDMAP_XDR_MAPPING_ONLY */
program IDMAP_PROG {
version IDMAP_V1 {
#ifndef IDMAP_XDR_MAPPING_ONLY
void
IDMAP_NULL(void) = 0;
#endif /* IDMAP_XDR_MAPPING_ONLY */
/* Batch of requests to get mapped identities */
idmap_ids_res
IDMAP_GET_MAPPED_IDS(idmap_mapping_batch batch) = 1;
#ifndef IDMAP_XDR_MAPPING_ONLY
/* List all identity mappings */
idmap_mappings_res
IDMAP_LIST_MAPPINGS(int64_t lastrowid,
uint64_t limit, int32_t flag) = 2;
/* List all name-based mapping rules */
idmap_namerules_res
IDMAP_LIST_NAMERULES(idmap_namerule rule,
uint64_t lastrowid, uint64_t limit) = 3;
/* Batch of update requests */
idmap_update_res
IDMAP_UPDATE(idmap_update_batch batch) = 4;
/* Get mapped identity by name */
idmap_mappings_res
IDMAP_GET_MAPPED_ID_BY_NAME(idmap_mapping request) = 5;
/* Get configuration property */
idmap_prop_res
IDMAP_GET_PROP(idmap_prop_type) = 6;
/*
* Retrieve directory information about a list of users
* or groups by name or SID.
*
* ids is a list of user names, group names, or SIDs.
*
* types is a list of types of the ids in the id list.
* If the type list is shorter than the id list, the last
* type listed applies to all of the ids from that point.
* The defined types are:
* 'n' - name (could be user or group)
* 'u' - user
* 'g' - group
* 's' - SID
*
* attrs is a list of attribute names to retrieve.
*/
directory_results_rpc DIRECTORY_GET_COMMON(
idmap_utf8str_list ids,
idmap_utf8str types,
idmap_utf8str_list attrs) = 7;
idmap_retcode
IDMAP_FLUSH(idmap_flush_op) = 8;
#endif /* IDMAP_XDR_MAPPING_ONLY */
} = 1;
} = 100172;