Print this page
NEX-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
SUP-795 IDMAP: idmap_getwinnamebyuid() and idmap_getwinnamebygid() fails for empty domains
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
SUP-642 Regression leading to AD usernames not being displayed by zfs userspace command.
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libidmap/common/idmap_api.c
+++ new/usr/src/lib/libidmap/common/idmap_api.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 * Copyright Milan Jurik 2012. All rights reserved.
24 - * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
25 25 * Copyright 2015 Joyent, Inc.
26 26 */
27 27
28 28
29 29 /*
30 30 * libidmap API
31 31 */
32 32
33 33 #include <stdlib.h>
34 34 #include <sys/varargs.h>
35 35 #include <inttypes.h>
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
36 36 #include <errno.h>
37 37 #include <strings.h>
38 38 #include <ctype.h>
39 39 #include <sys/param.h>
40 40 #include <sys/types.h>
41 41 #include <sys/stat.h>
42 42 #include <dlfcn.h>
43 43 #include <libintl.h>
44 44 #include <syslog.h>
45 45 #include <assert.h>
46 +#include <unistd.h>
47 +#include <pwd.h>
48 +#include <grp.h>
49 +#include <netdb.h>
46 50 #include "idmap_impl.h"
47 51 #include "idmap_cache.h"
48 52
49 53 static struct timeval TIMEOUT = { 25, 0 };
50 54
51 55 static int idmap_stat2errno(idmap_stat);
52 56 static idmap_stat idmap_strdupnull(char **, const char *);
53 57
54 58 #define __ITER_CREATE(itera, argu, ityp)\
55 59 itera = calloc(1, sizeof (*itera));\
56 60 if (itera == NULL) {\
57 61 errno = ENOMEM;\
58 62 return (IDMAP_ERR_MEMORY);\
59 63 }\
60 64 argu = calloc(1, sizeof (*argu));\
61 65 if (argu == NULL) {\
62 66 free(itera);\
63 67 errno = ENOMEM;\
64 68 return (IDMAP_ERR_MEMORY);\
65 69 }\
66 70 itera->type = ityp;\
67 71 itera->retcode = IDMAP_NEXT;\
68 72 itera->limit = 1024;\
69 73 itera->arg = argu;
70 74
71 75 #define __ITER_CHECK(itera, ityp)\
72 76 if (itera == NULL) {\
73 77 errno = EINVAL;\
74 78 return (IDMAP_ERR_ARG);\
75 79 }\
76 80 if (itera->type != ityp) {\
77 81 errno = EINVAL;\
78 82 return (IDMAP_ERR_ARG);\
79 83 }
80 84
81 85 /*
82 86 * Free memory allocated by libidmap API
83 87 *
84 88 * Input:
85 89 * ptr - memory to be freed
86 90 */
87 91 void
88 92 idmap_free(void *ptr)
89 93 {
90 94 free(ptr);
91 95 }
92 96
93 97
94 98 static idmap_stat
95 99 idmap_get_prop(idmap_prop_type pr, idmap_prop_res *res)
96 100 {
97 101 idmap_stat retcode;
98 102
99 103 (void) memset(res, 0, sizeof (*res));
100 104
101 105 retcode = _idmap_clnt_call(IDMAP_GET_PROP,
102 106 (xdrproc_t)xdr_idmap_prop_type, (caddr_t)&pr,
103 107 (xdrproc_t)xdr_idmap_prop_res, (caddr_t)res, TIMEOUT);
104 108 if (retcode != IDMAP_SUCCESS)
105 109 return (retcode);
106 110
107 111 return (res->retcode); /* This might not be IDMAP_SUCCESS! */
108 112 }
109 113
110 114
111 115 idmap_stat
112 116 idmap_get_prop_ds(idmap_prop_type pr, idmap_ad_disc_ds_t *dc)
113 117 {
114 118 idmap_prop_res res;
115 119 idmap_stat rc = IDMAP_SUCCESS;
116 120
117 121 rc = idmap_get_prop(pr, &res);
118 122 if (rc < 0)
119 123 return (rc);
120 124
121 125 dc->port = res.value.idmap_prop_val_u.dsval.port;
122 126 (void) strlcpy(dc->host, res.value.idmap_prop_val_u.dsval.host,
123 127 AD_DISC_MAXHOSTNAME);
124 128
125 129 /* xdr doesn't guarantee 0-termination of char[]: */
126 130 dc->host[AD_DISC_MAXHOSTNAME - 1] = '\0';
127 131
128 132 return (rc);
129 133 }
130 134
131 135
132 136 /*
133 137 * Sometimes the property is not set. In that case, str is set to NULL but
134 138 * otherwise IDMAP_SUCCESS is returned.
135 139 */
136 140 idmap_stat
137 141 idmap_get_prop_str(idmap_prop_type pr, char **str)
138 142 {
139 143 idmap_prop_res res;
140 144 idmap_stat rc = IDMAP_SUCCESS;
141 145
142 146 rc = idmap_get_prop(pr, &res);
143 147 if (rc < 0)
144 148 return (rc);
145 149
146 150 rc = idmap_strdupnull(str, res.value.idmap_prop_val_u.utf8val);
147 151 return (rc);
148 152 }
149 153
150 154 /*
151 155 * Create/Initialize handle for updates
152 156 *
153 157 * Output:
154 158 * udthandle - update handle
155 159 */
156 160 idmap_stat
157 161 idmap_udt_create(idmap_udt_handle_t **udthandle)
158 162 {
159 163 idmap_udt_handle_t *tmp;
160 164
161 165 if (udthandle == NULL) {
162 166 errno = EINVAL;
163 167 return (IDMAP_ERR_ARG);
164 168 }
165 169 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
166 170 errno = ENOMEM;
167 171 return (IDMAP_ERR_MEMORY);
168 172 }
169 173
170 174 *udthandle = tmp;
171 175 return (IDMAP_SUCCESS);
172 176 }
173 177
174 178
175 179 /*
176 180 * All the updates specified by the update handle are committed
177 181 * in a single transaction. i.e either all succeed or none.
178 182 *
179 183 * Input:
180 184 * udthandle - update handle with the update requests
181 185 *
182 186 * Return value:
183 187 * Status of the commit
184 188 */
185 189 idmap_stat
186 190 idmap_udt_commit(idmap_udt_handle_t *udthandle)
187 191 {
188 192 idmap_update_res res;
189 193 idmap_stat retcode;
190 194
191 195 if (udthandle == NULL) {
192 196 errno = EINVAL;
193 197 return (IDMAP_ERR_ARG);
194 198 }
195 199
196 200 (void) memset(&res, 0, sizeof (res));
197 201
198 202 retcode = _idmap_clnt_call(IDMAP_UPDATE,
199 203 (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch,
200 204 (xdrproc_t)xdr_idmap_update_res, (caddr_t)&res,
201 205 TIMEOUT);
202 206 if (retcode != IDMAP_SUCCESS)
203 207 goto out;
204 208
205 209 retcode = udthandle->commit_stat = res.retcode;
206 210 udthandle->error_index = res.error_index;
207 211
208 212 if (retcode != IDMAP_SUCCESS) {
209 213
210 214 if (udthandle->error_index < 0)
211 215 goto out;
212 216
213 217 retcode = idmap_namerule_cpy(&udthandle->error_rule,
214 218 &res.error_rule);
215 219 if (retcode != IDMAP_SUCCESS) {
216 220 udthandle->error_index = -2;
217 221 goto out;
218 222 }
219 223
220 224 retcode = idmap_namerule_cpy(&udthandle->conflict_rule,
221 225 &res.conflict_rule);
222 226 if (retcode != IDMAP_SUCCESS) {
223 227 udthandle->error_index = -2;
224 228 goto out;
225 229 }
226 230 }
227 231
228 232 retcode = res.retcode;
229 233
230 234
231 235 out:
232 236 /* reset handle so that it can be used again */
233 237 if (retcode == IDMAP_SUCCESS) {
234 238 _IDMAP_RESET_UDT_HANDLE(udthandle);
235 239 }
236 240
237 241 xdr_free(xdr_idmap_update_res, (caddr_t)&res);
238 242 errno = idmap_stat2errno(retcode);
239 243 return (retcode);
240 244 }
241 245
242 246
243 247 static void
244 248 idmap_namerule_parts_clear(char **windomain, char **winname,
245 249 char **unixname, boolean_t *is_user, boolean_t *is_wuser,
246 250 boolean_t *is_nt4, int *direction)
247 251 {
248 252 if (windomain)
249 253 *windomain = NULL;
250 254 if (winname)
251 255 *winname = NULL;
252 256 if (unixname)
253 257 *unixname = NULL;
254 258
255 259 if (is_nt4)
256 260 *is_nt4 = 0;
257 261 if (is_user)
258 262 *is_user = -1;
259 263 if (is_wuser)
260 264 *is_wuser = -1;
261 265 if (direction)
262 266 *direction = IDMAP_DIRECTION_UNDEF;
263 267 }
264 268
265 269 static idmap_stat
266 270 idmap_namerule2parts(idmap_namerule *rule,
267 271 char **windomain, char **winname,
268 272 char **unixname, boolean_t *is_user, boolean_t *is_wuser,
269 273 boolean_t *is_nt4, int *direction)
270 274 {
271 275 idmap_stat retcode;
272 276
273 277 if (EMPTY_STRING(rule->winname) && EMPTY_STRING(rule->unixname))
274 278 return (IDMAP_ERR_NORESULT);
275 279
276 280
277 281 retcode = idmap_strdupnull(windomain, rule->windomain);
278 282 if (retcode != IDMAP_SUCCESS)
279 283 goto errout;
280 284
281 285 retcode = idmap_strdupnull(winname, rule->winname);
282 286 if (retcode != IDMAP_SUCCESS)
283 287 goto errout;
284 288
285 289 retcode = idmap_strdupnull(unixname, rule->unixname);
286 290 if (retcode != IDMAP_SUCCESS)
287 291 goto errout;
288 292
289 293
290 294 if (is_user)
291 295 *is_user = rule->is_user;
292 296 if (is_wuser)
293 297 *is_wuser = rule->is_wuser;
294 298 if (is_nt4)
295 299 *is_nt4 = rule->is_nt4;
296 300 if (direction)
297 301 *direction = rule->direction;
298 302
299 303
300 304 return (IDMAP_SUCCESS);
301 305
302 306 errout:
303 307 if (windomain && *windomain)
304 308 free(*windomain);
305 309 if (winname && *winname)
306 310 free(*winname);
307 311 if (unixname && *unixname)
308 312 free(*unixname);
309 313
310 314 idmap_namerule_parts_clear(windomain, winname,
311 315 unixname, is_user, is_wuser, is_nt4, direction);
312 316
313 317 return (retcode);
314 318
315 319 }
316 320
317 321 /*
318 322 * Retrieve the index of the failed batch element. error_index == -1
319 323 * indicates failure at the beginning, -2 at the end.
320 324 *
321 325 * If idmap_udt_commit didn't return error, the returned value is undefined.
322 326 *
323 327 * Return value:
324 328 * IDMAP_SUCCESS
325 329 */
326 330
327 331 idmap_stat
328 332 idmap_udt_get_error_index(idmap_udt_handle_t *udthandle,
329 333 int64_t *error_index)
330 334 {
331 335 if (error_index)
332 336 *error_index = udthandle->error_index;
333 337
334 338 return (IDMAP_SUCCESS);
335 339 }
336 340
337 341
338 342 /*
339 343 * Retrieve the rule which caused the batch to fail. If
340 344 * idmap_udt_commit didn't return error or if error_index is < 0, the
341 345 * retrieved rule is undefined.
342 346 *
343 347 * Return value:
344 348 * IDMAP_ERR_NORESULT if there is no error rule.
345 349 * IDMAP_SUCCESS if the rule was obtained OK.
346 350 * other error code (IDMAP_ERR_NOMEMORY etc)
347 351 */
348 352
349 353 idmap_stat
350 354 idmap_udt_get_error_rule(idmap_udt_handle_t *udthandle,
351 355 char **windomain, char **winname,
352 356 char **unixname, boolean_t *is_user, boolean_t *is_wuser,
353 357 boolean_t *is_nt4, int *direction)
354 358 {
355 359 idmap_namerule_parts_clear(windomain, winname,
356 360 unixname, is_user, is_wuser, is_nt4, direction);
357 361
358 362 if (udthandle->commit_stat == IDMAP_SUCCESS ||
359 363 udthandle->error_index < 0)
360 364 return (IDMAP_ERR_NORESULT);
361 365
362 366 return (idmap_namerule2parts(
363 367 &udthandle->error_rule,
364 368 windomain,
365 369 winname,
366 370 unixname,
367 371 is_user,
368 372 is_wuser,
369 373 is_nt4,
370 374 direction));
371 375 }
372 376
373 377 /*
374 378 * Retrieve the rule with which there was a conflict. TODO: retrieve
375 379 * the value.
376 380 *
377 381 * Return value:
378 382 * IDMAP_ERR_NORESULT if there is no error rule.
379 383 * IDMAP_SUCCESS if the rule was obtained OK.
380 384 * other error code (IDMAP_ERR_NOMEMORY etc)
381 385 */
382 386
383 387 idmap_stat
384 388 idmap_udt_get_conflict_rule(idmap_udt_handle_t *udthandle,
385 389 char **windomain, char **winname,
386 390 char **unixname, boolean_t *is_user, boolean_t *is_wuser,
387 391 boolean_t *is_nt4, int *direction)
388 392 {
389 393 idmap_namerule_parts_clear(windomain, winname,
390 394 unixname, is_user, is_wuser, is_nt4, direction);
391 395
392 396 if (udthandle->commit_stat != IDMAP_ERR_W2U_NAMERULE_CONFLICT &&
393 397 udthandle->commit_stat != IDMAP_ERR_U2W_NAMERULE_CONFLICT) {
394 398 return (IDMAP_ERR_NORESULT);
395 399 }
396 400
397 401 return (idmap_namerule2parts(
398 402 &udthandle->conflict_rule,
399 403 windomain,
400 404 winname,
401 405 unixname,
402 406 is_user,
403 407 is_wuser,
404 408 is_nt4,
405 409 direction));
406 410 }
407 411
408 412
409 413 /*
410 414 * Destroy the update handle
411 415 */
412 416 void
413 417 idmap_udt_destroy(idmap_udt_handle_t *udthandle)
414 418 {
415 419 if (udthandle == NULL)
416 420 return;
417 421 xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
418 422 xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->error_rule);
419 423 xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->conflict_rule);
420 424 free(udthandle);
421 425 }
422 426
423 427
424 428 idmap_stat
425 429 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain,
426 430 boolean_t is_user, boolean_t is_wuser, const char *winname,
427 431 const char *unixname, boolean_t is_nt4, int direction)
428 432 {
429 433 idmap_retcode retcode;
430 434 idmap_namerule *rule = NULL;
431 435
432 436 retcode = _udt_extend_batch(udthandle);
433 437 if (retcode != IDMAP_SUCCESS)
434 438 goto errout;
435 439
436 440 rule = &udthandle->batch.
437 441 idmap_update_batch_val[udthandle->next].
438 442 idmap_update_op_u.rule;
439 443 rule->is_user = is_user;
440 444 rule->is_wuser = is_wuser;
441 445 rule->direction = direction;
442 446 rule->is_nt4 = is_nt4;
443 447
444 448 retcode = idmap_strdupnull(&rule->windomain, windomain);
445 449 if (retcode != IDMAP_SUCCESS)
446 450 goto errout;
447 451
448 452 retcode = idmap_strdupnull(&rule->winname, winname);
449 453 if (retcode != IDMAP_SUCCESS)
450 454 goto errout;
451 455
452 456 retcode = idmap_strdupnull(&rule->unixname, unixname);
453 457 if (retcode != IDMAP_SUCCESS)
454 458 goto errout;
455 459
456 460 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
457 461 OP_ADD_NAMERULE;
458 462 udthandle->next++;
459 463 return (IDMAP_SUCCESS);
460 464
461 465 errout:
462 466 /* The batch should still be usable */
463 467 if (rule)
464 468 xdr_free(xdr_idmap_namerule, (caddr_t)rule);
465 469 errno = idmap_stat2errno(retcode);
466 470 return (retcode);
467 471 }
468 472
469 473
470 474 /* ARGSUSED */
471 475 idmap_stat
472 476 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user,
473 477 boolean_t is_wuser, const char *windomain, const char *winname,
474 478 const char *unixname, int direction)
475 479 {
476 480 idmap_retcode retcode;
477 481 idmap_namerule *rule = NULL;
478 482
479 483 retcode = _udt_extend_batch(udthandle);
480 484 if (retcode != IDMAP_SUCCESS)
481 485 goto errout;
482 486
483 487 rule = &udthandle->batch.
484 488 idmap_update_batch_val[udthandle->next].
485 489 idmap_update_op_u.rule;
486 490 rule->is_user = is_user;
487 491 rule->is_wuser = is_wuser;
488 492 rule->direction = direction;
489 493
490 494 retcode = idmap_strdupnull(&rule->windomain, windomain);
491 495 if (retcode != IDMAP_SUCCESS)
492 496 goto errout;
493 497
494 498 retcode = idmap_strdupnull(&rule->winname, winname);
495 499 if (retcode != IDMAP_SUCCESS)
496 500 goto errout;
497 501
498 502 retcode = idmap_strdupnull(&rule->unixname, unixname);
499 503 if (retcode != IDMAP_SUCCESS)
500 504 goto errout;
501 505
502 506 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
503 507 OP_RM_NAMERULE;
504 508 udthandle->next++;
505 509 return (IDMAP_SUCCESS);
506 510
507 511 errout:
508 512 if (rule)
509 513 xdr_free(xdr_idmap_namerule, (caddr_t)rule);
510 514 errno = idmap_stat2errno(retcode);
511 515 return (retcode);
512 516 }
513 517
514 518
515 519 /* ARGSUSED */
516 520 idmap_stat
517 521 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle)
518 522 {
519 523 idmap_retcode retcode;
520 524
521 525 retcode = _udt_extend_batch(udthandle);
522 526 if (retcode != IDMAP_SUCCESS)
523 527 goto errout;
524 528
525 529 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
526 530 OP_FLUSH_NAMERULES;
527 531 udthandle->next++;
528 532 return (IDMAP_SUCCESS);
529 533
530 534 errout:
531 535 errno = idmap_stat2errno(retcode);
532 536 return (retcode);
533 537 }
534 538
535 539
536 540 /*
537 541 * Set the number of entries requested per batch by the iterator
538 542 *
539 543 * Input:
540 544 * iter - iterator
541 545 * limit - number of entries requested per batch
542 546 */
543 547 idmap_stat
544 548 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit)
545 549 {
546 550 if (iter == NULL) {
547 551 errno = EINVAL;
548 552 return (IDMAP_ERR_ARG);
549 553 }
550 554 iter->limit = limit;
551 555 return (IDMAP_SUCCESS);
552 556 }
553 557
554 558
555 559 /*
556 560 * Create iterator to get name-based mapping rules
557 561 *
558 562 * Input:
559 563 * windomain - Windows domain
560 564 * is_user - user or group rules
561 565 * winname - Windows user or group name
562 566 * unixname - Unix user or group name
563 567 *
564 568 * Output:
565 569 * iter - iterator
566 570 */
567 571 idmap_stat
568 572 idmap_iter_namerules(const char *windomain, boolean_t is_user,
569 573 boolean_t is_wuser, const char *winname, const char *unixname,
570 574 idmap_iter_t **iter)
571 575 {
572 576
573 577 idmap_iter_t *tmpiter;
574 578 idmap_list_namerules_1_argument *arg = NULL;
575 579 idmap_namerule *rule;
576 580 idmap_retcode retcode;
577 581
578 582 __ITER_CREATE(tmpiter, arg, IDMAP_LIST_NAMERULES);
579 583
580 584 rule = &arg->rule;
581 585 rule->is_user = is_user;
582 586 rule->is_wuser = is_wuser;
583 587 rule->direction = IDMAP_DIRECTION_UNDEF;
584 588
585 589 retcode = idmap_strdupnull(&rule->windomain, windomain);
586 590 if (retcode != IDMAP_SUCCESS)
587 591 goto errout;
588 592
589 593 retcode = idmap_strdupnull(&rule->winname, winname);
590 594 if (retcode != IDMAP_SUCCESS)
591 595 goto errout;
592 596
593 597 retcode = idmap_strdupnull(&rule->unixname, unixname);
594 598 if (retcode != IDMAP_SUCCESS)
595 599 goto errout;
596 600
597 601 *iter = tmpiter;
598 602 return (IDMAP_SUCCESS);
599 603
600 604 errout:
601 605 if (arg) {
602 606 xdr_free(xdr_idmap_list_namerules_1_argument, (char *)arg);
603 607 free(arg);
604 608 }
605 609 if (tmpiter)
606 610 free(tmpiter);
607 611
608 612 return (retcode);
609 613 }
610 614
611 615
612 616 /*
613 617 * Iterate through the name-based mapping rules
614 618 *
615 619 * Input:
616 620 * iter - iterator
617 621 *
618 622 * Output:
619 623 * windomain - Windows domain
620 624 * winname - Windows user or group name
621 625 * unixname - Unix user or group name
622 626 * is_nt4 - NT4 or AD
623 627 * direction - bi(0), win2unix(1), unix2win(2)
624 628 *
625 629 * Return value:
626 630 * 0 - done
627 631 * 1 - more results available
628 632 * < 0 - error
629 633 */
630 634 idmap_stat
631 635 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain,
632 636 char **winname, char **unixname, boolean_t *is_user,
633 637 boolean_t *is_wuser, boolean_t *is_nt4, int *direction)
634 638 {
635 639 idmap_namerules_res *namerules;
636 640 idmap_list_namerules_1_argument *arg;
637 641 idmap_retcode retcode;
638 642
639 643 idmap_namerule_parts_clear(windomain, winname,
640 644 unixname, is_user, is_wuser, is_nt4, direction);
641 645
642 646
643 647 __ITER_CHECK(iter, IDMAP_LIST_NAMERULES);
644 648
645 649 namerules = (idmap_namerules_res *)iter->retlist;
646 650 if (iter->retcode == IDMAP_NEXT && (namerules == NULL ||
647 651 iter->next >= namerules->rules.rules_len)) {
648 652
649 653 if ((arg = iter->arg) == NULL) {
650 654 errno = EINVAL;
651 655 return (IDMAP_ERR_ARG);
652 656 }
653 657 arg->limit = iter->limit;
654 658
655 659 retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES,
656 660 iter, arg,
657 661 (uchar_t **)&namerules, sizeof (*namerules),
658 662 (xdrproc_t)xdr_idmap_list_namerules_1_argument,
659 663 (xdrproc_t)xdr_idmap_namerules_res);
660 664 if (retcode != IDMAP_SUCCESS)
661 665 return (retcode);
662 666
663 667 if (IDMAP_ERROR(namerules->retcode)) {
664 668 retcode = namerules->retcode;
665 669 xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules);
666 670 free(namerules);
667 671 iter->retlist = NULL;
668 672 return (retcode);
669 673 }
670 674 iter->retcode = namerules->retcode;
671 675 arg->lastrowid = namerules->lastrowid;
672 676 }
673 677
674 678 if (namerules == NULL || namerules->rules.rules_len == 0)
675 679 return (IDMAP_SUCCESS);
676 680
677 681 if (iter->next >= namerules->rules.rules_len) {
678 682 return (IDMAP_ERR_ARG);
679 683 }
680 684
681 685 retcode = idmap_strdupnull(windomain,
682 686 namerules->rules.rules_val[iter->next].windomain);
683 687 if (retcode != IDMAP_SUCCESS)
684 688 goto errout;
685 689
686 690 retcode = idmap_strdupnull(winname,
687 691 namerules->rules.rules_val[iter->next].winname);
688 692 if (retcode != IDMAP_SUCCESS)
689 693 goto errout;
690 694
691 695 retcode = idmap_strdupnull(unixname,
692 696 namerules->rules.rules_val[iter->next].unixname);
693 697 if (retcode != IDMAP_SUCCESS)
694 698 goto errout;
695 699
696 700 if (is_nt4)
697 701 *is_nt4 = namerules->rules.rules_val[iter->next].is_nt4;
698 702 if (is_user)
699 703 *is_user = namerules->rules.rules_val[iter->next].is_user;
700 704 if (is_wuser)
701 705 *is_wuser = namerules->rules.rules_val[iter->next].is_wuser;
702 706 if (direction)
703 707 *direction = namerules->rules.rules_val[iter->next].direction;
704 708 iter->next++;
705 709
706 710 if (iter->next == namerules->rules.rules_len)
707 711 return (iter->retcode);
708 712 else
709 713 return (IDMAP_NEXT);
710 714
711 715 errout:
712 716 if (windomain && *windomain)
713 717 free(*windomain);
714 718 if (winname && *winname)
715 719 free(*winname);
716 720 if (unixname && *unixname)
717 721 free(*unixname);
718 722 return (retcode);
719 723 }
720 724
721 725
722 726 /*
723 727 * Create iterator to get SID to UID/GID mappings
724 728 *
725 729 * Output:
726 730 * iter - iterator
727 731 */
728 732 idmap_stat
729 733 idmap_iter_mappings(idmap_iter_t **iter, int flag)
730 734 {
731 735 idmap_iter_t *tmpiter;
732 736 idmap_list_mappings_1_argument *arg = NULL;
733 737
734 738 __ITER_CREATE(tmpiter, arg, IDMAP_LIST_MAPPINGS);
735 739
736 740 arg->flag = flag;
737 741 *iter = tmpiter;
738 742 return (IDMAP_SUCCESS);
739 743 }
740 744
741 745
742 746 /*
743 747 * Iterate through the SID to UID/GID mappings
744 748 *
745 749 * Input:
746 750 * iter - iterator
747 751 *
748 752 * Output:
749 753 * sid - SID in canonical form
750 754 * pid - UID or GID
751 755 *
752 756 * Return value:
753 757 * 0 - done
754 758 * 1 - more results available
755 759 * < 0 - error
756 760 */
757 761 idmap_stat
758 762 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix,
759 763 idmap_rid_t *rid, uid_t *pid, char **winname,
760 764 char **windomain, char **unixname, boolean_t *is_user,
761 765 boolean_t *is_wuser, int *direction, idmap_info *info)
762 766 {
763 767 idmap_mappings_res *mappings;
764 768 idmap_list_mappings_1_argument *arg;
765 769 idmap_retcode retcode;
766 770 char *str;
767 771
768 772 if (sidprefix)
769 773 *sidprefix = NULL;
770 774 if (rid)
771 775 *rid = UINT32_MAX;
772 776 if (winname)
773 777 *winname = NULL;
774 778 if (windomain)
775 779 *windomain = NULL;
776 780 if (unixname)
777 781 *unixname = NULL;
778 782 if (pid)
779 783 *pid = UINT32_MAX;
780 784 if (is_user)
781 785 *is_user = -1;
782 786 if (is_wuser)
783 787 *is_wuser = -1;
784 788 if (direction)
785 789 *direction = IDMAP_DIRECTION_UNDEF;
786 790
787 791 __ITER_CHECK(iter, IDMAP_LIST_MAPPINGS);
788 792
789 793 mappings = (idmap_mappings_res *)iter->retlist;
790 794 if (iter->retcode == IDMAP_NEXT && (mappings == NULL ||
791 795 iter->next >= mappings->mappings.mappings_len)) {
792 796
793 797 if ((arg = iter->arg) == NULL) {
794 798 errno = EINVAL;
795 799 return (IDMAP_ERR_ARG);
796 800 }
797 801 arg->limit = iter->limit;
798 802
799 803 retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS,
800 804 iter, arg,
801 805 (uchar_t **)&mappings, sizeof (*mappings),
802 806 (xdrproc_t)xdr_idmap_list_mappings_1_argument,
803 807 (xdrproc_t)xdr_idmap_mappings_res);
804 808 if (retcode != IDMAP_SUCCESS)
805 809 return (retcode);
806 810
807 811 if (IDMAP_ERROR(mappings->retcode)) {
808 812 retcode = mappings->retcode;
809 813 xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings);
810 814 free(mappings);
811 815 iter->retlist = NULL;
812 816 return (retcode);
813 817 }
814 818 iter->retcode = mappings->retcode;
815 819 arg->lastrowid = mappings->lastrowid;
816 820 }
817 821
818 822 if (mappings == NULL || mappings->mappings.mappings_len == 0)
819 823 return (IDMAP_SUCCESS);
820 824
821 825 if (iter->next >= mappings->mappings.mappings_len) {
822 826 return (IDMAP_ERR_ARG);
823 827 }
824 828
825 829 if (sidprefix) {
826 830 str = mappings->mappings.mappings_val[iter->next].id1.
827 831 idmap_id_u.sid.prefix;
828 832 if (str && *str != '\0') {
829 833 *sidprefix = strdup(str);
830 834 if (*sidprefix == NULL) {
831 835 retcode = IDMAP_ERR_MEMORY;
832 836 goto errout;
833 837 }
834 838 }
835 839 }
836 840 if (rid)
837 841 *rid = mappings->mappings.mappings_val[iter->next].id1.
838 842 idmap_id_u.sid.rid;
839 843
840 844 retcode = idmap_strdupnull(windomain,
841 845 mappings->mappings.mappings_val[iter->next].id1domain);
842 846 if (retcode != IDMAP_SUCCESS)
843 847 goto errout;
844 848
845 849 retcode = idmap_strdupnull(winname,
846 850 mappings->mappings.mappings_val[iter->next].id1name);
847 851 if (retcode != IDMAP_SUCCESS)
848 852 goto errout;
849 853
850 854 retcode = idmap_strdupnull(unixname,
851 855 mappings->mappings.mappings_val[iter->next].id2name);
852 856 if (retcode != IDMAP_SUCCESS)
853 857 goto errout;
854 858
855 859
856 860 if (pid)
857 861 *pid = mappings->mappings.mappings_val[iter->next].id2.
858 862 idmap_id_u.uid;
859 863 if (direction)
860 864 *direction = mappings->mappings.mappings_val[iter->next].
861 865 direction;
862 866 if (is_user)
863 867 *is_user = (mappings->mappings.mappings_val[iter->next].id2
864 868 .idtype == IDMAP_UID)?1:0;
865 869 if (is_wuser)
866 870 *is_wuser = (mappings->mappings.mappings_val[iter->next].id1
867 871 .idtype == IDMAP_USID)?1:0;
868 872
869 873 if (info) {
870 874 idmap_info_mov(info,
871 875 &mappings->mappings.mappings_val[iter->next].info);
872 876 }
873 877 iter->next++;
874 878
875 879 if (iter->next == mappings->mappings.mappings_len)
876 880 return (iter->retcode);
877 881 else
878 882 return (IDMAP_NEXT);
879 883
880 884 errout:
881 885 if (sidprefix && *sidprefix)
882 886 free(*sidprefix);
883 887 if (winname && *winname)
884 888 free(*winname);
885 889 if (windomain && *windomain)
886 890 free(*windomain);
887 891 if (unixname && *unixname)
888 892 free(*unixname);
889 893 return (retcode);
890 894 }
891 895
892 896
893 897 /*
894 898 * Destroy the iterator
895 899 */
896 900 void
897 901 idmap_iter_destroy(idmap_iter_t *iter)
898 902 {
899 903 xdrproc_t _xdr_argument, _xdr_result;
900 904
901 905 if (iter == NULL)
902 906 return;
903 907
904 908 switch (iter->type) {
905 909 case IDMAP_LIST_NAMERULES:
906 910 _xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument;
907 911 _xdr_result = (xdrproc_t)xdr_idmap_namerules_res;
908 912 break;
909 913 case IDMAP_LIST_MAPPINGS:
910 914 _xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument;
911 915 _xdr_result = (xdrproc_t)xdr_idmap_mappings_res;
912 916 break;
913 917 default:
914 918 free(iter);
915 919 return;
916 920 };
917 921
918 922 if (iter->arg) {
919 923 xdr_free(_xdr_argument, (caddr_t)iter->arg);
920 924 free(iter->arg);
921 925 }
922 926 if (iter->retlist) {
923 927 xdr_free(_xdr_result, (caddr_t)iter->retlist);
924 928 free(iter->retlist);
925 929 }
926 930 free(iter);
927 931 }
928 932
929 933
930 934 /*
931 935 * Create handle to get SID to UID/GID mapping entries
932 936 *
933 937 * Input:
934 938 * gh - "get mapping" handle
935 939 */
936 940 idmap_stat
937 941 idmap_get_create(idmap_get_handle_t **gh)
938 942 {
939 943 idmap_get_handle_t *tmp;
940 944
941 945 /* allocate the handle */
942 946 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
943 947 errno = ENOMEM;
944 948 return (IDMAP_ERR_MEMORY);
945 949 }
946 950
947 951 *gh = tmp;
948 952 return (IDMAP_SUCCESS);
949 953 }
950 954
951 955
952 956 /*
953 957 * Given SID, get UID
954 958 *
955 959 * Input:
956 960 * sidprefix - SID prefix
957 961 * rid - RID
958 962 * flag - flag
959 963 *
960 964 * Output:
961 965 * stat - status of the get request
962 966 * uid - POSIX UID if stat = 0
963 967 *
964 968 * Note: The output parameters will be set by idmap_get_mappings()
965 969 */
966 970 idmap_stat
967 971 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
968 972 int flag, uid_t *uid, idmap_stat *stat)
969 973 {
970 974 return (idmap_getext_uidbysid(gh, sidprefix, rid, flag, uid,
971 975 NULL, stat));
972 976 }
973 977
974 978 /*
975 979 * Given SID, get UID
976 980 *
977 981 * Input:
978 982 * sidprefix - SID prefix
979 983 * rid - RID
980 984 * flag - flag
981 985 *
982 986 * Output:
983 987 * stat - status of the get request
984 988 * uid - POSIX UID if stat = 0
985 989 * how - mapping type if stat = 0
986 990 *
987 991 * Note: The output parameters will be set by idmap_get_mappings()
988 992 */
989 993
990 994 idmap_stat
991 995 idmap_getext_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
992 996 int flag, uid_t *uid, idmap_info *info, idmap_stat *stat)
993 997 {
994 998 idmap_retcode retcode;
995 999 idmap_mapping *mapping = NULL;
996 1000
997 1001 /* sanity checks */
998 1002 if (gh == NULL)
999 1003 return (IDMAP_ERR_ARG);
1000 1004 if (uid == NULL || sidprefix == NULL)
1001 1005 return (IDMAP_ERR_ARG);
1002 1006
1003 1007 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1004 1008 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1005 1009 retcode = idmap_cache_lookup_uidbysid(sidprefix, rid, uid);
1006 1010 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1007 1011 *stat = retcode;
1008 1012 return (retcode);
1009 1013 }
1010 1014 }
1011 1015
1012 1016 /* Extend the request array and the return list */
1013 1017 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1014 1018 goto errout;
1015 1019
1016 1020 /* Setup the request */
1017 1021 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1018 1022 mapping->flag = flag;
1019 1023 mapping->id1.idtype = IDMAP_SID;
1020 1024 mapping->id1.idmap_id_u.sid.rid = rid;
1021 1025 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1022 1026 retcode = IDMAP_ERR_MEMORY;
1023 1027 goto errout;
1024 1028 }
1025 1029 mapping->id2.idtype = IDMAP_UID;
1026 1030
1027 1031 /* Setup pointers for the result */
1028 1032 gh->retlist[gh->next].idtype = IDMAP_UID;
1029 1033 gh->retlist[gh->next].uid = uid;
1030 1034 gh->retlist[gh->next].stat = stat;
1031 1035 gh->retlist[gh->next].info = info;
1032 1036 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1033 1037
1034 1038 gh->next++;
1035 1039 return (IDMAP_SUCCESS);
1036 1040
1037 1041 errout:
1038 1042 /* Batch created so far should still be usable */
1039 1043 if (mapping)
1040 1044 (void) memset(mapping, 0, sizeof (*mapping));
1041 1045 errno = idmap_stat2errno(retcode);
1042 1046 return (retcode);
1043 1047 }
1044 1048
1045 1049
1046 1050 /*
1047 1051 * Given SID, get GID
1048 1052 *
1049 1053 * Input:
1050 1054 * sidprefix - SID prefix
1051 1055 * rid - rid
1052 1056 * flag - flag
1053 1057 *
1054 1058 * Output:
1055 1059 * stat - status of the get request
1056 1060 * gid - POSIX GID if stat = 0
1057 1061 *
1058 1062 * Note: The output parameters will be set by idmap_get_mappings()
1059 1063 */
1060 1064 idmap_stat
1061 1065 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1062 1066 int flag, gid_t *gid, idmap_stat *stat)
1063 1067 {
1064 1068 return (idmap_getext_gidbysid(gh, sidprefix, rid, flag, gid,
1065 1069 NULL, stat));
1066 1070 }
1067 1071
1068 1072
1069 1073 /*
1070 1074 * Given SID, get GID
1071 1075 *
1072 1076 * Input:
1073 1077 * sidprefix - SID prefix
1074 1078 * rid - rid
1075 1079 * flag - flag
1076 1080 *
1077 1081 * Output:
1078 1082 * stat - status of the get request
1079 1083 * gid - POSIX GID if stat = 0
1080 1084 * how - mapping type if stat = 0
1081 1085 *
1082 1086 * Note: The output parameters will be set by idmap_get_mappings()
1083 1087 */
1084 1088 idmap_stat
1085 1089 idmap_getext_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1086 1090 int flag, gid_t *gid, idmap_info *info, idmap_stat *stat)
1087 1091 {
1088 1092
1089 1093 idmap_retcode retcode;
1090 1094 idmap_mapping *mapping = NULL;
1091 1095
1092 1096 /* sanity checks */
1093 1097 if (gh == NULL)
1094 1098 return (IDMAP_ERR_ARG);
1095 1099 if (gid == NULL || sidprefix == NULL)
1096 1100 return (IDMAP_ERR_ARG);
1097 1101
1098 1102 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1099 1103 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1100 1104 retcode = idmap_cache_lookup_gidbysid(sidprefix, rid, gid);
1101 1105 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1102 1106 *stat = retcode;
1103 1107 return (retcode);
1104 1108 }
1105 1109 }
1106 1110
1107 1111 /* Extend the request array and the return list */
1108 1112 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1109 1113 goto errout;
1110 1114
1111 1115 /* Setup the request */
1112 1116 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1113 1117 mapping->flag = flag;
1114 1118 mapping->id1.idtype = IDMAP_SID;
1115 1119 mapping->id1.idmap_id_u.sid.rid = rid;
1116 1120 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1117 1121 retcode = IDMAP_ERR_MEMORY;
1118 1122 goto errout;
1119 1123 }
1120 1124 mapping->id2.idtype = IDMAP_GID;
1121 1125
1122 1126 /* Setup pointers for the result */
1123 1127 gh->retlist[gh->next].idtype = IDMAP_GID;
1124 1128 gh->retlist[gh->next].gid = gid;
1125 1129 gh->retlist[gh->next].stat = stat;
1126 1130 gh->retlist[gh->next].info = info;
1127 1131 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1128 1132
1129 1133 gh->next++;
1130 1134 return (IDMAP_SUCCESS);
1131 1135
1132 1136 errout:
1133 1137 if (mapping)
1134 1138 (void) memset(mapping, 0, sizeof (*mapping));
1135 1139 errno = idmap_stat2errno(retcode);
1136 1140 return (retcode);
1137 1141 }
1138 1142
1139 1143
1140 1144
1141 1145 /*
1142 1146 * Given SID, get POSIX ID i.e. UID/GID
1143 1147 *
1144 1148 * Input:
1145 1149 * sidprefix - SID prefix
1146 1150 * rid - rid
1147 1151 * flag - flag
1148 1152 *
1149 1153 * Output:
1150 1154 * stat - status of the get request
1151 1155 * is_user - user or group
1152 1156 * pid - POSIX UID if stat = 0 and is_user = 1
1153 1157 * POSIX GID if stat = 0 and is_user = 0
1154 1158 *
1155 1159 * Note: The output parameters will be set by idmap_get_mappings()
1156 1160 */
1157 1161 idmap_stat
1158 1162 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1159 1163 int flag, uid_t *pid, int *is_user, idmap_stat *stat)
1160 1164 {
1161 1165 return (idmap_getext_pidbysid(gh, sidprefix, rid, flag, pid, is_user,
1162 1166 NULL, stat));
1163 1167 }
1164 1168
1165 1169
1166 1170
1167 1171 /*
1168 1172 * Given SID, get POSIX ID i.e. UID/GID
1169 1173 *
1170 1174 * Input:
1171 1175 * sidprefix - SID prefix
1172 1176 * rid - rid
1173 1177 * flag - flag
1174 1178 *
1175 1179 * Output:
1176 1180 * stat - status of the get request
1177 1181 * is_user - user or group
1178 1182 * pid - POSIX UID if stat = 0 and is_user = 1
1179 1183 * POSIX GID if stat = 0 and is_user = 0
1180 1184 * how - mapping type if stat = 0
1181 1185 *
1182 1186 * Note: The output parameters will be set by idmap_get_mappings()
1183 1187 */
1184 1188 idmap_stat
1185 1189 idmap_getext_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1186 1190 int flag, uid_t *pid, int *is_user, idmap_info *info, idmap_stat *stat)
1187 1191 {
1188 1192 idmap_retcode retcode;
1189 1193 idmap_mapping *mapping = NULL;
1190 1194
1191 1195 /* sanity checks */
1192 1196 if (gh == NULL)
1193 1197 return (IDMAP_ERR_ARG);
1194 1198 if (pid == NULL || sidprefix == NULL || is_user == NULL)
1195 1199 return (IDMAP_ERR_ARG);
1196 1200
1197 1201 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1198 1202 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1199 1203 retcode = idmap_cache_lookup_pidbysid(sidprefix, rid, pid,
1200 1204 is_user);
1201 1205 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1202 1206 *stat = retcode;
1203 1207 return (retcode);
1204 1208 }
1205 1209 }
1206 1210
1207 1211 /* Extend the request array and the return list */
1208 1212 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1209 1213 goto errout;
1210 1214
1211 1215 /* Setup the request */
1212 1216 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1213 1217 mapping->flag = flag;
1214 1218 mapping->id1.idtype = IDMAP_SID;
1215 1219 mapping->id1.idmap_id_u.sid.rid = rid;
1216 1220 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1217 1221 retcode = IDMAP_ERR_MEMORY;
1218 1222 goto errout;
1219 1223 }
1220 1224 mapping->id2.idtype = IDMAP_POSIXID;
1221 1225
1222 1226 /* Setup pointers for the result */
1223 1227 gh->retlist[gh->next].idtype = IDMAP_POSIXID;
1224 1228 gh->retlist[gh->next].uid = pid;
1225 1229 gh->retlist[gh->next].gid = pid;
1226 1230 gh->retlist[gh->next].is_user = is_user;
1227 1231 gh->retlist[gh->next].stat = stat;
1228 1232 gh->retlist[gh->next].info = info;
1229 1233 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1230 1234
1231 1235 gh->next++;
1232 1236 return (IDMAP_SUCCESS);
1233 1237
1234 1238 errout:
1235 1239 if (mapping)
1236 1240 (void) memset(mapping, 0, sizeof (*mapping));
1237 1241 errno = idmap_stat2errno(retcode);
1238 1242 return (retcode);
1239 1243 }
1240 1244
1241 1245
1242 1246 /*
1243 1247 * Given UID, get SID
1244 1248 *
1245 1249 * Input:
1246 1250 * uid - POSIX UID
1247 1251 * flag - flag
1248 1252 *
1249 1253 * Output:
1250 1254 * stat - status of the get request
1251 1255 * sid - SID prefix (if stat == 0)
1252 1256 * rid - rid
1253 1257 *
1254 1258 * Note: The output parameters will be set by idmap_get_mappings()
1255 1259 */
1256 1260 idmap_stat
1257 1261 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
1258 1262 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
1259 1263 {
1260 1264 return (idmap_getext_sidbyuid(gh, uid, flag, sidprefix, rid,
1261 1265 NULL, stat));
1262 1266 }
1263 1267
1264 1268
1265 1269 /*
1266 1270 * Given UID, get SID
1267 1271 *
1268 1272 * Input:
1269 1273 * uid - POSIX UID
1270 1274 * flag - flag
1271 1275 *
1272 1276 * Output:
1273 1277 * stat - status of the get request
1274 1278 * sid - SID prefix (if stat == 0)
1275 1279 * rid - rid
1276 1280 * how - mapping type if stat = 0
1277 1281 *
1278 1282 * Note: The output parameters will be set by idmap_get_mappings()
1279 1283 */
1280 1284 idmap_stat
1281 1285 idmap_getext_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
1282 1286 char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
1283 1287 {
1284 1288
1285 1289 idmap_retcode retcode;
1286 1290 idmap_mapping *mapping = NULL;
1287 1291
1288 1292 /* sanity checks */
1289 1293 if (gh == NULL)
1290 1294 return (IDMAP_ERR_ARG);
1291 1295 if (sidprefix == NULL)
1292 1296 return (IDMAP_ERR_ARG);
1293 1297
1294 1298 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1295 1299 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1296 1300 retcode = idmap_cache_lookup_sidbyuid(sidprefix, rid, uid);
1297 1301 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1298 1302 *stat = retcode;
1299 1303 return (retcode);
1300 1304 }
1301 1305 }
1302 1306
1303 1307 /* Extend the request array and the return list */
1304 1308 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1305 1309 goto errout;
1306 1310
1307 1311 /* Setup the request */
1308 1312 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1309 1313 mapping->flag = flag;
1310 1314 mapping->id1.idtype = IDMAP_UID;
1311 1315 mapping->id1.idmap_id_u.uid = uid;
1312 1316 mapping->id2.idtype = IDMAP_SID;
1313 1317
1314 1318 /* Setup pointers for the result */
1315 1319 gh->retlist[gh->next].idtype = IDMAP_SID;
1316 1320 gh->retlist[gh->next].sidprefix = sidprefix;
1317 1321 gh->retlist[gh->next].rid = rid;
1318 1322 gh->retlist[gh->next].stat = stat;
1319 1323 gh->retlist[gh->next].info = info;
1320 1324 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1321 1325
1322 1326 gh->next++;
1323 1327 return (IDMAP_SUCCESS);
1324 1328
1325 1329 errout:
1326 1330 if (mapping)
1327 1331 (void) memset(mapping, 0, sizeof (*mapping));
1328 1332 errno = idmap_stat2errno(retcode);
1329 1333 return (retcode);
1330 1334 }
1331 1335
1332 1336
1333 1337 /*
1334 1338 * Given GID, get SID
1335 1339 *
1336 1340 * Input:
1337 1341 * gid - POSIX GID
1338 1342 * flag - flag
1339 1343 *
1340 1344 * Output:
1341 1345 * stat - status of the get request
1342 1346 * sidprefix - SID prefix (if stat == 0)
1343 1347 * rid - rid
1344 1348 *
1345 1349 * Note: The output parameters will be set by idmap_get_mappings()
1346 1350 */
1347 1351 idmap_stat
1348 1352 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
1349 1353 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
1350 1354 {
1351 1355 return (idmap_getext_sidbygid(gh, gid, flag, sidprefix, rid,
1352 1356 NULL, stat));
1353 1357 }
1354 1358
1355 1359
1356 1360 /*
1357 1361 * Given GID, get SID
1358 1362 *
1359 1363 * Input:
1360 1364 * gid - POSIX GID
1361 1365 * flag - flag
1362 1366 *
1363 1367 * Output:
1364 1368 * stat - status of the get request
1365 1369 * sidprefix - SID prefix (if stat == 0)
1366 1370 * rid - rid
1367 1371 * how - mapping type if stat = 0
1368 1372 *
1369 1373 * Note: The output parameters will be set by idmap_get_mappings()
1370 1374 */
1371 1375 idmap_stat
1372 1376 idmap_getext_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
1373 1377 char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
1374 1378 {
1375 1379
1376 1380 idmap_retcode retcode;
1377 1381 idmap_mapping *mapping = NULL;
1378 1382
1379 1383 /* sanity checks */
1380 1384 if (gh == NULL)
1381 1385 return (IDMAP_ERR_ARG);
1382 1386 if (sidprefix == NULL)
1383 1387 return (IDMAP_ERR_ARG);
1384 1388
1385 1389 if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
1386 1390 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
1387 1391 retcode = idmap_cache_lookup_sidbygid(sidprefix, rid, gid);
1388 1392 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
1389 1393 *stat = retcode;
1390 1394 return (retcode);
1391 1395 }
1392 1396 }
1393 1397
1394 1398 /* Extend the request array and the return list */
1395 1399 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1396 1400 goto errout;
1397 1401
1398 1402 /* Setup the request */
1399 1403 mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1400 1404 mapping->flag = flag;
1401 1405 mapping->id1.idtype = IDMAP_GID;
1402 1406 mapping->id1.idmap_id_u.gid = gid;
1403 1407 mapping->id2.idtype = IDMAP_SID;
1404 1408
1405 1409 /* Setup pointers for the result */
1406 1410 gh->retlist[gh->next].idtype = IDMAP_SID;
1407 1411 gh->retlist[gh->next].sidprefix = sidprefix;
1408 1412 gh->retlist[gh->next].rid = rid;
1409 1413 gh->retlist[gh->next].stat = stat;
1410 1414 gh->retlist[gh->next].info = info;
1411 1415 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1412 1416
1413 1417 gh->next++;
1414 1418 return (IDMAP_SUCCESS);
1415 1419
1416 1420 errout:
1417 1421 if (mapping)
1418 1422 (void) memset(mapping, 0, sizeof (*mapping));
1419 1423 errno = idmap_stat2errno(retcode);
1420 1424 return (retcode);
1421 1425 }
1422 1426
1423 1427
1424 1428 /*
1425 1429 * Process the batched "get mapping" requests. The results (i.e.
1426 1430 * status and identity) will be available in the data areas
1427 1431 * provided by individual requests.
1428 1432 */
1429 1433 idmap_stat
1430 1434 idmap_get_mappings(idmap_get_handle_t *gh)
1431 1435 {
1432 1436 idmap_retcode retcode;
1433 1437 idmap_ids_res res;
1434 1438 idmap_id *res_id;
1435 1439 int i;
1436 1440 idmap_id *req_id;
1437 1441 int direction;
1438 1442
1439 1443 if (gh == NULL) {
1440 1444 errno = EINVAL;
1441 1445 return (IDMAP_ERR_ARG);
1442 1446 }
1443 1447
1444 1448 (void) memset(&res, 0, sizeof (idmap_ids_res));
1445 1449 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_IDS,
1446 1450 (xdrproc_t)xdr_idmap_mapping_batch,
1447 1451 (caddr_t)&gh->batch,
1448 1452 (xdrproc_t)xdr_idmap_ids_res,
1449 1453 (caddr_t)&res,
1450 1454 TIMEOUT);
1451 1455 if (retcode != IDMAP_SUCCESS) {
1452 1456 goto out;
1453 1457 }
1454 1458 if (res.retcode != IDMAP_SUCCESS) {
1455 1459 retcode = res.retcode;
1456 1460 goto out;
1457 1461 }
1458 1462 for (i = 0; i < gh->next; i++) {
1459 1463 if (i >= res.ids.ids_len) {
1460 1464 *gh->retlist[i].stat = IDMAP_ERR_NORESULT;
1461 1465 continue;
1462 1466 }
1463 1467 *gh->retlist[i].stat = res.ids.ids_val[i].retcode;
1464 1468 res_id = &res.ids.ids_val[i].id;
1465 1469 direction = res.ids.ids_val[i].direction;
1466 1470 req_id = &gh->batch.idmap_mapping_batch_val[i].id1;
1467 1471 switch (res_id->idtype) {
1468 1472 case IDMAP_UID:
1469 1473 if (gh->retlist[i].uid)
1470 1474 *gh->retlist[i].uid = res_id->idmap_id_u.uid;
1471 1475 if (gh->retlist[i].is_user)
1472 1476 *gh->retlist[i].is_user = 1;
1473 1477
1474 1478 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
1475 1479 gh->retlist[i].cache_res) {
1476 1480 if (gh->retlist[i].is_user != NULL)
1477 1481 idmap_cache_add_sid2pid(
1478 1482 req_id->idmap_id_u.sid.prefix,
1479 1483 req_id->idmap_id_u.sid.rid,
1480 1484 res_id->idmap_id_u.uid, 1,
1481 1485 direction);
1482 1486 else
1483 1487 idmap_cache_add_sid2uid(
1484 1488 req_id->idmap_id_u.sid.prefix,
1485 1489 req_id->idmap_id_u.sid.rid,
1486 1490 res_id->idmap_id_u.uid,
1487 1491 direction);
1488 1492 }
1489 1493 break;
1490 1494
1491 1495 case IDMAP_GID:
1492 1496 if (gh->retlist[i].gid)
1493 1497 *gh->retlist[i].gid = res_id->idmap_id_u.gid;
1494 1498 if (gh->retlist[i].is_user)
1495 1499 *gh->retlist[i].is_user = 0;
1496 1500
1497 1501 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
1498 1502 gh->retlist[i].cache_res) {
1499 1503 if (gh->retlist[i].is_user != NULL)
1500 1504 idmap_cache_add_sid2pid(
1501 1505 req_id->idmap_id_u.sid.prefix,
1502 1506 req_id->idmap_id_u.sid.rid,
1503 1507 res_id->idmap_id_u.gid, 0,
1504 1508 direction);
1505 1509 else
1506 1510 idmap_cache_add_sid2gid(
1507 1511 req_id->idmap_id_u.sid.prefix,
1508 1512 req_id->idmap_id_u.sid.rid,
1509 1513 res_id->idmap_id_u.gid,
1510 1514 direction);
1511 1515 }
1512 1516 break;
1513 1517
1514 1518 case IDMAP_POSIXID:
1515 1519 if (gh->retlist[i].uid)
1516 1520 *gh->retlist[i].uid = 60001;
1517 1521 if (gh->retlist[i].is_user)
1518 1522 *gh->retlist[i].is_user = -1;
1519 1523 break;
1520 1524
1521 1525 case IDMAP_SID:
1522 1526 case IDMAP_USID:
1523 1527 case IDMAP_GSID:
1524 1528 if (gh->retlist[i].rid)
1525 1529 *gh->retlist[i].rid =
1526 1530 res_id->idmap_id_u.sid.rid;
1527 1531 if (gh->retlist[i].sidprefix) {
1528 1532 if (res_id->idmap_id_u.sid.prefix == NULL ||
1529 1533 *res_id->idmap_id_u.sid.prefix == '\0') {
1530 1534 *gh->retlist[i].sidprefix = NULL;
1531 1535 break;
1532 1536 }
1533 1537 *gh->retlist[i].sidprefix =
1534 1538 strdup(res_id->idmap_id_u.sid.prefix);
1535 1539 if (*gh->retlist[i].sidprefix == NULL)
1536 1540 *gh->retlist[i].stat =
1537 1541 IDMAP_ERR_MEMORY;
1538 1542 }
1539 1543 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
1540 1544 gh->retlist[i].cache_res) {
1541 1545 if (req_id->idtype == IDMAP_UID)
1542 1546 idmap_cache_add_sid2uid(
1543 1547 res_id->idmap_id_u.sid.prefix,
1544 1548 res_id->idmap_id_u.sid.rid,
1545 1549 req_id->idmap_id_u.uid,
1546 1550 direction);
1547 1551 else /* req_id->idtype == IDMAP_GID */
1548 1552 idmap_cache_add_sid2gid(
1549 1553 res_id->idmap_id_u.sid.prefix,
1550 1554 res_id->idmap_id_u.sid.rid,
1551 1555 req_id->idmap_id_u.gid,
1552 1556 direction);
1553 1557 }
1554 1558 break;
1555 1559
1556 1560 case IDMAP_NONE:
1557 1561 break;
1558 1562
1559 1563 default:
1560 1564 *gh->retlist[i].stat = IDMAP_ERR_NORESULT;
1561 1565 break;
1562 1566 }
1563 1567 if (gh->retlist[i].info != NULL) {
1564 1568 idmap_info_mov(gh->retlist[i].info,
1565 1569 &res.ids.ids_val[i].info);
1566 1570 }
1567 1571 }
1568 1572 retcode = IDMAP_SUCCESS;
1569 1573
1570 1574 out:
1571 1575 _IDMAP_RESET_GET_HANDLE(gh);
1572 1576 xdr_free(xdr_idmap_ids_res, (caddr_t)&res);
1573 1577 errno = idmap_stat2errno(retcode);
1574 1578 return (retcode);
1575 1579 }
1576 1580
1577 1581
1578 1582 /*
1579 1583 * Destroy the "get mapping" handle
1580 1584 */
1581 1585 void
1582 1586 idmap_get_destroy(idmap_get_handle_t *gh)
1583 1587 {
1584 1588 if (gh == NULL)
1585 1589 return;
1586 1590 xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
1587 1591 if (gh->retlist)
1588 1592 free(gh->retlist);
1589 1593 free(gh);
1590 1594 }
1591 1595
1592 1596
1593 1597 /*
1594 1598 * Get windows to unix mapping
1595 1599 */
1596 1600 idmap_stat
1597 1601 idmap_get_w2u_mapping(
1598 1602 const char *sidprefix, idmap_rid_t *rid,
1599 1603 const char *winname, const char *windomain,
1600 1604 int flag, int *is_user, int *is_wuser,
1601 1605 uid_t *pid, char **unixname, int *direction, idmap_info *info)
1602 1606 {
1603 1607 idmap_mapping request, *mapping;
1604 1608 idmap_mappings_res result;
1605 1609 idmap_retcode retcode, rc;
1606 1610
1607 1611 (void) memset(&request, 0, sizeof (request));
1608 1612 (void) memset(&result, 0, sizeof (result));
1609 1613
1610 1614 if (pid)
1611 1615 *pid = UINT32_MAX;
1612 1616 if (unixname)
1613 1617 *unixname = NULL;
1614 1618 if (direction)
1615 1619 *direction = IDMAP_DIRECTION_UNDEF;
1616 1620
1617 1621 request.flag = flag;
1618 1622 request.id1.idtype = IDMAP_SID;
1619 1623 if (sidprefix && rid) {
1620 1624 request.id1.idmap_id_u.sid.prefix = (char *)sidprefix;
1621 1625 request.id1.idmap_id_u.sid.rid = *rid;
1622 1626 } else if (winname) {
1623 1627 retcode = idmap_strdupnull(&request.id1name, winname);
1624 1628 if (retcode != IDMAP_SUCCESS)
1625 1629 goto out;
1626 1630
1627 1631 retcode = idmap_strdupnull(&request.id1domain, windomain);
1628 1632 if (retcode != IDMAP_SUCCESS)
1629 1633 goto out;
1630 1634
1631 1635 request.id1.idmap_id_u.sid.prefix = NULL;
1632 1636 } else {
1633 1637 errno = EINVAL;
1634 1638 return (IDMAP_ERR_ARG);
1635 1639 }
1636 1640
1637 1641 if (*is_user == 1)
1638 1642 request.id2.idtype = IDMAP_UID;
1639 1643 else if (*is_user == 0)
1640 1644 request.id2.idtype = IDMAP_GID;
1641 1645 else
1642 1646 request.id2.idtype = IDMAP_POSIXID;
1643 1647
1644 1648 if (*is_wuser == 1)
1645 1649 request.id1.idtype = IDMAP_USID;
1646 1650 else if (*is_wuser == 0)
1647 1651 request.id1.idtype = IDMAP_GSID;
1648 1652 else
1649 1653 request.id1.idtype = IDMAP_SID;
1650 1654
1651 1655 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME,
1652 1656 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
1653 1657 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
1654 1658 TIMEOUT);
1655 1659
1656 1660 if (retcode != IDMAP_SUCCESS)
1657 1661 goto out;
1658 1662
1659 1663 retcode = result.retcode;
1660 1664
1661 1665 if ((mapping = result.mappings.mappings_val) == NULL) {
1662 1666 if (retcode == IDMAP_SUCCESS)
1663 1667 retcode = IDMAP_ERR_NORESULT;
1664 1668 goto out;
1665 1669 }
1666 1670
1667 1671 if (info != NULL)
1668 1672 idmap_info_mov(info, &mapping->info);
1669 1673
1670 1674 if (mapping->id2.idtype == IDMAP_UID) {
1671 1675 *is_user = 1;
1672 1676 } else if (mapping->id2.idtype == IDMAP_GID) {
1673 1677 *is_user = 0;
1674 1678 } else {
1675 1679 goto out;
1676 1680 }
1677 1681
1678 1682 if (mapping->id1.idtype == IDMAP_USID) {
1679 1683 *is_wuser = 1;
1680 1684 } else if (mapping->id1.idtype == IDMAP_GSID) {
1681 1685 *is_wuser = 0;
1682 1686 } else {
1683 1687 goto out;
1684 1688 }
1685 1689
1686 1690 if (direction)
1687 1691 *direction = mapping->direction;
1688 1692 if (pid)
1689 1693 *pid = mapping->id2.idmap_id_u.uid;
1690 1694
1691 1695 rc = idmap_strdupnull(unixname, mapping->id2name);
1692 1696 if (rc != IDMAP_SUCCESS)
1693 1697 retcode = rc;
1694 1698
1695 1699 out:
1696 1700 if (request.id1name != NULL)
1697 1701 free(request.id1name);
1698 1702 if (request.id1domain != NULL)
1699 1703 free(request.id1domain);
1700 1704 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
1701 1705 if (retcode != IDMAP_SUCCESS)
1702 1706 errno = idmap_stat2errno(retcode);
1703 1707 return (retcode);
1704 1708 }
1705 1709
1706 1710
1707 1711 /*
1708 1712 * Get unix to windows mapping
1709 1713 */
1710 1714 idmap_stat
1711 1715 idmap_get_u2w_mapping(
1712 1716 uid_t *pid, const char *unixname,
1713 1717 int flag, int is_user, int *is_wuser,
1714 1718 char **sidprefix, idmap_rid_t *rid,
1715 1719 char **winname, char **windomain,
1716 1720 int *direction, idmap_info *info)
1717 1721 {
1718 1722 idmap_mapping request, *mapping;
1719 1723 idmap_mappings_res result;
1720 1724 idmap_retcode retcode, rc;
1721 1725
1722 1726 if (sidprefix)
1723 1727 *sidprefix = NULL;
1724 1728 if (winname)
1725 1729 *winname = NULL;
1726 1730 if (windomain)
1727 1731 *windomain = NULL;
1728 1732 if (rid)
1729 1733 *rid = UINT32_MAX;
1730 1734 if (direction)
1731 1735 *direction = IDMAP_DIRECTION_UNDEF;
1732 1736
1733 1737 (void) memset(&request, 0, sizeof (request));
1734 1738 (void) memset(&result, 0, sizeof (result));
1735 1739
1736 1740 request.flag = flag;
1737 1741 request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID;
1738 1742
1739 1743 if (pid && *pid != UINT32_MAX) {
1740 1744 request.id1.idmap_id_u.uid = *pid;
1741 1745 } else if (unixname) {
1742 1746 request.id1name = (char *)unixname;
1743 1747 request.id1.idmap_id_u.uid = UINT32_MAX;
1744 1748 } else {
1745 1749 errno = EINVAL;
1746 1750 return (IDMAP_ERR_ARG);
1747 1751 }
1748 1752
1749 1753 if (is_wuser == NULL)
1750 1754 request.id2.idtype = IDMAP_SID;
1751 1755 else if (*is_wuser == -1)
1752 1756 request.id2.idtype = IDMAP_SID;
1753 1757 else if (*is_wuser == 0)
1754 1758 request.id2.idtype = IDMAP_GSID;
1755 1759 else if (*is_wuser == 1)
1756 1760 request.id2.idtype = IDMAP_USID;
1757 1761
1758 1762 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME,
1759 1763 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
1760 1764 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
1761 1765 TIMEOUT);
1762 1766
1763 1767 if (retcode != IDMAP_SUCCESS)
1764 1768 return (retcode);
1765 1769
1766 1770 retcode = result.retcode;
1767 1771
1768 1772 if ((mapping = result.mappings.mappings_val) == NULL) {
1769 1773 if (retcode == IDMAP_SUCCESS)
1770 1774 retcode = IDMAP_ERR_NORESULT;
1771 1775 goto out;
1772 1776 }
1773 1777
1774 1778 if (info != NULL)
1775 1779 idmap_info_mov(info, &mapping->info);
1776 1780
1777 1781 if (direction != NULL)
1778 1782 *direction = mapping->direction;
1779 1783
1780 1784 if (is_wuser != NULL) {
1781 1785 if (mapping->id2.idtype == IDMAP_USID)
1782 1786 *is_wuser = 1;
1783 1787 else if (mapping->id2.idtype == IDMAP_GSID)
1784 1788 *is_wuser = 0;
1785 1789 else
1786 1790 *is_wuser = -1;
1787 1791 }
1788 1792
1789 1793 if (sidprefix && mapping->id2.idmap_id_u.sid.prefix &&
1790 1794 *mapping->id2.idmap_id_u.sid.prefix != '\0') {
1791 1795 *sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix);
1792 1796 if (*sidprefix == NULL) {
1793 1797 retcode = IDMAP_ERR_MEMORY;
1794 1798 goto errout;
1795 1799 }
1796 1800 }
1797 1801 if (rid)
1798 1802 *rid = mapping->id2.idmap_id_u.sid.rid;
1799 1803
1800 1804 rc = idmap_strdupnull(winname, mapping->id2name);
1801 1805 if (rc != IDMAP_SUCCESS)
1802 1806 retcode = rc;
1803 1807
1804 1808 rc = idmap_strdupnull(windomain, mapping->id2domain);
1805 1809 if (rc != IDMAP_SUCCESS)
1806 1810 retcode = rc;
1807 1811
1808 1812 goto out;
1809 1813
1810 1814 errout:
1811 1815 if (sidprefix && *sidprefix) {
1812 1816 free(*sidprefix);
1813 1817 *sidprefix = NULL;
1814 1818 }
1815 1819 if (winname && *winname) {
1816 1820 free(*winname);
1817 1821 *winname = NULL;
1818 1822 }
1819 1823 if (windomain && *windomain) {
1820 1824 free(*windomain);
1821 1825 *windomain = NULL;
1822 1826 }
1823 1827
1824 1828 out:
1825 1829 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
1826 1830 if (retcode != IDMAP_SUCCESS)
1827 1831 errno = idmap_stat2errno(retcode);
1828 1832 return (retcode);
1829 1833 }
1830 1834
1831 1835
1832 1836
1833 1837 #define gettext(s) s
1834 1838 static stat_table_t stattable[] = {
1835 1839 {IDMAP_SUCCESS, gettext("Success"), 0},
1836 1840 {IDMAP_NEXT, gettext("More results available"), 0},
1837 1841 {IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL},
1838 1842 {IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL},
1839 1843 {IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM},
1840 1844 {IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL},
1841 1845 {IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL},
1842 1846 {IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL},
1843 1847 {IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP},
1844 1848 {IDMAP_ERR_W2U_NAMERULE,
1845 1849 gettext("Invalid Windows to UNIX name-based rule"), EINVAL},
1846 1850 {IDMAP_ERR_U2W_NAMERULE,
1847 1851 gettext("Invalid UNIX to Windows name-based rule"), EINVAL},
1848 1852 {IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL},
1849 1853 {IDMAP_ERR_DB, gettext("Invalid database"), EINVAL},
1850 1854 {IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL},
1851 1855 {IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL},
1852 1856 {IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL},
1853 1857 {IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF},
1854 1858 {IDMAP_ERR_RPC, gettext("RPC error"), EINVAL},
1855 1859 {IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL},
1856 1860 {IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY},
1857 1861 {IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES},
1858 1862 {IDMAP_ERR_NOMAPPING,
1859 1863 gettext("Mapping not found or inhibited"), EINVAL},
1860 1864 {IDMAP_ERR_NEW_ID_ALLOC_REQD,
1861 1865 gettext("New mapping needs to be created"), EINVAL},
1862 1866 {IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL},
1863 1867 {IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL},
1864 1868 {IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL},
1865 1869 {IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL},
1866 1870 {IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL},
1867 1871 {IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL},
1868 1872 {IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL},
1869 1873 {IDMAP_ERR_NOTMAPPED_WELLKNOWN,
1870 1874 gettext("No mapping for well-known SID"), EINVAL},
1871 1875 {IDMAP_ERR_RETRIABLE_NET_ERR,
1872 1876 gettext("Windows lookup failed"), EINVAL},
1873 1877 {IDMAP_ERR_W2U_NAMERULE_CONFLICT,
1874 1878 gettext("Duplicate rule or conflicts with an existing "
1875 1879 "Windows to UNIX name-based rule"), EINVAL},
1876 1880 {IDMAP_ERR_U2W_NAMERULE_CONFLICT,
1877 1881 gettext("Duplicate rule or conflicts with an existing "
1878 1882 "Unix to Windows name-based rule"), EINVAL},
1879 1883 {IDMAP_ERR_BAD_UTF8,
1880 1884 gettext("Invalid or illegal UTF-8 sequence found in "
1881 1885 "a given Windows entity name or domain name"), EINVAL},
1882 1886 {IDMAP_ERR_NONE_GENERATED,
1883 1887 gettext("Mapping not found and none created (see -c option)"),
1884 1888 EINVAL},
1885 1889 {IDMAP_ERR_PROP_UNKNOWN,
1886 1890 gettext("Undefined property"),
1887 1891 EINVAL},
1888 1892 {IDMAP_ERR_NS_LDAP_CFG,
1889 1893 gettext("Native LDAP configuration error"), EINVAL},
1890 1894 {IDMAP_ERR_NS_LDAP_PARTIAL,
1891 1895 gettext("Partial result from Native LDAP"), EINVAL},
1892 1896 {IDMAP_ERR_NS_LDAP_OP_FAILED,
1893 1897 gettext("Native LDAP operation failed"), EINVAL},
1894 1898 {IDMAP_ERR_NS_LDAP_BAD_WINNAME,
1895 1899 gettext("Improper winname form found in Native LDAP"), EINVAL},
1896 1900 {IDMAP_ERR_NO_ACTIVEDIRECTORY,
1897 1901 gettext("No AD servers"),
1898 1902 EINVAL},
1899 1903 {-1, NULL, 0}
1900 1904 };
1901 1905 #undef gettext
1902 1906
1903 1907
1904 1908 /*
1905 1909 * Get description of status code
1906 1910 *
1907 1911 * Input:
1908 1912 * status - Status code returned by libidmap API call
1909 1913 *
1910 1914 * Return Value:
1911 1915 * human-readable localized description of idmap_stat
1912 1916 */
1913 1917 const char *
1914 1918 idmap_stat2string(idmap_stat status)
1915 1919 {
1916 1920 int i;
1917 1921
1918 1922 for (i = 0; stattable[i].msg; i++) {
1919 1923 if (stattable[i].retcode == status)
1920 1924 return (dgettext(TEXT_DOMAIN, stattable[i].msg));
1921 1925 }
1922 1926 return (dgettext(TEXT_DOMAIN, "Unknown error"));
1923 1927 }
1924 1928
1925 1929
1926 1930 static int
1927 1931 idmap_stat2errno(idmap_stat stat)
1928 1932 {
1929 1933 int i;
1930 1934 for (i = 0; stattable[i].msg; i++) {
1931 1935 if (stattable[i].retcode == stat)
1932 1936 return (stattable[i].errnum);
1933 1937 }
1934 1938 return (EINVAL);
1935 1939 }
1936 1940
1937 1941
1938 1942 /*
1939 1943 * Get status code from string
1940 1944 */
1941 1945 idmap_stat
1942 1946 idmap_string2stat(const char *str)
1943 1947 {
1944 1948 if (str == NULL)
1945 1949 return (IDMAP_ERR_INTERNAL);
1946 1950
1947 1951 #define return_cmp(a) \
1948 1952 if (0 == strcmp(str, "IDMAP_ERR_" #a)) \
1949 1953 return (IDMAP_ERR_ ## a);
1950 1954
1951 1955 return_cmp(OTHER);
1952 1956 return_cmp(INTERNAL);
1953 1957 return_cmp(MEMORY);
1954 1958 return_cmp(NORESULT);
1955 1959 return_cmp(NOTUSER);
1956 1960 return_cmp(NOTGROUP);
1957 1961 return_cmp(NOTSUPPORTED);
1958 1962 return_cmp(W2U_NAMERULE);
1959 1963 return_cmp(U2W_NAMERULE);
1960 1964 return_cmp(CACHE);
1961 1965 return_cmp(DB);
1962 1966 return_cmp(ARG);
1963 1967 return_cmp(SID);
1964 1968 return_cmp(IDTYPE);
1965 1969 return_cmp(RPC_HANDLE);
1966 1970 return_cmp(RPC);
1967 1971 return_cmp(CLIENT_HANDLE);
1968 1972 return_cmp(BUSY);
1969 1973 return_cmp(PERMISSION_DENIED);
1970 1974 return_cmp(NOMAPPING);
1971 1975 return_cmp(NEW_ID_ALLOC_REQD);
1972 1976 return_cmp(DOMAIN);
1973 1977 return_cmp(SECURITY);
1974 1978 return_cmp(NOTFOUND);
1975 1979 return_cmp(DOMAIN_NOTFOUND);
1976 1980 return_cmp(MEMORY);
1977 1981 return_cmp(UPDATE_NOTALLOWED);
1978 1982 return_cmp(CFG);
1979 1983 return_cmp(CFG_CHANGE);
1980 1984 return_cmp(NOTMAPPED_WELLKNOWN);
1981 1985 return_cmp(RETRIABLE_NET_ERR);
1982 1986 return_cmp(W2U_NAMERULE_CONFLICT);
1983 1987 return_cmp(U2W_NAMERULE_CONFLICT);
1984 1988 return_cmp(BAD_UTF8);
1985 1989 return_cmp(NONE_GENERATED);
1986 1990 return_cmp(PROP_UNKNOWN);
1987 1991 return_cmp(NS_LDAP_CFG);
1988 1992 return_cmp(NS_LDAP_PARTIAL);
1989 1993 return_cmp(NS_LDAP_OP_FAILED);
1990 1994 return_cmp(NS_LDAP_BAD_WINNAME);
1991 1995 return_cmp(NO_ACTIVEDIRECTORY);
1992 1996 #undef return_cmp
1993 1997
1994 1998 return (IDMAP_ERR_OTHER);
1995 1999 }
1996 2000
1997 2001
1998 2002 /*
1999 2003 * Map the given status to one that can be returned by the protocol
2000 2004 */
2001 2005 idmap_stat
2002 2006 idmap_stat4prot(idmap_stat status)
2003 2007 {
2004 2008 switch (status) {
2005 2009 case IDMAP_ERR_MEMORY:
2006 2010 case IDMAP_ERR_CACHE:
2007 2011 return (IDMAP_ERR_INTERNAL);
2008 2012 }
2009 2013 return (status);
2010 2014 }
2011 2015
2012 2016
2013 2017 /*
2014 2018 * This is a convenience routine which duplicates a string after
2015 2019 * checking for NULL pointers. This function will return success if
2016 2020 * either the 'to' OR 'from' pointers are NULL.
2017 2021 */
2018 2022 static idmap_stat
2019 2023 idmap_strdupnull(char **to, const char *from)
2020 2024 {
2021 2025 if (to == NULL)
2022 2026 return (IDMAP_SUCCESS);
2023 2027
2024 2028 if (from == NULL || *from == '\0') {
2025 2029 *to = NULL;
2026 2030 return (IDMAP_SUCCESS);
2027 2031 }
2028 2032
2029 2033 *to = strdup(from);
2030 2034 if (*to == NULL)
2031 2035 return (IDMAP_ERR_MEMORY);
2032 2036 return (IDMAP_SUCCESS);
2033 2037 }
2034 2038
2035 2039
2036 2040 idmap_stat
2037 2041 idmap_namerule_cpy(idmap_namerule *to, idmap_namerule *from)
2038 2042 {
2039 2043 idmap_stat retval;
2040 2044
2041 2045 if (to == NULL)
2042 2046 return (IDMAP_SUCCESS);
2043 2047
2044 2048 (void) memcpy(to, from, sizeof (idmap_namerule));
2045 2049 to->windomain = NULL;
2046 2050 to->winname = NULL;
2047 2051 to->unixname = NULL;
2048 2052
2049 2053 retval = idmap_strdupnull(&to->windomain, from->windomain);
2050 2054 if (retval != IDMAP_SUCCESS)
2051 2055 return (retval);
2052 2056
2053 2057 retval = idmap_strdupnull(&to->winname, from->winname);
2054 2058 if (retval != IDMAP_SUCCESS) {
2055 2059 free(to->windomain);
2056 2060 to->windomain = NULL;
2057 2061 return (retval);
2058 2062 }
2059 2063
2060 2064 retval = idmap_strdupnull(&to->unixname, from->unixname);
2061 2065 if (retval != IDMAP_SUCCESS) {
2062 2066 free(to->windomain);
2063 2067 to->windomain = NULL;
2064 2068 free(to->winname);
2065 2069 to->winname = NULL;
2066 2070 return (retval);
2067 2071 }
2068 2072
2069 2073 return (retval);
2070 2074 }
2071 2075
2072 2076
2073 2077 /*
2074 2078 * Move the contents of the "info" structure from "from" to "to".
2075 2079 */
2076 2080 void
2077 2081 idmap_info_mov(idmap_info *to, idmap_info *from)
2078 2082 {
2079 2083 (void) memcpy(to, from, sizeof (idmap_info));
2080 2084 (void) memset(from, 0, sizeof (idmap_info));
2081 2085 }
2082 2086
2083 2087
2084 2088 void
2085 2089 idmap_info_free(idmap_info *info)
2086 2090 {
2087 2091 if (info == NULL)
2088 2092 return;
2089 2093
2090 2094 xdr_free(xdr_idmap_info, (caddr_t)info);
2091 2095 (void) memset(info, 0, sizeof (idmap_info));
2092 2096 }
2093 2097
2094 2098
2095 2099 void
2096 2100 idmap_how_clear(idmap_how *how)
2097 2101 {
2098 2102 xdr_free(xdr_idmap_how, (caddr_t)how);
2099 2103 (void) memset(how, 0, sizeof (*how));
2100 2104 }
2101 2105
2102 2106
2103 2107 /*
2104 2108 * Get uid given Windows name
2105 2109 */
2106 2110 idmap_stat
2107 2111 idmap_getuidbywinname(const char *name, const char *domain, int flag,
2108 2112 uid_t *uid)
2109 2113 {
2110 2114 idmap_retcode rc;
2111 2115 int is_user = 1;
2112 2116 int is_wuser = -1;
2113 2117 int direction;
2114 2118
2115 2119 if (uid == NULL)
2116 2120 return (IDMAP_ERR_ARG);
2117 2121
2118 2122 if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2119 2123 rc = idmap_cache_lookup_uidbywinname(name, domain, uid);
2120 2124 if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY)
2121 2125 return (rc);
2122 2126 }
2123 2127 /* Get mapping */
2124 2128 rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag,
2125 2129 &is_user, &is_wuser, uid, NULL, &direction, NULL);
2126 2130
2127 2131 if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
2128 2132 /* If we have not got the domain don't store UID to winname */
2129 2133 if (domain == NULL)
2130 2134 direction = IDMAP_DIRECTION_W2U;
2131 2135 idmap_cache_add_winname2uid(name, domain, *uid, direction);
2132 2136 }
2133 2137
2134 2138 return (rc);
2135 2139 }
2136 2140
2137 2141
2138 2142 /*
2139 2143 * Get gid given Windows name
2140 2144 */
2141 2145 idmap_stat
2142 2146 idmap_getgidbywinname(const char *name, const char *domain, int flag,
2143 2147 gid_t *gid)
2144 2148 {
2145 2149 idmap_retcode rc;
2146 2150 int is_user = 0;
2147 2151 int is_wuser = -1;
2148 2152 int direction;
2149 2153
2150 2154 if (gid == NULL)
2151 2155 return (IDMAP_ERR_ARG);
2152 2156
2153 2157 if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2154 2158 rc = idmap_cache_lookup_gidbywinname(name, domain, gid);
2155 2159 if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY)
2156 2160 return (rc);
2157 2161 }
2158 2162
2159 2163 /* Get mapping */
2160 2164 rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag,
2161 2165 &is_user, &is_wuser, gid, NULL, &direction, NULL);
2162 2166
2163 2167 if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
2164 2168 /* If we have not got the domain don't store GID to winname */
2165 2169 if (domain == NULL)
2166 2170 direction = IDMAP_DIRECTION_W2U;
2167 2171 idmap_cache_add_winname2gid(name, domain, *gid, direction);
2168 2172 }
2169 2173
2170 2174 return (rc);
2171 2175 }
2172 2176
2173 2177
2174 2178 /*
2175 2179 * Get winname given pid
2176 2180 */
2177 2181 idmap_stat
2178 2182 idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name,
2179 2183 char **domain)
2180 2184 {
2181 2185 idmap_retcode rc;
2182 2186 int len;
2183 2187 char *winname, *windomain;
2184 2188 int direction;
2185 2189
2186 2190 if (name == NULL)
2187 2191 return (IDMAP_ERR_ARG);
2188 2192
2189 2193 if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2190 2194 if (is_user)
2191 2195 rc = idmap_cache_lookup_winnamebyuid(&winname,
2192 2196 &windomain, pid);
2193 2197 else
2194 2198 rc = idmap_cache_lookup_winnamebygid(&winname,
2195 2199 &windomain, pid);
2196 2200 if (rc == IDMAP_SUCCESS)
2197 2201 goto out;
2198 2202 if (rc == IDMAP_ERR_MEMORY)
2199 2203 return (rc);
2200 2204 }
2201 2205
2202 2206 /* Get mapping */
2203 2207 rc = idmap_get_u2w_mapping(&pid, NULL, flag, is_user, NULL,
2204 2208 NULL, NULL, &winname, &windomain, &direction, NULL);
2205 2209
2206 2210 /* Return on error */
2207 2211 if (rc != IDMAP_SUCCESS)
2208 2212 return (rc);
2209 2213
2210 2214 /*
2211 2215 * The given PID may have been mapped to a locally
2212 2216 * generated SID in which case there isn't any
2213 2217 * Windows name
2214 2218 */
2215 2219 if (winname == NULL) {
2216 2220 idmap_free(windomain);
2217 2221 return (IDMAP_ERR_NORESULT);
2218 2222 }
2219 2223
2220 2224 if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2221 2225 if (is_user)
2222 2226 idmap_cache_add_winname2uid(winname, windomain,
2223 2227 pid, direction);
2224 2228 else
2225 2229 idmap_cache_add_winname2gid(winname, windomain,
2226 2230 pid, direction);
2227 2231 }
2228 2232
2229 2233 out:
2230 2234 if (domain != NULL) {
2231 2235 *name = winname;
2232 2236 *domain = windomain;
2233 2237 } else {
2234 2238 char *wd = windomain != NULL ? windomain : "";
2235 2239 len = snprintf(NULL, 0, "%s@%s", winname, wd) + 1;
2236 2240 if ((*name = malloc(len)) != NULL)
2237 2241 (void) snprintf(*name, len, "%s@%s", winname, wd);
2238 2242 else
2239 2243 rc = IDMAP_ERR_MEMORY;
2240 2244 idmap_free(winname);
2241 2245 idmap_free(windomain);
2242 2246 }
2243 2247
2244 2248 return (rc);
2245 2249 }
2246 2250
2247 2251
2248 2252 /*
2249 2253 * Get winname given uid
2250 2254 */
2251 2255 idmap_stat
2252 2256 idmap_getwinnamebyuid(uid_t uid, int flag, char **name, char **domain)
2253 2257 {
2254 2258 return (idmap_getwinnamebypid(uid, 1, flag, name, domain));
2255 2259 }
2256 2260
|
↓ open down ↓ |
2201 lines elided |
↑ open up ↑ |
2257 2261
2258 2262 /*
2259 2263 * Get winname given gid
2260 2264 */
2261 2265 idmap_stat
2262 2266 idmap_getwinnamebygid(gid_t gid, int flag, char **name, char **domain)
2263 2267 {
2264 2268 return (idmap_getwinnamebypid(gid, 0, flag, name, domain));
2265 2269 }
2266 2270
2271 +/*
2272 + * Get winname given SID
2273 + */
2274 +int
2275 +idmap_getwinnamebysid(char *sid, int flag, char **name)
2276 +{
2277 + uid_t pid;
2278 + idmap_get_handle_t *get_hdl = NULL;
2279 + idmap_rid_t rid;
2280 + idmap_stat stat;
2281 + char *ridp = NULL;
2282 + char *end;
2283 + int is_user = 0;
2284 + int rc;
2285 +
2286 + if ((ridp = strrchr(sid, '-')) == NULL)
2287 + return (IDMAP_ERR_SID);
2288 +
2289 + *ridp = '\0';
2290 +
2291 + errno = 0;
2292 + rid = strtoul(ridp + 1, &end, 10);
2293 +
2294 + if (errno != 0 || *end != '\0')
2295 + return (IDMAP_ERR_SID);
2296 +
2297 + rc = idmap_get_create(&get_hdl);
2298 + if (rc != IDMAP_SUCCESS)
2299 + return (rc);
2300 +
2301 + rc = idmap_get_pidbysid(get_hdl, sid, rid, flag, &pid, &is_user, &stat);
2302 + *ridp = '-';
2303 +
2304 + if (rc == IDMAP_SUCCESS)
2305 + rc = idmap_get_mappings(get_hdl);
2306 +
2307 + if (rc == IDMAP_SUCCESS && stat != IDMAP_SUCCESS)
2308 + rc = stat;
2309 +
2310 + idmap_get_destroy(get_hdl);
2311 + get_hdl = NULL;
2312 +
2313 + if (rc == IDMAP_SUCCESS) {
2314 + rc = idmap_getwinnamebypid(pid, is_user, flag, name, NULL);
2315 +
2316 + if (rc == IDMAP_ERR_NORESULT && !IDMAP_ID_IS_EPHEMERAL(pid)) {
2317 + /*
2318 + * Unlike LSA, idmap doesn't map a winname for local
2319 + * accounts. Recreate one.
2320 + */
2321 + char buf[1024];
2322 + char hostname[MAXHOSTNAMELEN];
2323 + struct group gr;
2324 + struct passwd pwd;
2325 + char *unixname = NULL;
2326 +
2327 + if (is_user) {
2328 + if (getpwuid_r(pid, &pwd, buf,
2329 + sizeof (buf)) != NULL)
2330 + unixname = pwd.pw_name;
2331 + } else {
2332 + if (getgrgid_r(pid, &gr, buf,
2333 + sizeof (buf)) != NULL)
2334 + unixname = gr.gr_name;
2335 + }
2336 +
2337 + if (unixname == NULL)
2338 + return (rc);
2339 +
2340 + hostname[0] = '\0';
2341 + if (gethostname(hostname, sizeof (hostname)) == 0)
2342 + hostname[MAXHOSTNAMELEN - 1] = '\0';
2343 +
2344 + if (asprintf(name, "%s%s%s", unixname,
2345 + (hostname[0] != '\0') ? "@" : "", hostname) >= 0)
2346 + rc = IDMAP_SUCCESS;
2347 + }
2348 + }
2349 +
2350 + return (rc);
2351 +}
2352 +
2267 2353 idmap_stat
2268 2354 idmap_flush(idmap_flush_op op)
2269 2355 {
2270 2356 idmap_retcode rc1, rc2;
2271 2357
2272 2358 rc1 = _idmap_clnt_call(IDMAP_FLUSH,
2273 2359 (xdrproc_t)xdr_idmap_flush_op, (caddr_t)&op,
2274 2360 (xdrproc_t)xdr_idmap_retcode, (caddr_t)&rc2, TIMEOUT);
2275 2361
2276 2362 if (rc1 != IDMAP_SUCCESS)
2277 2363 return (rc1);
2278 2364 return (rc2);
2279 2365 }
2280 2366
2281 2367
2282 2368 /*
2283 2369 * syslog is the default logger.
2284 2370 * It can be overwritten by supplying a logger
2285 2371 * with idmap_set_logger()
2286 2372 */
2287 2373 idmap_logger_t logger = syslog;
2288 2374
2289 2375
2290 2376 void
2291 2377 idmap_set_logger(idmap_logger_t funct)
2292 2378 {
2293 2379 logger = funct;
2294 2380 }
2295 2381
2296 2382 /*
2297 2383 * Helper functions that concatenate two parts of a name and then
2298 2384 * look up a value, so that the same set of functions can be used to
2299 2385 * process both "in" and "out" parameters.
2300 2386 */
2301 2387 static
2302 2388 boolean_t
2303 2389 idmap_trace_get_str(nvlist_t *entry, char *n1, char *n2, char **ret)
2304 2390 {
2305 2391 char name[IDMAP_TRACE_NAME_MAX+1]; /* Max used is about 11 */
2306 2392 int err;
2307 2393
2308 2394 (void) strlcpy(name, n1, sizeof (name));
2309 2395 if (n2 != NULL)
2310 2396 (void) strlcat(name, n2, sizeof (name));
2311 2397
2312 2398 err = nvlist_lookup_string(entry, name, ret);
2313 2399 return (err == 0);
2314 2400 }
2315 2401
2316 2402 static
2317 2403 boolean_t
2318 2404 idmap_trace_get_int(nvlist_t *entry, char *n1, char *n2, int64_t *ret)
2319 2405 {
2320 2406 char name[IDMAP_TRACE_NAME_MAX+1]; /* Max used is about 11 */
2321 2407 int err;
2322 2408
2323 2409 (void) strlcpy(name, n1, sizeof (name));
2324 2410 if (n2 != NULL)
2325 2411 (void) strlcat(name, n2, sizeof (name));
2326 2412
2327 2413 err = nvlist_lookup_int64(entry, name, ret);
2328 2414 return (err == 0);
2329 2415 }
2330 2416
2331 2417 static
2332 2418 void
2333 2419 idmap_trace_print_id(FILE *out, nvlist_t *entry, char *fromto)
2334 2420 {
2335 2421 char *s;
2336 2422 int64_t i64;
2337 2423
2338 2424 if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_TYPE, &i64)) {
2339 2425 switch (i64) {
2340 2426 case IDMAP_POSIXID:
2341 2427 (void) fprintf(out, "unixname ");
2342 2428 break;
2343 2429 case IDMAP_UID:
2344 2430 (void) fprintf(out, "unixuser ");
2345 2431 break;
2346 2432 case IDMAP_GID:
2347 2433 (void) fprintf(out, "unixgroup ");
2348 2434 break;
2349 2435 case IDMAP_SID:
2350 2436 (void) fprintf(out, "winname ");
2351 2437 break;
2352 2438 case IDMAP_USID:
2353 2439 (void) fprintf(out, "winuser ");
2354 2440 break;
2355 2441 case IDMAP_GSID:
2356 2442 (void) fprintf(out, "wingroup ");
2357 2443 break;
2358 2444 case IDMAP_NONE:
2359 2445 (void) fprintf(out, gettext("unknown "));
2360 2446 break;
2361 2447 default:
2362 2448 (void) fprintf(out, gettext("bad %d "), (int)i64);
2363 2449 break;
2364 2450 }
2365 2451 }
2366 2452
2367 2453 if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_NAME, &s))
2368 2454 (void) fprintf(out, "%s ", s);
2369 2455
2370 2456 if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_SID, &s))
2371 2457 (void) fprintf(out, "%s ", s);
2372 2458
2373 2459 if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_UNIXID, &i64))
2374 2460 (void) fprintf(out, "%u ", (uid_t)i64);
2375 2461 }
2376 2462
2377 2463 void
2378 2464 idmap_trace_print_1(FILE *out, char *prefix, nvlist_t *entry)
2379 2465 {
2380 2466 char *s;
2381 2467 int64_t i64;
2382 2468
2383 2469 (void) fprintf(out, "%s", prefix);
2384 2470 idmap_trace_print_id(out, entry, "from");
2385 2471 (void) fprintf(out, "-> ");
2386 2472 idmap_trace_print_id(out, entry, "to");
2387 2473 if (idmap_trace_get_int(entry, IDMAP_TRACE_ERROR, NULL, &i64))
2388 2474 (void) fprintf(out, gettext("Error %d "), (int)i64);
2389 2475 (void) fprintf(out, "-");
2390 2476 if (idmap_trace_get_str(entry, IDMAP_TRACE_MESSAGE, NULL, &s))
2391 2477 (void) fprintf(out, " %s", s);
2392 2478 (void) fprintf(out, "\n");
2393 2479 }
2394 2480
2395 2481 void
2396 2482 idmap_trace_print(FILE *out, char *prefix, nvlist_t *trace)
2397 2483 {
2398 2484 nvpair_t *nvp;
2399 2485
2400 2486 for (nvp = nvlist_next_nvpair(trace, NULL);
2401 2487 nvp != NULL;
2402 2488 nvp = nvlist_next_nvpair(trace, nvp)) {
2403 2489 nvlist_t *entry;
2404 2490 int err;
2405 2491
2406 2492 err = nvpair_value_nvlist(nvp, &entry);
2407 2493 assert(err == 0);
2408 2494
2409 2495 idmap_trace_print_1(out, prefix, entry);
2410 2496 }
2411 2497 }
|
↓ open down ↓ |
135 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX