1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME: 80** 81** comsoc.c 82** 83** FACILITY: 84** 85** Remote Procedure Call (RPC) 86** 87** ABSTRACT: 88** 89** Veneer over the BSD socket abstraction not provided by the old sock_ 90** or new rpc_{tower,addr}_ components. 91** 92** 93*/ 94 95#include <config.h> 96#include <dce/lrpc.h> 97#include <commonp.h> 98#include <com.h> 99#include <comprot.h> 100#include <comnaf.h> 101#include <comp.h> 102#include <comsoc_bsd.h> 103#include <fcntl.h> 104#include <sys/un.h> 105#include <sys/types.h> 106#include <sys/stat.h> 107#include <sys/param.h> 108#include <sys/socket.h> 109#include <cnp.h> 110 111#if HAVE_LW_BASE_H 112#include <lw/base.h> 113#endif 114 115#if HAVE_LWMAPSECURITY_LWMAPSECURITY_H 116#include <lwmapsecurity/lwmapsecurity.h> 117#endif 118 119/* Bizarre hack for HP-UX ia64 where a system header 120 * makes reference to a kernel-only data structure 121 */ 122#if defined(__hpux) && defined(__ia64) 123union mpinfou {}; 124#endif 125#include <net/if.h> 126#include <sys/ioctl.h> 127/* Hack to ensure we actually get a definition of ioctl on AIX */ 128#if defined(_AIX) && defined(_BSD) 129int ioctl(int d, int request, ...); 130#endif 131#include <unistd.h> 132#ifdef HAVE_SYS_SOCKIO_H 133#include <sys/sockio.h> /* Not just Linux */ 134#endif 135 136/*#include <dce/cma_ux_wrappers.h>*/ 137 138/* ======================================================================== */ 139 140/* 141 * What we think a socket's buffering is in case rpc__socket_set_bufs() 142 * fails miserably. The #ifndef is here so that these values can be 143 * overridden in a per-system file. 144 */ 145 146#ifndef RPC_C_SOCKET_GUESSED_RCVBUF 147# define RPC_C_SOCKET_GUESSED_RCVBUF (4 * 1024) 148#endif 149 150#ifndef RPC_C_SOCKET_GUESSED_SNDBUF 151# define RPC_C_SOCKET_GUESSED_SNDBUF (4 * 1024) 152#endif 153 154/* 155 * Maximum send and receive buffer sizes. The #ifndef is here so that 156 * these values can be overridden in a per-system file. 157 */ 158 159#ifndef RPC_C_SOCKET_MAX_RCVBUF 160# define RPC_C_SOCKET_MAX_RCVBUF (64 * 1024) 161#endif 162 163#ifndef RPC_C_SOCKET_MAX_SNDBUF 164# define RPC_C_SOCKET_MAX_SNDBUF (64 * 1024) 165#endif 166 167/* 168 * The RPC_SOCKET_DISABLE_CANCEL/RPC_SOCKET_RESTORE_CANCEL macros 169 * are used to disable cancellation before entering library calls 170 * which were non-cancelable under CMA threads but are generally 171 * cancelable on modern POSIX systems. 172 */ 173#define RPC_SOCKET_DISABLE_CANCEL { int __cs = dcethread_enableinterrupt_throw(0); 174#define RPC_SOCKET_RESTORE_CANCEL dcethread_enableinterrupt_throw(__cs); } 175 176/* 177 * Macros to paper over the difference between the 4.4bsd and 4.3bsd 178 * socket API. 179 * 180 * The layout of a 4.4 struct sockaddr includes a 1 byte "length" field 181 * which used to be one of the bytes of the "family" field. (The "family" 182 * field is now 1 byte instead of 2 bytes.) 4.4 provides binary 183 * compatibility with applications compiled with a 4.3 sockaddr definition 184 * by inferring a default length when the supplied length is zero. Source 185 * compatibility is blown however (if _SOCKADDR_LEN is #define'd) -- 186 * applications that assign only to the "family" field will leave the 187 * "length" field possibly non-zero. 188 * 189 * Note that RPC's "sockaddr_t" is always defined to contains only a 190 * family. (We defined "rpc_addr_t" to be a struct that contains a length 191 * and a sockaddr rather than mucking with the sockaddr itself.) We 192 * assumed that "sockaddr_t" and "struct sockaddr" are the same. At 193 * 4.4, this assumption caused problems. We use RPC_SOCKET_FIX_ADDRLEN 194 * at various opportunities to make sure sockaddrs' length is zero and 195 * that makes the problems go away. 196 * 197 * ADDENDUM: 198 * This only makes the problem go away on little-endian systems 199 * where the length field on the 4.4 struct occupies the same position 200 * as the high byte of the family field on the 4.3 struct. This is 201 * no good for i386 FreeBSD, so we have actually adapted sockaddr_t 202 * to match the system struct sockaddr. 203 * -- Brian Koropoff, Likewise 204 * 205 * RPC_SOCKET_FIX_ADDRLEN takes an "rpc_addr_p_t" (or "rpc_ip_addr_p_t") 206 * as input. The complicated casting (as opposed to simply setting 207 * ".sa_len" to zero) is to ensure that the right thing happens regardless 208 * of the integer endian-ness of the system). 209 * 210 * RPC_SOCKET_INIT_MGRHDR deals with the differences in the field names of 211 * the "struct msghdr" data type between 4.3 and 4.4. 212 */ 213 214#ifdef BSD_4_4_SOCKET 215#define RPC_SOCKET_INIT_MSGHDR(msgp) ( \ 216 (msgp)->msg_control = NULL, \ 217 (msgp)->msg_controllen = 0, \ 218 (msgp)->msg_flags = 0 \ 219) 220#else 221#define RPC_SOCKET_INIT_MSGHDR(msgp) ( \ 222 (msgp)->msg_accrights = NULL, \ 223 (msgp)->msg_accrightslen = 0 \ 224) 225#endif /* BSD_4_4_SOCKET */ 226 227/*#if defined(_SOCKADDR_LEN) 228#define RPC_SOCKET_FIX_ADDRLEN(addrp) ( \ 229 ((struct osockaddr *) &(addrp)->sa)->sa_family = \ 230 ((struct sockaddr *) &(addrp)->sa)->sa_family \ 231 ) 232 #else*/ 233#define RPC_SOCKET_FIX_ADDRLEN(addrp) do { } while (0) 234/*#endif*/ 235 236#ifndef CMSG_ALIGN 237#if defined(_CMSG_DATA_ALIGN) 238#define CMSG_ALIGN _CMSG_DATA_ALIGN 239 240#elif defined(_CMSG_ALIGN) 241#define CMSG_ALIGN _CMSG_ALIGN 242 243#elif defined(__DARWIN_ALIGN32) 244#define CMSG_ALIGN __DARWIN_ALIGN32 245 246#elif defined(ALIGN) 247#define CMSG_ALIGN ALIGN 248#endif 249#endif /* CMSG_ALIGN */ 250 251#ifndef CMSG_SPACE 252#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len)) 253#endif 254 255#ifndef CMSG_LEN 256#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) 257#endif 258 259/* 260 * BSD socket transport layer info structures 261 */ 262typedef struct rpc_bsd_transport_info_s 263{ 264 uid_t peer_uid; 265 gid_t peer_gid; 266} rpc_bsd_transport_info_t, *rpc_bsd_transport_info_p_t; 267 268typedef struct rpc_bsd_socket_s 269{ 270 int fd; 271 rpc_bsd_transport_info_t info; 272} rpc_bsd_socket_t, *rpc_bsd_socket_p_t; 273 274INTERNAL rpc_socket_error_t 275rpc__bsd_socket_set_default_options ( 276 rpc_socket_basic_t sockfd) 277{ 278#ifdef SO_NOSIGPIPE 279 int on = 1; 280 281 /* Set SO_NOSIGPIPE on the socket */ 282 if (setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof (on)) == -1) { 283 return errno; 284 } 285#endif 286 return RPC_C_SOCKET_OK; 287} 288 289INTERNAL rpc_socket_error_t rpc__bsd_socket_destruct 290( 291 rpc_socket_t sock 292); 293 294INTERNAL rpc_socket_error_t rpc__bsd_socket_construct( 295 rpc_socket_t sock, 296 rpc_protseq_id_t pseq_id, 297 rpc_transport_info_handle_t info 298); 299 300/* ======================================================================== */ 301/* 302 * R P C _ _ S O C K E T _ D U P L I C A T E 303 * 304 * Wrap the native socket representation in a rpc_socket_t. We duplicate the 305 * socket file descriptor because we will eventually end up close(2)ing it. 306 */ 307 308INTERNAL rpc_socket_error_t 309rpc__bsd_socket_duplicate( 310 rpc_socket_t sock, 311 rpc_protseq_id_t pseq_id ATTRIBUTE_UNUSED, 312 const void * sockrep /* pointer to native representation */ 313 ) 314{ 315 rpc_socket_error_t serr; 316 rpc_bsd_socket_p_t lrpc; 317 const int * sockfd = (const int *)sockrep; 318 319 if (sockfd == NULL || *sockfd == -1) { 320 return RPC_C_SOCKET_ENOTSOCK; 321 } 322 323 if (sock->pseq_id != pseq_id) { 324 return RPC_C_SOCKET_EINVAL; 325 } 326 327 serr = rpc__bsd_socket_destruct(sock); 328 if (serr != RPC_C_SOCKET_OK) { 329 return serr; 330 } 331 332 serr = rpc__bsd_socket_construct(sock, pseq_id, NULL); 333 if (serr != RPC_C_SOCKET_OK) { 334 return serr; 335 } 336 337 lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 338 339 RPC_SOCKET_DISABLE_CANCEL; 340 341 if (lrpc->fd != -1) { 342 close(lrpc->fd); 343 } 344 345 lrpc->fd = dup(*sockfd); 346 347 serr = ((lrpc->fd == -1) ? errno : RPC_C_SOCKET_OK); 348 if (serr != RPC_C_SOCKET_OK) { 349 goto error; 350 } 351 352 serr = rpc__bsd_socket_set_default_options(lrpc->fd); 353 if (serr != RPC_C_SOCKET_OK) { 354 goto error; 355 } 356 357 RPC_SOCKET_RESTORE_CANCEL; 358 359 return RPC_C_SOCKET_OK; 360 361error: 362 rpc__bsd_socket_destruct(sock); 363 return serr; 364} 365 366/* 367 * R P C _ _ S O C K E T _ C O N S T R U C T 368 * 369 * Create a new socket for the specified Protocol Sequence. 370 * The new socket has blocking IO semantics. 371 * 372 * (see BSD UNIX socket(2)). 373 */ 374 375INTERNAL rpc_socket_error_t 376rpc__bsd_socket_construct( 377 rpc_socket_t sock, 378 rpc_protseq_id_t pseq_id, 379 rpc_transport_info_handle_t info ATTRIBUTE_UNUSED 380 ) 381{ 382 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 383 rpc_bsd_socket_p_t lrpc = NULL; 384 385 /* set data.point to be 0 in case we get an error 386 and have to call rpc__bsd_socket_destruct */ 387 sock->data.pointer = NULL; 388 389 lrpc = calloc(1, sizeof(*lrpc)); 390 391 if (!lrpc) 392 { 393 serr = ENOMEM; 394 goto error; 395 } 396 397 sock->data.pointer = (void*) lrpc; 398 399 lrpc->fd = -1; 400 lrpc->info.peer_uid = -1; 401 lrpc->info.peer_gid = -1; 402 403 RPC_SOCKET_DISABLE_CANCEL; 404 lrpc->fd = socket( 405 (int) RPC_PROTSEQ_INQ_NAF_ID(pseq_id), 406 (int) RPC_PROTSEQ_INQ_NET_IF_ID(pseq_id), 407 0 /*(int) RPC_PROTSEQ_INQ_NET_PROT_ID(pseq_id)*/); 408 serr = ((lrpc->fd == -1) ? errno : RPC_C_SOCKET_OK); 409 410 if (serr == RPC_C_SOCKET_OK) { 411 serr = rpc__bsd_socket_set_default_options(lrpc->fd); 412 if (serr != RPC_C_SOCKET_OK) 413 close (lrpc->fd); 414 } 415 RPC_SOCKET_RESTORE_CANCEL; 416 417 if (serr) 418 { 419 goto error; 420 } 421 422done: 423 return serr; 424 425error: 426 if (lrpc) 427 { 428 rpc__bsd_socket_destruct(sock); 429 } 430 431 goto done; 432} 433 434/* 435 * R P C _ _ S O C K E T _ O P E N _ B A S I C 436 * 437 * A special version of socket_open that is used *only* by 438 * the low level initialization code when it is trying to 439 * determine what network services are supported by the host OS. 440 */ 441 442PRIVATE rpc_socket_error_t 443rpc__bsd_socket_open_basic( 444 rpc_naf_id_t naf, 445 rpc_network_if_id_t net_if, 446 rpc_network_protocol_id_t net_prot ATTRIBUTE_UNUSED, 447 rpc_socket_basic_t *sock 448 ) 449{ 450 rpc_socket_error_t serr; 451 452 /* 453 * Always pass zero as socket protocol to compensate for 454 * overloading the protocol field for named pipes 455 */ 456 RPC_SOCKET_DISABLE_CANCEL; 457 *sock = socket((int) naf, (int) net_if, 0); 458 serr = ((*sock == -1) ? errno : RPC_C_SOCKET_OK); 459 460 if (serr == RPC_C_SOCKET_OK) { 461 serr = rpc__bsd_socket_set_default_options(*sock); 462 if (serr != RPC_C_SOCKET_OK) 463 close (*sock); 464 } 465 RPC_SOCKET_RESTORE_CANCEL; 466 467 return serr; 468} 469 470PRIVATE rpc_socket_error_t 471rpc__bsd_socket_close_basic( 472 rpc_socket_basic_t sock 473 ) 474{ 475 rpc_socket_error_t serr; 476 477 RPC_LOG_SOCKET_CLOSE_NTR; 478 RPC_SOCKET_DISABLE_CANCEL; 479 serr = (close(sock) == -1) ? errno : RPC_C_SOCKET_OK; 480 RPC_SOCKET_RESTORE_CANCEL; 481 RPC_LOG_SOCKET_CLOSE_XIT; 482 483 return (serr); 484} 485 486 487/* 488 * R P C _ _ S O C K E T _ C L O S E 489 * 490 * Close (destroy) a socket. 491 * 492 * (see BSD UNIX close(2)). 493 */ 494 495INTERNAL rpc_socket_error_t rpc__bsd_socket_destruct 496( 497 rpc_socket_t sock 498) 499{ 500 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 501 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 502 503 if (lrpc && lrpc->fd > 0) 504 { 505 506 RPC_LOG_SOCKET_CLOSE_NTR; 507 RPC_SOCKET_DISABLE_CANCEL; 508 serr = (close(lrpc->fd) == -1) ? errno : RPC_C_SOCKET_OK; 509 RPC_SOCKET_RESTORE_CANCEL; 510 RPC_LOG_SOCKET_CLOSE_XIT; 511 } 512 513 if (lrpc) 514 { 515 free(lrpc); 516 sock->data.pointer = NULL; 517 } 518 519 return serr; 520} 521 522/* 523 * R P C _ _ S O C K E T _ B I N D 524 * 525 * Bind a socket to a specified local address. 526 * 527 * (see BSD UNIX bind(2)). 528 */ 529 530INTERNAL rpc_socket_error_t rpc__bsd_socket_bind 531( 532 rpc_socket_t sock, 533 rpc_addr_p_t addr 534) 535{ 536 rpc_socket_error_t serr = EINVAL; 537 unsigned32 status; 538 rpc_addr_p_t temp_addr = NULL; 539 boolean has_endpoint = false; 540 int setsock_val = 1; 541 int ncalrpc; 542 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 543 544 RPC_LOG_SOCKET_BIND_NTR; 545 546 ncalrpc = addr->rpc_protseq_id == rpc_c_protseq_id_ncalrpc; 547 548 /* 549 * Check if the address has a well-known endpoint. 550 */ 551 if (addr->rpc_protseq_id == rpc_c_protseq_id_ncacn_ip_tcp || ncalrpc) 552 { 553 unsigned_char_t *endpoint; 554 555 rpc__naf_addr_inq_endpoint (addr, &endpoint, &status); 556 557 if (status == rpc_s_ok && endpoint != NULL) 558 { 559 if (endpoint[0] != '\0') /* test for null string */ 560 has_endpoint = true; 561 562 rpc_string_free (&endpoint, &status); 563 } 564 status = rpc_s_ok; 565 } 566 567 /* 568 * If there is no port restriction in this address family, then do a 569 * simple bind. 570 */ 571 572 if (! RPC_PROTSEQ_TEST_PORT_RESTRICTION (addr -> rpc_protseq_id)) 573 { 574 if (!has_endpoint && ncalrpc) 575 { 576 serr = 0; 577 } 578 else 579 { 580#if defined(SOL_SOCKET) && defined(SO_REUSEADDR) 581 setsockopt(lrpc->fd, SOL_SOCKET, SO_REUSEADDR, 582 &setsock_val, sizeof(setsock_val)); 583#endif 584 if (addr->sa.family == AF_UNIX && addr->sa.data[0] != '\0') 585 { 586 // This function is going to bind a named socket. First, try 587 // to delete the path incase a previous instance of a program 588 // left it behind. 589 // 590 // Ignore any errors from this function. 591 unlink((const char*)addr->sa.data); 592 } 593 serr = 594 (bind(lrpc->fd, (struct sockaddr *)&addr->sa, addr->len) == -1) ? 595 errno : RPC_C_SOCKET_OK; 596 } 597 } /* no port restriction */ 598 599 else 600 { 601 /* 602 * Port restriction is in place. If the address has a well-known 603 * endpoint, then do a simple bind. 604 */ 605 606 if (has_endpoint) 607 { 608#if defined(SOL_SOCKET) && defined(SO_REUSEADDR) 609 setsockopt(lrpc->fd, SOL_SOCKET, SO_REUSEADDR, 610 &setsock_val, sizeof(setsock_val)); 611#endif 612 serr = (bind(lrpc->fd, (struct sockaddr *)&addr->sa, addr->len) == -1)? 613 errno : RPC_C_SOCKET_OK; 614 } /* well-known endpoint */ 615 else 616 { 617 618 unsigned_char_t *endpoint; 619 unsigned char c; 620 621 rpc__naf_addr_inq_endpoint (addr, &endpoint, &status); 622 623 c = endpoint[0]; /* grab first char */ 624 rpc_string_free (&endpoint, &status); 625 626 if (c != '\0') /* test for null string */ 627 { 628 serr = (bind(lrpc->fd, (struct sockaddr *)&addr->sa, addr->len) == -1)? 629 errno : RPC_C_SOCKET_OK; 630 } /* well-known endpoint */ 631 632 else 633 { 634 /* 635 * Port restriction is in place and the address doesn't have a 636 * well-known endpoint. Try to bind until we hit a good port, 637 * or exhaust the retry count. 638 * 639 * Make a copy of the address to work in; if we hardwire an 640 * endpoint into our caller's address, later logic could infer 641 * that it is a well-known endpoint. 642 */ 643 644 unsigned32 i; 645 boolean found; 646 647 for (i = 0, found = false; 648 (i < RPC_PORT_RESTRICTION_INQ_N_TRIES (addr->rpc_protseq_id)) 649 && !found; 650 i++) 651 { 652 unsigned_char_p_t port_name; 653 654 rpc__naf_addr_overcopy (addr, &temp_addr, &status); 655 656 if (status != rpc_s_ok) 657 { 658 serr = RPC_C_SOCKET_EIO; 659 break; 660 } 661 662 rpc__naf_get_next_restricted_port (temp_addr -> rpc_protseq_id, 663 &port_name, &status); 664 665 if (status != rpc_s_ok) 666 { 667 serr = RPC_C_SOCKET_EIO; 668 break; 669 } 670 671 rpc__naf_addr_set_endpoint (port_name, &temp_addr, &status); 672 673 if (status != rpc_s_ok) 674 { 675 serr = RPC_C_SOCKET_EIO; 676 rpc_string_free (&port_name, &status); 677 break; 678 } 679 680 if (bind(lrpc->fd, (struct sockaddr *)&temp_addr->sa, temp_addr->len) == 0) 681 { 682 found = true; 683 serr = RPC_C_SOCKET_OK; 684 } 685 else 686 serr = RPC_C_SOCKET_EIO; 687 688 rpc_string_free (&port_name, &status); 689 } /* for i */ 690 691 if (!found) 692 { 693 serr = RPC_C_SOCKET_EADDRINUSE; 694 } 695 } /* no well-known endpoint */ 696 } /* has endpoint */ 697 } /* port restriction is in place */ 698 699 if (serr == RPC_C_SOCKET_OK && ncalrpc && has_endpoint) 700 { 701 struct sockaddr_un *skun = (struct sockaddr_un *)&addr->sa; 702 703 serr = chmod(skun->sun_path, 704 S_IRUSR | S_IWUSR | S_IXUSR | 705 S_IRGRP | S_IWGRP | S_IXGRP | 706 S_IROTH | S_IWOTH | S_IXOTH) == -1 ? errno : RPC_C_SOCKET_OK; 707 } 708 709 if (temp_addr != NULL) 710 rpc__naf_addr_free (&temp_addr, &status); 711 712 RPC_LOG_SOCKET_BIND_XIT; 713 return (serr); 714} 715 716INTERNAL rpc_socket_error_t rpc__bsd_socket_getpeereid 717( 718 rpc_socket_t sock, 719 uid_t *euid, 720 gid_t *egid 721); 722 723#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) 724 725INTERNAL rpc_socket_error_t rpc__bsd_socket_sendpeereid 726( 727 rpc_socket_t sock, 728 rpc_addr_p_t addr 729); 730 731INTERNAL rpc_socket_error_t rpc__bsd_socket_recvpeereid 732( 733 rpc_socket_t sock, 734 uid_t *euid, 735 gid_t *egid 736); 737 738#endif 739 740 741/* 742 * R P C _ _ S O C K E T _ C O N N E C T 743 * 744 * Connect a socket to a specified peer's address. 745 * This is used only by Connection oriented Protocol Services. 746 * 747 * (see BSD UNIX connect(2)). 748 */ 749 750INTERNAL rpc_socket_error_t rpc__bsd_socket_connect 751( 752 rpc_socket_t sock, 753 rpc_addr_p_t addr, 754 rpc_cn_assoc_t *assoc ATTRIBUTE_UNUSED 755) 756{ 757 rpc_socket_error_t serr; 758 //rpc_binding_rep_t *binding_rep; 759 unsigned_char_t *netaddr, *endpoint; 760 unsigned32 dbg_status; 761 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 762 763 rpc__naf_addr_inq_netaddr (addr, 764 &netaddr, 765 &dbg_status); 766 rpc__naf_addr_inq_endpoint (addr, 767 &endpoint, 768 &dbg_status); 769 770 RPC_DBG_PRINTF (rpc_e_dbg_general, RPC_C_CN_DBG_GENERAL, 771 ("CN: connection request initiated to %s[%s]\n", 772 netaddr, 773 endpoint)); 774 775connect_again: 776 RPC_LOG_SOCKET_CONNECT_NTR; 777 serr = (connect ( 778 (int) lrpc->fd, 779 (struct sockaddr *) (&addr->sa), 780 (int) (addr->len)) 781 == -1) ? errno : RPC_C_SOCKET_OK; 782 RPC_LOG_SOCKET_CONNECT_XIT; 783 if (serr == EINTR) 784 { 785 goto connect_again; 786 } 787 else if (serr != RPC_C_SOCKET_OK) 788 { 789 goto error; 790 } 791 792#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) 793 serr = rpc__bsd_socket_sendpeereid(sock, addr); 794#endif 795 796cleanup: 797 rpc_string_free (&netaddr, &dbg_status); 798 rpc_string_free (&endpoint, &dbg_status); 799 800 return serr; 801 802error: 803 goto cleanup; 804} 805 806/* 807 * R P C _ _ S O C K E T _ A C C E P T 808 * 809 * Accept a connection on a socket, creating a new socket for the new 810 * connection. A rpc_addr_t appropriate for the NAF corresponding to 811 * this socket must be provided. addr.len must set to the actual size 812 * of addr.sa. This operation fills in addr.sa and sets addr.len to 813 * the new size of the field. This is used only by Connection oriented 814 * Protocol Services. 815 * 816 * (see BSD UNIX accept(2)). 817 */ 818 819INTERNAL rpc_socket_error_t rpc__bsd_socket_accept 820( 821 rpc_socket_t sock, 822 rpc_addr_p_t addr, 823 rpc_socket_t *newsock 824) 825{ 826 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 827 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 828 rpc_bsd_socket_p_t newlrpc = NULL; 829 uid_t euid = -1; 830 gid_t egid = -1; 831 832 *newsock = malloc(sizeof (**newsock)); 833 834 if (!*newsock) 835 { 836 return ENOMEM; 837 } 838 839 (*newsock)->vtbl = sock->vtbl; 840 (*newsock)->pseq_id = sock->pseq_id; 841 842 newlrpc = malloc(sizeof(*newlrpc)); 843 if (!newlrpc) 844 { 845 return ENOMEM; 846 } 847 848 newlrpc->info.peer_uid = -1; 849 newlrpc->info.peer_gid = -1; 850 851 (*newsock)->data.pointer = newlrpc; 852 853accept_again: 854 RPC_LOG_SOCKET_ACCEPT_NTR; 855 if (addr == NULL) 856 { 857 socklen_t addrlen; 858 859 addrlen = 0; 860 newlrpc->fd = accept 861 ((int) lrpc->fd, (struct sockaddr *) NULL, &addrlen); 862 } 863 else 864 { 865 newlrpc->fd = accept 866 ((int) lrpc->fd, (struct sockaddr *) (&addr->sa), (&addr->len)); 867 } 868 serr = (newlrpc->fd == -1) ? errno : RPC_C_SOCKET_OK; 869 RPC_LOG_SOCKET_ACCEPT_XIT; 870 871 if (!serr) 872 { 873 serr = rpc__bsd_socket_getpeereid((*newsock), &euid, &egid); 874 } 875 else 876 { 877 goto cleanup; 878 } 879 880 if (serr == EINTR) 881 { 882 goto accept_again; 883 } 884 885 newlrpc->info.peer_uid = euid; 886 newlrpc->info.peer_gid = egid; 887 888cleanup: 889 if (serr && newlrpc) 890 { 891 free(newlrpc); 892 } 893 894 if (serr && *newsock) 895 { 896 free(*newsock); 897 } 898 899 return serr; 900} 901 902/* 903 * R P C _ _ S O C K E T _ L I S T E N 904 * 905 * Listen for a connection on a socket. 906 * This is used only by Connection oriented Protocol Services. 907 * 908 * (see BSD UNIX listen(2)). 909 */ 910 911INTERNAL rpc_socket_error_t rpc__bsd_socket_listen 912( 913 rpc_socket_t sock, 914 int backlog 915) 916{ 917 rpc_socket_error_t serr; 918 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 919 920 RPC_LOG_SOCKET_LISTEN_NTR; 921 RPC_SOCKET_DISABLE_CANCEL; 922 serr = (listen(lrpc->fd, backlog) == -1) ? errno : RPC_C_SOCKET_OK; 923 RPC_SOCKET_RESTORE_CANCEL; 924 RPC_LOG_SOCKET_LISTEN_XIT; 925 return (serr); 926} 927 928/* 929 * R P C _ _ S O C K E T _ S E N D M S G 930 * 931 * Send a message over a given socket. An error code as well as the 932 * actual number of bytes sent are returned. 933 * 934 * (see BSD UNIX sendmsg(2)). 935 */ 936 937INTERNAL rpc_socket_error_t rpc__bsd_socket_sendmsg 938( 939 rpc_socket_t sock, 940 rpc_socket_iovec_p_t iov, /* array of bufs of data to send */ 941 int iovcnt, /* number of bufs */ 942 rpc_addr_p_t addr, /* addr of receiver */ 943 size_t *cc /* returned number of bytes actually sent */ 944) 945{ 946 ssize_t ret; 947 rpc_socket_error_t serr; 948 struct msghdr msg; 949 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 950 951 *cc = 0; 952 953sendmsg_again: 954 955 memset(&msg, 0, sizeof(msg)); 956 RPC_LOG_SOCKET_SENDMSG_NTR; 957 RPC_SOCKET_INIT_MSGHDR(&msg); 958 if ((addr) != NULL) 959 { 960 RPC_SOCKET_FIX_ADDRLEN(addr); 961 msg.msg_name = (caddr_t) &(addr)->sa; 962 msg.msg_namelen = (addr)->len; 963 } 964 else 965 { 966 msg.msg_name = (caddr_t) NULL; 967 } 968 msg.msg_iov = iov; 969 msg.msg_iovlen = iovcnt; 970 971 ret = dcethread_sendmsg (lrpc->fd, &msg, 0); 972 if (ret == (size_t) -1) 973 { 974 serr = errno; 975 } 976 else 977 { 978 serr = RPC_C_SOCKET_OK; 979 *cc = ret; 980 } 981 982 RPC_LOG_SOCKET_SENDMSG_XIT; 983 if (serr == EINTR) 984 { 985 goto sendmsg_again; 986 } 987 988 return (serr); 989} 990 991/* 992 * R P C _ _ S O C K E T _ R E C V F R O M 993 * 994 * Recieve the next buffer worth of information from a socket. A 995 * rpc_addr_t appropriate for the NAF corresponding to this socket must 996 * be provided. addr.len must set to the actual size of addr.sa. This 997 * operation fills in addr.sa and sets addr.len to the new size of the 998 * field. An error status as well as the actual number of bytes received 999 * are also returned. 1000 * 1001 * (see BSD UNIX recvfrom(2)). 1002 */ 1003 1004INTERNAL rpc_socket_error_t rpc__bsd_socket_recvfrom 1005( 1006 rpc_socket_t sock, 1007 byte_p_t buf, /* buf for rcvd data */ 1008 int len, /* len of above buf */ 1009 rpc_addr_p_t from, /* addr of sender */ 1010 size_t *cc /* returned number of bytes actually rcvd */ 1011) 1012{ 1013 ssize_t ret; 1014 rpc_socket_error_t serr; 1015 struct msghdr msg; 1016 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1017 1018 *cc = 0; 1019 1020recvfrom_again: 1021 if (from != NULL) 1022 { 1023 RPC_SOCKET_FIX_ADDRLEN(from); 1024 } 1025 1026 RPC_LOG_SOCKET_RECVFROM_NTR; 1027 1028 ret = dcethread_recvfrom(lrpc->fd, buf, len, 0 /* flags */, 1029 &from->sa, &from->len); 1030 if (ret == (size_t) -1) 1031 { 1032 serr = errno; 1033 } 1034 else 1035 { 1036 serr = RPC_C_SOCKET_OK; 1037 *cc = ret; 1038 } 1039 1040 RPC_LOG_SOCKET_RECVFROM_XIT; 1041 RPC_SOCKET_FIX_ADDRLEN(from); 1042 if (serr == EINTR) 1043 { 1044 goto recvfrom_again; 1045 } 1046 1047 return serr; 1048} 1049 1050/* 1051 * R P C _ _ S O C K E T _ R E C V M S G 1052 * 1053 * Receive a message over a given socket. A rpc_addr_t appropriate for 1054 * the NAF corresponding to this socket must be provided. addr.len must 1055 * set to the actual size of addr.sa. This operation fills in addr.sa 1056 * and sets addr.len to the new size of the field. An error code as 1057 * well as the actual number of bytes received are also returned. 1058 * 1059 * (see BSD UNIX recvmsg(2)). 1060 */ 1061 1062INTERNAL rpc_socket_error_t rpc__bsd_socket_recvmsg 1063( 1064 rpc_socket_t sock, 1065 rpc_socket_iovec_p_t iov, /* array of bufs for rcvd data */ 1066 int iovcnt, /* number of bufs */ 1067 rpc_addr_p_t addr, /* addr of sender */ 1068 size_t *cc /* returned number of bytes actually rcvd */ 1069) 1070{ 1071 ssize_t ret; 1072 rpc_socket_error_t serr; 1073 struct msghdr msg; 1074 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1075 int block = 0; 1076 1077 *cc = 0; 1078 1079recvmsg_again: 1080 1081 memset(&msg, 0, sizeof(msg)); 1082 RPC_LOG_SOCKET_RECVMSG_NTR; 1083 RPC_SOCKET_INIT_MSGHDR(&msg); 1084 if (addr != NULL) 1085 { 1086 RPC_SOCKET_FIX_ADDRLEN(addr); 1087 msg.msg_name = (caddr_t) &addr->sa; 1088 msg.msg_namelen = addr->len; 1089 } 1090 else 1091 { 1092 msg.msg_name = (caddr_t) NULL; 1093 } 1094 msg.msg_iov = iov; 1095 msg.msg_iovlen = iovcnt; 1096 1097 /* 1098 * WORKAROUND : 1099 * - Inconsistency between kernel socket state and socket file descriptor state - 1100 * fcntl(F_GETFL) here tells us that socket is blocking (O_NONBLOCK not set in flags), 1101 * however kernel dtrace probe for soreceive says socket is SS_NBIO. 1102 * See 18110085 / 17781539 for details. 1103 * Setting FIONBIO to 0 from userland will resolve this incosistency and make both 1104 * socket state and socket file descriptor state in the kernel land, and gurantees a 1105 * blocking socket before recvmsg() is called. 1106 */ 1107 ioctl(lrpc->fd, FIONBIO, &block); 1108 1109 ret = dcethread_recvmsg (lrpc->fd, &msg, 0); 1110 if (ret == (ssize_t)-1) 1111 { 1112 serr = errno; 1113 } 1114 else 1115 { 1116 serr = RPC_C_SOCKET_OK; 1117 *cc = ret; 1118 } 1119 1120 RPC_LOG_SOCKET_RECVMSG_XIT; 1121 if (serr == EINTR) 1122 { 1123 goto recvmsg_again; 1124 } 1125 1126 if (addr != NULL) 1127 { 1128 addr->len = msg.msg_namelen; 1129 } 1130 1131 return serr; 1132} 1133 1134/* 1135 * R P C _ _ S O C K E T _ I N Q _ A D D R 1136 * 1137 * Return the local address associated with a socket. A rpc_addr_t 1138 * appropriate for the NAF corresponding to this socket must be provided. 1139 * addr.len must set to the actual size of addr.sa. This operation fills 1140 * in addr.sa and sets addr.len to the new size of the field. 1141 * 1142 * !!! NOTE: You should use rpc__naf_desc_inq_addr() !!! 1143 * 1144 * This routine is indended for use only by the internal routine: 1145 * rpc__naf_desc_inq_addr(). rpc__bsd_socket_inq_endpoint() only has the 1146 * functionality of BSD UNIX getsockname() which doesn't (at least not 1147 * on all systems) return the local network portion of a socket's address. 1148 * rpc__naf_desc_inq_addr() returns the complete address for a socket. 1149 * 1150 * (see BSD UNIX getsockname(2)). 1151 */ 1152 1153INTERNAL rpc_socket_error_t rpc__bsd_socket_inq_endpoint 1154( 1155 rpc_socket_t sock, 1156 rpc_addr_p_t addr 1157) 1158{ 1159 rpc_socket_error_t serr; 1160 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1161 1162 RPC_LOG_SOCKET_INQ_EP_NTR; 1163 RPC_SOCKET_FIX_ADDRLEN(addr); 1164 RPC_SOCKET_DISABLE_CANCEL; 1165 serr = (getsockname(lrpc->fd, (void*)&addr->sa, &addr->len) == -1) ? errno : RPC_C_SOCKET_OK; 1166 RPC_SOCKET_RESTORE_CANCEL; 1167 RPC_SOCKET_FIX_ADDRLEN(addr); 1168 RPC_LOG_SOCKET_INQ_EP_XIT; 1169 return (serr); 1170} 1171 1172/* 1173 * R P C _ _ S O C K E T _ S E T _ B R O A D C A S T 1174 * 1175 * Enable broadcasting for the socket (as best it can). 1176 * Used only by Datagram based Protocol Services. 1177 */ 1178 1179INTERNAL rpc_socket_error_t rpc__bsd_socket_set_broadcast 1180( 1181 rpc_socket_t sock 1182) 1183{ 1184#ifdef SO_BROADCAST 1185 int setsock_val = 1; 1186 rpc_socket_error_t serr; 1187 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1188 1189 RPC_SOCKET_DISABLE_CANCEL; 1190 serr = (setsockopt(lrpc->fd, SOL_SOCKET, SO_BROADCAST, 1191 &setsock_val, sizeof(setsock_val)) == -1) ? errno : RPC_C_SOCKET_OK; 1192 RPC_SOCKET_RESTORE_CANCEL; 1193 if (serr) 1194 { 1195 RPC_DBG_GPRINTF(("(rpc__bsd_socket_set_broadcast) error=%d\n", serr)); 1196 } 1197 1198 return(serr); 1199#else 1200 return(RPC_C_SOCKET_OK); 1201#endif 1202} 1203 1204/* 1205 * R P C _ _ S O C K E T _ S E T _ B U F S 1206 * 1207 * Set the socket's send and receive buffer sizes and return the new 1208 * values. Note that the sizes are min'd with 1209 * "rpc_c_socket_max_{snd,rcv}buf" because systems tend to fail the 1210 * operation rather than give the max buffering if the max is exceeded. 1211 * 1212 * If for some reason your system is screwed up and defines SOL_SOCKET 1213 * and SO_SNDBUF, but doesn't actually support the SO_SNDBUF and SO_RCVBUF 1214 * operations AND using them would result in nasty behaviour (i.e. they 1215 * don't just return some error code), define NO_SO_SNDBUF. 1216 * 1217 * If the buffer sizes provided are 0, then we use the operating 1218 * system default (i.e. we don't set anything at all). 1219 */ 1220 1221INTERNAL rpc_socket_error_t rpc__bsd_socket_set_bufs 1222( 1223 rpc_socket_t sock, 1224 unsigned32 txsize, 1225 unsigned32 rxsize, 1226 unsigned32 *ntxsize, 1227 unsigned32 *nrxsize 1228) 1229{ 1230 socklen_t sizelen; 1231 int e; 1232 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1233 1234 RPC_SOCKET_DISABLE_CANCEL; 1235 1236#if (defined (SOL_SOCKET) && defined(SO_SNDBUF)) && !defined(NO_SO_SNDBUF) 1237 1238 /* 1239 * Set the new sizes. 1240 */ 1241 1242 txsize = MIN(txsize, RPC_C_SOCKET_MAX_SNDBUF); 1243 if (txsize != 0) 1244 { 1245 e = setsockopt(lrpc->fd, SOL_SOCKET, SO_SNDBUF, &txsize, sizeof(txsize)); 1246 if (e == -1) 1247 { 1248 RPC_DBG_GPRINTF 1249 (("(rpc__bsd_socket_set_bufs) WARNING: set sndbuf (%d) failed - error = %d\n", 1250 txsize, errno)); 1251 } 1252 } 1253 1254 rxsize = MIN(rxsize, RPC_C_SOCKET_MAX_RCVBUF); 1255 if (rxsize != 0) 1256 { 1257 e = setsockopt(lrpc->fd, SOL_SOCKET, SO_RCVBUF, &rxsize, sizeof(rxsize)); 1258 if (e == -1) 1259 { 1260 RPC_DBG_GPRINTF 1261 (("(rpc__bsd_socket_set_bufs) WARNING: set rcvbuf (%d) failed - error = %d\n", 1262 rxsize, errno)); 1263 } 1264 } 1265 1266 /* 1267 * Get the new sizes. If this fails, just return some guessed sizes. 1268 */ 1269 *ntxsize = 0; 1270 sizelen = sizeof *ntxsize; 1271 e = getsockopt(lrpc->fd, SOL_SOCKET, SO_SNDBUF, ntxsize, &sizelen); 1272 if (e == -1) 1273 { 1274 RPC_DBG_GPRINTF 1275 (("(rpc__bsd_socket_set_bufs) WARNING: get sndbuf failed - error = %d\n", errno)); 1276 *ntxsize = RPC_C_SOCKET_GUESSED_SNDBUF; 1277 } 1278 1279 *nrxsize = 0; 1280 sizelen = sizeof *nrxsize; 1281 e = getsockopt(lrpc->fd, SOL_SOCKET, SO_RCVBUF, nrxsize, &sizelen); 1282 if (e == -1) 1283 { 1284 RPC_DBG_GPRINTF 1285 (("(rpc__bsd_socket_set_bufs) WARNING: get rcvbuf failed - error = %d\n", errno)); 1286 *nrxsize = RPC_C_SOCKET_GUESSED_RCVBUF; 1287 } 1288 1289# ifdef apollo 1290 /* 1291 * On Apollo, modifying the socket buffering doesn't actually do 1292 * anything on IP sockets, but the calls succeed anyway. We can 1293 * detect this by the fact that the new buffer length returned is 1294 * 0. Return what we think the actually length is. 1295 */ 1296 if (rxsize != 0 && *nrxsize == 0) 1297 { 1298 *nrxsize = (8 * 1024); 1299 } 1300 if (txsize != 0 && *ntxsize == 0) 1301 { 1302 *ntxsize = (8 * 1024); 1303 } 1304# endif 1305 1306#else 1307 1308 *ntxsize = RPC_C_SOCKET_GUESSED_SNDBUF; 1309 *nrxsize = RPC_C_SOCKET_GUESSED_RCVBUF; 1310 1311#endif 1312 1313 RPC_SOCKET_RESTORE_CANCEL; 1314 1315 return (RPC_C_SOCKET_OK); 1316} 1317 1318/* 1319 * R P C _ _ S O C K E T _ S E T _ N B I O 1320 * 1321 * Set a socket to non-blocking mode. 1322 * 1323 * Return RPC_C_SOCKET_OK on success, otherwise an error value. 1324 */ 1325 1326INTERNAL rpc_socket_error_t rpc__bsd_socket_set_nbio 1327( 1328 rpc_socket_t sock 1329) 1330{ 1331 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1332 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1333 1334 RPC_SOCKET_DISABLE_CANCEL; 1335 serr = ((fcntl(lrpc->fd, F_SETFL, O_NDELAY) == -1) ? errno : RPC_C_SOCKET_OK); 1336 RPC_SOCKET_RESTORE_CANCEL; 1337 if (serr) 1338 { 1339 RPC_DBG_GPRINTF(("(rpc__bsd_socket_set_nbio) error=%d\n", serr)); 1340 } 1341 1342 return (serr); 1343} 1344 1345/* 1346 * R P C _ _ S O C K E T _ S E T _ C L O S E _ O N _ E X E C 1347 * 1348 * 1349 * Set a socket to a mode whereby it is not inherited by a spawned process 1350 * executing some new image. This is possibly a no-op on some systems. 1351 * 1352 * Return RPC_C_SOCKET_OK on success, otherwise an error value. 1353 */ 1354 1355INTERNAL rpc_socket_error_t rpc__bsd_socket_set_close_on_exec 1356( 1357 rpc_socket_t sock 1358) 1359{ 1360 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1361 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1362 1363 RPC_SOCKET_DISABLE_CANCEL; 1364 serr = ((fcntl(lrpc->fd, F_SETFD, 1) == -1) ? errno : RPC_C_SOCKET_OK); 1365 RPC_SOCKET_RESTORE_CANCEL; 1366 if (serr) 1367 { 1368 RPC_DBG_GPRINTF(("(rpc__bsd_socket_set_close_on_exec) error=%d\n", serr)); 1369 } 1370 return (serr); 1371} 1372 1373/* 1374 * R P C _ _ S O C K E T _ G E T P E E R N A M E 1375 * 1376 * Get name of connected peer. 1377 * This is used only by Connection oriented Protocol Services. 1378 * 1379 * (see BSD UNIX getpeername(2)). 1380 */ 1381 1382INTERNAL rpc_socket_error_t rpc__bsd_socket_getpeername 1383( 1384 rpc_socket_t sock, 1385 rpc_addr_p_t addr 1386) 1387{ 1388 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1389 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1390 1391 RPC_SOCKET_FIX_ADDRLEN(addr); 1392 RPC_SOCKET_DISABLE_CANCEL; 1393 serr = (getpeername(lrpc->fd, (void *)&addr->sa, &addr->len) == -1) ? errno : RPC_C_SOCKET_OK; 1394 RPC_SOCKET_RESTORE_CANCEL; 1395 RPC_SOCKET_FIX_ADDRLEN(addr); 1396 1397 return (serr); 1398} 1399 1400/* 1401 * R P C _ _ S O C K E T _ G E T _ I F _ I D 1402 * 1403 * Get socket network interface id (socket type). 1404 * 1405 * (see BSD UNIX getsockopt(2)). 1406 */ 1407 1408INTERNAL rpc_socket_error_t rpc__bsd_socket_get_if_id 1409( 1410 rpc_socket_t sock, 1411 rpc_network_if_id_t *network_if_id 1412) 1413{ 1414 socklen_t optlen = 0; 1415 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1416 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1417 1418 optlen = sizeof(rpc_network_if_id_t); 1419 1420 RPC_SOCKET_DISABLE_CANCEL; 1421 serr = (getsockopt (lrpc->fd, 1422 SOL_SOCKET, 1423 SO_TYPE, 1424 network_if_id, 1425 &optlen) == -1 ? errno : RPC_C_SOCKET_OK); 1426 RPC_SOCKET_RESTORE_CANCEL; 1427 return serr; 1428} 1429 1430/* 1431 * R P C _ _ S O C K E T _ S E T _ K E E P A L I V E 1432 * 1433 * Enable periodic transmissions on a connected socket, when no 1434 * other data is being exchanged. If the other end does not respond to 1435 * these messages, the connection is considered broken and the 1436 * so_error variable is set to ETIMEDOUT. 1437 * Used only by Connection based Protocol Services. 1438 * 1439 * (see BSD UNIX setsockopt(2)). 1440 */ 1441 1442INTERNAL rpc_socket_error_t rpc__bsd_socket_set_keepalive 1443( 1444 rpc_socket_t sock 1445) 1446{ 1447#ifdef SO_KEEPALIVE 1448 int setsock_val = 1; 1449 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1450 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1451 1452 RPC_SOCKET_DISABLE_CANCEL; 1453 serr = ((setsockopt(lrpc->fd, SOL_SOCKET, SO_KEEPALIVE, 1454 &setsock_val, sizeof(setsock_val)) == -1) ? errno : RPC_C_SOCKET_OK); 1455 RPC_SOCKET_RESTORE_CANCEL; 1456 if (serr) 1457 { 1458 RPC_DBG_GPRINTF(("(rpc__bsd_socket_set_keepalive) error=%d\n", serr)); 1459 } 1460 1461 return(serr); 1462#else 1463 return(RPC_C_SOCKET_OK); 1464#endif 1465} 1466 1467 1468/* 1469 * R P C _ _ S O C K E T _ N O W R I T E B L O C K _ W A I T 1470 * 1471 * Wait until the a write on the socket should succede without 1472 * blocking. If tmo is NULL, the wait is unbounded, otherwise 1473 * tmo specifies the max time to wait. RPC_C_SOCKET_ETIMEDOUT 1474 * if a timeout occurs. This operation in not cancellable. 1475 */ 1476 1477INTERNAL rpc_socket_error_t rpc__bsd_socket_nowriteblock_wait 1478( 1479 rpc_socket_t sock, 1480 struct timeval *tmo 1481) 1482{ 1483 fd_set write_fds; 1484 int nfds, num_found; 1485 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1486 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1487 1488 FD_ZERO (&write_fds); 1489 FD_SET (lrpc->fd, &write_fds); 1490 nfds = lrpc->fd + 1; 1491 1492 RPC_SOCKET_DISABLE_CANCEL; 1493 num_found = dcethread_select(nfds, NULL, (void *)&write_fds, NULL, tmo); 1494 serr = ((num_found < 0) ? errno : RPC_C_SOCKET_OK); 1495 RPC_SOCKET_RESTORE_CANCEL; 1496 1497 if (serr) 1498 { 1499 RPC_DBG_GPRINTF(("(rpc__bsd_socket_nowriteblock_wait) error=%d\n", serr)); 1500 return serr; 1501 } 1502 1503 if (num_found == 0) 1504 { 1505 RPC_DBG_GPRINTF(("(rpc__bsd_socket_nowriteblock_wait) timeout\n")); 1506 return RPC_C_SOCKET_ETIMEDOUT; 1507 } 1508 1509 return RPC_C_SOCKET_OK; 1510} 1511 1512 1513/* 1514 * R P C _ _ S O C K E T _ S E T _ R C V T I M E O 1515 * 1516 * Set receive timeout on a socket 1517 * Used only by Connection based Protocol Services. 1518 * 1519 * (see BSD UNIX setsockopt(2)). 1520 */ 1521 1522INTERNAL rpc_socket_error_t rpc__bsd_socket_set_rcvtimeo 1523( 1524 rpc_socket_t sock, 1525 struct timeval *tmo 1526) 1527{ 1528#ifdef SO_RCVTIMEO 1529 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1530 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1531 1532 RPC_SOCKET_DISABLE_CANCEL; 1533 serr = ((setsockopt(lrpc->fd, SOL_SOCKET, SO_RCVTIMEO, 1534 tmo, sizeof(*tmo)) == -1) ? errno : RPC_C_SOCKET_OK); 1535 RPC_SOCKET_RESTORE_CANCEL; 1536 if (serr) 1537 { 1538 RPC_DBG_GPRINTF(("(rpc__bsd_socket_set_rcvtimeo) error=%d\n", serr)); 1539 } 1540 1541 return(serr); 1542#else 1543 return(RPC_C_SOCKET_OK); 1544#endif 1545} 1546 1547/* 1548 * R P C _ _ S O C K E T _ G E T _ P E E R E I D 1549 * 1550 * Get UNIX domain socket peer credentials 1551 */ 1552 1553INTERNAL rpc_socket_error_t rpc__bsd_socket_getpeereid 1554( 1555 rpc_socket_t sock, 1556 uid_t *euid, 1557 gid_t *egid 1558) 1559{ 1560 rpc_socket_error_t serr = RPC_C_SOCKET_ENOTSUP; 1561 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1562 1563#if HAVE_GETPEEREID 1564 1565 RPC_SOCKET_DISABLE_CANCEL; 1566 serr = ((getpeereid(lrpc->fd, euid, egid) == -1) ? errno 1567 : RPC_C_SOCKET_OK); 1568 RPC_SOCKET_RESTORE_CANCEL; 1569 1570 if (serr != RPC_C_SOCKET_OK) 1571 { 1572 RPC_DBG_GPRINTF(("(rpc__bsd_socket_getpeereid) error=%d\n", serr)); 1573 } 1574 1575#elif defined(SO_PEERCRED) 1576 struct ucred peercred = {0}; 1577 socklen_t peercredlen = sizeof(peercred); 1578 1579 RPC_SOCKET_DISABLE_CANCEL; 1580 serr = ((getsockopt(lrpc->fd, SOL_SOCKET, SO_PEERCRED, 1581 &peercred, &peercredlen) == -1) ? errno : RPC_C_SOCKET_OK); 1582 RPC_SOCKET_RESTORE_CANCEL; 1583 if (serr == RPC_C_SOCKET_OK) 1584 { 1585 *euid = peercred.uid; 1586 *egid = peercred.gid; 1587 } 1588 else 1589 { 1590 RPC_DBG_GPRINTF(("(rpc__bsd_socket_getpeereid) error=%d\n", serr)); 1591 } 1592#else 1593 serr = rpc__bsd_socket_recvpeereid(sock, euid, egid); 1594#endif 1595 1596 return serr; 1597} 1598 1599#if !defined(SO_PEERCRED) && !defined(HAVE_GETPEEREID) 1600 1601INTERNAL rpc_socket_error_t rpc__bsd_socket_sendpeereid 1602( 1603 rpc_socket_t sock, 1604 rpc_addr_p_t addr 1605) 1606{ 1607 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1608 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1609 struct sockaddr_un *endpoint_addr = NULL; 1610 struct stat endpoint_stat = {0}; 1611 uid_t ep_uid = -1; 1612 int pipefd[2] = {-1, -1}; 1613 char empty_buf[] = {'\0'}; 1614 rpc_socket_iovec_t iovec = {0}; 1615 union 1616 { 1617 /* Using union ensures correct alignment on some platforms */ 1618 struct cmsghdr cm; 1619 char buf[CMSG_SPACE(sizeof(pipefd[0]))]; 1620 } cm_un; 1621 struct msghdr msg = {0}; 1622 struct cmsghdr *cmsg = NULL; 1623 int bytes_sent = 0; 1624 1625 endpoint_addr = (struct sockaddr_un *)(&addr->sa); 1626 1627 if (stat(endpoint_addr->sun_path, &endpoint_stat)) 1628 { 1629 serr = errno; 1630 goto error; 1631 } 1632 1633 ep_uid = endpoint_stat.st_uid; 1634 if (ep_uid == 0 || ep_uid == getuid()) 1635 { 1636 if (pipe(pipefd) != 0) 1637 { 1638 serr = errno; 1639 goto error; 1640 } 1641 } 1642 1643 iovec.iov_base = &empty_buf; 1644 iovec.iov_len = sizeof(empty_buf); 1645 1646 msg.msg_iov = &iovec; 1647 msg.msg_iovlen = 1; 1648 msg.msg_control = cm_un.buf; 1649 msg.msg_controllen = sizeof(cm_un.buf); 1650 msg.msg_flags = 0; 1651 1652 memset(&cm_un, 0, sizeof(cm_un)); 1653 1654 cmsg = CMSG_FIRSTHDR(&msg); 1655 cmsg->cmsg_level = SOL_SOCKET; 1656 cmsg->cmsg_type = SCM_RIGHTS; 1657 cmsg->cmsg_len = CMSG_LEN(sizeof(pipefd[0])); 1658 1659 memcpy(CMSG_DATA(cmsg), &pipefd[0], sizeof(pipefd[0])); 1660 1661 RPC_SOCKET_DISABLE_CANCEL; 1662 bytes_sent = sendmsg(lrpc->fd, &msg, 0); 1663 RPC_SOCKET_RESTORE_CANCEL; 1664 if (bytes_sent == -1) 1665 { 1666 serr = errno; 1667 goto error; 1668 } 1669 1670cleanup: 1671 1672 if (pipefd[0] != -1) 1673 { 1674 close(pipefd[0]); 1675 } 1676 1677 if (pipefd[1] != -1) 1678 { 1679 close(pipefd[1]); 1680 } 1681 1682 return serr; 1683 1684error: 1685 1686 goto cleanup; 1687} 1688 1689INTERNAL rpc_socket_error_t rpc__bsd_socket_recvpeereid 1690( 1691 rpc_socket_t sock, 1692 uid_t *euid, 1693 gid_t *egid 1694) 1695{ 1696 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 1697 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1698 int fd = -1; 1699 int bytes_rcvd = 0; 1700 struct stat pipe_stat = {0}; 1701 char empty_buf[] = {'\0'}; 1702 rpc_socket_iovec_t iovec = {0}; 1703 union 1704 { 1705 /* Using union ensures correct alignment on some platforms */ 1706 struct cmsghdr cm; 1707 char buf[CMSG_SPACE(sizeof(fd))]; 1708 } cm_un; 1709 struct cmsghdr *cmsg = NULL; 1710 struct msghdr msg = {0}; 1711 1712 iovec.iov_base = &empty_buf; 1713 iovec.iov_len = sizeof(empty_buf); 1714 1715 memset(&cm_un, 0, sizeof(cm_un)); 1716 1717 msg.msg_iov = &iovec; 1718 msg.msg_iovlen = 1; 1719 msg.msg_control = cm_un.buf; 1720 msg.msg_controllen = sizeof(cm_un.buf); 1721 msg.msg_flags = 0; 1722 1723 RPC_SOCKET_DISABLE_CANCEL; 1724 bytes_rcvd = recvmsg(lrpc->fd, &msg, 0); 1725 RPC_SOCKET_RESTORE_CANCEL; 1726 if (bytes_rcvd == -1) 1727 { 1728 serr = errno; 1729 goto error; 1730 } 1731 1732 if (msg.msg_controllen == 0 || 1733 msg.msg_controllen > sizeof(cm_un)) 1734 { 1735 serr = RPC_C_SOCKET_EACCESS; 1736 goto error; 1737 } 1738 1739 cmsg = CMSG_FIRSTHDR(&msg); 1740 if (!cmsg || 1741 !(cmsg->cmsg_type == SCM_RIGHTS) || 1742 cmsg->cmsg_len - CMSG_ALIGN(sizeof(*cmsg)) != sizeof(fd)) 1743 { 1744 serr = RPC_C_SOCKET_EACCESS; 1745 goto error; 1746 } 1747 1748 memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd)); 1749 1750 if (fstat(fd, &pipe_stat)) 1751 { 1752 serr = errno; 1753 goto error; 1754 } 1755 1756 if (!S_ISFIFO(pipe_stat.st_mode) || 1757 (pipe_stat.st_mode & (S_IRWXO | S_IRWXG)) != 0) 1758 { 1759 serr = RPC_C_SOCKET_EACCESS; 1760 goto error; 1761 } 1762 1763 *euid = pipe_stat.st_uid; 1764 *egid = pipe_stat.st_gid; 1765 1766cleanup: 1767 1768 if (fd > 0) 1769 { 1770 close(fd); 1771 } 1772 1773 return serr; 1774 1775error: 1776 1777 *euid = -1; 1778 *egid = -1; 1779 1780 goto cleanup; 1781} 1782 1783#endif 1784 1785INTERNAL 1786int rpc__bsd_socket_get_select_desc( 1787 rpc_socket_t sock 1788 ) 1789{ 1790 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1791 1792 return lrpc->fd; 1793} 1794 1795INTERNAL 1796rpc_socket_error_t 1797rpc__bsd_socket_enum_ifaces( 1798 rpc_socket_t sock, 1799 rpc_socket_enum_iface_fn_p_t efun, 1800 rpc_addr_vector_p_t *rpc_addr_vec, 1801 rpc_addr_vector_p_t *netmask_addr_vec, 1802 rpc_addr_vector_p_t *broadcast_addr_vec 1803) 1804{ 1805 rpc_ip_addr_p_t ip_addr = NULL; 1806 rpc_ip_addr_p_t netmask_addr = NULL; 1807 rpc_ip_addr_p_t broadcast_addr = NULL; 1808 int n_ifs; 1809 union 1810 { 1811 unsigned char buf[1024]; 1812 struct ifreq req; 1813 } reqbuf; 1814 struct ifconf ifc; 1815 struct ifreq *ifr, *last_ifr; 1816 struct ifreq ifreq; 1817 short if_flags; 1818 struct sockaddr if_addr; 1819 unsigned int i; 1820#ifdef _SOCKADDR_LEN 1821 int prev_size; 1822#else 1823 const int prev_size = sizeof(struct ifreq) ; 1824#endif 1825 rpc_socket_error_t err = 0; 1826 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 1827 1828 /* 1829 * Get the list of network interfaces. 1830 */ 1831 ifc.ifc_len = sizeof (reqbuf.buf); 1832 ifc.ifc_buf = (caddr_t) reqbuf.buf; 1833 1834ifconf_again: 1835 if (ioctl (lrpc->fd, SIOCGIFCONF, (caddr_t) &ifc) < 0) 1836 { 1837 if (errno == EINTR) 1838 { 1839 goto ifconf_again; 1840 } 1841 err = errno; /* !!! */ 1842 goto done; 1843 } 1844 1845 /* 1846 * Figure out how many interfaces there must be and allocate an 1847 * RPC address vector with the appropriate number of elements. 1848 * (We may ask for a few too many in case some of the interfaces 1849 * are uninteresting.) 1850 */ 1851 n_ifs = ifc.ifc_len / sizeof (struct ifreq); 1852 RPC_DBG_PRINTF(rpc_e_dbg_general, 10, 1853 ("%lu bytes of ifreqs, ifreq is %lu bytes\n", 1854 (unsigned long)ifc.ifc_len, 1855 (unsigned long)sizeof(struct ifreq))); 1856 1857#ifdef MAX_DEBUG 1858 if (RPC_DBG2(rpc_e_dbg_general, 15)) 1859 { 1860 int i; 1861 char msgbuf[128]; 1862 1863 for (i=0; i<ifc.ifc_len; i++) { 1864 if ((i % 32) == 0) { 1865 if (i != 0) 1866 RPC_DBG_PRINTF(rpc_e_dbg_general, 15, ("%s\n",msgbuf)); 1867 sprintf(msgbuf, "%4x: ", i); 1868 } 1869 sprintf(msgbuf, "%s%02x ", msgbuf, reqbuf.buf[i]); 1870 } 1871 if (i != 0) 1872 RPC_DBG_PRINTF(rpc_e_dbg_general, 15, ("%s\n",msgbuf)); 1873 } 1874#endif 1875 1876 if (rpc_addr_vec != NULL) 1877 { 1878 RPC_MEM_ALLOC ( 1879 *rpc_addr_vec, 1880 rpc_addr_vector_p_t, 1881 (sizeof **rpc_addr_vec) + ((n_ifs - 1) * (sizeof (rpc_addr_p_t))), 1882 RPC_C_MEM_RPC_ADDR_VEC, 1883 RPC_C_MEM_WAITOK); 1884 1885 if (*rpc_addr_vec == NULL) 1886 { 1887 err = ENOMEM; 1888 goto done; 1889 } 1890 } 1891 1892 if (netmask_addr_vec != NULL) 1893 { 1894 RPC_MEM_ALLOC ( 1895 *netmask_addr_vec, 1896 rpc_addr_vector_p_t, 1897 (sizeof **netmask_addr_vec) + ((n_ifs - 1) * (sizeof (rpc_addr_p_t))), 1898 RPC_C_MEM_RPC_ADDR_VEC, 1899 RPC_C_MEM_WAITOK); 1900 1901 if (*netmask_addr_vec == NULL) 1902 { 1903 err = ENOMEM; 1904 RPC_MEM_FREE (*netmask_addr_vec, RPC_C_MEM_RPC_ADDR_VEC); 1905 goto done; 1906 } 1907 1908 (*netmask_addr_vec)->len = 0; 1909 } 1910 1911 if (broadcast_addr_vec != NULL) 1912 { 1913 RPC_MEM_ALLOC ( 1914 *broadcast_addr_vec, 1915 rpc_addr_vector_p_t, 1916 (sizeof **broadcast_addr_vec) + ((n_ifs - 1) * (sizeof (rpc_addr_p_t))), 1917 RPC_C_MEM_RPC_ADDR_VEC, 1918 RPC_C_MEM_WAITOK); 1919 1920 if (*broadcast_addr_vec == NULL) 1921 { 1922 err = ENOMEM; 1923 RPC_MEM_FREE (*broadcast_addr_vec, RPC_C_MEM_RPC_ADDR_VEC); 1924 goto done; 1925 } 1926 1927 (*broadcast_addr_vec)->len = 0; 1928 } 1929 1930 /* 1931 * Go through the interfaces and get the info associated with them. 1932 */ 1933 assert(rpc_addr_vec != NULL); 1934 (*rpc_addr_vec)->len = 0; 1935 last_ifr = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len); 1936 1937 for (i=0, ifr = ifc.ifc_req; ifr < last_ifr ; 1938 i++, ifr = (struct ifreq *)(( (char *) ifr ) + prev_size)) 1939 { 1940#ifdef _SOCKADDR_LEN 1941 prev_size = sizeof (struct ifreq) - sizeof(struct sockaddr) + ifr->ifr_addr.sa_len ; 1942#endif 1943 RPC_DBG_PRINTF(rpc_e_dbg_general, 10, ("interface %d: %s\n", 1944 i, ifr->ifr_name)); 1945 /* 1946 * Get the interface's flags. If the flags say that the interface 1947 * is not up or is the loopback interface, skip it. Do the 1948 * SIOCGIFFLAGS on a copy of the ifr so we don't lose the original 1949 * contents of the ifr. (ifr's are unions that hold only one 1950 * of the interesting interface attributes [address, flags, etc.] 1951 * at a time.) 1952 */ 1953 memcpy(&ifreq, ifr, sizeof(ifreq)); 1954ifflags_again: 1955 if (ioctl(lrpc->fd, SIOCGIFFLAGS, &ifreq) < 0) 1956 { 1957 RPC_DBG_PRINTF(rpc_e_dbg_general, 10, 1958 ("SIOCGIFFLAGS returned errno %d\n", errno)); 1959 if (errno == EINTR) 1960 { 1961 goto ifflags_again; 1962 } 1963 continue; 1964 } 1965 if_flags = ifreq.ifr_flags; /* Copy out the flags */ 1966 RPC_DBG_PRINTF(rpc_e_dbg_general, 10, ("flags are %x\n", if_flags)); 1967 1968 /* 1969 * Ignore interfaces which are not 'up'. 1970 */ 1971 if ((if_flags & IFF_UP) == 0) 1972 1973 continue; 1974 1975#ifndef USE_LOOPBACK 1976 /* 1977 * Ignore the loopback interface 1978 */ 1979 1980 if (if_flags & IFF_LOOPBACK) continue; 1981#endif 1982 /* 1983 * Ignore Point-to-Point interfaces (i.e. SLIP/PPP ) 1984 * *** NOTE: We need an Environment Variable Evaluation at 1985 * some point so we can selectively allow RPC servers to 1986 * some up with/without SLIP/PPP bindings. For Dynamic PPP/SLIP 1987 * interfaces, this creates problems for now. 1988 */ 1989 1990 if (if_flags & IFF_POINTOPOINT) continue; 1991 1992 /* 1993 * Get the addressing stuff for this interface. 1994 */ 1995 1996#ifdef NO_SIOCGIFADDR 1997 1998 /* 1999 * Note that some systems do not return the address for the 2000 * interface given. However the ifr array elts contained in 2001 * the ifc block returned from the SIOCGIFCONF ioctl above already 2002 * contains the correct addresses. So these systems should define 2003 * NO_SIOCGIFADDR in their platform specific include file. 2004 */ 2005 if_addr = ifr->ifr_addr; 2006 2007#else 2008 2009 /* 2010 * Do the SIOCGIFADDR on a copy of the ifr. See above. 2011 */ 2012 memcpy(&ifreq, ifr, sizeof(ifreq)); 2013 ifaddr_again: 2014 if (ioctl(lrpc->fd, SIOCGIFADDR, &ifreq) < 0) 2015 { 2016 /* 2017 * UP but no ip address, skip it 2018 */ 2019 if (errno == EADDRNOTAVAIL) continue; 2020 2021 RPC_DBG_PRINTF(rpc_e_dbg_general, 10, 2022 ("SIOCGIFADDR returned errno %d\n", errno)); 2023 if (errno == EINTR) 2024 { 2025 goto ifaddr_again; 2026 } 2027 2028 err = errno; 2029 goto FREE_IT; 2030 } 2031 2032 memcpy (&if_addr, &ifr->ifr_addr, sizeof(struct sockaddr)); 2033 2034#endif /* NO_SIOCGIFADDR */ 2035 2036 /* 2037 * If this isn't an Internet-family address, ignore it. 2038 */ 2039 if (if_addr.sa_family != AF_INET) 2040 { 2041 RPC_DBG_PRINTF(rpc_e_dbg_general, 10, ("AF %d not INET\n", 2042 if_addr.sa_family)); 2043 continue; 2044 } 2045 2046 if (rpc_addr_vec != NULL) 2047 { 2048 /* 2049 * Allocate and fill in an IP RPC address for this interface. 2050 */ 2051 RPC_MEM_ALLOC ( 2052 ip_addr, 2053 rpc_ip_addr_p_t, 2054 sizeof (rpc_ip_addr_t), 2055 RPC_C_MEM_RPC_ADDR, 2056 RPC_C_MEM_WAITOK); 2057 2058 if (ip_addr == NULL) 2059 { 2060 err = ENOMEM; 2061 goto FREE_IT; 2062 } 2063 2064 ip_addr->rpc_protseq_id = sock->pseq_id; 2065 ip_addr->len = sizeof (struct sockaddr_in); 2066 2067 memcpy (&ip_addr->sa, &if_addr, sizeof(struct sockaddr_in)); 2068 } 2069 else 2070 { 2071 ip_addr = NULL; 2072 } 2073 2074 if (netmask_addr_vec != NULL && (if_flags & IFF_LOOPBACK) == 0) 2075 { 2076 memcpy(&ifreq, ifr, sizeof(ifreq)); 2077 2078 while (ioctl(lrpc->fd, SIOCGIFNETMASK, &ifreq) == -1) 2079 { 2080 if (errno != EINTR) 2081 { 2082 err = errno; 2083 goto FREE_IT; 2084 } 2085 } 2086 2087 RPC_MEM_ALLOC ( 2088 netmask_addr, 2089 rpc_ip_addr_p_t, 2090 sizeof (rpc_ip_addr_t), 2091 RPC_C_MEM_RPC_ADDR, 2092 RPC_C_MEM_WAITOK); 2093 2094 if (netmask_addr == NULL) 2095 { 2096 err = ENOMEM; 2097 goto FREE_IT; 2098 } 2099 2100 netmask_addr->rpc_protseq_id = sock->pseq_id; 2101 netmask_addr->len = sizeof (struct sockaddr_in); 2102 memcpy(&netmask_addr->sa, &ifreq.ifr_addr, sizeof(struct sockaddr_in)); 2103 } 2104 else 2105 { 2106 netmask_addr = NULL; 2107 } 2108 2109 if (broadcast_addr_vec != NULL && (if_flags & IFF_BROADCAST)) 2110 { 2111 memcpy(&ifreq, ifr, sizeof(ifreq)); 2112 2113 while (ioctl(lrpc->fd, SIOCGIFBRDADDR, &ifreq) == -1) 2114 { 2115 if (errno != EINTR) 2116 { 2117 err = errno; 2118 goto FREE_IT; 2119 } 2120 } 2121 2122 RPC_MEM_ALLOC ( 2123 broadcast_addr, 2124 rpc_ip_addr_p_t, 2125 sizeof (rpc_ip_addr_t), 2126 RPC_C_MEM_RPC_ADDR, 2127 RPC_C_MEM_WAITOK); 2128 2129 if (broadcast_addr == NULL) 2130 { 2131 err = ENOMEM; 2132 goto FREE_IT; 2133 } 2134 2135 broadcast_addr->rpc_protseq_id = sock->pseq_id; 2136 broadcast_addr->len = sizeof (struct sockaddr_in); 2137 memcpy(&broadcast_addr->sa, &ifreq.ifr_broadaddr, sizeof(struct sockaddr_in)); 2138 } 2139 else 2140 { 2141 broadcast_addr = NULL; 2142 } 2143 2144 /* 2145 * Call out to do any final filtering and get the desired IP address 2146 * for this interface. If the callout function returns false, we 2147 * forget about this interface. 2148 */ 2149 if ((*efun) (sock, (rpc_addr_p_t) ip_addr, (rpc_addr_p_t) netmask_addr, (rpc_addr_p_t) broadcast_addr) == false) 2150 { 2151 if (ip_addr != NULL) 2152 { 2153 RPC_MEM_FREE (ip_addr, RPC_C_MEM_RPC_ADDR); 2154 ip_addr = NULL; 2155 } 2156 if (netmask_addr != NULL) 2157 { 2158 RPC_MEM_FREE (netmask_addr, RPC_C_MEM_RPC_ADDR); 2159 netmask_addr = NULL; 2160 } 2161 if (broadcast_addr != NULL) 2162 { 2163 RPC_MEM_FREE (broadcast_addr, RPC_C_MEM_RPC_ADDR); 2164 broadcast_addr = NULL; 2165 } 2166 continue; 2167 } 2168 2169 if (rpc_addr_vec != NULL && ip_addr != NULL) 2170 { 2171 (*rpc_addr_vec)->addrs[(*rpc_addr_vec)->len++] 2172 = (rpc_addr_p_t) ip_addr; 2173 ip_addr = NULL; 2174 } 2175 if (netmask_addr_vec != NULL && netmask_addr != NULL) 2176 { 2177 (*netmask_addr_vec)->addrs[(*netmask_addr_vec)->len++] 2178 = (rpc_addr_p_t) netmask_addr; 2179 netmask_addr = NULL; 2180 } 2181 if (broadcast_addr_vec != NULL && broadcast_addr != NULL) 2182 { 2183 (*broadcast_addr_vec)->addrs[(*broadcast_addr_vec)->len++] 2184 = (rpc_addr_p_t) broadcast_addr; 2185 broadcast_addr = NULL; 2186 } 2187 } 2188 2189 if ((*rpc_addr_vec)->len == 0) 2190 { 2191 err = EINVAL; /* !!! */ 2192 goto FREE_IT; 2193 } 2194 2195 err = RPC_C_SOCKET_OK; 2196done: 2197 2198 return err; 2199 2200FREE_IT: 2201 2202 if (ip_addr != NULL) 2203 { 2204 RPC_MEM_FREE (ip_addr, RPC_C_MEM_RPC_ADDR); 2205 } 2206 if (netmask_addr != NULL) 2207 { 2208 RPC_MEM_FREE (netmask_addr, RPC_C_MEM_RPC_ADDR); 2209 } 2210 if (broadcast_addr != NULL) 2211 { 2212 RPC_MEM_FREE (broadcast_addr, RPC_C_MEM_RPC_ADDR); 2213 } 2214 2215 if (rpc_addr_vec != NULL && *rpc_addr_vec != NULL) 2216 { 2217 for (i = 0; i < (*rpc_addr_vec)->len; i++) 2218 { 2219 RPC_MEM_FREE ((*rpc_addr_vec)->addrs[i], RPC_C_MEM_RPC_ADDR); 2220 } 2221 RPC_MEM_FREE (*rpc_addr_vec, RPC_C_MEM_RPC_ADDR_VEC); 2222 *rpc_addr_vec = NULL; 2223 } 2224 if (netmask_addr_vec != NULL && *netmask_addr_vec != NULL) 2225 { 2226 for (i = 0; i < (*netmask_addr_vec)->len; i++) 2227 { 2228 RPC_MEM_FREE ((*netmask_addr_vec)->addrs[i], RPC_C_MEM_RPC_ADDR); 2229 } 2230 RPC_MEM_FREE (*netmask_addr_vec, RPC_C_MEM_RPC_ADDR_VEC); 2231 *netmask_addr_vec = NULL; 2232 } 2233 if (broadcast_addr_vec != NULL && *broadcast_addr_vec != NULL) 2234 { 2235 assert(broadcast_addr_vec != NULL); 2236 for (i = 0; i < (*broadcast_addr_vec)->len; i++) 2237 { 2238 RPC_MEM_FREE ((*broadcast_addr_vec)->addrs[i], RPC_C_MEM_RPC_ADDR); 2239 } 2240 RPC_MEM_FREE (*broadcast_addr_vec, RPC_C_MEM_RPC_ADDR_VEC); 2241 *broadcast_addr_vec = NULL; 2242 } 2243 2244 goto done; 2245} 2246 2247INTERNAL 2248rpc_socket_error_t 2249rpc__bsd_socket_inq_transport_info( 2250 rpc_socket_t sock ATTRIBUTE_UNUSED, 2251 rpc_transport_info_handle_t* info 2252 ) 2253{ 2254 rpc_socket_error_t serr = RPC_C_SOCKET_OK; 2255 rpc_bsd_socket_p_t lrpc = (rpc_bsd_socket_p_t) sock->data.pointer; 2256 rpc_bsd_transport_info_p_t lrpc_info = NULL; 2257 2258 lrpc_info = calloc(1, sizeof(*lrpc_info)); 2259 2260 if (!lrpc_info) 2261 { 2262 serr = ENOMEM; 2263 goto error; 2264 } 2265 2266 lrpc_info->peer_uid = lrpc->info.peer_uid; 2267 lrpc_info->peer_gid = lrpc->info.peer_gid; 2268 2269 *info = (rpc_transport_info_handle_t) lrpc_info; 2270 2271error: 2272 if (serr) 2273 { 2274 *info = NULL; 2275 2276 if (lrpc_info) 2277 { 2278 rpc_lrpc_transport_info_free((rpc_transport_info_handle_t) lrpc_info); 2279 } 2280 } 2281 2282 return serr; 2283} 2284 2285void 2286rpc_lrpc_transport_info_free( 2287 rpc_transport_info_handle_t info 2288 ) 2289{ 2290 if (info) 2291 { 2292 free(info); 2293 } 2294} 2295 2296void 2297rpc_lrpc_transport_info_inq_peer_eid( 2298 rpc_transport_info_handle_t info, 2299 unsigned32 *uid, 2300 unsigned32 *gid 2301 ) 2302{ 2303 rpc_bsd_transport_info_p_t lrpc_info = (rpc_bsd_transport_info_p_t) info; 2304 2305 if (uid) 2306 { 2307 *uid = lrpc_info->peer_uid; 2308 } 2309 2310 if (gid) 2311 { 2312 *gid = lrpc_info->peer_gid; 2313 } 2314} 2315 2316INTERNAL 2317boolean 2318rpc__bsd_socket_transport_info_equal( 2319 rpc_transport_info_handle_t info1, 2320 rpc_transport_info_handle_t info2 2321 ) 2322{ 2323 rpc_bsd_transport_info_p_t bsd_info1 = (rpc_bsd_transport_info_p_t) info1; 2324 rpc_bsd_transport_info_p_t bsd_info2 = (rpc_bsd_transport_info_p_t) info2; 2325 2326 if ((bsd_info1 != NULL) && (bsd_info2 != NULL)) 2327 { 2328 return 2329 (bsd_info1->peer_uid == bsd_info2->peer_uid && 2330 bsd_info1->peer_gid == bsd_info2->peer_gid); 2331 } else if (bsd_info1 == bsd_info2){ 2332 return true; 2333 } 2334 2335 rpc_bsd_transport_info_p_t tmp = bsd_info1 != NULL ? bsd_info1: bsd_info2; 2336 return (tmp->peer_uid == getuid() && tmp->peer_gid == getgid()); 2337} 2338 2339INTERNAL 2340rpc_socket_error_t 2341rpc__bsd_socket_transport_inq_access_token( 2342 rpc_transport_info_handle_t info ATTRIBUTE_UNUSED, 2343 rpc_access_token_p_t* token ATTRIBUTE_UNUSED 2344 ) 2345{ 2346#if HAVE_LIKEWISE_LWMAPSECURITY 2347 rpc_bsd_transport_info_p_t lrpc_info = (rpc_bsd_transport_info_p_t) info; 2348 NTSTATUS status = STATUS_SUCCESS; 2349 PLW_MAP_SECURITY_CONTEXT context = NULL; 2350 2351 status = LwMapSecurityCreateContext(&context); 2352 if (status) goto error; 2353 2354 status = LwMapSecurityCreateAccessTokenFromUidGid( 2355 context, 2356 token, 2357 lrpc_info->peer_uid, 2358 lrpc_info->peer_gid); 2359 if (status) goto error; 2360 2361error: 2362 2363 LwMapSecurityFreeContext(&context); 2364 2365 return LwNtStatusToErrno(status); 2366#else 2367 return RPC_C_SOCKET_ENOTSUP; 2368#endif 2369} 2370 2371PRIVATE const rpc_socket_vtbl_t rpc_g_bsd_socket_vtbl = 2372{ 2373 .socket_duplicate = rpc__bsd_socket_duplicate, 2374 .socket_construct = rpc__bsd_socket_construct, 2375 .socket_destruct = rpc__bsd_socket_destruct, 2376 .socket_bind = rpc__bsd_socket_bind, 2377 .socket_connect = rpc__bsd_socket_connect, 2378 .socket_accept = rpc__bsd_socket_accept, 2379 .socket_listen = rpc__bsd_socket_listen, 2380 .socket_sendmsg = rpc__bsd_socket_sendmsg, 2381 .socket_recvfrom = rpc__bsd_socket_recvfrom, 2382 .socket_recvmsg = rpc__bsd_socket_recvmsg, 2383 .socket_inq_endpoint = rpc__bsd_socket_inq_endpoint, 2384 .socket_set_broadcast = rpc__bsd_socket_set_broadcast, 2385 .socket_set_bufs = rpc__bsd_socket_set_bufs, 2386 .socket_set_nbio = rpc__bsd_socket_set_nbio, 2387 .socket_set_close_on_exec = rpc__bsd_socket_set_close_on_exec, 2388 .socket_getpeername = rpc__bsd_socket_getpeername, 2389 .socket_get_if_id = rpc__bsd_socket_get_if_id, 2390 .socket_set_keepalive = rpc__bsd_socket_set_keepalive, 2391 .socket_nowriteblock_wait = rpc__bsd_socket_nowriteblock_wait, 2392 .socket_set_rcvtimeo = rpc__bsd_socket_set_rcvtimeo, 2393 .socket_getpeereid = rpc__bsd_socket_getpeereid, 2394 .socket_get_select_desc = rpc__bsd_socket_get_select_desc, 2395 .socket_enum_ifaces = rpc__bsd_socket_enum_ifaces, 2396 .socket_inq_transport_info = rpc__bsd_socket_inq_transport_info, 2397 .transport_info_free = rpc_lrpc_transport_info_free, 2398 .transport_info_equal = rpc__bsd_socket_transport_info_equal, 2399 .transport_inq_access_token = rpc__bsd_socket_transport_inq_access_token 2400}; 2401