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** mgmt.c 82** 83** FACILITY: 84** 85** Remote Procedure Call (RPC) 86** 87** ABSTRACT: 88** 89** Definition of the Management Component of the RPC Runtime Sytem. 90** This module contains both Local management functions (those which 91** only execute locally) and Local/Remote management functions (those 92** which can execute either locally or on a remote server). The class 93** into which each function falls is identified in its description. 94** For each Local/Remote function there is a corresponding routine that 95** provides the remote (manager) implementation of its functionality. 96** 97** 98*/ 99 100#include <commonp.h> /* Common declarations for all RPC runtime */ 101#include <com.h> /* Common communications services */ 102#include <comp.h> /* Private communications services */ 103#include <mgmtp.h> /* Private management services */ 104#include <dce/mgmt.h> /* Remote RPC Management Interface */ 105 106 107/* 108 * Authorization function to use to check remote access. 109 */ 110 111INTERNAL rpc_mgmt_authorization_fn_t authorization_fn = NULL; 112 113/* 114 * Default server comm timeout value. 115 */ 116INTERNAL unsigned32 server_com_timeout; 117 118/* 119 * Size of buffer used when asking for remote server's principal name 120 */ 121 122#define MAX_SERVER_PRINC_NAME_LEN 500 123 124 125/* 126 * Forward definitions of network manager entry points (implementation 127 * of mgmt.idl). 128 */ 129 130INTERNAL void inq_if_ids ( 131 rpc_binding_handle_t /*binding_h*/, 132 rpc_if_id_vector_p_t * /*if_id_vector*/, 133 unsigned32 * /*status*/ 134 ); 135 136INTERNAL void inq_stats ( 137 rpc_binding_handle_t /*binding_h*/, 138 unsigned32 * /*count*/, 139 unsigned32 statistics[], 140 unsigned32 * /*status*/ 141 ); 142 143INTERNAL boolean32 is_server_listening ( 144 rpc_binding_handle_t /*binding_h*/, 145 unsigned32 * /*status*/ 146 ); 147 148 149INTERNAL void inq_princ_name ( 150 rpc_binding_handle_t /*binding_h*/, 151 unsigned32 /*authn_proto*/, 152 unsigned32 /*princ_name_size*/, 153 idl_char princ_name[], 154 unsigned32 * /*status*/ 155 ); 156 157 158INTERNAL idl_void_p_t my_allocate ( 159 idl_void_p_t /* context */, 160 idl_size_t /*size*/ 161 ); 162 163INTERNAL void my_free ( 164 idl_void_p_t /* context */, 165 idl_void_p_t /*ptr*/ 166 ); 167 168INTERNAL void remote_binding_validate ( 169 rpc_binding_handle_t /*binding_h*/, 170 unsigned32 * /*status*/ 171 ); 172 173 174/* 175**++ 176** 177** ROUTINE NAME: rpc__mgmt_init 178** 179** SCOPE: PRIVATE - declared in cominit.c 180** 181** DESCRIPTION: 182** 183** Initialize the management component. Register the remote management 184** interface for the RPC runtime. 185** 186** INPUTS: none 187** 188** INPUTS/OUTPUTS: none 189** 190** OUTPUTS: none 191** 192** IMPLICIT INPUTS: none 193** 194** IMPLICIT OUTPUTS: none 195** 196** FUNCTION VALUE: 197** 198** returns rpc_s_ok if everything went well, otherwise returns 199** an error status 200** 201** SIDE EFFECTS: none 202** 203**-- 204**/ 205 206PRIVATE unsigned32 rpc__mgmt_init(void) 207 208{ 209 unsigned32 status; 210 211 /* 212 * Manager EPV for implementation of mgmt.idl. 213 */ 214 static mgmt_v1_0_epv_t mgmt_v1_0_mgr_epv = 215 { 216 inq_if_ids, 217 inq_stats, 218 is_server_listening, 219 rpc__mgmt_stop_server_lsn_mgr, 220 inq_princ_name, 221 rpc_mgmt_set_server_idle_timeout, 222 rpc_mgmt_inq_server_idle_timeout 223 }; 224 225 /* 226 * register the remote management interface with the runtime 227 * as an internal interface 228 */ 229 rpc__server_register_if_int 230 ((rpc_if_handle_t) mgmt_v1_0_s_ifspec, NULL, 231 (rpc_mgr_epv_t) &mgmt_v1_0_mgr_epv, 0, 232 rpc_c_listen_max_calls_default, -1, NULL, 233 true, &status); 234 235 authorization_fn = NULL; 236 237 server_com_timeout = rpc_c_binding_default_timeout; 238 239 return (status); 240} 241 242/* 243**++ 244** 245** ROUTINE NAME: rpc_mgmt_inq_com_timeout 246** 247** SCOPE: PUBLIC - declared in rpc.idl 248** 249** DESCRIPTION: 250** 251** This is a Local management function that inquires what the timeout 252** value is in a binding. 253** 254** INPUTS: 255** 256** binding_h The binding handle which points to the binding 257** rep data structure to be read. 258** 259** INPUTS/OUTPUTS: none 260** 261** OUTPUTS: 262** 263** timeout The relative timeout value used when making a 264** connection to the location specified in the 265** binding rep. 266** 267** status A value indicating the status of the routine. 268** 269** rpc_s_ok The call was successful. 270** rpc_s_invalid_binding 271** RPC Protocol ID in binding handle was invalid. 272** 273** IMPLICIT INPUTS: none 274** 275** IMPLICIT OUTPUTS: none 276** 277** FUNCTION VALUE: void 278** 279** SIDE EFFECTS: none 280** 281**-- 282**/ 283 284PUBLIC void rpc_mgmt_inq_com_timeout (binding_handle, timeout, status) 285 286rpc_binding_handle_t binding_handle; 287unsigned32 *timeout; 288unsigned32 *status; 289 290{ 291 rpc_binding_rep_p_t binding_rep = (rpc_binding_rep_p_t) binding_handle; 292 293 assert(binding_rep != NULL); 294 295 RPC_VERIFY_INIT (); 296 297 RPC_BINDING_VALIDATE_CLIENT(binding_rep, status); 298 if (*status != rpc_s_ok) 299 return; 300 301 *timeout = binding_rep->timeout; 302 *status = rpc_s_ok; 303} 304 305/* 306**++ 307** 308** ROUTINE NAME: rpc_mgmt_inq_server_com_timeout 309** 310** SCOPE: PUBLIC - declared in rpcpvt.idl 311** 312** DESCRIPTION: 313** 314** This is a Local management function that returns the default server-side 315** com timeout setting. 316** 317** INPUTS: none 318** 319** INPUTS/OUTPUTS: none 320** 321** OUTPUTS: none 322** RPC Protocol ID in binding handle was invalid. 323** 324** IMPLICIT INPUTS: none 325** 326** IMPLICIT OUTPUTS: none 327** 328** FUNCTION VALUE: unsigned32, the current com timeout setting 329** 330** SIDE EFFECTS: none 331** 332**-- 333**/ 334 335PUBLIC unsigned32 rpc_mgmt_inq_server_com_timeout (void) 336 337{ 338 RPC_VERIFY_INIT (); 339 340 return (server_com_timeout); 341} 342 343 344/* 345**++ 346** 347** ROUTINE NAME: rpc_mgmt_inq_if_ids 348** 349** SCOPE: PUBLIC - declared in rpc.idl 350** 351** DESCRIPTION: 352** 353** This is a Local/Remote management function that obtains a vector of 354** interface identifications listing the interfaces registered with the 355** RPC runtime. If a server has not registered any interfaces this routine 356** will return an rpc_s_no_interfaces status code and a NULL if_id_vector. 357** The application is responsible for calling rpc_if_id_vector_free to 358** release the memory used by the vector. 359** 360** INPUTS: 361** 362** binding_h The binding handle for this remote call. 363** 364** INPUTS/OUTPUTS: none 365** 366** OUTPUTS: 367** 368** if_id_vector A vector of the if id's registered for this server 369** 370** status A value indicating the status of the routine. 371** 372** rpc_s_ok The call was successful. 373** rpc_s_invalid_binding 374** RPC Protocol ID in binding handle was invalid. 375** 376** IMPLICIT INPUTS: none 377** 378** IMPLICIT OUTPUTS: none 379** 380** FUNCTION VALUE: void 381** 382** SIDE EFFECTS: none 383** 384**-- 385**/ 386 387PRIVATE void rpc_mgmt_inq_if_ids 388( 389 rpc_binding_handle_t binding_h, 390 rpc_if_id_vector_p_t *if_id_vector, 391 unsigned32 *status 392) 393{ 394 rpc_ss_p_alloc_t old_allocate; 395 rpc_ss_p_alloc_t tmp_allocate; 396 rpc_ss_p_free_t old_free; 397 rpc_ss_p_free_t tmp_free; 398 399 RPC_VERIFY_INIT (); 400 401 /* 402 * if this is a local request, just do it locally 403 */ 404 if (binding_h == NULL) 405 { 406 rpc__if_mgmt_inq_if_ids (if_id_vector, status); 407 } 408 else 409 { 410 remote_binding_validate(binding_h, status); 411 if (*status != rpc_s_ok) 412 return; 413 414 /* 415 * force the stubs to use malloc and free (because the caller is going 416 * to have to free the if id vector using rpc_if_id_vector_free() later 417 */ 418 rpc_ss_swap_client_alloc_free 419 (my_allocate, my_free, &old_allocate, &old_free); 420 421 /* 422 * call the corresponding remote routine to get an if id vector 423 */ 424 (*mgmt_v1_0_c_epv.rpc__mgmt_inq_if_ids) 425 (binding_h, if_id_vector, status); 426 427 if (*status == rpc_s_call_cancelled) 428 dcethread_interrupt_throw(dcethread_self()); 429 430 /* 431 * restore the memory allocation scheme in effect before we got here 432 */ 433 rpc_ss_swap_client_alloc_free 434 (old_allocate, old_free, &tmp_allocate, &tmp_free); 435 } 436} 437 438/* 439**++ 440** 441** ROUTINE NAME: rpc_mgmt_inq_stats 442** 443** SCOPE: PUBLIC - declared in rpc.idl 444** 445** DESCRIPTION: 446** 447** This is a Local/Remote management function that obtains statistics 448** about the specified server from the RPC runtime. Each element in the 449** returned argument contains an integer value which can be indexed using 450** the defined statistics constants. 451** 452** INPUTS: 453** 454** binding_h The binding handle for this remote call. 455** 456** INPUTS/OUTPUTS: none 457** 458** OUTPUTS: 459** 460** stats An vector of statistics values for this server. 461** 462** status A value indicating the status of the routine. 463** 464** rpc_s_ok The call was successful. 465** rpc_s_invalid_binding 466** RPC Protocol ID in binding handle was invalid. 467** 468** IMPLICIT INPUTS: none 469** 470** IMPLICIT OUTPUTS: none 471** 472** FUNCTION VALUE: void 473** 474** SIDE EFFECTS: none 475** 476**-- 477**/ 478 479PUBLIC void rpc_mgmt_inq_stats 480( 481 rpc_binding_handle_t binding_h, 482 rpc_stats_vector_p_t *statistics, 483 unsigned32 *status 484) 485{ 486 unsigned32 i; 487 488 RPC_VERIFY_INIT (); 489 490 /* 491 * Allocate a stats vector large enough to hold all the 492 * statistics we know about and set the vector count to match 493 * the size allocated. 494 */ 495 RPC_MEM_ALLOC (*statistics, rpc_stats_vector_p_t, 496 sizeof (rpc_stats_vector_t) 497 + (sizeof ((*statistics)->stats) * 498 (rpc_c_stats_array_max_size - 1)), 499 RPC_C_MEM_STATS_VECTOR, 500 RPC_C_MEM_WAITOK); 501 (*statistics)->count = rpc_c_stats_array_max_size; 502 503 /* 504 * If this is a local request, just do it locally. 505 */ 506 if (binding_h == NULL) 507 { 508 /* 509 * Clear the output array and query each protocol service 510 * for its information. Sum the results in the output array. 511 */ 512 memset (&(*statistics)->stats[0], 0, ((*statistics)->count * sizeof (unsigned32))); 513 for (i = 0; i < RPC_C_PROTOCOL_ID_MAX; i++) 514 { 515 if (RPC_PROTOCOL_INQ_SUPPORTED (i)) 516 { 517 (*statistics)->stats[rpc_c_stats_calls_in] += 518 (*rpc_g_protocol_id[i].mgmt_epv->mgmt_inq_calls_rcvd)(); 519 520 (*statistics)->stats[rpc_c_stats_calls_out] += 521 (*rpc_g_protocol_id[i].mgmt_epv->mgmt_inq_calls_sent)(); 522 523 (*statistics)->stats[rpc_c_stats_pkts_in] += 524 (*rpc_g_protocol_id[i].mgmt_epv->mgmt_inq_pkts_rcvd)(); 525 526 (*statistics)->stats[rpc_c_stats_pkts_out] += 527 (*rpc_g_protocol_id[i].mgmt_epv->mgmt_inq_pkts_sent)(); 528 } 529 } 530 *status = rpc_s_ok; 531 } 532 else 533 { 534 535 remote_binding_validate(binding_h, status); 536 if (*status != rpc_s_ok) 537 return; 538 539 /* 540 * Call the corresponding remote routine to get remote stats. 541 */ 542 (*mgmt_v1_0_c_epv.rpc__mgmt_inq_stats) (binding_h, 543 &(*statistics)->count, 544 &(*statistics)->stats[0], 545 status); 546 547 if (*status == rpc_s_call_cancelled) 548 dcethread_interrupt_throw(dcethread_self()); 549 } 550} 551 552/* 553**++ 554** 555** ROUTINE NAME: rpc_mgmt_stats_vector_free 556** 557** SCOPE: PUBLIC - declared in rpc.idl 558** 559** DESCRIPTION: 560** 561** This routine will free the statistics vector memory allocated by 562** and returned by rpc_mgmt_inq_stats. 563** 564** INPUTS: none 565** 566** INPUTS/OUTPUTS: 567** 568** stats A pointer to a pointer to the stats vector. 569** The contents will be NULL on output. 570** 571** OUTPUTS: 572** 573** status A value indicating the status of the routine. 574** 575** rpc_s_ok The call was successful. 576** 577** IMPLICIT INPUTS: none 578** 579** IMPLICIT OUTPUTS: none 580** 581** FUNCTION VALUE: void 582** 583** SIDE EFFECTS: none 584** 585**-- 586**/ 587 588PUBLIC void rpc_mgmt_stats_vector_free 589( 590 rpc_stats_vector_p_t *statistics, 591 unsigned32 *status 592) 593{ 594 RPC_MEM_FREE (*statistics, RPC_C_MEM_STATS_VECTOR); 595 *statistics = NULL; 596 *status = rpc_s_ok; 597} 598 599/* 600**++ 601** 602** ROUTINE NAME: rpc_mgmt_is_server_listening 603** 604** SCOPE: PUBLIC - declared in rpc.idl 605** 606** DESCRIPTION: 607** 608** This is a Local/Remote management function that determines if the 609** specified server is listening for remote procedure calls. 610** 611** INPUTS: 612** 613** binding_h The binding handle for this remote call. 614** 615** INPUTS/OUTPUTS: none 616** 617** OUTPUTS: 618** 619** status A value indicating the status of the routine. 620** 621** rpc_s_ok The call was successful. 622** rpc_s_invalid_binding 623** RPC Protocol ID in binding handle was invalid. 624** 625** IMPLICIT INPUTS: none 626** 627** IMPLICIT OUTPUTS: none 628** 629** FUNCTION VALUE: 630** 631** true - if server is listening 632** false - if server is not listening :-) 633** 634** SIDE EFFECTS: none 635** 636**-- 637**/ 638 639PUBLIC boolean32 rpc_mgmt_is_server_listening 640( 641 rpc_binding_handle_t binding_h, 642 unsigned32 *status 643) 644{ 645 646 RPC_VERIFY_INIT (); 647 648 /* 649 * if this is a local request, just do it locally 650 */ 651 if (binding_h == NULL) 652 { 653 *status = rpc_s_ok; 654 return (rpc__server_is_listening()); 655 } 656 else 657 { 658 remote_binding_validate(binding_h, status); 659 if (*status != rpc_s_ok) 660 return (false); 661 662 /* 663 * call the corresponding remote routine 664 */ 665 (*mgmt_v1_0_c_epv.rpc__mgmt_is_server_listening) (binding_h, status); 666 667 if (*status == rpc_s_call_cancelled) 668 dcethread_interrupt_throw(dcethread_self()); 669 670 return (*status == rpc_s_ok ? true : false); 671 } 672} 673 674/* 675**++ 676** 677** ROUTINE NAME: rpc_mgmt_set_server_idle_timeout 678** 679** SCOPE: PUBLIC - declared in rpc.idl 680** 681** DESCRIPTION: 682** 683** This is a Local/Remote management function that determines sets the 684** idle timout for a server. If the server is idle for the specified number 685** of seconds, it is free to exit. 686** 687** INPUTS: 688** 689** binding_h The binding handle for this remote call. 690** idle_secs The idle timout in seconds. 691** 692** INPUTS/OUTPUTS: none 693** 694** OUTPUTS: 695** 696** status A value indicating the status of the routine. 697** 698** rpc_s_ok The call was successful. 699** rpc_s_invalid_binding 700** RPC Protocol ID in binding handle was invalid. 701** 702** IMPLICIT INPUTS: none 703** 704** IMPLICIT OUTPUTS: none 705** 706** FUNCTION VALUE: void 707** 708** SIDE EFFECTS: none 709** 710**-- 711**/ 712 713PUBLIC void rpc_mgmt_set_server_idle_timeout 714( 715 rpc_binding_handle_t binding_h, 716 unsigned32 idle_secs, 717 unsigned32 *status 718) 719{ 720 721 RPC_VERIFY_INIT (); 722 723 /* 724 * if this is a local request, just do it locally 725 */ 726 if (binding_h == NULL) 727 { 728 *status = rpc_s_ok; 729 rpc__server_set_idle_timeout(idle_secs, status); 730 } 731 else 732 { 733 remote_binding_validate(binding_h, status); 734 if (*status != rpc_s_ok) 735 return; 736 737 /* 738 * call the corresponding remote routine 739 */ 740 (*mgmt_v1_0_c_epv.rpc__mgmt_set_server_idle_timeout) 741 (binding_h, idle_secs, status); 742 743 if (*status == rpc_s_call_cancelled) 744 dcethread_interrupt_throw(dcethread_self()); 745 } 746} 747 748/* 749**++ 750** 751** ROUTINE NAME: rpc_mgmt_inq_server_idle_timeout 752** 753** SCOPE: PUBLIC - declared in rpc.idl 754** 755** DESCRIPTION: 756** 757** This is a Local/Remote management function that queries the 758** idle timout for a server. If the server is idle for the specified 759** number of seconds, it is free to exit. 760** 761** INPUTS: 762** 763** binding_h The binding handle for this remote call. 764** 765** INPUTS/OUTPUTS: none 766** 767** OUTPUTS: 768** 769** status A value indicating the status of the routine. 770** 771** rpc_s_ok The call was successful. 772** rpc_s_invalid_binding 773** RPC Protocol ID in binding handle was invalid. 774** 775** IMPLICIT INPUTS: none 776** 777** IMPLICIT OUTPUTS: none 778** 779** FUNCTION VALUE: void 780** 781** return - The idle timeout in seconds. 782** 783** SIDE EFFECTS: none 784** 785**-- 786**/ 787 788PUBLIC unsigned32 rpc_mgmt_inq_server_idle_timeout 789( 790 rpc_binding_handle_t binding_h, 791 error_status_t *status 792) 793{ 794 795 RPC_VERIFY_INIT (); 796 797 /* 798 * if this is a local request, just do it locally 799 */ 800 if (binding_h == NULL) 801 { 802 *status = rpc_s_ok; 803 return rpc__server_inq_idle_timeout(); 804 } 805 else 806 { 807 remote_binding_validate(binding_h, status); 808 if (*status != rpc_s_ok) 809 return (false); 810 811 /* 812 * call the corresponding remote routine 813 */ 814 (*mgmt_v1_0_c_epv.rpc__mgmt_inq_server_idle_timeout) 815 (binding_h, status); 816 817 if (*status == rpc_s_call_cancelled) 818 dcethread_interrupt_throw(dcethread_self()); 819 820 return (*status == rpc_s_ok ? true : false); 821 } 822} 823 824 825/* 826**++ 827** 828** ROUTINE NAME: rpc_mgmt_set_cancel_timeout 829** 830** SCOPE: PUBLIC - declared in rpc.idl 831** 832** DESCRIPTION: 833** 834** This is a Local management function that sets the amount of time the 835** RPC runtime is to wait for a server to acknowledge a cancel before 836** orphaning the call. The application should specify to either wait 837** forever or to wait the length of the time specified in seconds. If the 838** value of seconds is 0 the remote procedure call is orphaned as soon as 839** a cancel is received by the server and control returns immediately to 840** the client application. The default is to wait forever for the call to 841** complete. 842** 843** The value for the cancel timeout applies to all remote procedure calls 844** made in the current thread. A multi-threaded client that wishes to change 845** the default timeout value must call this routine in each thread of 846** execution. 847** 848** INPUTS: 849** 850** seconds The number of seconds to wait for an acknowledgement. 851** 852** INPUTS/OUTPUTS: none 853** 854** OUTPUTS: 855** 856** status A value indicating the status of the routine. 857** 858** rpc_s_ok The call was successful. 859** rpc_s_no_memory 860** rpc_s_coding_error 861** 862** IMPLICIT INPUTS: none 863** 864** IMPLICIT OUTPUTS: none 865** 866** FUNCTION VALUE: void 867** 868** SIDE EFFECTS: none 869** 870**-- 871**/ 872 873PUBLIC void rpc_mgmt_set_cancel_timeout 874( 875 signed32 seconds, 876 unsigned32 *status 877) 878{ 879 CODING_ERROR (status); 880 RPC_VERIFY_INIT (); 881 882 /* 883 * set the cancel timeout value in the per-thread context block 884 * for this thread 885 */ 886 RPC_SET_CANCEL_TIMEOUT (seconds, status); 887} 888 889/* 890**++ 891** 892** ROUTINE NAME: rpc_mgmt_set_call_timeout 893** 894** SCOPE: PUBLIC - (SHOULD BE) declared in rpc.idl 895** 896** DESCRIPTION: 897** 898** This is a Local management function that sets the amount of time the 899** RPC runtime is to wait for a server to complete a call. A timeout of 900** 0 means no max call execution time is imposed (this is the default). 901** 902** The value for the call timeout applies to all remote procedure calls 903** made using the specified binding handle. 904** 905** This function currently is NOT a documented API operation (i.e. it 906** is not in rpc.idl). At least initially, only the ncadg_ protocols 907** support the use of this timeout. This function is necessary for 908** "kernel" RPC support since kernels don't support a cancel mechanism. 909** User space applications can build an equivalent mechanism using 910** cancels. This code is not conditionally compiled for the kernel 911** so that we can test it in user space. 912** 913** INPUTS: 914** 915** binding The binding handle to use. 916** seconds The number of seconds to wait for call completion. 917** 918** INPUTS/OUTPUTS: none 919** 920** OUTPUTS: 921** 922** status A value indicating the status of the routine. 923** 924** rpc_s_ok The call was successful. 925** rpc_s_no_memory 926** rpc_s_coding_error 927** rpc_s_invalid_binding 928** RPC Protocol ID in binding handle was invalid. 929** 930** IMPLICIT INPUTS: none 931** 932** IMPLICIT OUTPUTS: none 933** 934** FUNCTION VALUE: void 935** 936** SIDE EFFECTS: none 937** 938**-- 939**/ 940 941PUBLIC void rpc_mgmt_set_call_timeout ( 942 rpc_binding_handle_t /*binding_h*/, 943 unsigned32 /*seconds*/, 944 unsigned32 * /*status*/ 945 ); 946 947PUBLIC void rpc_mgmt_set_call_timeout 948( 949 rpc_binding_handle_t binding_h, 950 unsigned32 seconds, 951 unsigned32 *status 952) 953{ 954 rpc_binding_rep_p_t binding_rep = (rpc_binding_rep_p_t) binding_h; 955 956 assert(binding_rep != NULL); 957 958 CODING_ERROR (status); 959 RPC_VERIFY_INIT (); 960 961 RPC_BINDING_VALIDATE_CLIENT(binding_rep, status); 962 if (*status != rpc_s_ok) 963 return; 964 965 binding_rep->call_timeout_time = RPC_CLOCK_SEC(seconds); 966 *status = rpc_s_ok; 967} 968 969/* 970**++ 971** 972** ROUTINE NAME: rpc_mgmt_set_com_timeout 973** 974** SCOPE: PUBLIC - declared in rpc.idl 975** 976** DESCRIPTION: 977** 978** This is a Local management function that sets the RPC timeout for a 979** binding. The timeout value is a metric indicating the relative amount 980** of time retries to contact the server should be made. The value 10 981** indicates an unbounded wait. A zero value indicates no wait. Values 1-5 982** favor fast reponse time over correctness in determining whether the server 983** is alive. Values 6-9 favor correctness over response time. The RPC 984** Protocol Service identified by the RPC Protocol ID in the Binding Rep 985** will be notified that the Binding Rep has changed. 986** 987** INPUTS: 988** 989** binding_h The binding handle which points to the binding 990** rep data structure to be modified. 991** 992** timeout The relative timeout value to be used when making 993** a connection to the location in the binding rep. 994** 995** 0 - rpc_c_binding_min_timeout 996** 5 - rpc_c_binding_default_timeout 997** 9 - rpc-c_binding_max_timeout 998** 10 - rpc_c_binding_infinite_timeout 999** 1000** INPUTS/OUTPUTS: none 1001** 1002** OUTPUTS: 1003** 1004** status A value indicating the status of the routine. 1005** 1006** rpc_s_ok The call was successful. 1007** rpc_s_invalid_binding 1008** RPC Protocol ID in binding handle was invalid. 1009** rpc_s_invalid_timeout 1010** Timeout value is not in the range -1 to 10 1011** rpc_s_coding_error 1012** 1013** IMPLICIT INPUTS: none 1014** 1015** IMPLICIT OUTPUTS: none 1016** 1017** FUNCTION VALUE: void 1018** 1019** SIDE EFFECTS: none 1020** 1021**-- 1022**/ 1023 1024PUBLIC void rpc_mgmt_set_com_timeout 1025( 1026 rpc_binding_handle_t binding_h, 1027 unsigned32 timeout, 1028 unsigned32 *status 1029) 1030{ 1031 rpc_binding_rep_p_t binding_rep = (rpc_binding_rep_p_t) binding_h; 1032 1033 assert(binding_rep != NULL); 1034 1035 CODING_ERROR (status); 1036 RPC_VERIFY_INIT (); 1037 1038 RPC_BINDING_VALIDATE_CLIENT(binding_rep, status); 1039 if (*status != rpc_s_ok) 1040 return; 1041 1042 /* 1043 * see if the timeout value is valid 1044 */ 1045 if (/*timeout < rpc_c_binding_min_timeout ||*/ 1046 timeout > rpc_c_binding_max_timeout) 1047 { 1048 if (timeout != rpc_c_binding_infinite_timeout) 1049 { 1050 *status = rpc_s_invalid_timeout; 1051 return; 1052 } 1053 } 1054 1055 /* 1056 * copy the new timeout value into the binding rep 1057 */ 1058 binding_rep->timeout = timeout; 1059 1060 /* 1061 * notify the protocol service that the binding has changed 1062 */ 1063#ifdef FOO 1064 1065Note: there should be a dispatching routine in com... 1066 1067 (*rpc_g_protocol_id[binding_rep->protocol_id].binding_epv 1068 ->binding_changed) (binding_rep, status); 1069 1070#else 1071 1072 *status = rpc_s_ok; 1073 1074#endif 1075} 1076 1077/* 1078**++ 1079** 1080** ROUTINE NAME: rpc_mgmt_set_server_com_timeout 1081** 1082** SCOPE: PUBLIC - declared in rpcpvt.idl 1083** 1084** DESCRIPTION: 1085** 1086** This is a Local management function that sets a default RPC timeout for 1087** all calls handled by a server. The timeout value is a metric indicating 1088** the relative amount of time retries to contact the client should be made. 1089** The value 10 indicates an unbounded wait. A zero value indicates no wait. 1090** Values 1-5 favor fast reponse time over correctness in determining whether 1091** the client is alive. Values 6-9 favor correctness over response time. 1092** 1093** INPUTS: 1094** 1095** timeout The relative timeout value to be used by all calls 1096** run on this server. 1097** 1098** 0 - rpc_c_binding_min_timeout 1099** 5 - rpc_c_binding_default_timeout 1100** 9 - rpc-c_binding_max_timeout 1101** 10 - rpc_c_binding_infinite_timeout 1102** 1103** INPUTS/OUTPUTS: none 1104** 1105** OUTPUTS: 1106** 1107** status A value indicating the status of the routine. 1108** 1109** rpc_s_ok The call was successful. 1110** rpc_s_invalid_timeout 1111** Timeout value is not in the range -1 to 10 1112** rpc_s_coding_error 1113** 1114** IMPLICIT INPUTS: none 1115** 1116** IMPLICIT OUTPUTS: none 1117** 1118** FUNCTION VALUE: void 1119** 1120** SIDE EFFECTS: none 1121** 1122**-- 1123**/ 1124 1125PUBLIC void rpc_mgmt_set_server_com_timeout 1126( 1127 unsigned32 timeout, 1128 unsigned32 * status 1129) 1130{ 1131 1132 CODING_ERROR (status); 1133 RPC_VERIFY_INIT (); 1134 1135 /* 1136 * see if the timeout value is valid 1137 */ 1138 if (/*timeout < rpc_c_binding_min_timeout ||*/ 1139 timeout > rpc_c_binding_max_timeout) 1140 { 1141 if (timeout != rpc_c_binding_infinite_timeout) 1142 { 1143 *status = rpc_s_invalid_timeout; 1144 return; 1145 } 1146 } 1147 1148 server_com_timeout = timeout; 1149 1150 *status = rpc_s_ok; 1151} 1152 1153/* 1154**++ 1155** 1156** ROUTINE NAME: rpc_mgmt_set_server_stack_size 1157** 1158** SCOPE: PUBLIC - declared in rpc.idl 1159** 1160** DESCRIPTION: 1161** 1162** This is a Local management function that sets the value that the 1163** RPC runtime is to use in specifying the the thread stack size when 1164** creating call threads. This value will be applied to all threads 1165** created for the server. 1166** 1167** INPUTS: 1168** 1169** thread_stack_size The value to be used by the RPC runtime for 1170** specifying the stack size when creating threads. 1171** 1172** INPUTS/OUTPUTS: none 1173** 1174** OUTPUTS: 1175** 1176** status A value indicating the status of the routine. 1177** 1178** rpc_s_ok The call was successful. 1179** rpc_s_coding_error 1180** 1181** IMPLICIT INPUTS: none 1182** 1183** IMPLICIT OUTPUTS: none 1184** 1185** FUNCTION VALUE: void 1186** 1187** SIDE EFFECTS: none 1188** 1189**-- 1190**/ 1191 1192PUBLIC void rpc_mgmt_set_server_stack_size 1193( 1194 unsigned32 thread_stack_size, 1195 unsigned32 *status 1196) 1197{ 1198 CODING_ERROR (status); 1199 RPC_VERIFY_INIT (); 1200 1201/* !!! the 2nd one is due to a CMA pthreads bug and should go away */ 1202#if !defined(_POSIX_THREAD_ATTR_STACKSIZE) && !defined(_POSIX_PTHREAD_ATTR_STACKSIZE) 1203 *status = rpc_s_not_supported; 1204#else 1205# ifndef PTHREAD_EXC 1206 if (dcethread_attr_setstacksize_throw 1207 (&rpc_g_server_dcethread_attr, thread_stack_size) == -1) 1208 { 1209 *status = rpc_s_invalid_arg; 1210 return; 1211 } 1212 1213 *status = rpc_s_ok; 1214# else 1215 1216 dcethread_attr_setstacksize 1217 (&rpc_g_server_dcethread_attr, thread_stack_size); 1218 1219 *status = rpc_s_ok; 1220# endif 1221#endif 1222} 1223 1224/* 1225**++ 1226** 1227** ROUTINE NAME: rpc_mgmt_stop_server_listening 1228** 1229** SCOPE: PUBLIC - declared in rpc.idl 1230** 1231** DESCRIPTION: 1232** 1233** This is a Local/Remote management function that directs a server to 1234** stop listening for remote procedure calls. On receipt of a stop listening 1235** request the RPC runtime stops accepting new remote procedure calls for all 1236** registered interfaces. Executing calls are allowed to complete, including 1237** callbacks. After alls executing calls complete the rpc_server_listen() 1238** routine returns to the caller. 1239** 1240** INPUTS: 1241** 1242** binding_h The binding handle for this remote call. 1243** 1244** INPUTS/OUTPUTS: none 1245** 1246** OUTPUTS: 1247** 1248** status A value indicating the status of the routine. 1249** 1250** rpc_s_ok The call was successful. 1251** rpc_s_invalid_binding 1252** RPC Protocol ID in binding handle was invalid. 1253** 1254** IMPLICIT INPUTS: none 1255** 1256** IMPLICIT OUTPUTS: none 1257** 1258** FUNCTION VALUE: void 1259** 1260** SIDE EFFECTS: none 1261** 1262**-- 1263**/ 1264 1265PUBLIC void rpc_mgmt_stop_server_listening 1266( 1267 rpc_binding_handle_t binding_h, 1268 unsigned32 *status 1269) 1270{ 1271 1272 RPC_VERIFY_INIT (); 1273 1274 /* 1275 * if this is a local request, just do it locally 1276 */ 1277 if (binding_h == NULL) 1278 { 1279 rpc__server_stop_listening (status); 1280 } 1281 else 1282 { 1283 1284 remote_binding_validate(binding_h, status); 1285 if (*status != rpc_s_ok) 1286 return; 1287 1288 /* 1289 * call the corresponding remote routine 1290 */ 1291 (*mgmt_v1_0_c_epv.rpc__mgmt_stop_server_listening) (binding_h, status); 1292 1293 if (*status == rpc_s_call_cancelled) 1294 dcethread_interrupt_throw(dcethread_self()); 1295 } 1296} 1297 1298/* 1299**++ 1300** 1301** ROUTINE NAME: rpc_mgmt_inq_server_princ_name 1302** 1303** SCOPE: PUBLIC - declared in rpc.idl 1304** 1305** DESCRIPTION: 1306** 1307** This is a Local/Remote management function that directs a server to 1308** 1309** 1310** 1311** 1312** 1313** 1314** INPUTS: 1315** 1316** binding_h The binding handle for this remote call. 1317** 1318** INPUTS/OUTPUTS: none 1319** 1320** OUTPUTS: 1321** 1322** status A value indicating the status of the routine. 1323** 1324** rpc_s_ok The call was successful. 1325** rpc_s_invalid_binding 1326** RPC Protocol ID in binding handle was invalid. 1327** 1328** IMPLICIT INPUTS: none 1329** 1330** IMPLICIT OUTPUTS: none 1331** 1332** FUNCTION VALUE: void 1333** 1334** SIDE EFFECTS: none 1335** 1336**-- 1337**/ 1338 1339PUBLIC void rpc_mgmt_inq_server_princ_name 1340( 1341 rpc_binding_handle_t binding_h, 1342 unsigned32 authn_protocol, 1343 unsigned_char_p_t *server_princ_name, 1344 unsigned32 *status 1345) 1346{ 1347 unsigned32 dce_rpc_authn_protocol; 1348 1349 RPC_VERIFY_INIT (); 1350 1351 RPC_AUTHN_CHECK_SUPPORTED (authn_protocol, status); 1352 1353 dce_rpc_authn_protocol = 1354 rpc_g_authn_protocol_id[authn_protocol].dce_rpc_authn_protocol_id; 1355 1356 RPC_MEM_ALLOC ( 1357 *server_princ_name, 1358 unsigned_char_p_t, 1359 MAX_SERVER_PRINC_NAME_LEN, 1360 RPC_C_MEM_STRING, 1361 RPC_C_MEM_WAITOK); 1362 1363 /* 1364 * if this is a local request, just do it locally 1365 */ 1366 if (binding_h == NULL) 1367 { 1368 rpc__auth_inq_my_princ_name 1369 (dce_rpc_authn_protocol, MAX_SERVER_PRINC_NAME_LEN, 1370 *server_princ_name, status); 1371 } 1372 else 1373 { 1374 remote_binding_validate(binding_h, status); 1375 if (*status != rpc_s_ok) 1376 { 1377 RPC_MEM_FREE (*server_princ_name, RPC_C_MEM_STRING); 1378 return; 1379 } 1380 1381 /* 1382 * call the corresponding remote routine 1383 */ 1384 (*mgmt_v1_0_c_epv.rpc__mgmt_inq_princ_name) 1385 (binding_h, 1386 dce_rpc_authn_protocol, 1387 MAX_SERVER_PRINC_NAME_LEN, 1388 *server_princ_name, 1389 status); 1390 1391 if (*status != rpc_s_ok) 1392 { 1393 RPC_MEM_FREE (*server_princ_name, RPC_C_MEM_STRING); 1394 if (*status == rpc_s_call_cancelled) 1395 dcethread_interrupt_throw(dcethread_self()); 1396 return; 1397 } 1398 } 1399} 1400 1401/* 1402**++ 1403** 1404** ROUTINE NAME: rpc_mgmt_set_authorization_fn 1405** 1406** SCOPE: PUBLIC - declared in rpc.idl 1407** 1408** DESCRIPTION: 1409** 1410** A server application calls the rpc_mgmt_set_authorization_fn routine 1411** to specify an authorization function to control remote access to 1412** the server's remote management routines. 1413** 1414** INPUTS: 1415** 1416** authorization_fn 1417** Authorization function to be used 1418** 1419** INPUTS/OUTPUTS: none 1420** 1421** OUTPUTS: 1422** 1423** status A value indicating the status of the routine. 1424** 1425** rpc_s_ok The call was successful. 1426** 1427** IMPLICIT INPUTS: none 1428** 1429** IMPLICIT OUTPUTS: none 1430** 1431** FUNCTION VALUE: void 1432** 1433** SIDE EFFECTS: none 1434** 1435**-- 1436**/ 1437 1438PUBLIC void rpc_mgmt_set_authorization_fn 1439( 1440 rpc_mgmt_authorization_fn_t authorization_fn_arg, 1441 unsigned32 *status 1442) 1443{ 1444 RPC_VERIFY_INIT (); 1445 authorization_fn = authorization_fn_arg; 1446 *status = rpc_s_ok; 1447} 1448 1449/* 1450**++ 1451** 1452** ROUTINE NAME: inq_if_ids 1453** 1454** SCOPE: INTERNAL 1455** 1456** DESCRIPTION: 1457** 1458** This is the manager routine that provides remote access to the 1459** rpc_mgmt_inq_if_ids function. 1460** 1461** INPUTS: 1462** 1463** binding_h The binding handle for this remote call. 1464** 1465** INPUTS/OUTPUTS: none 1466** 1467** OUTPUTS: 1468** 1469** if_id_vector A vector of the if id's registered for this server 1470** 1471** status A value indicating the status of the routine. 1472** 1473** rpc_s_ok The call was successful. 1474** rpc_s_no_memory 1475** 1476** IMPLICIT INPUTS: none 1477** 1478** IMPLICIT OUTPUTS: none 1479** 1480** FUNCTION VALUE: void 1481** 1482** SIDE EFFECTS: none 1483** 1484**-- 1485**/ 1486 1487INTERNAL void inq_if_ids 1488( 1489 rpc_binding_handle_t binding_h, 1490 rpc_if_id_vector_p_t *if_id_vector, 1491 unsigned32 *status 1492) 1493{ 1494 rpc_if_id_vector_p_t local_if_id_vector; 1495 unsigned32 index; 1496 unsigned32 temp_status; 1497 1498 if (! rpc__mgmt_authorization_check (binding_h, rpc_c_mgmt_inq_if_ids, 1499 true, status)) 1500 { 1501 *if_id_vector = NULL; 1502 return; 1503 } 1504 1505 /* 1506 * call the corresponding local routine to get a local if id vector 1507 */ 1508 rpc_mgmt_inq_if_ids (NULL, &local_if_id_vector, status); 1509 1510 if (*status != rpc_s_ok) 1511 { 1512 *if_id_vector = NULL; 1513 return; 1514 } 1515 1516 /* 1517 * allocate memory to hold the output argument so that it can be 1518 * freed by the stubs when we're done 1519 */ 1520 *if_id_vector = (rpc_if_id_vector_p_t) 1521 rpc_ss_allocate (((sizeof local_if_id_vector->count) + 1522 (local_if_id_vector->count * sizeof (rpc_if_id_p_t)))); 1523 1524 if (*if_id_vector == NULL) 1525 { 1526 *status = rpc_s_no_memory; 1527 return; 1528 } 1529 1530 /* 1531 * set the count field in the output vector 1532 */ 1533 (*if_id_vector)->count = local_if_id_vector->count; 1534 1535 /* 1536 * walk the local vector and for each element create a copy in the 1537 * output vector 1538 */ 1539 for (index = 0; index < local_if_id_vector->count; index++) 1540 { 1541 (*if_id_vector)->if_id[index] = (rpc_if_id_p_t) 1542 rpc_ss_allocate (sizeof (rpc_if_id_t)); 1543 1544 if ((*if_id_vector)->if_id[index] == NULL) 1545 { 1546 /* 1547 * if we can't create a copy of any element, free the local 1548 * vector, free all existing elements in the output vector, 1549 * and free the output vector itself 1550 */ 1551 rpc_if_id_vector_free (&local_if_id_vector, &temp_status); 1552 1553 /* FIXME: mdn 24 Oct 1999: change index >=0 to index > 0 */ 1554 while (index > 0) 1555 { 1556 rpc_ss_free ((char *) (*if_id_vector)->if_id[--index]); 1557 } 1558 1559 rpc_ss_free ((char *) *if_id_vector); 1560 1561 *if_id_vector = NULL; 1562 *status = rpc_s_no_memory; 1563 return; 1564 } 1565 1566 /* 1567 * Copy the the entry in the local vector to the output vector. 1568 */ 1569 (*if_id_vector)->if_id[index]->uuid = 1570 local_if_id_vector->if_id[index]->uuid; 1571 (*if_id_vector)->if_id[index]->vers_major = 1572 local_if_id_vector->if_id[index]->vers_major; 1573 (*if_id_vector)->if_id[index]->vers_minor = 1574 local_if_id_vector->if_id[index]->vers_minor; 1575 } 1576 1577 /* 1578 * free the local vector 1579 */ 1580 rpc_if_id_vector_free (&local_if_id_vector, &temp_status); 1581 1582 /* 1583 * return the output vector 1584 */ 1585 *status = rpc_s_ok; 1586} 1587 1588/* 1589**++ 1590** 1591** ROUTINE NAME: rpc__mgmt_stop_server_lsn_mgr 1592** 1593** SCOPE: PRIVATE - declared in mgmtp.h 1594** 1595** DESCRIPTION: 1596** 1597** This is the manager routine that provides remote access to the 1598** rpc_mgmt_stop_server_listening function. This routine is PRIVATE 1599** instead of INTERNAL so it can be used by the RRPC i/f as well. 1600** 1601** INPUTS: 1602** 1603** binding_h The binding handle for this remote call. 1604** 1605** INPUTS/OUTPUTS: none 1606** 1607** OUTPUTS: 1608** 1609** status A value indicating the status of the routine. 1610** 1611** rpc_s_ok The call was successful. 1612** 1613** IMPLICIT INPUTS: none 1614** 1615** IMPLICIT OUTPUTS: none 1616** 1617** FUNCTION VALUE: void 1618** 1619** SIDE EFFECTS: none 1620** 1621**-- 1622**/ 1623 1624PRIVATE void rpc__mgmt_stop_server_lsn_mgr 1625( 1626 rpc_binding_handle_t binding_h, 1627 unsigned32 *status 1628) 1629{ 1630 if (! rpc__mgmt_authorization_check (binding_h, rpc_c_mgmt_stop_server_listen, 1631 false, status)) 1632 { 1633 return; 1634 } 1635 1636 rpc_mgmt_stop_server_listening (NULL, status); 1637} 1638 1639/* 1640**++ 1641** 1642** ROUTINE NAME: inq_stats 1643** 1644** SCOPE: INTERNAL 1645** 1646** DESCRIPTION: 1647** 1648** This is the manager routine that provides remote access to the 1649** rpc_mgmt_inq_stats function. 1650** 1651** INPUTS: 1652** 1653** binding_h The binding handle for this remote call. 1654** 1655** INPUTS/OUTPUTS: 1656** 1657** count The maximum size of the array on input and 1658** the actual size of the array on output. 1659** 1660** OUTPUTS: 1661** 1662** stats An array of statistics values for this server. 1663** 1664** status A value indicating the status of the routine. 1665** 1666** rpc_s_ok The call was successful. 1667** 1668** IMPLICIT INPUTS: none 1669** 1670** IMPLICIT OUTPUTS: none 1671** 1672** FUNCTION VALUE: void 1673** 1674** SIDE EFFECTS: none 1675** 1676**-- 1677**/ 1678 1679INTERNAL void inq_stats 1680( 1681 rpc_binding_handle_t binding_h, 1682 unsigned32 *count, 1683 unsigned32 statistics[], 1684 unsigned32 *status 1685) 1686{ 1687 rpc_stats_vector_p_t stats_vector; 1688 unsigned32 temp_status; 1689 unsigned32 i; 1690 1691 if (! rpc__mgmt_authorization_check (binding_h, rpc_c_mgmt_inq_stats, 1692 true, status)) 1693 { 1694 *count = 0; 1695 return; 1696 } 1697 1698 /* 1699 * Call the corresponding local routine to get the stats array 1700 */ 1701 rpc_mgmt_inq_stats (NULL, &stats_vector, status); 1702 if (*status != rpc_s_ok) 1703 { 1704 *count = 0; 1705 return; 1706 } 1707 1708 *count = stats_vector->count; 1709 1710 for (i = 0; i < *count; i++) 1711 { 1712 statistics[i] = stats_vector->stats[i]; 1713 } 1714 rpc_mgmt_stats_vector_free (&stats_vector, &temp_status); 1715} 1716 1717/* 1718**++ 1719** 1720** ROUTINE NAME: is_server_listening 1721** 1722** SCOPE: INTERNAL 1723** 1724** DESCRIPTION: 1725** 1726** This is the manager routine that returns true if it is ever executed to 1727** indicate that the server is listening for remote calls. 1728** 1729** INPUTS: 1730** 1731** binding_h The binding handle for this remote call. 1732** 1733** INPUTS/OUTPUTS: none 1734** 1735** OUTPUTS: 1736** 1737** status A value indicating the status of the routine. 1738** 1739** rpc_s_ok The call was successful. 1740** 1741** IMPLICIT INPUTS: none 1742** 1743** IMPLICIT OUTPUTS: none 1744** 1745** FUNCTION VALUE: 1746** 1747** true - if server is listening 1748** false - if server is not listening :-) 1749** 1750** SIDE EFFECTS: none 1751** 1752**-- 1753**/ 1754 1755INTERNAL boolean32 is_server_listening 1756( 1757 rpc_binding_handle_t binding_h, 1758 unsigned32 *status 1759) 1760{ 1761 if (! rpc__mgmt_authorization_check (binding_h, rpc_c_mgmt_is_server_listen, 1762 true, status)) 1763 { 1764 return (false); /* Sort of pointless, since we're answering anyway */ 1765 } 1766 1767 /* 1768 * Cogito ergo sum. 1769 */ 1770 *status = rpc_s_ok; 1771 return (true); 1772} 1773 1774/* 1775**++ 1776** 1777** ROUTINE NAME: inq_princ_name 1778** 1779** SCOPE: INTERNAL 1780** 1781** DESCRIPTION: 1782** 1783** This is a manager routine that provides a remote caller with the 1784** principal name (really one of the principal names) for a server. 1785** 1786** INPUTS: 1787** 1788** binding_h The binding handle for this remote call. 1789** 1790** authn_proto The *wire* authentication protocol ID we're 1791** interested in 1792** 1793** princ_name_size The max size of princ_name 1794** 1795** INPUTS/OUTPUTS: none 1796** 1797** OUTPUTS: 1798** 1799** princ_name Server's principal name 1800** 1801** status A value indicating the status of the routine. 1802** 1803** rpc_s_ok The call was successful. 1804** 1805** IMPLICIT INPUTS: none 1806** 1807** IMPLICIT OUTPUTS: none 1808** 1809** FUNCTION VALUE: none 1810** 1811** SIDE EFFECTS: none 1812** 1813**-- 1814**/ 1815 1816INTERNAL void inq_princ_name 1817( 1818 rpc_binding_handle_t binding_h, 1819 unsigned32 authn_proto, 1820 unsigned32 princ_name_size, 1821 idl_char princ_name[], 1822 unsigned32 *status 1823) 1824{ 1825 if (! rpc__mgmt_authorization_check (binding_h, rpc_c_mgmt_inq_princ_name, 1826 true, status)) 1827 { 1828 princ_name[0] = '\0'; 1829 return; 1830 } 1831 1832 rpc__auth_inq_my_princ_name 1833 (authn_proto, princ_name_size, (unsigned_char_p_t) princ_name, status); 1834 1835 if (*status != rpc_s_ok) 1836 { 1837 princ_name[0] = '\0'; 1838 } 1839} 1840 1841 1842/* 1843**++ 1844** 1845** ROUTINE NAME: rpc__mgmt_authorization_check 1846** 1847** SCOPE: PRIVATE - declared in mgmtp.h 1848** 1849** DESCRIPTION: 1850** 1851** Routine to check whether a management operation is allowed. This 1852** routine is PRIVATE instead of INTERNAL so it can be used by the RRPC 1853** i/f as well. 1854** 1855** INPUTS: 1856** 1857** binding_h RPC binding handle 1858** 1859** op Management operation in question 1860** 1861** deflt What to return in there's no authorization function set 1862** 1863** INPUTS/OUTPUTS: none 1864** 1865** OUTPUTS: 1866** 1867** status A value indicating the status of the routine. 1868** 1869** IMPLICIT INPUTS: none 1870** 1871** IMPLICIT OUTPUTS: none 1872** 1873** FUNCTION VALUE: boolean 1874** 1875** return Whether operation is allowed 1876** 1877** SIDE EFFECTS: none 1878** 1879**-- 1880**/ 1881 1882PRIVATE boolean32 rpc__mgmt_authorization_check 1883( 1884 rpc_binding_handle_t binding_h, 1885 unsigned32 op, 1886 boolean32 deflt, 1887 unsigned32 *status 1888) 1889{ 1890 if (authorization_fn == NULL) 1891 { 1892 *status = deflt ? rpc_s_ok : rpc_s_mgmt_op_disallowed; 1893 return (deflt); 1894 } 1895 else 1896 { 1897 if ((*authorization_fn) (binding_h, op, status)) 1898 { 1899 *status = rpc_s_ok; /* Be consistent */ 1900 return (true); 1901 } 1902 else 1903 { 1904 *status = rpc_s_mgmt_op_disallowed; 1905 return (false); 1906 } 1907 } 1908} 1909 1910/* 1911**++ 1912** 1913** ROUTINE NAME: my_allocate 1914** 1915** SCOPE: INTERNAL 1916** 1917** DESCRIPTION: 1918** 1919** Wrapper around RPC_MEM_ALLOC to use in call to 1920** rpc_ss_swap_client_alloc_free. 1921** 1922** INPUTS: 1923** 1924** size number of bytes to allocate 1925** 1926** INPUTS/OUTPUTS: none 1927** 1928** OUTPUTS: none 1929** 1930** IMPLICIT INPUTS: none 1931** 1932** IMPLICIT OUTPUTS: none 1933** 1934** FUNCTION VALUE: idl_void_p_t 1935** 1936** return pointer to allocated storage 1937** 1938** SIDE EFFECTS: none 1939** 1940**-- 1941**/ 1942 1943INTERNAL idl_void_p_t my_allocate 1944( 1945 idl_void_p_t context ATTRIBUTE_UNUSED, 1946 idl_size_t size 1947) 1948{ 1949 idl_void_p_t ptr; 1950 1951 RPC_MEM_ALLOC ( 1952 ptr, 1953 idl_void_p_t, 1954 size, 1955 RPC_C_MEM_STRING, 1956 RPC_C_MEM_WAITOK); 1957 1958 return (ptr); 1959} 1960 1961/* 1962**++ 1963** 1964** ROUTINE NAME: my_free 1965** 1966** SCOPE: INTERNAL 1967** 1968** DESCRIPTION: 1969** 1970** Wrapper around RPC_MEM_FREE to use in call to 1971** rpc_ss_swap_client_alloc_free. 1972** 1973** INPUTS: 1974** 1975** ptr storage to free 1976** 1977** INPUTS/OUTPUTS: none 1978** 1979** OUTPUTS: none 1980** 1981** IMPLICIT INPUTS: none 1982** 1983** IMPLICIT OUTPUTS: none 1984** 1985** FUNCTION VALUE: none 1986** 1987** SIDE EFFECTS: none 1988** 1989**-- 1990**/ 1991 1992INTERNAL void my_free 1993( 1994 idl_void_p_t context ATTRIBUTE_UNUSED, 1995 idl_void_p_t ptr 1996) 1997{ 1998 RPC_MEM_FREE (ptr, RPC_C_MEM_STRING); 1999} 2000 2001 2002/* 2003**++ 2004** 2005** ROUTINE NAME: remote_binding_validate 2006** 2007** SCOPE: INTERNAL 2008** 2009** DESCRIPTION: 2010** 2011** Function to make sure a binding is sensible to use as a parameter to 2012** one of the local/remote mgmt calls. "Sensible" means (a) it's a 2013** client binding, and (b) it has at least one of an object UUID or an 2014** endpoint (so the call has a reasonable chance of making it to a real 2015** server process). 2016** 2017** INPUTS: 2018** 2019** binding_h RPC binding handle 2020** 2021** INPUTS/OUTPUTS: none 2022** 2023** OUTPUTS: 2024** 2025** status A value indicating the status of the routine. 2026** 2027** IMPLICIT INPUTS: none 2028** 2029** IMPLICIT OUTPUTS: none 2030** 2031** FUNCTION VALUE: none 2032** 2033** SIDE EFFECTS: none 2034** 2035**-- 2036**/ 2037 2038INTERNAL void remote_binding_validate 2039( 2040 rpc_binding_handle_t binding_h, 2041 unsigned32 *status 2042) 2043{ 2044 rpc_binding_rep_p_t binding_rep = (rpc_binding_rep_p_t) binding_h; 2045 2046 assert(binding_rep != NULL); 2047 2048 RPC_BINDING_VALIDATE_CLIENT (binding_rep, status); 2049 if (*status != rpc_s_ok) 2050 return; 2051 2052 if ((! binding_rep->addr_has_endpoint) && UUID_IS_NIL (&binding_rep->obj, status)) 2053 { 2054 *status = rpc_s_binding_incomplete; 2055 return; 2056 } 2057 2058 *status = rpc_s_ok; 2059} 2060