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