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