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