1/*
2 * SAMR test
3 *
4 * Jim Doyle, jrd@bu.edu  09-05-1998
5 * Stefan Metzmacher, metze@samba.org, 2008
6 *
7 *
8 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#ifndef _POSIX_PTHREAD_SEMANTICS
14#define _POSIX_PTHREAD_SEMANTICS 1
15#endif
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <signal.h>
21#include <compat/dcerpc.h>
22#include "samrt.h"
23#include "misc.h"
24
25#ifndef _WIN32
26static void wait_for_signals(void);
27#endif
28
29/*
30 *
31 * A template DCE RPC server
32 *
33 * main() contains the basic calls needed to register an interface,
34 * get communications endpoints, and register the endpoints
35 * with the endpoint mapper.
36 *
37 * ReverseIt() implements the interface specified in echo.idl
38 *
39 */
40
41
42int main(int ac ATTRIBUTE_UNUSED, char *av[] ATTRIBUTE_UNUSED)
43{
44  unsigned32 status;
45  rpc_binding_vector_p_t     server_binding;
46  char * string_binding;
47  unsigned32 i;
48
49  /*
50   * Register the Interface with the local endpoint mapper (rpcd)
51   */
52
53  printf ("Registering server.... \n");
54  rpc_server_register_if(samrt_v1_0_s_ifspec,
55			 NULL,
56			 NULL,
57			 &status);
58      chk_dce_err(status, "rpc_server_register_if()", "", 1);
59
60      printf("registered.\nPreparing binding handle...\n");
61
62      rpc_server_use_protseq((unsigned_char_p_t)"ncacn_ip_tcp",
63	      rpc_c_protseq_max_calls_default, &status);
64
65      chk_dce_err(status, "rpc_server_use_all_protseqs()", "", 1);
66      rpc_server_inq_bindings(&server_binding, &status);
67      chk_dce_err(status, "rpc_server_inq_bindings()", "", 1);
68
69      /*
70       * Register bindings with the endpoint mapper
71       */
72
73	printf("registering bindings with endpoint mapper\n");
74
75  rpc_ep_register(samrt_v1_0_s_ifspec,
76		  server_binding,
77		  NULL,
78		  (unsigned char *)"QDA application server",
79		  &status);
80      chk_dce_err(status, "rpc_ep_register()", "", 1);
81
82	printf("registered.\n");
83
84      /*
85       * Print out the servers endpoints (TCP and UDP port numbers)
86       */
87
88  printf ("Server's communications endpoints are:\n");
89
90    for (i=0; i<RPC_FIELD_COUNT(server_binding); i++)
91    {
92        rpc_binding_to_string_binding(RPC_FIELD_BINDING_H(server_binding)[i],
93				    (unsigned char **)&string_binding,
94				    &status
95				    );
96      if (string_binding)
97		printf("\t%s\n",string_binding);
98    }
99
100
101#ifndef _WIN32
102  /*
103   * Start the signal waiting thread in background. This thread will
104   * Catch SIGINT and gracefully shutdown the server.
105   */
106
107  wait_for_signals();
108#endif
109
110  /*
111   * Begin listening for calls
112   */
113
114  printf ("listening for calls.... \n");
115
116  DCETHREAD_TRY
117    {
118      rpc_server_listen(rpc_c_listen_max_calls_default, &status);
119    }
120  DCETHREAD_CATCH_ALL(THIS_CATCH)
121    {
122      printf ("Server stoppped listening\n");
123    }
124  DCETHREAD_ENDTRY
125
126    /*
127     * If we reached this point, then the server was stopped, most likely
128     * by the signal handler thread called rpc_mgmt_stop_server().
129     * gracefully cleanup and unregister the bindings from the
130     * endpoint mapper.
131     */
132
133#ifndef _WIN32
134    /*
135     * Kill the signal handling thread
136     */
137
138#endif
139
140  printf ("Unregistering server from the endpoint mapper.... \n");
141  rpc_ep_unregister(samrt_v1_0_s_ifspec,
142		    server_binding,
143		    NULL,
144		    &status);
145  chk_dce_err(status, "rpc_ep_unregister()", "", 0);
146
147  /*
148   * retire the binding information
149   */
150
151  printf("Cleaning up communications endpoints... \n");
152  rpc_server_unregister_if(samrt_v1_0_s_ifspec,
153			   NULL,
154			   &status);
155  chk_dce_err(status, "rpc_server_unregister_if()", "", 0);
156
157  exit(0);
158
159}
160
161
162/*=========================================================================
163 *
164 * Server implementation of ReverseIt()
165 *
166 *=========================================================================*/
167
168unsigned32
169samrt_Connect(
170     handle_t h,
171     unsigned16 *system_name ATTRIBUTE_UNUSED,
172     unsigned32 access_mask,
173     void **handle)
174{
175
176  char * binding_info;
177  error_status_t e;
178  unsigned32 authn_protocol;
179  void *mech_ctx;
180
181  /*
182   * Get some info about the client binding
183   */
184
185  rpc_binding_to_string_binding(h, (unsigned char **)&binding_info, &e);
186  if (e == rpc_s_ok)
187    {
188      printf ("samrt_Connect() called by client: %s\n", binding_info);
189    }
190
191  mech_ctx = NULL;
192  rpc_binding_inq_security_context(h, &authn_protocol, &mech_ctx, &e);
193
194  printf("\n\nFunction samrt_Connect() -- input argments\n");
195
196  printf("\taccess_mask = %d\n", access_mask);
197
198  printf ("\n=========================================\n");
199
200  *handle = NULL;
201  return 0;
202
203}
204
205
206#ifndef _WIN32
207/*=========================================================================
208 *
209 * wait_for_signals()
210 *
211 *
212 * Set up the process environment to properly deal with signals.
213 * By default, we isolate all threads from receiving asynchronous
214 * signals. We create a thread that handles all async signals.
215 * The signal handling actions are handled in the handler thread.
216 *
217 * For AIX, we cant use a thread that sigwaits() on a specific signal,
218 * we use a plain old, lame old Unix signal handler.
219 *
220 *=========================================================================*/
221
222void
223wait_for_signals(void)
224{
225    sigset_t signals;
226
227    sigemptyset(&signals);
228    sigaddset(&signals, SIGINT);
229
230    dcethread_signal_to_interrupt(&signals, dcethread_self());
231}
232
233#endif
234