1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * svc_door.c, Server side for doors IPC based RPC. 29 */ 30 31 #include "mt.h" 32 #include "rpc_mt.h" 33 #include <stdio.h> 34 #include <unistd.h> 35 #include <sys/types.h> 36 #include <rpc/rpc.h> 37 #include <errno.h> 38 #include <syslog.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <sys/stat.h> 42 #include <door.h> 43 #include <alloca.h> 44 #include <dlfcn.h> 45 #include <limits.h> 46 #include <rpc/svc_mt.h> 47 48 static void svc_door_destroy_pvt(); 49 static int return_xprt_copy(); 50 51 int __rpc_default_door_buf_size = 16000; 52 int __rpc_min_door_buf_size = 1000; 53 54 static struct xp_ops *svc_door_ops(); 55 56 mutex_t svc_door_mutex = DEFAULTMUTEX; 57 cond_t svc_door_waitcv = DEFAULTCV; 58 int svc_ndoorfds = 0; 59 60 /* 61 * Dispatch information for door calls. 62 */ 63 typedef struct { 64 rpcprog_t prognum; 65 rpcvers_t versnum; 66 void (*dispatch)(); 67 } call_info_t; 68 69 /* 70 * kept in xprt->xp_p2 71 */ 72 struct svc_door_data { 73 uint_t su_iosz; /* size of send/recv buffer */ 74 uint32_t su_xid; /* transaction id */ 75 XDR su_xdrs; /* XDR handle */ 76 char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ 77 call_info_t call_info; /* dispatch info */ 78 char *argbuf; /* argument buffer */ 79 size_t arglen; /* argument length */ 80 char *buf; /* result buffer */ 81 int len; /* result length */ 82 }; 83 #define su_data(xprt) ((struct svc_door_data *)(xprt->xp_p2)) 84 85 static SVCXPRT *get_xprt_copy(); 86 static bool_t svc_door_recv(); 87 static void svc_door_destroy(); 88 89 static SVCXPRT_LIST *dxlist; /* list of door based service handles */ 90 91 /* 92 * List management routines. 93 */ 94 bool_t 95 __svc_add_to_xlist(SVCXPRT_LIST **list, SVCXPRT *xprt, mutex_t *lockp) 96 { 97 SVCXPRT_LIST *l; 98 99 if ((l = malloc(sizeof (*l))) == NULL) 100 return (FALSE); 101 l->xprt = xprt; 102 if (lockp != NULL) 103 (void) mutex_lock(lockp); 104 l->next = *list; 105 *list = l; 106 if (lockp != NULL) 107 (void) mutex_unlock(lockp); 108 return (TRUE); 109 } 110 111 void 112 __svc_rm_from_xlist(SVCXPRT_LIST **list, SVCXPRT *xprt, mutex_t *lockp) 113 { 114 SVCXPRT_LIST **l, *tmp; 115 116 if (lockp != NULL) 117 (void) mutex_lock(lockp); 118 for (l = list; *l != NULL; l = &(*l)->next) { 119 if ((*l)->xprt == xprt) { 120 tmp = (*l)->next; 121 free(*l); 122 *l = tmp; 123 break; 124 } 125 } 126 if (lockp != NULL) 127 (void) mutex_unlock(lockp); 128 } 129 130 void 131 __svc_free_xlist(SVCXPRT_LIST **list, mutex_t *lockp) 132 { 133 SVCXPRT_LIST *tmp; 134 135 if (lockp != NULL) 136 (void) mutex_lock(lockp); 137 while (*list != NULL) { 138 tmp = (*list)->next; 139 free(*list); 140 *list = tmp; 141 } 142 if (lockp != NULL) 143 (void) mutex_unlock(lockp); 144 } 145 146 /* 147 * Destroy all door based service handles. 148 */ 149 void 150 __svc_cleanup_door_xprts(void) 151 { 152 SVCXPRT_LIST *l, *tmp = NULL; 153 154 (void) mutex_lock(&svc_door_mutex); 155 for (l = dxlist; l != NULL; l = tmp) { 156 tmp = l->next; 157 svc_door_destroy_pvt(l->xprt); 158 } 159 (void) mutex_unlock(&svc_door_mutex); 160 } 161 162 static bool_t 163 make_tmp_dir(void) 164 { 165 struct stat statbuf; 166 167 if (stat(RPC_DOOR_DIR, &statbuf) < 0) { 168 (void) mkdir(RPC_DOOR_DIR, (mode_t)0755); 169 (void) chmod(RPC_DOOR_DIR, (mode_t)01777); 170 if (stat(RPC_DOOR_DIR, &statbuf) < 0) 171 return (FALSE); 172 } 173 return ((statbuf.st_mode & S_IFMT) == S_IFDIR && 174 (statbuf.st_mode & 01777) == 01777); 175 } 176 177 static void 178 svc_door_dispatch(SVCXPRT *xprt, struct rpc_msg *msg, struct svc_req *r) 179 { 180 enum auth_stat why; 181 /* LINTED pointer alignment */ 182 struct svc_door_data *su = su_data(xprt); 183 bool_t nd; 184 185 r->rq_xprt = xprt; 186 r->rq_prog = msg->rm_call.cb_prog; 187 r->rq_vers = msg->rm_call.cb_vers; 188 r->rq_proc = msg->rm_call.cb_proc; 189 r->rq_cred = msg->rm_call.cb_cred; 190 191 if (msg->rm_call.cb_cred.oa_flavor == AUTH_NULL) { 192 r->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; 193 r->rq_xprt->xp_verf.oa_length = 0; 194 195 } else if ((why = __gss_authenticate(r, msg, &nd)) != AUTH_OK) { 196 svcerr_auth(xprt, why); 197 return; 198 } 199 200 if (su->call_info.prognum == r->rq_prog && su->call_info.versnum == 201 r->rq_vers) { 202 (*su->call_info.dispatch)(r, xprt); 203 return; 204 } 205 206 /* 207 * if we got here, the program or version 208 * is not served ... 209 */ 210 if (su->call_info.prognum == r->rq_prog) 211 svcerr_progvers(xprt, su->call_info.versnum, 212 su->call_info.versnum); 213 else 214 svcerr_noprog(xprt); 215 } 216 217 /* 218 * This is the door server procedure. 219 */ 220 /* ARGSUSED */ 221 static void 222 door_server(void *cookie, char *argp, size_t arg_size, 223 door_desc_t *dp, uint_t n_did) 224 { 225 SVCXPRT *parent = (SVCXPRT *)cookie; 226 SVCXPRT *xprt; 227 struct rpc_msg *msg; 228 struct svc_req *r; 229 char *cred_area; 230 char *result_buf; 231 int len; 232 struct svc_door_data *su; 233 234 /* 235 * allocate result buffer 236 */ 237 /* LINTED pointer alignment */ 238 result_buf = alloca(su_data(parent)->su_iosz); 239 if (result_buf == NULL) { 240 (void) syslog(LOG_ERR, "door_server: alloca failed"); 241 (void) door_return(NULL, 0, NULL, 0); 242 /*NOTREACHED*/ 243 } 244 245 (void) mutex_lock(&svc_door_mutex); 246 if ((xprt = get_xprt_copy(parent, result_buf)) == NULL) { 247 (void) syslog(LOG_ERR, 248 "door_server: memory allocation failure"); 249 (void) mutex_unlock(&svc_door_mutex); 250 (void) door_return(NULL, 0, NULL, 0); 251 /*NOTREACHED*/ 252 } 253 (void) mutex_unlock(&svc_door_mutex); 254 255 /* LINTED pointer alignment */ 256 msg = SVCEXT(xprt)->msg; 257 /* LINTED pointer alignment */ 258 r = SVCEXT(xprt)->req; 259 /* LINTED pointer alignment */ 260 cred_area = SVCEXT(xprt)->cred_area; 261 262 msg->rm_call.cb_cred.oa_base = cred_area; 263 msg->rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); 264 r->rq_clntcred = &(cred_area[2 * MAX_AUTH_BYTES]); 265 266 /* LINTED pointer alignment */ 267 su = su_data(xprt); 268 su->argbuf = argp; 269 su->arglen = arg_size; 270 271 if (svc_door_recv(xprt, msg)) 272 svc_door_dispatch(xprt, msg, r); 273 274 if ((len = return_xprt_copy(xprt)) > 0) { 275 (void) door_return(result_buf, (size_t)len, NULL, 0); 276 /*NOTREACHED*/ 277 } else { 278 (void) door_return(NULL, 0, NULL, 0); 279 /*NOTREACHED*/ 280 } 281 } 282 283 /* 284 * Usage: 285 * xprt = svc_door_create(dispatch, prognum, versnum, sendsize); 286 * Once *xprt is initialized, it is registered. 287 * see (svc.h, xprt_register). If recvsize or sendsize are 0 suitable 288 * system defaults are chosen. 289 * The routines returns NULL if a problem occurred. 290 */ 291 292 void 293 svc_door_xprtfree(SVCXPRT *xprt) 294 { 295 /* LINTED pointer alignment */ 296 struct svc_door_data *su = xprt ? su_data(xprt) : NULL; 297 298 if (xprt == NULL) 299 return; 300 if (xprt->xp_netid) 301 free(xprt->xp_netid); 302 if (xprt->xp_tp) 303 free(xprt->xp_tp); 304 if (su != NULL) 305 free(su); 306 svc_xprt_free(xprt); 307 } 308 309 SVCXPRT * 310 svc_door_create(void (*dispatch)(), const rpcprog_t prognum, 311 const rpcvers_t versnum, const uint_t sendsize) 312 { 313 SVCXPRT *xprt; 314 struct svc_door_data *su = NULL; 315 char rendezvous[128] = ""; 316 int fd; 317 int did = -1; 318 mode_t mask; 319 uint_t ssize; 320 321 (void) mutex_lock(&svc_door_mutex); 322 323 if (!make_tmp_dir()) { 324 (void) syslog(LOG_ERR, "svc_door_create: cannot open %s", 325 RPC_DOOR_DIR); 326 (void) mutex_unlock(&svc_door_mutex); 327 return (NULL); 328 } 329 330 if ((xprt = svc_xprt_alloc()) == NULL) { 331 (void) syslog(LOG_ERR, "svc_door_create: out of memory"); 332 goto freedata; 333 } 334 /* LINTED pointer alignment */ 335 svc_flags(xprt) |= SVC_DOOR; 336 337 (void) sprintf(rendezvous, RPC_DOOR_RENDEZVOUS, (int)prognum, 338 (int)versnum); 339 mask = umask(0); 340 fd = open(rendezvous, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0644); 341 (void) umask(mask); 342 if (fd < 0) { 343 if (errno == EEXIST) { 344 if (unlink(rendezvous) < 0) { 345 (void) syslog(LOG_ERR, 346 "svc_door_create: %s %s:%m", rendezvous, 347 "exists and could not be removed"); 348 goto freedata; 349 } 350 mask = umask(0); 351 fd = open(rendezvous, O_WRONLY|O_CREAT|O_EXCL| 352 O_TRUNC, 0644); 353 (void) umask(mask); 354 if (fd < 0) { 355 (void) syslog(LOG_ERR, 356 "svc_door_create: %s %s:%m", 357 "could not create", rendezvous); 358 goto freedata; 359 } 360 } else { 361 (void) syslog(LOG_ERR, 362 "svc_door_create: could not create %s:%m", 363 rendezvous); 364 goto freedata; 365 } 366 } 367 (void) close(fd); 368 did = door_create(door_server, (void *)xprt, DOOR_REFUSE_DESC); 369 if (did < 0) { 370 (void) syslog(LOG_ERR, 371 "svc_door_create: door_create failed: %m"); 372 goto freedata; 373 } 374 375 if (fattach(did, rendezvous) < 0) { 376 if (errno != EBUSY || fdetach(rendezvous) < 0 || 377 fattach(did, rendezvous) < 0) { 378 (void) syslog(LOG_ERR, 379 "svc_door_create: fattach failed: %m"); 380 goto freedata; 381 } 382 } 383 384 /* 385 * Determine send size 386 */ 387 if (sendsize < __rpc_min_door_buf_size) 388 ssize = __rpc_default_door_buf_size; 389 else 390 ssize = RNDUP(sendsize); 391 392 su = malloc(sizeof (*su)); 393 if (su == NULL) { 394 (void) syslog(LOG_ERR, "svc_door_create: out of memory"); 395 goto freedata; 396 } 397 su->su_iosz = ssize; 398 su->call_info.prognum = prognum; 399 su->call_info.versnum = versnum; 400 su->call_info.dispatch = dispatch; 401 402 xprt->xp_p2 = (caddr_t)su; 403 xprt->xp_verf.oa_base = su->su_verfbody; 404 xprt->xp_ops = svc_door_ops(); 405 xprt->xp_netid = strdup("door"); 406 if (xprt->xp_netid == NULL) { 407 syslog(LOG_ERR, "svc_door_create: strdup failed"); 408 goto freedata; 409 } 410 xprt->xp_tp = strdup(rendezvous); 411 if (xprt->xp_tp == NULL) { 412 syslog(LOG_ERR, "svc_door_create: strdup failed"); 413 goto freedata; 414 } 415 xprt->xp_fd = did; 416 417 svc_ndoorfds++; 418 if (!__svc_add_to_xlist(&dxlist, xprt, NULL)) { 419 420 (void) syslog(LOG_ERR, "svc_door_create: out of memory"); 421 goto freedata; 422 } 423 (void) mutex_unlock(&svc_door_mutex); 424 return (xprt); 425 freedata: 426 (void) fdetach(rendezvous); 427 (void) unlink(rendezvous); 428 if (did >= 0) 429 (void) door_revoke(did); 430 if (xprt) 431 svc_door_xprtfree(xprt); 432 (void) mutex_unlock(&svc_door_mutex); 433 return (NULL); 434 } 435 436 437 static SVCXPRT * 438 svc_door_xprtcopy(SVCXPRT *parent) 439 { 440 SVCXPRT *xprt; 441 struct svc_door_data *su; 442 443 if ((xprt = svc_xprt_alloc()) == NULL) 444 return (NULL); 445 446 /* LINTED pointer alignment */ 447 SVCEXT(xprt)->parent = parent; 448 /* LINTED pointer alignment */ 449 SVCEXT(xprt)->flags = SVCEXT(parent)->flags; 450 451 xprt->xp_fd = parent->xp_fd; 452 xprt->xp_port = parent->xp_port; 453 xprt->xp_ops = svc_door_ops(); 454 if (parent->xp_tp) { 455 xprt->xp_tp = (char *)strdup(parent->xp_tp); 456 if (xprt->xp_tp == NULL) { 457 syslog(LOG_ERR, "svc_door_xprtcopy: strdup failed"); 458 svc_door_xprtfree(xprt); 459 return (NULL); 460 } 461 } 462 if (parent->xp_netid) { 463 xprt->xp_netid = (char *)strdup(parent->xp_netid); 464 if (xprt->xp_netid == NULL) { 465 syslog(LOG_ERR, "svc_door_xprtcopy: strdup failed"); 466 if (parent->xp_tp) 467 free(parent->xp_tp); 468 svc_door_xprtfree(xprt); 469 return (NULL); 470 } 471 } 472 xprt->xp_type = parent->xp_type; 473 474 if ((su = malloc(sizeof (struct svc_door_data))) == NULL) { 475 svc_door_xprtfree(xprt); 476 return (NULL); 477 } 478 /* LINTED pointer alignment */ 479 su->su_iosz = su_data(parent)->su_iosz; 480 /* LINTED pointer alignment */ 481 su->call_info = su_data(parent)->call_info; 482 483 xprt->xp_p2 = (caddr_t)su; /* su_data(xprt) = su */ 484 xprt->xp_verf.oa_base = su->su_verfbody; 485 486 return (xprt); 487 } 488 489 490 static SVCXPRT * 491 get_xprt_copy(SVCXPRT *parent, char *buf) 492 { 493 /* LINTED pointer alignment */ 494 SVCXPRT_LIST *xlist = SVCEXT(parent)->my_xlist; 495 SVCXPRT_LIST *xret; 496 SVCXPRT *xprt; 497 struct svc_door_data *su; 498 499 xret = xlist->next; 500 if (xret) { 501 xlist->next = xret->next; 502 xret->next = NULL; 503 xprt = xret->xprt; 504 /* LINTED pointer alignment */ 505 svc_flags(xprt) = svc_flags(parent); 506 } else 507 xprt = svc_door_xprtcopy(parent); 508 509 if (xprt) { 510 /* LINTED pointer alignment */ 511 SVCEXT(parent)->refcnt++; 512 /* LINTED pointer alignment */ 513 su = su_data(xprt); 514 su->buf = buf; 515 su->len = 0; 516 } 517 return (xprt); 518 } 519 520 int 521 return_xprt_copy(SVCXPRT *xprt) 522 { 523 SVCXPRT *parent; 524 SVCXPRT_LIST *xhead, *xlist; 525 /* LINTED pointer alignment */ 526 int len = su_data(xprt)->len; 527 528 (void) mutex_lock(&svc_door_mutex); 529 /* LINTED pointer alignment */ 530 if ((parent = SVCEXT(xprt)->parent) == NULL) { 531 (void) mutex_unlock(&svc_door_mutex); 532 return (0); 533 } 534 /* LINTED pointer alignment */ 535 xhead = SVCEXT(parent)->my_xlist; 536 /* LINTED pointer alignment */ 537 xlist = SVCEXT(xprt)->my_xlist; 538 xlist->next = xhead->next; 539 xhead->next = xlist; 540 /* LINTED pointer alignment */ 541 SVCEXT(parent)->refcnt--; 542 543 /* 544 * Propagate any error flags. This is done in both directions to 545 * ensure that if one child gets an error, everyone will see it 546 * (even if there are multiple outstanding children) and the 547 * door will get closed. 548 */ 549 /* LINTED pointer alignment */ 550 svc_flags(xprt) |= svc_flags(parent); 551 /* LINTED pointer alignment */ 552 if (svc_defunct(xprt)) { 553 /* LINTED pointer alignment */ 554 svc_flags(parent) |= SVC_DEFUNCT; 555 /* LINTED pointer cast */ 556 if (SVCEXT(parent)->refcnt == 0) 557 svc_door_destroy(xprt); 558 } 559 (void) mutex_unlock(&svc_door_mutex); 560 return (len); 561 } 562 563 /* ARGSUSED */ 564 static enum xprt_stat 565 svc_door_stat(SVCXPRT *xprt) 566 { 567 return (XPRT_IDLE); 568 } 569 570 static bool_t 571 svc_door_recv(SVCXPRT *xprt, struct rpc_msg *msg) 572 { 573 /* LINTED pointer alignment */ 574 struct svc_door_data *su = su_data(xprt); 575 XDR *xdrs = &(su->su_xdrs); 576 577 xdrmem_create(xdrs, su->argbuf, su->arglen, XDR_DECODE); 578 if (!xdr_callmsg(xdrs, msg)) 579 return (FALSE); 580 su->su_xid = msg->rm_xid; 581 return (TRUE); 582 } 583 584 static bool_t 585 svc_door_reply(SVCXPRT *xprt, struct rpc_msg *msg) 586 { 587 /* LINTED pointer alignment */ 588 struct svc_door_data *su = su_data(xprt); 589 XDR *xdrs = &(su->su_xdrs); 590 591 xdrmem_create(xdrs, su->buf, su->su_iosz, XDR_ENCODE); 592 msg->rm_xid = su->su_xid; 593 if (xdr_replymsg(xdrs, msg)) { 594 su->len = (int)XDR_GETPOS(xdrs); 595 return (TRUE); 596 } 597 return (FALSE); 598 } 599 600 static bool_t 601 svc_door_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) 602 { 603 /* LINTED pointer alignment */ 604 return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr)); 605 } 606 607 static bool_t 608 svc_door_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr) 609 { 610 /* LINTED pointer alignment */ 611 XDR *xdrs = &(su_data(xprt)->su_xdrs); 612 613 xdrs->x_op = XDR_FREE; 614 return ((*xdr_args)(xdrs, args_ptr)); 615 } 616 617 static void 618 svc_door_destroy(SVCXPRT *xprt) 619 { 620 (void) mutex_lock(&svc_door_mutex); 621 svc_door_destroy_pvt(xprt); 622 (void) mutex_unlock(&svc_door_mutex); 623 } 624 625 static void 626 svc_door_destroy_pvt(SVCXPRT *xprt) 627 { 628 /* LINTED pointer alignment */ 629 if (SVCEXT(xprt)->parent) 630 /* LINTED pointer alignment */ 631 xprt = SVCEXT(xprt)->parent; 632 /* LINTED pointer alignment */ 633 svc_flags(xprt) |= SVC_DEFUNCT; 634 /* LINTED pointer alignment */ 635 if (SVCEXT(xprt)->refcnt > 0) 636 return; 637 638 __svc_rm_from_xlist(&dxlist, xprt, NULL); 639 640 if (xprt->xp_tp) { 641 (void) fdetach(xprt->xp_tp); 642 (void) unlink(xprt->xp_tp); 643 } 644 (void) door_revoke(xprt->xp_fd); 645 646 svc_xprt_destroy(xprt); 647 if (--svc_ndoorfds == 0) 648 /* wake up door dispatching */ 649 (void) cond_signal(&svc_door_waitcv); 650 } 651 652 /* ARGSUSED */ 653 static bool_t 654 svc_door_control(SVCXPRT *xprt, const uint_t rq, void *in) 655 { 656 extern int __rpc_legal_connmaxrec(int); 657 658 size_t door_param; 659 int tmp; 660 661 switch (rq) { 662 case SVCSET_CONNMAXREC: 663 tmp = __rpc_legal_connmaxrec(*(int *)in); 664 if (tmp >= 0) { 665 door_param = (tmp == 0)? SIZE_MAX : 666 (size_t)(ssize_t)tmp; 667 if (door_setparam(xprt->xp_fd, DOOR_PARAM_DATA_MAX, 668 door_param) == 0) 669 return (TRUE); 670 return (FALSE); 671 } 672 return (FALSE); 673 case SVCGET_CONNMAXREC: 674 if (door_getparam(xprt->xp_fd, DOOR_PARAM_DATA_MAX, 675 &door_param) == 0) { 676 if (door_param == SIZE_MAX) 677 tmp = 0; 678 else if (door_param > INT_MAX) 679 tmp = INT_MAX; 680 else if (door_param > 0) 681 tmp = (int)door_param; 682 else 683 return (FALSE); 684 685 *(int *)in = tmp; 686 return (TRUE); 687 } 688 return (FALSE); 689 } 690 return (FALSE); 691 } 692 693 static struct xp_ops * 694 svc_door_ops(void) 695 { 696 static struct xp_ops ops; 697 extern mutex_t ops_lock; 698 699 (void) mutex_lock(&ops_lock); 700 if (ops.xp_recv == NULL) { 701 ops.xp_recv = svc_door_recv; 702 ops.xp_stat = svc_door_stat; 703 ops.xp_getargs = svc_door_getargs; 704 ops.xp_reply = svc_door_reply; 705 ops.xp_freeargs = svc_door_freeargs; 706 ops.xp_destroy = svc_door_destroy; 707 ops.xp_control = svc_door_control; 708 } 709 (void) mutex_unlock(&ops_lock); 710 return (&ops); 711 } 712 713 /* 714 * Return door credentials. 715 */ 716 /* ARGSUSED */ 717 bool_t 718 __svc_get_door_cred(SVCXPRT *xprt, svc_local_cred_t *lcred) 719 { 720 door_cred_t dc; 721 722 if (door_cred(&dc) < 0) 723 return (FALSE); 724 lcred->euid = dc.dc_euid; 725 lcred->egid = dc.dc_egid; 726 lcred->ruid = dc.dc_ruid; 727 lcred->rgid = dc.dc_rgid; 728 lcred->pid = dc.dc_pid; 729 return (TRUE); 730 } 731 732 /* ARGSUSED */ 733 bool_t 734 __svc_get_door_ucred(const SVCXPRT *xprt, ucred_t *ucp) 735 { 736 return (door_ucred(&ucp) == 0); 737 } 738