1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 %#if defined(_KERNEL) 26 %#include <sys/nvpair.h> 27 %#else 28 %#include <libnvpair.h> 29 %#endif 30 31 /* 32 * XDR support for nvlist_t. libnvpair includes support for serializing 33 * an nvlist, but does not include any direct XDR plug-in support. Support 34 * is made trickier by the fact that on read xdr_pointer() wants to allocate 35 * structures on its own, even when there's a custom xdr_*() function for 36 * the structure. nvlist_unpack *also* wants to allocate the nvlist_t, 37 * and it seems wrong to burn sizeof(nvlist_t) into the program binary. 38 * 39 * Another possibility is to use opaque<> in this declaration, but that 40 * requires moving part of the encoding (the interaction with nvlist_pack 41 * and nvlist_unpack) out into the application, instead of keeping it 42 * all encapsulated in this layer. 43 * 44 * The resolution here is to put an nvlist_t * into a new typedef, and have 45 * *that* typedef have a custom xdr_*() function. xdr allocates space for 46 * the pointer, but leaves all initialization of it nvlist_t *) to the 47 * custom function. 48 */ 49 #if defined(RPC_HDR) 50 %typedef nvlist_t *nvlist_t_ptr; 51 #endif 52 53 #if defined(RPC_XDR) 54 %#if !defined(_KERNEL) 55 %#include <string.h> 56 %#include <stdio.h> 57 %#endif 58 % 59 %bool_t 60 %xdr_nvlist_t_ptr(XDR *xdrs, nvlist_t_ptr *n) 61 %{ 62 % char *buf; 63 % u_int len; 64 % bool_t ret; 65 % int err; 66 % size_t sz; 67 % bool_t present; 68 % 69 % switch (xdrs->x_op) { 70 % case XDR_DECODE: 71 % if (!xdr_bool(xdrs, &present)) 72 % return (FALSE); 73 % if (!present) { 74 % *n = NULL; 75 % return (TRUE); 76 % } 77 % buf = NULL; 78 % if (!xdr_bytes(xdrs, &buf, &len, ~0)) 79 % return (FALSE); 80 % 81 % err = nvlist_unpack(buf, (size_t)len, n, 0); 82 %#if defined(_KERNEL) 83 % kmem_free(buf, len); 84 %#else 85 % free(buf); 86 %#endif 87 % 88 % if (err != 0) { 89 %#if !defined(_KERNEL) 90 % fprintf(stderr, "xdr_nvlist_t unpack: %s\n", 91 % strerror(err)); 92 %#endif 93 % return (FALSE); 94 % } 95 % return (TRUE); 96 % 97 % case XDR_ENCODE: 98 % present = (*n != NULL); 99 % if (!xdr_bool(xdrs, &present)) 100 % return (FALSE); 101 % if (!present) 102 % return (TRUE); 103 % buf = NULL; 104 % err = nvlist_pack(*n, &buf, &sz, NV_ENCODE_XDR, 0); 105 % if (err != 0) { 106 %#if !defined(_KERNEL) 107 % fprintf(stderr, "xdr_nvlist_t pack: %s\n", 108 % strerror(err)); 109 %#endif 110 % return (FALSE); 111 % } 112 % 113 % /* nvlist_pack() and xdr_bytes() want different types */ 114 % len = (u_int) sz; 115 % 116 % ret = xdr_bytes(xdrs, &buf, &len, ~0); 117 %#if defined(_KERNEL) 118 % kmem_free(buf, len); 119 %#else 120 % free(buf); 121 %#endif 122 % 123 % return (ret); 124 % 125 % case XDR_FREE: 126 % if (*n != NULL) { 127 % nvlist_free(*n); 128 % *n = NULL; 129 % } 130 % return (TRUE); 131 % 132 % default: 133 % return (FALSE); 134 % } 135 %} 136 #endif 137 138 /* opaque type to support non-ASCII strings */ 139 typedef string idmap_utf8str<>; 140 typedef idmap_utf8str idmap_utf8str_list<>; 141 142 /* Return status */ 143 typedef int idmap_retcode; 144 145 /* Identity types */ 146 enum idmap_id_type { 147 IDMAP_NONE = 0, 148 IDMAP_UID = 1, 149 IDMAP_GID, 150 IDMAP_SID, 151 IDMAP_USID, 152 IDMAP_GSID, 153 IDMAP_POSIXID 154 }; 155 156 /* The type of ID mapping */ 157 enum idmap_map_type { 158 IDMAP_MAP_TYPE_UNKNOWN = 0, 159 IDMAP_MAP_TYPE_DS_AD, 160 IDMAP_MAP_TYPE_DS_NLDAP, 161 IDMAP_MAP_TYPE_RULE_BASED, 162 IDMAP_MAP_TYPE_EPHEMERAL, 163 IDMAP_MAP_TYPE_LOCAL_SID, 164 IDMAP_MAP_TYPE_KNOWN_SID, 165 IDMAP_MAP_TYPE_IDMU 166 }; 167 168 169 /* Source of ID mapping */ 170 enum idmap_map_src { 171 IDMAP_MAP_SRC_UNKNOWN = 0, 172 IDMAP_MAP_SRC_NEW, 173 IDMAP_MAP_SRC_CACHE, 174 IDMAP_MAP_SRC_HARD_CODED, 175 IDMAP_MAP_SRC_ALGORITHMIC 176 }; 177 178 179 /* SID */ 180 struct idmap_sid { 181 string prefix<>; 182 uint32_t rid; 183 }; 184 185 /* Identity (sid-posix) */ 186 union idmap_id switch(idmap_id_type idtype) { 187 case IDMAP_UID: uint32_t uid; 188 case IDMAP_GID: uint32_t gid; 189 case IDMAP_SID: idmap_sid sid; 190 case IDMAP_USID: idmap_sid usid; 191 case IDMAP_GSID: idmap_sid gsid; 192 case IDMAP_NONE: void; 193 case IDMAP_POSIXID: void; 194 }; 195 196 197 /* Name-based mapping rules */ 198 struct idmap_namerule { 199 bool is_user; 200 bool is_wuser; 201 int direction; 202 idmap_utf8str windomain; 203 idmap_utf8str winname; 204 idmap_utf8str unixname; 205 bool is_nt4; 206 }; 207 struct idmap_namerules_res { 208 idmap_retcode retcode; 209 uint64_t lastrowid; 210 idmap_namerule rules<>; 211 }; 212 213 /* How ID is mapped */ 214 struct idmap_how_ds_based { 215 idmap_utf8str dn; 216 idmap_utf8str attr; 217 idmap_utf8str value; 218 }; 219 220 union idmap_how switch(idmap_map_type map_type) { 221 case IDMAP_MAP_TYPE_UNKNOWN: void; 222 case IDMAP_MAP_TYPE_DS_AD: idmap_how_ds_based ad; 223 case IDMAP_MAP_TYPE_DS_NLDAP: idmap_how_ds_based nldap; 224 case IDMAP_MAP_TYPE_RULE_BASED: idmap_namerule rule; 225 case IDMAP_MAP_TYPE_EPHEMERAL: void; 226 case IDMAP_MAP_TYPE_LOCAL_SID: void; 227 case IDMAP_MAP_TYPE_KNOWN_SID: void; 228 case IDMAP_MAP_TYPE_IDMU: idmap_how_ds_based idmu; 229 }; 230 231 struct idmap_info { 232 idmap_map_src src; 233 idmap_how how; 234 nvlist_t_ptr trace; 235 }; 236 237 238 /* Id result */ 239 struct idmap_id_res { 240 idmap_retcode retcode; 241 idmap_id id; 242 int direction; 243 idmap_info info; 244 }; 245 struct idmap_ids_res { 246 idmap_retcode retcode; 247 idmap_id_res ids<>; 248 }; 249 250 251 /* 252 * Flag supported by mapping requests 253 */ 254 255 /* Don't allocate a new value for the mapping */ 256 const IDMAP_REQ_FLG_NO_NEW_ID_ALLOC = 0x00000001; 257 258 /* Validate the given identity before mapping */ 259 const IDMAP_REQ_FLG_VALIDATE = 0x00000002; 260 261 /* Avoid name service lookups to prevent looping */ 262 const IDMAP_REQ_FLG_NO_NAMESERVICE = 0x00000004; 263 264 /* Request how a mapping was formed */ 265 const IDMAP_REQ_FLG_MAPPING_INFO = 0x00000008; 266 267 /* 268 * This libidmap only flag is defined in idmap.h 269 * It enables use of the libidmap cache 270 * const IDMAP_REQ_FLG_USE_CACHE = 0x00000010; 271 */ 272 273 /* Request mapping for well-known or local SIDs only */ 274 const IDMAP_REQ_FLG_WK_OR_LOCAL_SIDS_ONLY = 0x00000020; 275 276 /* Request trace of mapping process */ 277 const IDMAP_REQ_FLG_TRACE = 0x00000040; 278 279 280 /* 281 * Mapping direction definitions 282 */ 283 const IDMAP_DIRECTION_UNDEF = -1; /* not defined */ 284 const IDMAP_DIRECTION_BI = 0; /* bi-directional */ 285 const IDMAP_DIRECTION_W2U = 1; /* windows to unix only */ 286 const IDMAP_DIRECTION_U2W = 2; /* unix to windows only */ 287 288 289 /* Identity mappings (sid-posix) */ 290 struct idmap_mapping { 291 int32_t flag; 292 int direction; 293 idmap_id id1; 294 idmap_utf8str id1domain; 295 idmap_utf8str id1name; 296 idmap_id id2; 297 idmap_utf8str id2domain; 298 idmap_utf8str id2name; 299 idmap_info info; 300 }; 301 302 typedef idmap_mapping idmap_mapping_batch<>; 303 304 #ifndef IDMAP_XDR_MAPPING_ONLY 305 struct idmap_mappings_res { 306 idmap_retcode retcode; 307 uint64_t lastrowid; 308 idmap_mapping mappings<>; 309 }; 310 311 312 /* Update result */ 313 struct idmap_update_res { 314 idmap_retcode retcode; 315 int64_t error_index; 316 idmap_namerule error_rule; 317 idmap_namerule conflict_rule; 318 }; 319 320 /* Update requests */ 321 enum idmap_opnum { 322 OP_NONE = 0, 323 OP_ADD_NAMERULE = 1, 324 OP_RM_NAMERULE = 2, 325 OP_FLUSH_NAMERULES = 3 326 }; 327 union idmap_update_op switch(idmap_opnum opnum) { 328 case OP_ADD_NAMERULE: 329 case OP_RM_NAMERULE: 330 idmap_namerule rule; 331 default: 332 void; 333 }; 334 typedef idmap_update_op idmap_update_batch<>; 335 336 const AD_DISC_MAXHOSTNAME = 256; 337 338 struct idmap_ad_disc_ds_t { 339 int port; 340 int priority; 341 int weight; 342 char host[AD_DISC_MAXHOSTNAME]; 343 }; 344 345 346 /* get-prop, set-prop */ 347 enum idmap_prop_type { 348 PROP_UNKNOWN = 0, 349 PROP_LIST_SIZE_LIMIT = 1, 350 PROP_DEFAULT_DOMAIN = 2, /* default domain name */ 351 PROP_DOMAIN_NAME = 3, /* AD domain name */ 352 PROP_MACHINE_SID = 4, /* machine sid */ 353 PROP_DOMAIN_CONTROLLER = 5, /* domain controller hosts */ 354 PROP_FOREST_NAME = 6, /* forest name */ 355 PROP_SITE_NAME = 7, /* site name */ 356 PROP_GLOBAL_CATALOG = 8, /* global catalog hosts */ 357 PROP_AD_UNIXUSER_ATTR = 9, 358 PROP_AD_UNIXGROUP_ATTR = 10, 359 PROP_NLDAP_WINNAME_ATTR = 11, 360 PROP_DIRECTORY_BASED_MAPPING = 12 361 }; 362 363 union idmap_prop_val switch(idmap_prop_type prop) { 364 case PROP_LIST_SIZE_LIMIT: 365 uint64_t intval; 366 case PROP_DEFAULT_DOMAIN: 367 case PROP_DOMAIN_NAME: 368 case PROP_MACHINE_SID: 369 case PROP_FOREST_NAME: 370 case PROP_SITE_NAME: 371 case PROP_AD_UNIXUSER_ATTR: 372 case PROP_AD_UNIXGROUP_ATTR: 373 case PROP_NLDAP_WINNAME_ATTR: 374 case PROP_DIRECTORY_BASED_MAPPING: 375 idmap_utf8str utf8val; 376 case PROP_DOMAIN_CONTROLLER: 377 case PROP_GLOBAL_CATALOG: 378 idmap_ad_disc_ds_t dsval; 379 default: 380 void; 381 }; 382 383 struct idmap_prop_res { 384 idmap_retcode retcode; 385 idmap_prop_val value; 386 bool auto_discovered; 387 }; 388 389 enum idmap_flush_op { 390 IDMAP_FLUSH_EXPIRE = 0, 391 IDMAP_FLUSH_DELETE = 1 392 }; 393 394 /* 395 * Represents an error from the directory lookup service. 396 * 397 * code is an ASCII string that is a key for the error. It is not 398 * localized. 399 * 400 * fmt is a format string with %n markers for where to include 401 * params[n-1]. It should be, but NEEDSWORK is not localized to 402 * the caller's locale. 403 * 404 * params is a list of parameters for the error - e.g. the name that 405 * encountered a failure, the server that reported the failure, et cetera. 406 * The values are to be used both as marked in fmt and for machine 407 * interpretation of the error. 408 */ 409 struct directory_error_rpc { 410 idmap_utf8str code; 411 idmap_utf8str fmt; 412 idmap_utf8str params<>; 413 }; 414 415 /* 416 * One value of a multivalued attribute. 417 */ 418 typedef opaque directory_value_rpc<>; 419 420 /* 421 * The value of an attribute, if found. Note that this is a list 422 * of directory_value_rpc objects, to support multivalued attributes. 423 */ 424 union directory_values_rpc switch (bool found) { 425 case TRUE: 426 directory_value_rpc values<>; 427 case FALSE: 428 void; 429 }; 430 431 /* 432 * The status of the lookup for any particular identifier. 433 */ 434 enum directory_lookup_status_rpc { 435 DIRECTORY_NOT_FOUND = 0, 436 DIRECTORY_FOUND = 1, 437 DIRECTORY_ERROR = 2 438 }; 439 440 /* 441 * This is the data returned for a particular identifier, either a 442 * list of attribute values or an error. 443 */ 444 union directory_entry_rpc switch (directory_lookup_status_rpc status) { 445 case DIRECTORY_NOT_FOUND: 446 void; 447 case DIRECTORY_FOUND: 448 directory_values_rpc attrs<>; 449 case DIRECTORY_ERROR: 450 directory_error_rpc err; 451 }; 452 453 /* 454 * This is the result from a request, either a list of the entries for 455 * the identifiers specified, or an error. 456 */ 457 union directory_results_rpc switch (bool failed) { 458 case TRUE: 459 directory_error_rpc err; 460 case FALSE: 461 directory_entry_rpc entries<>; 462 }; 463 #endif /* IDMAP_XDR_MAPPING_ONLY */ 464 465 program IDMAP_PROG { 466 version IDMAP_V1 { 467 #ifndef IDMAP_XDR_MAPPING_ONLY 468 void 469 IDMAP_NULL(void) = 0; 470 #endif /* IDMAP_XDR_MAPPING_ONLY */ 471 472 /* Batch of requests to get mapped identities */ 473 idmap_ids_res 474 IDMAP_GET_MAPPED_IDS(idmap_mapping_batch batch) = 1; 475 476 #ifndef IDMAP_XDR_MAPPING_ONLY 477 /* List all identity mappings */ 478 idmap_mappings_res 479 IDMAP_LIST_MAPPINGS(int64_t lastrowid, 480 uint64_t limit, int32_t flag) = 2; 481 482 /* List all name-based mapping rules */ 483 idmap_namerules_res 484 IDMAP_LIST_NAMERULES(idmap_namerule rule, 485 uint64_t lastrowid, uint64_t limit) = 3; 486 487 /* Batch of update requests */ 488 idmap_update_res 489 IDMAP_UPDATE(idmap_update_batch batch) = 4; 490 491 /* Get mapped identity by name */ 492 idmap_mappings_res 493 IDMAP_GET_MAPPED_ID_BY_NAME(idmap_mapping request) = 5; 494 495 /* Get configuration property */ 496 idmap_prop_res 497 IDMAP_GET_PROP(idmap_prop_type) = 6; 498 499 /* 500 * Retrieve directory information about a list of users 501 * or groups by name or SID. 502 * 503 * ids is a list of user names, group names, or SIDs. 504 * 505 * types is a list of types of the ids in the id list. 506 * If the type list is shorter than the id list, the last 507 * type listed applies to all of the ids from that point. 508 * The defined types are: 509 * 'n' - name (could be user or group) 510 * 'u' - user 511 * 'g' - group 512 * 's' - SID 513 * 514 * attrs is a list of attribute names to retrieve. 515 */ 516 directory_results_rpc DIRECTORY_GET_COMMON( 517 idmap_utf8str_list ids, 518 idmap_utf8str types, 519 idmap_utf8str_list attrs) = 7; 520 521 idmap_retcode 522 IDMAP_FLUSH(idmap_flush_op) = 8; 523 #endif /* IDMAP_XDR_MAPPING_ONLY */ 524 } = 1; 525 } = 100172; 526