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