r4559: prevent the RPC-EPMAPPER test from looping forever against w2k3
[samba.git] / source / torture / rpc / epmapper.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for epmapper rpc operations
4
5    Copyright (C) Andrew Tridgell 2003
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "system/network.h"
24 #include "librpc/gen_ndr/ndr_epmapper.h"
25
26
27 /*
28   display any protocol tower
29  */
30 static void display_tower(TALLOC_CTX *mem_ctx, struct epm_tower *twr)
31 {
32         int i;
33         const char *uuid;
34
35         for (i=0;i<twr->num_floors;i++) {
36                 struct epm_lhs *lhs = &twr->floors[i].lhs;
37                 union epm_rhs *rhs = &twr->floors[i].rhs;
38
39                 switch(lhs->protocol) {
40                 case EPM_PROTOCOL_UUID:
41                         uuid = GUID_string(mem_ctx, &lhs->info.uuid.uuid);
42                         if (strcasecmp(uuid, NDR_GUID) == 0) {
43                                 printf(" NDR");
44                         } else {
45                                 printf(" uuid %s/0x%02x", uuid, lhs->info.uuid.version);
46                         }
47                         break;
48
49                 case EPM_PROTOCOL_NCACN:
50                         printf(" RPC-C");
51                         break;
52
53                 case EPM_PROTOCOL_NCADG:
54                         printf(" RPC");
55                         break;
56
57                 case EPM_PROTOCOL_NCALRPC:
58                         printf(" NCALRPC");
59                         break;
60
61                 case EPM_PROTOCOL_DNET_NSP:
62                         printf(" DNET/NSP");
63                         break;
64
65                 case EPM_PROTOCOL_IP:
66                         printf(" IP:");
67                         {
68                                 struct ipv4_addr in;
69                                 in.addr = htonl(rhs->ip.address);
70                                 printf("%s", sys_inet_ntoa(in));
71                         }
72                         break;
73
74                 case EPM_PROTOCOL_PIPE:
75                         printf(" PIPE:%s", rhs->pipe.path);
76                         break;
77
78                 case EPM_PROTOCOL_SMB:
79                         printf(" SMB:%s", rhs->smb.unc);
80                         break;
81
82                 case EPM_PROTOCOL_UNIX_DS:
83                         printf(" Unix:%s", rhs->unix_ds.path);
84                         break;
85
86                 case EPM_PROTOCOL_NETBIOS:
87                         printf(" NetBIOS:%s", rhs->netbios.name);
88                         break;
89
90                 case EPM_PROTOCOL_NETBEUI:
91                         printf(" NETBeui");
92                         break;
93
94                 case EPM_PROTOCOL_SPX:
95                         printf(" SPX");
96                         break;
97
98                 case EPM_PROTOCOL_NB_IPX:
99                         printf(" NB_IPX");
100                         break;
101
102                 case EPM_PROTOCOL_HTTP:
103                         printf(" HTTP:%d", rhs->http.port);
104                         break;
105
106                 case EPM_PROTOCOL_TCP:
107                         /* what is the difference between this and 0x1f? */
108                         printf(" TCP:%d", rhs->tcp.port);
109                         break;
110
111                 case EPM_PROTOCOL_UDP:
112                         printf(" UDP:%d", rhs->udp.port);
113                         break;
114
115                 default:
116                         printf(" UNK(%02x):", lhs->protocol);
117                         if (rhs->unknown.length == 2) {
118                                 printf("%d", RSVAL(rhs->unknown.data, 0));
119                         }
120                         break;
121                 }
122         }
123         printf("\n");
124 }
125
126
127 static BOOL test_Map(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
128                      struct epm_twr_t *twr)
129 {
130         NTSTATUS status;
131         struct epm_Map r;
132         struct GUID uuid;
133         const char *uuid_str;
134         struct policy_handle handle;
135         int i;
136
137         ZERO_STRUCT(uuid);
138         ZERO_STRUCT(handle);
139
140         r.in.object = &uuid;
141         r.in.map_tower = twr;
142         r.in.entry_handle = &handle;    
143         r.out.entry_handle = &handle;
144         r.in.max_towers = 100;
145
146         uuid_str = GUID_string(mem_ctx, &twr->tower.floors[0].lhs.info.uuid.uuid);
147
148         printf("epm_Map results for '%s':\n", 
149                idl_pipe_name(uuid_str, twr->tower.floors[0].lhs.info.uuid.version));
150
151         twr->tower.floors[2].lhs.protocol = EPM_PROTOCOL_NCACN;
152         twr->tower.floors[2].lhs.info.lhs_data = data_blob(NULL, 0);
153         twr->tower.floors[2].rhs.ncacn.minor_version = 0;
154
155         twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_TCP;
156         twr->tower.floors[3].lhs.info.lhs_data = data_blob(NULL, 0);
157         twr->tower.floors[3].rhs.tcp.port = 0;
158
159         twr->tower.floors[4].lhs.protocol = EPM_PROTOCOL_IP;
160         twr->tower.floors[4].lhs.info.lhs_data = data_blob(NULL, 0);
161         twr->tower.floors[4].rhs.ip.address = 0;
162
163         status = dcerpc_epm_Map(p, mem_ctx, &r);
164         if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
165                 for (i=0;i<r.out.num_towers;i++) {
166                         if (r.out.towers[i].twr) {
167                                 display_tower(mem_ctx, &r.out.towers[i].twr->tower);
168                         }
169                 }
170         }
171
172         twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_HTTP;
173         twr->tower.floors[3].lhs.info.lhs_data = data_blob(NULL, 0);
174         twr->tower.floors[3].rhs.http.port = 0;
175
176         status = dcerpc_epm_Map(p, mem_ctx, &r);
177         if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
178                 for (i=0;i<r.out.num_towers;i++) {
179                         if (r.out.towers[i].twr) {
180                                 display_tower(mem_ctx, &r.out.towers[i].twr->tower);
181                         }
182                 }
183         }
184
185         twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_UDP;
186         twr->tower.floors[3].lhs.info.lhs_data = data_blob(NULL, 0);
187         twr->tower.floors[3].rhs.http.port = 0;
188
189         status = dcerpc_epm_Map(p, mem_ctx, &r);
190         if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
191                 for (i=0;i<r.out.num_towers;i++) {
192                         if (r.out.towers[i].twr) {
193                                 display_tower(mem_ctx, &r.out.towers[i].twr->tower);
194                         }
195                 }
196         }
197
198         twr->tower.floors[3].lhs.protocol = EPM_PROTOCOL_SMB;
199         twr->tower.floors[3].lhs.info.lhs_data = data_blob(NULL, 0);
200         twr->tower.floors[3].rhs.smb.unc = "";
201
202         twr->tower.floors[4].lhs.protocol = EPM_PROTOCOL_NETBIOS;
203         twr->tower.floors[4].lhs.info.lhs_data = data_blob(NULL, 0);
204         twr->tower.floors[4].rhs.netbios.name = "";
205
206         status = dcerpc_epm_Map(p, mem_ctx, &r);
207         if (NT_STATUS_IS_OK(status) && r.out.result == 0) {
208                 for (i=0;i<r.out.num_towers;i++) {
209                         if (r.out.towers[i].twr) {
210                                 display_tower(mem_ctx, &r.out.towers[i].twr->tower);
211                         }
212                 }
213         }
214
215         /* FIXME: Extend to do other protocols as well (ncacn_unix_stream, ncalrpc) */
216         
217         return True;
218 }
219
220 static BOOL test_Lookup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
221 {
222         NTSTATUS status;
223         struct epm_Lookup r;
224         struct GUID uuid;
225         struct rpc_if_id_t iface;
226         struct policy_handle handle;
227
228         ZERO_STRUCT(handle);
229
230         r.in.inquiry_type = 0;
231         r.in.object = &uuid;
232         r.in.interface_id = &iface;
233         r.in.vers_option = 0;
234         r.in.entry_handle = &handle;
235         r.out.entry_handle = &handle;
236         r.in.max_ents = 10;
237
238         do {
239                 int i;
240
241                 ZERO_STRUCT(uuid);
242                 ZERO_STRUCT(iface);
243
244                 status = dcerpc_epm_Lookup(p, mem_ctx, &r);
245                 if (!NT_STATUS_IS_OK(status) || r.out.result != 0) {
246                         break;
247                 }
248
249                 printf("epm_Lookup returned %d events GUID %s\n", 
250                        r.out.num_ents, GUID_string(mem_ctx, &handle.uuid));
251
252                 for (i=0;i<r.out.num_ents;i++) {
253                         printf("\nFound '%s'\n", r.out.entries[i].annotation);
254                         display_tower(mem_ctx, &r.out.entries[i].tower->tower);
255                         if (r.out.entries[i].tower->tower.num_floors == 5) {
256                                 test_Map(p, mem_ctx, r.out.entries[i].tower);
257                         }
258                 }
259         } while (NT_STATUS_IS_OK(status) && 
260                  r.out.result == 0 && 
261                  r.out.num_ents == r.in.max_ents &&
262                  !policy_handle_empty(&handle));
263
264         if (!NT_STATUS_IS_OK(status)) {
265                 printf("Lookup failed - %s\n", nt_errstr(status));
266                 return False;
267         }
268
269
270         return True;
271 }
272
273 static BOOL test_InqObject(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
274 {
275         NTSTATUS status;
276         struct epm_InqObject r;
277
278         r.in.epm_object = talloc_p(mem_ctx, struct GUID);
279         GUID_from_string(DCERPC_EPMAPPER_UUID, r.in.epm_object);
280
281         status = dcerpc_epm_InqObject(p, mem_ctx, &r);
282         if (NT_STATUS_IS_ERR(status)) {
283                 printf("InqObject failed - %s\n", nt_errstr(status));
284                 return False;
285         }
286
287         return True;
288 }
289
290 BOOL torture_rpc_epmapper(void)
291 {
292         NTSTATUS status;
293         struct dcerpc_pipe *p;
294         TALLOC_CTX *mem_ctx;
295         BOOL ret = True;
296
297         mem_ctx = talloc_init("torture_rpc_epmapper");
298
299         status = torture_rpc_connection(&p, 
300                                         DCERPC_EPMAPPER_NAME,
301                                         DCERPC_EPMAPPER_UUID,
302                                         DCERPC_EPMAPPER_VERSION);
303         if (!NT_STATUS_IS_OK(status)) {
304                 return False;
305         }
306
307         if (!test_Lookup(p, mem_ctx)) {
308                 ret = False;
309         }
310
311         if (!test_InqObject(p, mem_ctx)) {
312                 ret = False;
313         }
314
315         talloc_destroy(mem_ctx);
316
317         torture_rpc_close(p);
318
319         return ret;
320 }