dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libidmap / common / idmap_api.c
blob432814b4cb87a29db09d06fecdc7c440ddca7e37
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright Milan Jurik 2012. All rights reserved.
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2015 Joyent, Inc.
30 * libidmap API
33 #include <stdlib.h>
34 #include <sys/varargs.h>
35 #include <inttypes.h>
36 #include <errno.h>
37 #include <strings.h>
38 #include <ctype.h>
39 #include <sys/param.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <dlfcn.h>
43 #include <libintl.h>
44 #include <syslog.h>
45 #include <assert.h>
46 #include "idmap_impl.h"
47 #include "idmap_cache.h"
49 static struct timeval TIMEOUT = { 25, 0 };
51 static int idmap_stat2errno(idmap_stat);
52 static idmap_stat idmap_strdupnull(char **, const char *);
54 #define __ITER_CREATE(itera, argu, ityp)\
55 itera = calloc(1, sizeof (*itera));\
56 if (itera == NULL) {\
57 errno = ENOMEM;\
58 return (IDMAP_ERR_MEMORY);\
60 argu = calloc(1, sizeof (*argu));\
61 if (argu == NULL) {\
62 free(itera);\
63 errno = ENOMEM;\
64 return (IDMAP_ERR_MEMORY);\
66 itera->type = ityp;\
67 itera->retcode = IDMAP_NEXT;\
68 itera->limit = 1024;\
69 itera->arg = argu;
71 #define __ITER_CHECK(itera, ityp)\
72 if (itera == NULL) {\
73 errno = EINVAL;\
74 return (IDMAP_ERR_ARG);\
76 if (itera->type != ityp) {\
77 errno = EINVAL;\
78 return (IDMAP_ERR_ARG);\
82 * Free memory allocated by libidmap API
84 * Input:
85 * ptr - memory to be freed
87 void
88 idmap_free(void *ptr)
90 free(ptr);
94 static idmap_stat
95 idmap_get_prop(idmap_prop_type pr, idmap_prop_res *res)
97 idmap_stat retcode;
99 (void) memset(res, 0, sizeof (*res));
101 retcode = _idmap_clnt_call(IDMAP_GET_PROP,
102 (xdrproc_t)xdr_idmap_prop_type, (caddr_t)&pr,
103 (xdrproc_t)xdr_idmap_prop_res, (caddr_t)res, TIMEOUT);
104 if (retcode != IDMAP_SUCCESS)
105 return (retcode);
107 return (res->retcode); /* This might not be IDMAP_SUCCESS! */
111 idmap_stat
112 idmap_get_prop_ds(idmap_prop_type pr, idmap_ad_disc_ds_t *dc)
114 idmap_prop_res res;
115 idmap_stat rc = IDMAP_SUCCESS;
117 rc = idmap_get_prop(pr, &res);
118 if (rc < 0)
119 return (rc);
121 dc->port = res.value.idmap_prop_val_u.dsval.port;
122 (void) strlcpy(dc->host, res.value.idmap_prop_val_u.dsval.host,
123 AD_DISC_MAXHOSTNAME);
125 /* xdr doesn't guarantee 0-termination of char[]: */
126 dc->host[AD_DISC_MAXHOSTNAME - 1] = '\0';
128 return (rc);
133 * Sometimes the property is not set. In that case, str is set to NULL but
134 * otherwise IDMAP_SUCCESS is returned.
136 idmap_stat
137 idmap_get_prop_str(idmap_prop_type pr, char **str)
139 idmap_prop_res res;
140 idmap_stat rc = IDMAP_SUCCESS;
142 rc = idmap_get_prop(pr, &res);
143 if (rc < 0)
144 return (rc);
146 rc = idmap_strdupnull(str, res.value.idmap_prop_val_u.utf8val);
147 return (rc);
151 * Create/Initialize handle for updates
153 * Output:
154 * udthandle - update handle
156 idmap_stat
157 idmap_udt_create(idmap_udt_handle_t **udthandle)
159 idmap_udt_handle_t *tmp;
161 if (udthandle == NULL) {
162 errno = EINVAL;
163 return (IDMAP_ERR_ARG);
165 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
166 errno = ENOMEM;
167 return (IDMAP_ERR_MEMORY);
170 *udthandle = tmp;
171 return (IDMAP_SUCCESS);
176 * All the updates specified by the update handle are committed
177 * in a single transaction. i.e either all succeed or none.
179 * Input:
180 * udthandle - update handle with the update requests
182 * Return value:
183 * Status of the commit
185 idmap_stat
186 idmap_udt_commit(idmap_udt_handle_t *udthandle)
188 idmap_update_res res;
189 idmap_stat retcode;
191 if (udthandle == NULL) {
192 errno = EINVAL;
193 return (IDMAP_ERR_ARG);
196 (void) memset(&res, 0, sizeof (res));
198 retcode = _idmap_clnt_call(IDMAP_UPDATE,
199 (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch,
200 (xdrproc_t)xdr_idmap_update_res, (caddr_t)&res,
201 TIMEOUT);
202 if (retcode != IDMAP_SUCCESS)
203 goto out;
205 retcode = udthandle->commit_stat = res.retcode;
206 udthandle->error_index = res.error_index;
208 if (retcode != IDMAP_SUCCESS) {
210 if (udthandle->error_index < 0)
211 goto out;
213 retcode = idmap_namerule_cpy(&udthandle->error_rule,
214 &res.error_rule);
215 if (retcode != IDMAP_SUCCESS) {
216 udthandle->error_index = -2;
217 goto out;
220 retcode = idmap_namerule_cpy(&udthandle->conflict_rule,
221 &res.conflict_rule);
222 if (retcode != IDMAP_SUCCESS) {
223 udthandle->error_index = -2;
224 goto out;
228 retcode = res.retcode;
231 out:
232 /* reset handle so that it can be used again */
233 if (retcode == IDMAP_SUCCESS) {
234 _IDMAP_RESET_UDT_HANDLE(udthandle);
237 xdr_free(xdr_idmap_update_res, (caddr_t)&res);
238 errno = idmap_stat2errno(retcode);
239 return (retcode);
243 static void
244 idmap_namerule_parts_clear(char **windomain, char **winname,
245 char **unixname, boolean_t *is_user, boolean_t *is_wuser,
246 boolean_t *is_nt4, int *direction)
248 if (windomain)
249 *windomain = NULL;
250 if (winname)
251 *winname = NULL;
252 if (unixname)
253 *unixname = NULL;
255 if (is_nt4)
256 *is_nt4 = 0;
257 if (is_user)
258 *is_user = -1;
259 if (is_wuser)
260 *is_wuser = -1;
261 if (direction)
262 *direction = IDMAP_DIRECTION_UNDEF;
265 static idmap_stat
266 idmap_namerule2parts(idmap_namerule *rule,
267 char **windomain, char **winname,
268 char **unixname, boolean_t *is_user, boolean_t *is_wuser,
269 boolean_t *is_nt4, int *direction)
271 idmap_stat retcode;
273 if (EMPTY_STRING(rule->winname) && EMPTY_STRING(rule->unixname))
274 return (IDMAP_ERR_NORESULT);
277 retcode = idmap_strdupnull(windomain, rule->windomain);
278 if (retcode != IDMAP_SUCCESS)
279 goto errout;
281 retcode = idmap_strdupnull(winname, rule->winname);
282 if (retcode != IDMAP_SUCCESS)
283 goto errout;
285 retcode = idmap_strdupnull(unixname, rule->unixname);
286 if (retcode != IDMAP_SUCCESS)
287 goto errout;
290 if (is_user)
291 *is_user = rule->is_user;
292 if (is_wuser)
293 *is_wuser = rule->is_wuser;
294 if (is_nt4)
295 *is_nt4 = rule->is_nt4;
296 if (direction)
297 *direction = rule->direction;
300 return (IDMAP_SUCCESS);
302 errout:
303 if (windomain)
304 free(*windomain);
305 if (winname)
306 free(*winname);
307 if (unixname)
308 free(*unixname);
310 idmap_namerule_parts_clear(windomain, winname,
311 unixname, is_user, is_wuser, is_nt4, direction);
313 return (retcode);
318 * Retrieve the index of the failed batch element. error_index == -1
319 * indicates failure at the beginning, -2 at the end.
321 * If idmap_udt_commit didn't return error, the returned value is undefined.
323 * Return value:
324 * IDMAP_SUCCESS
327 idmap_stat
328 idmap_udt_get_error_index(idmap_udt_handle_t *udthandle,
329 int64_t *error_index)
331 if (error_index)
332 *error_index = udthandle->error_index;
334 return (IDMAP_SUCCESS);
339 * Retrieve the rule which caused the batch to fail. If
340 * idmap_udt_commit didn't return error or if error_index is < 0, the
341 * retrieved rule is undefined.
343 * Return value:
344 * IDMAP_ERR_NORESULT if there is no error rule.
345 * IDMAP_SUCCESS if the rule was obtained OK.
346 * other error code (IDMAP_ERR_NOMEMORY etc)
349 idmap_stat
350 idmap_udt_get_error_rule(idmap_udt_handle_t *udthandle,
351 char **windomain, char **winname,
352 char **unixname, boolean_t *is_user, boolean_t *is_wuser,
353 boolean_t *is_nt4, int *direction)
355 idmap_namerule_parts_clear(windomain, winname,
356 unixname, is_user, is_wuser, is_nt4, direction);
358 if (udthandle->commit_stat == IDMAP_SUCCESS ||
359 udthandle->error_index < 0)
360 return (IDMAP_ERR_NORESULT);
362 return (idmap_namerule2parts(
363 &udthandle->error_rule,
364 windomain,
365 winname,
366 unixname,
367 is_user,
368 is_wuser,
369 is_nt4,
370 direction));
374 * Retrieve the rule with which there was a conflict. TODO: retrieve
375 * the value.
377 * Return value:
378 * IDMAP_ERR_NORESULT if there is no error rule.
379 * IDMAP_SUCCESS if the rule was obtained OK.
380 * other error code (IDMAP_ERR_NOMEMORY etc)
383 idmap_stat
384 idmap_udt_get_conflict_rule(idmap_udt_handle_t *udthandle,
385 char **windomain, char **winname,
386 char **unixname, boolean_t *is_user, boolean_t *is_wuser,
387 boolean_t *is_nt4, int *direction)
389 idmap_namerule_parts_clear(windomain, winname,
390 unixname, is_user, is_wuser, is_nt4, direction);
392 if (udthandle->commit_stat != IDMAP_ERR_W2U_NAMERULE_CONFLICT &&
393 udthandle->commit_stat != IDMAP_ERR_U2W_NAMERULE_CONFLICT) {
394 return (IDMAP_ERR_NORESULT);
397 return (idmap_namerule2parts(
398 &udthandle->conflict_rule,
399 windomain,
400 winname,
401 unixname,
402 is_user,
403 is_wuser,
404 is_nt4,
405 direction));
410 * Destroy the update handle
412 void
413 idmap_udt_destroy(idmap_udt_handle_t *udthandle)
415 if (udthandle == NULL)
416 return;
417 xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
418 xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->error_rule);
419 xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->conflict_rule);
420 free(udthandle);
424 idmap_stat
425 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain,
426 boolean_t is_user, boolean_t is_wuser, const char *winname,
427 const char *unixname, boolean_t is_nt4, int direction)
429 idmap_retcode retcode;
430 idmap_namerule *rule = NULL;
432 retcode = _udt_extend_batch(udthandle);
433 if (retcode != IDMAP_SUCCESS)
434 goto errout;
436 rule = &udthandle->batch.
437 idmap_update_batch_val[udthandle->next].
438 idmap_update_op_u.rule;
439 rule->is_user = is_user;
440 rule->is_wuser = is_wuser;
441 rule->direction = direction;
442 rule->is_nt4 = is_nt4;
444 retcode = idmap_strdupnull(&rule->windomain, windomain);
445 if (retcode != IDMAP_SUCCESS)
446 goto errout;
448 retcode = idmap_strdupnull(&rule->winname, winname);
449 if (retcode != IDMAP_SUCCESS)
450 goto errout;
452 retcode = idmap_strdupnull(&rule->unixname, unixname);
453 if (retcode != IDMAP_SUCCESS)
454 goto errout;
456 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
457 OP_ADD_NAMERULE;
458 udthandle->next++;
459 return (IDMAP_SUCCESS);
461 errout:
462 /* The batch should still be usable */
463 if (rule)
464 xdr_free(xdr_idmap_namerule, (caddr_t)rule);
465 errno = idmap_stat2errno(retcode);
466 return (retcode);
470 /* ARGSUSED */
471 idmap_stat
472 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user,
473 boolean_t is_wuser, const char *windomain, const char *winname,
474 const char *unixname, int direction)
476 idmap_retcode retcode;
477 idmap_namerule *rule = NULL;
479 retcode = _udt_extend_batch(udthandle);
480 if (retcode != IDMAP_SUCCESS)
481 goto errout;
483 rule = &udthandle->batch.
484 idmap_update_batch_val[udthandle->next].
485 idmap_update_op_u.rule;
486 rule->is_user = is_user;
487 rule->is_wuser = is_wuser;
488 rule->direction = direction;
490 retcode = idmap_strdupnull(&rule->windomain, windomain);
491 if (retcode != IDMAP_SUCCESS)
492 goto errout;
494 retcode = idmap_strdupnull(&rule->winname, winname);
495 if (retcode != IDMAP_SUCCESS)
496 goto errout;
498 retcode = idmap_strdupnull(&rule->unixname, unixname);
499 if (retcode != IDMAP_SUCCESS)
500 goto errout;
502 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
503 OP_RM_NAMERULE;
504 udthandle->next++;
505 return (IDMAP_SUCCESS);
507 errout:
508 if (rule)
509 xdr_free(xdr_idmap_namerule, (caddr_t)rule);
510 errno = idmap_stat2errno(retcode);
511 return (retcode);
515 /* ARGSUSED */
516 idmap_stat
517 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle)
519 idmap_retcode retcode;
521 retcode = _udt_extend_batch(udthandle);
522 if (retcode != IDMAP_SUCCESS)
523 goto errout;
525 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
526 OP_FLUSH_NAMERULES;
527 udthandle->next++;
528 return (IDMAP_SUCCESS);
530 errout:
531 errno = idmap_stat2errno(retcode);
532 return (retcode);
537 * Set the number of entries requested per batch by the iterator
539 * Input:
540 * iter - iterator
541 * limit - number of entries requested per batch
543 idmap_stat
544 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit)
546 if (iter == NULL) {
547 errno = EINVAL;
548 return (IDMAP_ERR_ARG);
550 iter->limit = limit;
551 return (IDMAP_SUCCESS);
556 * Create iterator to get name-based mapping rules
558 * Input:
559 * windomain - Windows domain
560 * is_user - user or group rules
561 * winname - Windows user or group name
562 * unixname - Unix user or group name
564 * Output:
565 * iter - iterator
567 idmap_stat
568 idmap_iter_namerules(const char *windomain, boolean_t is_user,
569 boolean_t is_wuser, const char *winname, const char *unixname,
570 idmap_iter_t **iter)
573 idmap_iter_t *tmpiter;
574 idmap_list_namerules_1_argument *arg = NULL;
575 idmap_namerule *rule;
576 idmap_retcode retcode;
578 __ITER_CREATE(tmpiter, arg, IDMAP_LIST_NAMERULES);
580 rule = &arg->rule;
581 rule->is_user = is_user;
582 rule->is_wuser = is_wuser;
583 rule->direction = IDMAP_DIRECTION_UNDEF;
585 retcode = idmap_strdupnull(&rule->windomain, windomain);
586 if (retcode != IDMAP_SUCCESS)
587 goto errout;
589 retcode = idmap_strdupnull(&rule->winname, winname);
590 if (retcode != IDMAP_SUCCESS)
591 goto errout;
593 retcode = idmap_strdupnull(&rule->unixname, unixname);
594 if (retcode != IDMAP_SUCCESS)
595 goto errout;
597 *iter = tmpiter;
598 return (IDMAP_SUCCESS);
600 errout:
601 if (arg) {
602 xdr_free(xdr_idmap_list_namerules_1_argument, (char *)arg);
603 free(arg);
605 free(tmpiter);
607 return (retcode);
612 * Iterate through the name-based mapping rules
614 * Input:
615 * iter - iterator
617 * Output:
618 * windomain - Windows domain
619 * winname - Windows user or group name
620 * unixname - Unix user or group name
621 * is_nt4 - NT4 or AD
622 * direction - bi(0), win2unix(1), unix2win(2)
624 * Return value:
625 * 0 - done
626 * 1 - more results available
627 * < 0 - error
629 idmap_stat
630 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain,
631 char **winname, char **unixname, boolean_t *is_user,
632 boolean_t *is_wuser, boolean_t *is_nt4, int *direction)
634 idmap_namerules_res *namerules;
635 idmap_list_namerules_1_argument *arg;
636 idmap_retcode retcode;
638 idmap_namerule_parts_clear(windomain, winname,
639 unixname, is_user, is_wuser, is_nt4, direction);
642 __ITER_CHECK(iter, IDMAP_LIST_NAMERULES);
644 namerules = (idmap_namerules_res *)iter->retlist;
645 if (iter->retcode == IDMAP_NEXT && (namerules == NULL ||
646 iter->next >= namerules->rules.rules_len)) {
648 if ((arg = iter->arg) == NULL) {
649 errno = EINVAL;
650 return (IDMAP_ERR_ARG);
652 arg->limit = iter->limit;
654 retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES,
655 iter, arg,
656 (uchar_t **)&namerules, sizeof (*namerules),
657 (xdrproc_t)xdr_idmap_list_namerules_1_argument,
658 (xdrproc_t)xdr_idmap_namerules_res);
659 if (retcode != IDMAP_SUCCESS)
660 return (retcode);
662 if (IDMAP_ERROR(namerules->retcode)) {
663 retcode = namerules->retcode;
664 xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules);
665 free(namerules);
666 iter->retlist = NULL;
667 return (retcode);
669 iter->retcode = namerules->retcode;
670 arg->lastrowid = namerules->lastrowid;
673 if (namerules == NULL || namerules->rules.rules_len == 0)
674 return (IDMAP_SUCCESS);
676 if (iter->next >= namerules->rules.rules_len) {
677 return (IDMAP_ERR_ARG);
680 retcode = idmap_strdupnull(windomain,
681 namerules->rules.rules_val[iter->next].windomain);
682 if (retcode != IDMAP_SUCCESS)
683 goto errout;
685 retcode = idmap_strdupnull(winname,
686 namerules->rules.rules_val[iter->next].winname);
687 if (retcode != IDMAP_SUCCESS)
688 goto errout;
690 retcode = idmap_strdupnull(unixname,
691 namerules->rules.rules_val[iter->next].unixname);
692 if (retcode != IDMAP_SUCCESS)
693 goto errout;
695 if (is_nt4)
696 *is_nt4 = namerules->rules.rules_val[iter->next].is_nt4;
697 if (is_user)
698 *is_user = namerules->rules.rules_val[iter->next].is_user;
699 if (is_wuser)
700 *is_wuser = namerules->rules.rules_val[iter->next].is_wuser;
701 if (direction)
702 *direction = namerules->rules.rules_val[iter->next].direction;
703 iter->next++;
705 if (iter->next == namerules->rules.rules_len)
706 return (iter->retcode);
707 else
708 return (IDMAP_NEXT);
710 errout:
711 if (windomain)
712 free(*windomain);
713 if (winname)
714 free(*winname);
715 if (unixname)
716 free(*unixname);
717 return (retcode);
722 * Create iterator to get SID to UID/GID mappings
724 * Output:
725 * iter - iterator
727 idmap_stat
728 idmap_iter_mappings(idmap_iter_t **iter, int flag)
730 idmap_iter_t *tmpiter;
731 idmap_list_mappings_1_argument *arg = NULL;
733 __ITER_CREATE(tmpiter, arg, IDMAP_LIST_MAPPINGS);
735 arg->flag = flag;
736 *iter = tmpiter;
737 return (IDMAP_SUCCESS);
742 * Iterate through the SID to UID/GID mappings
744 * Input:
745 * iter - iterator
747 * Output:
748 * sid - SID in canonical form
749 * pid - UID or GID
751 * Return value:
752 * 0 - done
753 * 1 - more results available
754 * < 0 - error
756 idmap_stat
757 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix,
758 idmap_rid_t *rid, uid_t *pid, char **winname,
759 char **windomain, char **unixname, boolean_t *is_user,
760 boolean_t *is_wuser, int *direction, idmap_info *info)
762 idmap_mappings_res *mappings;
763 idmap_list_mappings_1_argument *arg;
764 idmap_retcode retcode;
765 char *str;
767 if (sidprefix)
768 *sidprefix = NULL;
769 if (rid)
770 *rid = UINT32_MAX;
771 if (winname)
772 *winname = NULL;
773 if (windomain)
774 *windomain = NULL;
775 if (unixname)
776 *unixname = NULL;
777 if (pid)
778 *pid = UINT32_MAX;
779 if (is_user)
780 *is_user = -1;
781 if (is_wuser)
782 *is_wuser = -1;
783 if (direction)
784 *direction = IDMAP_DIRECTION_UNDEF;
786 __ITER_CHECK(iter, IDMAP_LIST_MAPPINGS);
788 mappings = (idmap_mappings_res *)iter->retlist;
789 if (iter->retcode == IDMAP_NEXT && (mappings == NULL ||
790 iter->next >= mappings->mappings.mappings_len)) {
792 if ((arg = iter->arg) == NULL) {
793 errno = EINVAL;
794 return (IDMAP_ERR_ARG);
796 arg->limit = iter->limit;
798 retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS,
799 iter, arg,
800 (uchar_t **)&mappings, sizeof (*mappings),
801 (xdrproc_t)xdr_idmap_list_mappings_1_argument,
802 (xdrproc_t)xdr_idmap_mappings_res);
803 if (retcode != IDMAP_SUCCESS)
804 return (retcode);
806 if (IDMAP_ERROR(mappings->retcode)) {
807 retcode = mappings->retcode;
808 xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings);
809 free(mappings);
810 iter->retlist = NULL;
811 return (retcode);
813 iter->retcode = mappings->retcode;
814 arg->lastrowid = mappings->lastrowid;
817 if (mappings == NULL || mappings->mappings.mappings_len == 0)
818 return (IDMAP_SUCCESS);
820 if (iter->next >= mappings->mappings.mappings_len) {
821 return (IDMAP_ERR_ARG);
824 if (sidprefix) {
825 str = mappings->mappings.mappings_val[iter->next].id1.
826 idmap_id_u.sid.prefix;
827 if (str && *str != '\0') {
828 *sidprefix = strdup(str);
829 if (*sidprefix == NULL) {
830 retcode = IDMAP_ERR_MEMORY;
831 goto errout;
835 if (rid)
836 *rid = mappings->mappings.mappings_val[iter->next].id1.
837 idmap_id_u.sid.rid;
839 retcode = idmap_strdupnull(windomain,
840 mappings->mappings.mappings_val[iter->next].id1domain);
841 if (retcode != IDMAP_SUCCESS)
842 goto errout;
844 retcode = idmap_strdupnull(winname,
845 mappings->mappings.mappings_val[iter->next].id1name);
846 if (retcode != IDMAP_SUCCESS)
847 goto errout;
849 retcode = idmap_strdupnull(unixname,
850 mappings->mappings.mappings_val[iter->next].id2name);
851 if (retcode != IDMAP_SUCCESS)
852 goto errout;
855 if (pid)
856 *pid = mappings->mappings.mappings_val[iter->next].id2.
857 idmap_id_u.uid;
858 if (direction)
859 *direction = mappings->mappings.mappings_val[iter->next].
860 direction;
861 if (is_user)
862 *is_user = (mappings->mappings.mappings_val[iter->next].id2
863 .idtype == IDMAP_UID)?1:0;
864 if (is_wuser)
865 *is_wuser = (mappings->mappings.mappings_val[iter->next].id1
866 .idtype == IDMAP_USID)?1:0;
868 if (info) {
869 idmap_info_mov(info,
870 &mappings->mappings.mappings_val[iter->next].info);
872 iter->next++;
874 if (iter->next == mappings->mappings.mappings_len)
875 return (iter->retcode);
876 else
877 return (IDMAP_NEXT);
879 errout:
880 if (sidprefix)
881 free(*sidprefix);
882 if (winname)
883 free(*winname);
884 if (windomain)
885 free(*windomain);
886 if (unixname)
887 free(*unixname);
888 return (retcode);
893 * Destroy the iterator
895 void
896 idmap_iter_destroy(idmap_iter_t *iter)
898 xdrproc_t _xdr_argument, _xdr_result;
900 if (iter == NULL)
901 return;
903 switch (iter->type) {
904 case IDMAP_LIST_NAMERULES:
905 _xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument;
906 _xdr_result = (xdrproc_t)xdr_idmap_namerules_res;
907 break;
908 case IDMAP_LIST_MAPPINGS:
909 _xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument;
910 _xdr_result = (xdrproc_t)xdr_idmap_mappings_res;
911 break;
912 default:
913 free(iter);
914 return;
917 if (iter->arg) {
918 xdr_free(_xdr_argument, (caddr_t)iter->arg);
919 free(iter->arg);
921 if (iter->retlist) {
922 xdr_free(_xdr_result, (caddr_t)iter->retlist);
923 free(iter->retlist);
925 free(iter);
930 * Create handle to get SID to UID/GID mapping entries
932 * Input:
933 * gh - "get mapping" handle
935 idmap_stat
936 idmap_get_create(idmap_get_handle_t **gh)
938 idmap_get_handle_t *tmp;
940 /* allocate the handle */
941 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
942 errno = ENOMEM;
943 return (IDMAP_ERR_MEMORY);
946 *gh = tmp;
947 return (IDMAP_SUCCESS);
952 * Given SID, get UID
954 * Input:
955 * sidprefix - SID prefix
956 * rid - RID
957 * flag - flag
959 * Output:
960 * stat - status of the get request
961 * uid - POSIX UID if stat = 0
963 * Note: The output parameters will be set by idmap_get_mappings()
965 idmap_stat
966 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
967 int flag, uid_t *uid, idmap_stat *stat)
969 return (idmap_getext_uidbysid(gh, sidprefix, rid, flag, uid,
970 NULL, stat));
974 * Given SID, get UID
976 * Input:
977 * sidprefix - SID prefix
978 * rid - RID
979 * flag - flag
981 * Output:
982 * stat - status of the get request
983 * uid - POSIX UID if stat = 0
984 * how - mapping type if stat = 0
986 * Note: The output parameters will be set by idmap_get_mappings()
989 idmap_stat
990 idmap_getext_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
991 int flag, uid_t *uid, idmap_info *info, idmap_stat *stat)
993 idmap_retcode retcode;
994 idmap_mapping *mapping = NULL;
996 /* sanity checks */
997 if (gh == NULL)
998 return (IDMAP_ERR_ARG);
999 if (uid == NULL || sidprefix == NULL)
1000 return (IDMAP_ERR_ARG);
1002 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1003 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1004 retcode = idmap_cache_lookup_uidbysid(sidprefix, rid, uid);
1005 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1006 *stat = retcode;
1007 return (retcode);
1011 /* Extend the request array and the return list */
1012 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1013 goto errout;
1015 /* Setup the request */
1016 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1017 mapping->flag = flag;
1018 mapping->id1.idtype = IDMAP_SID;
1019 mapping->id1.idmap_id_u.sid.rid = rid;
1020 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1021 retcode = IDMAP_ERR_MEMORY;
1022 goto errout;
1024 mapping->id2.idtype = IDMAP_UID;
1026 /* Setup pointers for the result */
1027 gh->retlist[gh->next].idtype = IDMAP_UID;
1028 gh->retlist[gh->next].uid = uid;
1029 gh->retlist[gh->next].stat = stat;
1030 gh->retlist[gh->next].info = info;
1031 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1033 gh->next++;
1034 return (IDMAP_SUCCESS);
1036 errout:
1037 /* Batch created so far should still be usable */
1038 if (mapping)
1039 (void) memset(mapping, 0, sizeof (*mapping));
1040 errno = idmap_stat2errno(retcode);
1041 return (retcode);
1046 * Given SID, get GID
1048 * Input:
1049 * sidprefix - SID prefix
1050 * rid - rid
1051 * flag - flag
1053 * Output:
1054 * stat - status of the get request
1055 * gid - POSIX GID if stat = 0
1057 * Note: The output parameters will be set by idmap_get_mappings()
1059 idmap_stat
1060 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1061 int flag, gid_t *gid, idmap_stat *stat)
1063 return (idmap_getext_gidbysid(gh, sidprefix, rid, flag, gid,
1064 NULL, stat));
1069 * Given SID, get GID
1071 * Input:
1072 * sidprefix - SID prefix
1073 * rid - rid
1074 * flag - flag
1076 * Output:
1077 * stat - status of the get request
1078 * gid - POSIX GID if stat = 0
1079 * how - mapping type if stat = 0
1081 * Note: The output parameters will be set by idmap_get_mappings()
1083 idmap_stat
1084 idmap_getext_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1085 int flag, gid_t *gid, idmap_info *info, idmap_stat *stat)
1088 idmap_retcode retcode;
1089 idmap_mapping *mapping = NULL;
1091 /* sanity checks */
1092 if (gh == NULL)
1093 return (IDMAP_ERR_ARG);
1094 if (gid == NULL || sidprefix == NULL)
1095 return (IDMAP_ERR_ARG);
1097 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1098 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1099 retcode = idmap_cache_lookup_gidbysid(sidprefix, rid, gid);
1100 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1101 *stat = retcode;
1102 return (retcode);
1106 /* Extend the request array and the return list */
1107 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1108 goto errout;
1110 /* Setup the request */
1111 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1112 mapping->flag = flag;
1113 mapping->id1.idtype = IDMAP_SID;
1114 mapping->id1.idmap_id_u.sid.rid = rid;
1115 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1116 retcode = IDMAP_ERR_MEMORY;
1117 goto errout;
1119 mapping->id2.idtype = IDMAP_GID;
1121 /* Setup pointers for the result */
1122 gh->retlist[gh->next].idtype = IDMAP_GID;
1123 gh->retlist[gh->next].gid = gid;
1124 gh->retlist[gh->next].stat = stat;
1125 gh->retlist[gh->next].info = info;
1126 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1128 gh->next++;
1129 return (IDMAP_SUCCESS);
1131 errout:
1132 if (mapping)
1133 (void) memset(mapping, 0, sizeof (*mapping));
1134 errno = idmap_stat2errno(retcode);
1135 return (retcode);
1141 * Given SID, get POSIX ID i.e. UID/GID
1143 * Input:
1144 * sidprefix - SID prefix
1145 * rid - rid
1146 * flag - flag
1148 * Output:
1149 * stat - status of the get request
1150 * is_user - user or group
1151 * pid - POSIX UID if stat = 0 and is_user = 1
1152 * POSIX GID if stat = 0 and is_user = 0
1154 * Note: The output parameters will be set by idmap_get_mappings()
1156 idmap_stat
1157 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1158 int flag, uid_t *pid, int *is_user, idmap_stat *stat)
1160 return (idmap_getext_pidbysid(gh, sidprefix, rid, flag, pid, is_user,
1161 NULL, stat));
1167 * Given SID, get POSIX ID i.e. UID/GID
1169 * Input:
1170 * sidprefix - SID prefix
1171 * rid - rid
1172 * flag - flag
1174 * Output:
1175 * stat - status of the get request
1176 * is_user - user or group
1177 * pid - POSIX UID if stat = 0 and is_user = 1
1178 * POSIX GID if stat = 0 and is_user = 0
1179 * how - mapping type if stat = 0
1181 * Note: The output parameters will be set by idmap_get_mappings()
1183 idmap_stat
1184 idmap_getext_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1185 int flag, uid_t *pid, int *is_user, idmap_info *info, idmap_stat *stat)
1187 idmap_retcode retcode;
1188 idmap_mapping *mapping = NULL;
1190 /* sanity checks */
1191 if (gh == NULL)
1192 return (IDMAP_ERR_ARG);
1193 if (pid == NULL || sidprefix == NULL || is_user == NULL)
1194 return (IDMAP_ERR_ARG);
1196 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1197 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1198 retcode = idmap_cache_lookup_pidbysid(sidprefix, rid, pid,
1199 is_user);
1200 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1201 *stat = retcode;
1202 return (retcode);
1206 /* Extend the request array and the return list */
1207 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1208 goto errout;
1210 /* Setup the request */
1211 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1212 mapping->flag = flag;
1213 mapping->id1.idtype = IDMAP_SID;
1214 mapping->id1.idmap_id_u.sid.rid = rid;
1215 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1216 retcode = IDMAP_ERR_MEMORY;
1217 goto errout;
1219 mapping->id2.idtype = IDMAP_POSIXID;
1221 /* Setup pointers for the result */
1222 gh->retlist[gh->next].idtype = IDMAP_POSIXID;
1223 gh->retlist[gh->next].uid = pid;
1224 gh->retlist[gh->next].gid = pid;
1225 gh->retlist[gh->next].is_user = is_user;
1226 gh->retlist[gh->next].stat = stat;
1227 gh->retlist[gh->next].info = info;
1228 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1230 gh->next++;
1231 return (IDMAP_SUCCESS);
1233 errout:
1234 if (mapping)
1235 (void) memset(mapping, 0, sizeof (*mapping));
1236 errno = idmap_stat2errno(retcode);
1237 return (retcode);
1242 * Given UID, get SID
1244 * Input:
1245 * uid - POSIX UID
1246 * flag - flag
1248 * Output:
1249 * stat - status of the get request
1250 * sid - SID prefix (if stat == 0)
1251 * rid - rid
1253 * Note: The output parameters will be set by idmap_get_mappings()
1255 idmap_stat
1256 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
1257 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
1259 return (idmap_getext_sidbyuid(gh, uid, flag, sidprefix, rid,
1260 NULL, stat));
1265 * Given UID, get SID
1267 * Input:
1268 * uid - POSIX UID
1269 * flag - flag
1271 * Output:
1272 * stat - status of the get request
1273 * sid - SID prefix (if stat == 0)
1274 * rid - rid
1275 * how - mapping type if stat = 0
1277 * Note: The output parameters will be set by idmap_get_mappings()
1279 idmap_stat
1280 idmap_getext_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
1281 char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
1284 idmap_retcode retcode;
1285 idmap_mapping *mapping = NULL;
1287 /* sanity checks */
1288 if (gh == NULL)
1289 return (IDMAP_ERR_ARG);
1290 if (sidprefix == NULL)
1291 return (IDMAP_ERR_ARG);
1293 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1294 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1295 retcode = idmap_cache_lookup_sidbyuid(sidprefix, rid, uid);
1296 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1297 *stat = retcode;
1298 return (retcode);
1302 /* Extend the request array and the return list */
1303 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1304 goto errout;
1306 /* Setup the request */
1307 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1308 mapping->flag = flag;
1309 mapping->id1.idtype = IDMAP_UID;
1310 mapping->id1.idmap_id_u.uid = uid;
1311 mapping->id2.idtype = IDMAP_SID;
1313 /* Setup pointers for the result */
1314 gh->retlist[gh->next].idtype = IDMAP_SID;
1315 gh->retlist[gh->next].sidprefix = sidprefix;
1316 gh->retlist[gh->next].rid = rid;
1317 gh->retlist[gh->next].stat = stat;
1318 gh->retlist[gh->next].info = info;
1319 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1321 gh->next++;
1322 return (IDMAP_SUCCESS);
1324 errout:
1325 if (mapping)
1326 (void) memset(mapping, 0, sizeof (*mapping));
1327 errno = idmap_stat2errno(retcode);
1328 return (retcode);
1333 * Given GID, get SID
1335 * Input:
1336 * gid - POSIX GID
1337 * flag - flag
1339 * Output:
1340 * stat - status of the get request
1341 * sidprefix - SID prefix (if stat == 0)
1342 * rid - rid
1344 * Note: The output parameters will be set by idmap_get_mappings()
1346 idmap_stat
1347 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
1348 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
1350 return (idmap_getext_sidbygid(gh, gid, flag, sidprefix, rid,
1351 NULL, stat));
1356 * Given GID, get SID
1358 * Input:
1359 * gid - POSIX GID
1360 * flag - flag
1362 * Output:
1363 * stat - status of the get request
1364 * sidprefix - SID prefix (if stat == 0)
1365 * rid - rid
1366 * how - mapping type if stat = 0
1368 * Note: The output parameters will be set by idmap_get_mappings()
1370 idmap_stat
1371 idmap_getext_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
1372 char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
1375 idmap_retcode retcode;
1376 idmap_mapping *mapping = NULL;
1378 /* sanity checks */
1379 if (gh == NULL)
1380 return (IDMAP_ERR_ARG);
1381 if (sidprefix == NULL)
1382 return (IDMAP_ERR_ARG);
1384 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1385 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1386 retcode = idmap_cache_lookup_sidbygid(sidprefix, rid, gid);
1387 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1388 *stat = retcode;
1389 return (retcode);
1393 /* Extend the request array and the return list */
1394 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1395 goto errout;
1397 /* Setup the request */
1398 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1399 mapping->flag = flag;
1400 mapping->id1.idtype = IDMAP_GID;
1401 mapping->id1.idmap_id_u.gid = gid;
1402 mapping->id2.idtype = IDMAP_SID;
1404 /* Setup pointers for the result */
1405 gh->retlist[gh->next].idtype = IDMAP_SID;
1406 gh->retlist[gh->next].sidprefix = sidprefix;
1407 gh->retlist[gh->next].rid = rid;
1408 gh->retlist[gh->next].stat = stat;
1409 gh->retlist[gh->next].info = info;
1410 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1412 gh->next++;
1413 return (IDMAP_SUCCESS);
1415 errout:
1416 if (mapping)
1417 (void) memset(mapping, 0, sizeof (*mapping));
1418 errno = idmap_stat2errno(retcode);
1419 return (retcode);
1424 * Process the batched "get mapping" requests. The results (i.e.
1425 * status and identity) will be available in the data areas
1426 * provided by individual requests.
1428 idmap_stat
1429 idmap_get_mappings(idmap_get_handle_t *gh)
1431 idmap_retcode retcode;
1432 idmap_ids_res res;
1433 idmap_id *res_id;
1434 int i;
1435 idmap_id *req_id;
1436 int direction;
1438 if (gh == NULL) {
1439 errno = EINVAL;
1440 return (IDMAP_ERR_ARG);
1443 (void) memset(&res, 0, sizeof (idmap_ids_res));
1444 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_IDS,
1445 (xdrproc_t)xdr_idmap_mapping_batch,
1446 (caddr_t)&gh->batch,
1447 (xdrproc_t)xdr_idmap_ids_res,
1448 (caddr_t)&res,
1449 TIMEOUT);
1450 if (retcode != IDMAP_SUCCESS) {
1451 goto out;
1453 if (res.retcode != IDMAP_SUCCESS) {
1454 retcode = res.retcode;
1455 goto out;
1457 for (i = 0; i < gh->next; i++) {
1458 if (i >= res.ids.ids_len) {
1459 *gh->retlist[i].stat = IDMAP_ERR_NORESULT;
1460 continue;
1462 *gh->retlist[i].stat = res.ids.ids_val[i].retcode;
1463 res_id = &res.ids.ids_val[i].id;
1464 direction = res.ids.ids_val[i].direction;
1465 req_id = &gh->batch.idmap_mapping_batch_val[i].id1;
1466 switch (res_id->idtype) {
1467 case IDMAP_UID:
1468 if (gh->retlist[i].uid)
1469 *gh->retlist[i].uid = res_id->idmap_id_u.uid;
1470 if (gh->retlist[i].is_user)
1471 *gh->retlist[i].is_user = 1;
1473 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
1474 gh->retlist[i].cache_res) {
1475 if (gh->retlist[i].is_user != NULL)
1476 idmap_cache_add_sid2pid(
1477 req_id->idmap_id_u.sid.prefix,
1478 req_id->idmap_id_u.sid.rid,
1479 res_id->idmap_id_u.uid, 1,
1480 direction);
1481 else
1482 idmap_cache_add_sid2uid(
1483 req_id->idmap_id_u.sid.prefix,
1484 req_id->idmap_id_u.sid.rid,
1485 res_id->idmap_id_u.uid,
1486 direction);
1488 break;
1490 case IDMAP_GID:
1491 if (gh->retlist[i].gid)
1492 *gh->retlist[i].gid = res_id->idmap_id_u.gid;
1493 if (gh->retlist[i].is_user)
1494 *gh->retlist[i].is_user = 0;
1496 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
1497 gh->retlist[i].cache_res) {
1498 if (gh->retlist[i].is_user != NULL)
1499 idmap_cache_add_sid2pid(
1500 req_id->idmap_id_u.sid.prefix,
1501 req_id->idmap_id_u.sid.rid,
1502 res_id->idmap_id_u.gid, 0,
1503 direction);
1504 else
1505 idmap_cache_add_sid2gid(
1506 req_id->idmap_id_u.sid.prefix,
1507 req_id->idmap_id_u.sid.rid,
1508 res_id->idmap_id_u.gid,
1509 direction);
1511 break;
1513 case IDMAP_POSIXID:
1514 if (gh->retlist[i].uid)
1515 *gh->retlist[i].uid = 60001;
1516 if (gh->retlist[i].is_user)
1517 *gh->retlist[i].is_user = -1;
1518 break;
1520 case IDMAP_SID:
1521 case IDMAP_USID:
1522 case IDMAP_GSID:
1523 if (gh->retlist[i].rid)
1524 *gh->retlist[i].rid =
1525 res_id->idmap_id_u.sid.rid;
1526 if (gh->retlist[i].sidprefix) {
1527 if (res_id->idmap_id_u.sid.prefix == NULL ||
1528 *res_id->idmap_id_u.sid.prefix == '\0') {
1529 *gh->retlist[i].sidprefix = NULL;
1530 break;
1532 *gh->retlist[i].sidprefix =
1533 strdup(res_id->idmap_id_u.sid.prefix);
1534 if (*gh->retlist[i].sidprefix == NULL)
1535 *gh->retlist[i].stat =
1536 IDMAP_ERR_MEMORY;
1538 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
1539 gh->retlist[i].cache_res) {
1540 if (req_id->idtype == IDMAP_UID)
1541 idmap_cache_add_sid2uid(
1542 res_id->idmap_id_u.sid.prefix,
1543 res_id->idmap_id_u.sid.rid,
1544 req_id->idmap_id_u.uid,
1545 direction);
1546 else /* req_id->idtype == IDMAP_GID */
1547 idmap_cache_add_sid2gid(
1548 res_id->idmap_id_u.sid.prefix,
1549 res_id->idmap_id_u.sid.rid,
1550 req_id->idmap_id_u.gid,
1551 direction);
1553 break;
1555 case IDMAP_NONE:
1556 break;
1558 default:
1559 *gh->retlist[i].stat = IDMAP_ERR_NORESULT;
1560 break;
1562 if (gh->retlist[i].info != NULL) {
1563 idmap_info_mov(gh->retlist[i].info,
1564 &res.ids.ids_val[i].info);
1567 retcode = IDMAP_SUCCESS;
1569 out:
1570 _IDMAP_RESET_GET_HANDLE(gh);
1571 xdr_free(xdr_idmap_ids_res, (caddr_t)&res);
1572 errno = idmap_stat2errno(retcode);
1573 return (retcode);
1578 * Destroy the "get mapping" handle
1580 void
1581 idmap_get_destroy(idmap_get_handle_t *gh)
1583 if (gh == NULL)
1584 return;
1585 xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
1586 free(gh->retlist);
1587 free(gh);
1592 * Get windows to unix mapping
1594 idmap_stat
1595 idmap_get_w2u_mapping(
1596 const char *sidprefix, idmap_rid_t *rid,
1597 const char *winname, const char *windomain,
1598 int flag, int *is_user, int *is_wuser,
1599 uid_t *pid, char **unixname, int *direction, idmap_info *info)
1601 idmap_mapping request, *mapping;
1602 idmap_mappings_res result;
1603 idmap_retcode retcode, rc;
1605 (void) memset(&request, 0, sizeof (request));
1606 (void) memset(&result, 0, sizeof (result));
1608 if (pid)
1609 *pid = UINT32_MAX;
1610 if (unixname)
1611 *unixname = NULL;
1612 if (direction)
1613 *direction = IDMAP_DIRECTION_UNDEF;
1615 request.flag = flag;
1616 request.id1.idtype = IDMAP_SID;
1617 if (sidprefix && rid) {
1618 request.id1.idmap_id_u.sid.prefix = (char *)sidprefix;
1619 request.id1.idmap_id_u.sid.rid = *rid;
1620 } else if (winname) {
1621 retcode = idmap_strdupnull(&request.id1name, winname);
1622 if (retcode != IDMAP_SUCCESS)
1623 goto out;
1625 retcode = idmap_strdupnull(&request.id1domain, windomain);
1626 if (retcode != IDMAP_SUCCESS)
1627 goto out;
1629 request.id1.idmap_id_u.sid.prefix = NULL;
1630 } else {
1631 errno = EINVAL;
1632 return (IDMAP_ERR_ARG);
1635 if (*is_user == 1)
1636 request.id2.idtype = IDMAP_UID;
1637 else if (*is_user == 0)
1638 request.id2.idtype = IDMAP_GID;
1639 else
1640 request.id2.idtype = IDMAP_POSIXID;
1642 if (*is_wuser == 1)
1643 request.id1.idtype = IDMAP_USID;
1644 else if (*is_wuser == 0)
1645 request.id1.idtype = IDMAP_GSID;
1646 else
1647 request.id1.idtype = IDMAP_SID;
1649 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME,
1650 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
1651 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
1652 TIMEOUT);
1654 if (retcode != IDMAP_SUCCESS)
1655 goto out;
1657 retcode = result.retcode;
1659 if ((mapping = result.mappings.mappings_val) == NULL) {
1660 if (retcode == IDMAP_SUCCESS)
1661 retcode = IDMAP_ERR_NORESULT;
1662 goto out;
1665 if (info != NULL)
1666 idmap_info_mov(info, &mapping->info);
1668 if (mapping->id2.idtype == IDMAP_UID) {
1669 *is_user = 1;
1670 } else if (mapping->id2.idtype == IDMAP_GID) {
1671 *is_user = 0;
1672 } else {
1673 goto out;
1676 if (mapping->id1.idtype == IDMAP_USID) {
1677 *is_wuser = 1;
1678 } else if (mapping->id1.idtype == IDMAP_GSID) {
1679 *is_wuser = 0;
1680 } else {
1681 goto out;
1684 if (direction)
1685 *direction = mapping->direction;
1686 if (pid)
1687 *pid = mapping->id2.idmap_id_u.uid;
1689 rc = idmap_strdupnull(unixname, mapping->id2name);
1690 if (rc != IDMAP_SUCCESS)
1691 retcode = rc;
1693 out:
1694 free(request.id1name);
1695 free(request.id1domain);
1696 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
1697 if (retcode != IDMAP_SUCCESS)
1698 errno = idmap_stat2errno(retcode);
1699 return (retcode);
1704 * Get unix to windows mapping
1706 idmap_stat
1707 idmap_get_u2w_mapping(
1708 uid_t *pid, const char *unixname,
1709 int flag, int is_user, int *is_wuser,
1710 char **sidprefix, idmap_rid_t *rid,
1711 char **winname, char **windomain,
1712 int *direction, idmap_info *info)
1714 idmap_mapping request, *mapping;
1715 idmap_mappings_res result;
1716 idmap_retcode retcode, rc;
1718 if (sidprefix)
1719 *sidprefix = NULL;
1720 if (winname)
1721 *winname = NULL;
1722 if (windomain)
1723 *windomain = NULL;
1724 if (rid)
1725 *rid = UINT32_MAX;
1726 if (direction)
1727 *direction = IDMAP_DIRECTION_UNDEF;
1729 (void) memset(&request, 0, sizeof (request));
1730 (void) memset(&result, 0, sizeof (result));
1732 request.flag = flag;
1733 request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID;
1735 if (pid && *pid != UINT32_MAX) {
1736 request.id1.idmap_id_u.uid = *pid;
1737 } else if (unixname) {
1738 request.id1name = (char *)unixname;
1739 request.id1.idmap_id_u.uid = UINT32_MAX;
1740 } else {
1741 errno = EINVAL;
1742 return (IDMAP_ERR_ARG);
1745 if (is_wuser == NULL)
1746 request.id2.idtype = IDMAP_SID;
1747 else if (*is_wuser == -1)
1748 request.id2.idtype = IDMAP_SID;
1749 else if (*is_wuser == 0)
1750 request.id2.idtype = IDMAP_GSID;
1751 else if (*is_wuser == 1)
1752 request.id2.idtype = IDMAP_USID;
1754 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME,
1755 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
1756 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
1757 TIMEOUT);
1759 if (retcode != IDMAP_SUCCESS)
1760 goto out;
1762 retcode = result.retcode;
1764 if ((mapping = result.mappings.mappings_val) == NULL) {
1765 if (retcode == IDMAP_SUCCESS)
1766 retcode = IDMAP_ERR_NORESULT;
1767 goto out;
1770 if (info != NULL)
1771 idmap_info_mov(info, &mapping->info);
1773 if (direction != NULL)
1774 *direction = mapping->direction;
1776 if (is_wuser != NULL) {
1777 if (mapping->id2.idtype == IDMAP_USID)
1778 *is_wuser = 1;
1779 else if (mapping->id2.idtype == IDMAP_GSID)
1780 *is_wuser = 0;
1781 else
1782 *is_wuser = -1;
1785 if (sidprefix && mapping->id2.idmap_id_u.sid.prefix &&
1786 *mapping->id2.idmap_id_u.sid.prefix != '\0') {
1787 *sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix);
1788 if (*sidprefix == NULL) {
1789 retcode = IDMAP_ERR_MEMORY;
1790 goto errout;
1793 if (rid)
1794 *rid = mapping->id2.idmap_id_u.sid.rid;
1796 rc = idmap_strdupnull(winname, mapping->id2name);
1797 if (rc != IDMAP_SUCCESS)
1798 retcode = rc;
1800 rc = idmap_strdupnull(windomain, mapping->id2domain);
1801 if (rc != IDMAP_SUCCESS)
1802 retcode = rc;
1804 goto out;
1806 errout:
1807 if (sidprefix && *sidprefix) {
1808 free(*sidprefix);
1809 *sidprefix = NULL;
1811 if (winname && *winname) {
1812 free(*winname);
1813 *winname = NULL;
1815 if (windomain && *windomain) {
1816 free(*windomain);
1817 *windomain = NULL;
1820 out:
1821 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
1822 if (retcode != IDMAP_SUCCESS)
1823 errno = idmap_stat2errno(retcode);
1824 return (retcode);
1829 #define gettext(s) s
1830 static stat_table_t stattable[] = {
1831 {IDMAP_SUCCESS, gettext("Success"), 0},
1832 {IDMAP_NEXT, gettext("More results available"), 0},
1833 {IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL},
1834 {IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL},
1835 {IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM},
1836 {IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL},
1837 {IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL},
1838 {IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL},
1839 {IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP},
1840 {IDMAP_ERR_W2U_NAMERULE,
1841 gettext("Invalid Windows to UNIX name-based rule"), EINVAL},
1842 {IDMAP_ERR_U2W_NAMERULE,
1843 gettext("Invalid UNIX to Windows name-based rule"), EINVAL},
1844 {IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL},
1845 {IDMAP_ERR_DB, gettext("Invalid database"), EINVAL},
1846 {IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL},
1847 {IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL},
1848 {IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL},
1849 {IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF},
1850 {IDMAP_ERR_RPC, gettext("RPC error"), EINVAL},
1851 {IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL},
1852 {IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY},
1853 {IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES},
1854 {IDMAP_ERR_NOMAPPING,
1855 gettext("Mapping not found or inhibited"), EINVAL},
1856 {IDMAP_ERR_NEW_ID_ALLOC_REQD,
1857 gettext("New mapping needs to be created"), EINVAL},
1858 {IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL},
1859 {IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL},
1860 {IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL},
1861 {IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL},
1862 {IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL},
1863 {IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL},
1864 {IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL},
1865 {IDMAP_ERR_NOTMAPPED_WELLKNOWN,
1866 gettext("No mapping for well-known SID"), EINVAL},
1867 {IDMAP_ERR_RETRIABLE_NET_ERR,
1868 gettext("Windows lookup failed"), EINVAL},
1869 {IDMAP_ERR_W2U_NAMERULE_CONFLICT,
1870 gettext("Duplicate rule or conflicts with an existing "
1871 "Windows to UNIX name-based rule"), EINVAL},
1872 {IDMAP_ERR_U2W_NAMERULE_CONFLICT,
1873 gettext("Duplicate rule or conflicts with an existing "
1874 "Unix to Windows name-based rule"), EINVAL},
1875 {IDMAP_ERR_BAD_UTF8,
1876 gettext("Invalid or illegal UTF-8 sequence found in "
1877 "a given Windows entity name or domain name"), EINVAL},
1878 {IDMAP_ERR_NONE_GENERATED,
1879 gettext("Mapping not found and none created (see -c option)"),
1880 EINVAL},
1881 {IDMAP_ERR_PROP_UNKNOWN,
1882 gettext("Undefined property"),
1883 EINVAL},
1884 {IDMAP_ERR_NS_LDAP_CFG,
1885 gettext("Native LDAP configuration error"), EINVAL},
1886 {IDMAP_ERR_NS_LDAP_PARTIAL,
1887 gettext("Partial result from Native LDAP"), EINVAL},
1888 {IDMAP_ERR_NS_LDAP_OP_FAILED,
1889 gettext("Native LDAP operation failed"), EINVAL},
1890 {IDMAP_ERR_NS_LDAP_BAD_WINNAME,
1891 gettext("Improper winname form found in Native LDAP"), EINVAL},
1892 {IDMAP_ERR_NO_ACTIVEDIRECTORY,
1893 gettext("No AD servers"),
1894 EINVAL},
1895 {-1, NULL, 0}
1897 #undef gettext
1901 * Get description of status code
1903 * Input:
1904 * status - Status code returned by libidmap API call
1906 * Return Value:
1907 * human-readable localized description of idmap_stat
1909 const char *
1910 idmap_stat2string(idmap_stat status)
1912 int i;
1914 for (i = 0; stattable[i].msg; i++) {
1915 if (stattable[i].retcode == status)
1916 return (dgettext(TEXT_DOMAIN, stattable[i].msg));
1918 return (dgettext(TEXT_DOMAIN, "Unknown error"));
1922 static int
1923 idmap_stat2errno(idmap_stat stat)
1925 int i;
1926 for (i = 0; stattable[i].msg; i++) {
1927 if (stattable[i].retcode == stat)
1928 return (stattable[i].errnum);
1930 return (EINVAL);
1935 * Get status code from string
1937 idmap_stat
1938 idmap_string2stat(const char *str)
1940 if (str == NULL)
1941 return (IDMAP_ERR_INTERNAL);
1943 #define return_cmp(a) \
1944 if (0 == strcmp(str, "IDMAP_ERR_" #a)) \
1945 return (IDMAP_ERR_ ## a);
1947 return_cmp(OTHER);
1948 return_cmp(INTERNAL);
1949 return_cmp(MEMORY);
1950 return_cmp(NORESULT);
1951 return_cmp(NOTUSER);
1952 return_cmp(NOTGROUP);
1953 return_cmp(NOTSUPPORTED);
1954 return_cmp(W2U_NAMERULE);
1955 return_cmp(U2W_NAMERULE);
1956 return_cmp(CACHE);
1957 return_cmp(DB);
1958 return_cmp(ARG);
1959 return_cmp(SID);
1960 return_cmp(IDTYPE);
1961 return_cmp(RPC_HANDLE);
1962 return_cmp(RPC);
1963 return_cmp(CLIENT_HANDLE);
1964 return_cmp(BUSY);
1965 return_cmp(PERMISSION_DENIED);
1966 return_cmp(NOMAPPING);
1967 return_cmp(NEW_ID_ALLOC_REQD);
1968 return_cmp(DOMAIN);
1969 return_cmp(SECURITY);
1970 return_cmp(NOTFOUND);
1971 return_cmp(DOMAIN_NOTFOUND);
1972 return_cmp(MEMORY);
1973 return_cmp(UPDATE_NOTALLOWED);
1974 return_cmp(CFG);
1975 return_cmp(CFG_CHANGE);
1976 return_cmp(NOTMAPPED_WELLKNOWN);
1977 return_cmp(RETRIABLE_NET_ERR);
1978 return_cmp(W2U_NAMERULE_CONFLICT);
1979 return_cmp(U2W_NAMERULE_CONFLICT);
1980 return_cmp(BAD_UTF8);
1981 return_cmp(NONE_GENERATED);
1982 return_cmp(PROP_UNKNOWN);
1983 return_cmp(NS_LDAP_CFG);
1984 return_cmp(NS_LDAP_PARTIAL);
1985 return_cmp(NS_LDAP_OP_FAILED);
1986 return_cmp(NS_LDAP_BAD_WINNAME);
1987 return_cmp(NO_ACTIVEDIRECTORY);
1988 #undef return_cmp
1990 return (IDMAP_ERR_OTHER);
1995 * Map the given status to one that can be returned by the protocol
1997 idmap_stat
1998 idmap_stat4prot(idmap_stat status)
2000 switch (status) {
2001 case IDMAP_ERR_MEMORY:
2002 case IDMAP_ERR_CACHE:
2003 return (IDMAP_ERR_INTERNAL);
2005 return (status);
2010 * This is a convenience routine which duplicates a string after
2011 * checking for NULL pointers. This function will return success if
2012 * either the 'to' OR 'from' pointers are NULL.
2014 static idmap_stat
2015 idmap_strdupnull(char **to, const char *from)
2017 if (to == NULL)
2018 return (IDMAP_SUCCESS);
2020 if (from == NULL || *from == '\0') {
2021 *to = NULL;
2022 return (IDMAP_SUCCESS);
2025 *to = strdup(from);
2026 if (*to == NULL)
2027 return (IDMAP_ERR_MEMORY);
2028 return (IDMAP_SUCCESS);
2032 idmap_stat
2033 idmap_namerule_cpy(idmap_namerule *to, idmap_namerule *from)
2035 idmap_stat retval;
2037 if (to == NULL)
2038 return (IDMAP_SUCCESS);
2040 (void) memcpy(to, from, sizeof (idmap_namerule));
2041 to->windomain = NULL;
2042 to->winname = NULL;
2043 to->unixname = NULL;
2045 retval = idmap_strdupnull(&to->windomain, from->windomain);
2046 if (retval != IDMAP_SUCCESS)
2047 return (retval);
2049 retval = idmap_strdupnull(&to->winname, from->winname);
2050 if (retval != IDMAP_SUCCESS) {
2051 free(to->windomain);
2052 to->windomain = NULL;
2053 return (retval);
2056 retval = idmap_strdupnull(&to->unixname, from->unixname);
2057 if (retval != IDMAP_SUCCESS) {
2058 free(to->windomain);
2059 to->windomain = NULL;
2060 free(to->winname);
2061 to->winname = NULL;
2062 return (retval);
2065 return (retval);
2070 * Move the contents of the "info" structure from "from" to "to".
2072 void
2073 idmap_info_mov(idmap_info *to, idmap_info *from)
2075 (void) memcpy(to, from, sizeof (idmap_info));
2076 (void) memset(from, 0, sizeof (idmap_info));
2080 void
2081 idmap_info_free(idmap_info *info)
2083 if (info == NULL)
2084 return;
2086 xdr_free(xdr_idmap_info, (caddr_t)info);
2087 (void) memset(info, 0, sizeof (idmap_info));
2091 void
2092 idmap_how_clear(idmap_how *how)
2094 xdr_free(xdr_idmap_how, (caddr_t)how);
2095 (void) memset(how, 0, sizeof (*how));
2100 * Get uid given Windows name
2102 idmap_stat
2103 idmap_getuidbywinname(const char *name, const char *domain, int flag,
2104 uid_t *uid)
2106 idmap_retcode rc;
2107 int is_user = 1;
2108 int is_wuser = -1;
2109 int direction;
2111 if (uid == NULL)
2112 return (IDMAP_ERR_ARG);
2114 if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2115 rc = idmap_cache_lookup_uidbywinname(name, domain, uid);
2116 if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY)
2117 return (rc);
2119 /* Get mapping */
2120 rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag,
2121 &is_user, &is_wuser, uid, NULL, &direction, NULL);
2123 if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
2124 /* If we have not got the domain don't store UID to winname */
2125 if (domain == NULL)
2126 direction = IDMAP_DIRECTION_W2U;
2127 idmap_cache_add_winname2uid(name, domain, *uid, direction);
2130 return (rc);
2135 * Get gid given Windows name
2137 idmap_stat
2138 idmap_getgidbywinname(const char *name, const char *domain, int flag,
2139 gid_t *gid)
2141 idmap_retcode rc;
2142 int is_user = 0;
2143 int is_wuser = -1;
2144 int direction;
2146 if (gid == NULL)
2147 return (IDMAP_ERR_ARG);
2149 if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2150 rc = idmap_cache_lookup_gidbywinname(name, domain, gid);
2151 if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY)
2152 return (rc);
2155 /* Get mapping */
2156 rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag,
2157 &is_user, &is_wuser, gid, NULL, &direction, NULL);
2159 if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
2160 /* If we have not got the domain don't store GID to winname */
2161 if (domain == NULL)
2162 direction = IDMAP_DIRECTION_W2U;
2163 idmap_cache_add_winname2gid(name, domain, *gid, direction);
2166 return (rc);
2171 * Get winname given pid
2173 idmap_stat
2174 idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name,
2175 char **domain)
2177 idmap_retcode rc;
2178 int len;
2179 char *winname, *windomain;
2180 int direction;
2182 if (name == NULL)
2183 return (IDMAP_ERR_ARG);
2185 if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2186 if (is_user)
2187 rc = idmap_cache_lookup_winnamebyuid(&winname,
2188 &windomain, pid);
2189 else
2190 rc = idmap_cache_lookup_winnamebygid(&winname,
2191 &windomain, pid);
2192 if (rc == IDMAP_SUCCESS)
2193 goto out;
2194 if (rc == IDMAP_ERR_MEMORY)
2195 return (rc);
2198 /* Get mapping */
2199 rc = idmap_get_u2w_mapping(&pid, NULL, flag, is_user, NULL,
2200 NULL, NULL, &winname, &windomain, &direction, NULL);
2202 /* Return on error */
2203 if (rc != IDMAP_SUCCESS)
2204 return (rc);
2207 * The given PID may have been mapped to a locally
2208 * generated SID in which case there isn't any
2209 * Windows name
2211 if (winname == NULL) {
2212 idmap_free(windomain);
2213 return (IDMAP_ERR_NORESULT);
2216 if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2217 if (is_user)
2218 idmap_cache_add_winname2uid(winname, windomain,
2219 pid, direction);
2220 else
2221 idmap_cache_add_winname2gid(winname, windomain,
2222 pid, direction);
2225 out:
2226 if (domain != NULL) {
2227 *name = winname;
2228 *domain = windomain;
2229 } else {
2230 char *wd = windomain != NULL ? windomain : "";
2231 len = snprintf(NULL, 0, "%s@%s", winname, wd) + 1;
2232 if ((*name = malloc(len)) != NULL)
2233 (void) snprintf(*name, len, "%s@%s", winname, wd);
2234 else
2235 rc = IDMAP_ERR_MEMORY;
2236 idmap_free(winname);
2237 idmap_free(windomain);
2240 return (rc);
2245 * Get winname given uid
2247 idmap_stat
2248 idmap_getwinnamebyuid(uid_t uid, int flag, char **name, char **domain)
2250 return (idmap_getwinnamebypid(uid, 1, flag, name, domain));
2255 * Get winname given gid
2257 idmap_stat
2258 idmap_getwinnamebygid(gid_t gid, int flag, char **name, char **domain)
2260 return (idmap_getwinnamebypid(gid, 0, flag, name, domain));
2263 idmap_stat
2264 idmap_flush(idmap_flush_op op)
2266 idmap_retcode rc1, rc2;
2268 rc1 = _idmap_clnt_call(IDMAP_FLUSH,
2269 (xdrproc_t)xdr_idmap_flush_op, (caddr_t)&op,
2270 (xdrproc_t)xdr_idmap_retcode, (caddr_t)&rc2, TIMEOUT);
2272 if (rc1 != IDMAP_SUCCESS)
2273 return (rc1);
2274 return (rc2);
2279 * syslog is the default logger.
2280 * It can be overwritten by supplying a logger
2281 * with idmap_set_logger()
2283 idmap_logger_t logger = syslog;
2286 void
2287 idmap_set_logger(idmap_logger_t funct)
2289 logger = funct;
2293 * Helper functions that concatenate two parts of a name and then
2294 * look up a value, so that the same set of functions can be used to
2295 * process both "in" and "out" parameters.
2297 static
2298 boolean_t
2299 idmap_trace_get_str(nvlist_t *entry, char *n1, char *n2, char **ret)
2301 char name[IDMAP_TRACE_NAME_MAX+1]; /* Max used is about 11 */
2302 int err;
2304 (void) strlcpy(name, n1, sizeof (name));
2305 if (n2 != NULL)
2306 (void) strlcat(name, n2, sizeof (name));
2308 err = nvlist_lookup_string(entry, name, ret);
2309 return (err == 0);
2312 static
2313 boolean_t
2314 idmap_trace_get_int(nvlist_t *entry, char *n1, char *n2, int64_t *ret)
2316 char name[IDMAP_TRACE_NAME_MAX+1]; /* Max used is about 11 */
2317 int err;
2319 (void) strlcpy(name, n1, sizeof (name));
2320 if (n2 != NULL)
2321 (void) strlcat(name, n2, sizeof (name));
2323 err = nvlist_lookup_int64(entry, name, ret);
2324 return (err == 0);
2327 static
2328 void
2329 idmap_trace_print_id(FILE *out, nvlist_t *entry, char *fromto)
2331 char *s;
2332 int64_t i64;
2334 if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_TYPE, &i64)) {
2335 switch (i64) {
2336 case IDMAP_POSIXID:
2337 (void) fprintf(out, "unixname ");
2338 break;
2339 case IDMAP_UID:
2340 (void) fprintf(out, "unixuser ");
2341 break;
2342 case IDMAP_GID:
2343 (void) fprintf(out, "unixgroup ");
2344 break;
2345 case IDMAP_SID:
2346 (void) fprintf(out, "winname ");
2347 break;
2348 case IDMAP_USID:
2349 (void) fprintf(out, "winuser ");
2350 break;
2351 case IDMAP_GSID:
2352 (void) fprintf(out, "wingroup ");
2353 break;
2354 case IDMAP_NONE:
2355 (void) fprintf(out, gettext("unknown "));
2356 break;
2357 default:
2358 (void) fprintf(out, gettext("bad %d "), (int)i64);
2359 break;
2363 if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_NAME, &s))
2364 (void) fprintf(out, "%s ", s);
2366 if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_SID, &s))
2367 (void) fprintf(out, "%s ", s);
2369 if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_UNIXID, &i64))
2370 (void) fprintf(out, "%u ", (uid_t)i64);
2373 void
2374 idmap_trace_print_1(FILE *out, char *prefix, nvlist_t *entry)
2376 char *s;
2377 int64_t i64;
2379 (void) fprintf(out, "%s", prefix);
2380 idmap_trace_print_id(out, entry, "from");
2381 (void) fprintf(out, "-> ");
2382 idmap_trace_print_id(out, entry, "to");
2383 if (idmap_trace_get_int(entry, IDMAP_TRACE_ERROR, NULL, &i64))
2384 (void) fprintf(out, gettext("Error %d "), (int)i64);
2385 (void) fprintf(out, "-");
2386 if (idmap_trace_get_str(entry, IDMAP_TRACE_MESSAGE, NULL, &s))
2387 (void) fprintf(out, " %s", s);
2388 (void) fprintf(out, "\n");
2391 void
2392 idmap_trace_print(FILE *out, char *prefix, nvlist_t *trace)
2394 nvpair_t *nvp;
2396 for (nvp = nvlist_next_nvpair(trace, NULL);
2397 nvp != NULL;
2398 nvp = nvlist_next_nvpair(trace, nvp)) {
2399 nvlist_t *entry;
2400 int err;
2402 err = nvpair_value_nvlist(nvp, &entry);
2403 assert(err == 0);
2405 idmap_trace_print_1(out, prefix, entry);