r7633: this patch started as an attempt to make the dcerpc code use a given
[kai/samba-autobuild/.git] / source4 / torture / rpc / mgmt.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for mgmt 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 "librpc/gen_ndr/ndr_mgmt.h"
24
25
26 /*
27   ask the server what interface IDs are available on this endpoint
28 */
29 static BOOL test_inq_if_ids(struct dcerpc_pipe *p, 
30                             TALLOC_CTX *mem_ctx)
31 {
32         NTSTATUS status;
33         struct mgmt_inq_if_ids r;
34         int i;
35         
36         status = dcerpc_mgmt_inq_if_ids(p, mem_ctx, &r);
37         if (!NT_STATUS_IS_OK(status)) {
38                 printf("inq_if_ids failed - %s\n", nt_errstr(status));
39                 return False;
40         }
41
42         if (!W_ERROR_IS_OK(r.out.result)) {
43                 printf("inq_if_ids gave error code %s\n", win_errstr(r.out.result));
44                 return False;
45         }
46
47         if (!r.out.if_id_vector) {
48                 printf("inq_if_ids gave NULL if_id_vector\n");
49                 return False;
50         }
51
52         for (i=0;i<r.out.if_id_vector->count;i++) {
53                 const char *uuid;
54                 struct dcerpc_syntax_id *id = r.out.if_id_vector->if_id[i].id;
55                 if (!id) continue;
56
57                 uuid = GUID_string(mem_ctx, &id->uuid);
58
59                 printf("\tuuid %s  version 0x%08x  '%s'\n",
60                        uuid,
61                        id->if_version, idl_pipe_name(uuid, id->if_version));
62         }
63
64         return True;
65 }
66
67 static BOOL test_inq_stats(struct dcerpc_pipe *p, 
68                            TALLOC_CTX *mem_ctx)
69 {
70         NTSTATUS status;
71         struct mgmt_inq_stats r;
72
73         r.in.max_count = MGMT_STATS_ARRAY_MAX_SIZE;
74         r.in.unknown = 0;
75
76         status = dcerpc_mgmt_inq_stats(p, mem_ctx, &r);
77         if (!NT_STATUS_IS_OK(status)) {
78                 printf("inq_stats failed - %s\n", nt_errstr(status));
79                 return False;
80         }
81
82         if (r.out.statistics.count != MGMT_STATS_ARRAY_MAX_SIZE) {
83                 printf("Unexpected array size %d\n", r.out.statistics.count);
84                 return False;
85         }
86
87         printf("\tcalls_in %6d  calls_out %6d\n\tpkts_in  %6d  pkts_out  %6d\n",
88                r.out.statistics.statistics[MGMT_STATS_CALLS_IN],
89                r.out.statistics.statistics[MGMT_STATS_CALLS_OUT],
90                r.out.statistics.statistics[MGMT_STATS_PKTS_IN],
91                r.out.statistics.statistics[MGMT_STATS_PKTS_OUT]);
92
93         return True;
94 }
95
96 static BOOL test_inq_princ_name(struct dcerpc_pipe *p, 
97                                 TALLOC_CTX *mem_ctx)
98 {
99         NTSTATUS status;
100         struct mgmt_inq_princ_name r;
101         int i;
102         BOOL ret = False;
103
104         for (i=0;i<100;i++) {
105                 r.in.authn_proto = i;  /* DCERPC_AUTH_TYPE_* */
106                 r.in.princ_name_size = 100;
107
108                 status = dcerpc_mgmt_inq_princ_name(p, mem_ctx, &r);
109                 if (!NT_STATUS_IS_OK(status)) {
110                         continue;
111                 }
112                 if (W_ERROR_IS_OK(r.out.result)) {
113                         const char *name = gensec_get_name_by_authtype(i);
114                         ret = True;
115                         if (name) {
116                                 printf("\tprinciple name for proto %u (%s) is '%s'\n", 
117                                        i, name, r.out.princ_name);
118                         } else {
119                                 printf("\tprinciple name for proto %u is '%s'\n", 
120                                        i, r.out.princ_name);
121                         }
122                 }
123         }
124
125         if (!ret) {
126                 printf("\tno principle names?\n");
127         }
128
129         return True;
130 }
131
132 static BOOL test_is_server_listening(struct dcerpc_pipe *p, 
133                                      TALLOC_CTX *mem_ctx)
134 {
135         NTSTATUS status;
136         struct mgmt_is_server_listening r;
137
138         status = dcerpc_mgmt_is_server_listening(p, mem_ctx, &r);
139         if (!NT_STATUS_IS_OK(status)) {
140                 printf("is_server_listening failed - %s\n", nt_errstr(status));
141                 return False;
142         }
143
144         if (r.out.status != 0 || r.out.result == 0) {
145                 printf("\tserver is NOT listening\n");
146         } else {
147                 printf("\tserver is listening\n");
148         }
149
150         return True;
151 }
152
153 static BOOL test_stop_server_listening(struct dcerpc_pipe *p, 
154                                        TALLOC_CTX *mem_ctx)
155 {
156         NTSTATUS status;
157         struct mgmt_stop_server_listening r;
158
159         status = dcerpc_mgmt_stop_server_listening(p, mem_ctx, &r);
160         if (!NT_STATUS_IS_OK(status)) {
161                 printf("stop_server_listening failed - %s\n", nt_errstr(status));
162                 return False;
163         }
164
165         if (!W_ERROR_IS_OK(r.out.result)) {
166                 printf("\tserver refused to stop listening - %s\n", win_errstr(r.out.result));
167         } else {
168                 printf("\tserver allowed a stop_server_listening request\n");
169                 return False;
170         }
171
172         return True;
173 }
174
175
176 BOOL torture_rpc_mgmt(void)
177 {
178         NTSTATUS status;
179         struct dcerpc_pipe *p;
180         TALLOC_CTX *mem_ctx, *loop_ctx;
181         BOOL ret = True;
182         const char *binding = lp_parm_string(-1, "torture", "binding");
183         const struct dcerpc_interface_list *l;
184         struct dcerpc_binding *b;
185
186         mem_ctx = talloc_init("torture_rpc_mgmt");
187
188         if (!binding) {
189                 printf("You must supply a ncacn binding string\n");
190                 return False;
191         }
192         
193         status = dcerpc_parse_binding(mem_ctx, binding, &b);
194         if (!NT_STATUS_IS_OK(status)) {
195                 talloc_free(mem_ctx);
196                 printf("Failed to parse binding '%s'\n", binding);
197                 return False;
198         }
199
200         for (l=librpc_dcerpc_pipes();l;l=l->next) {             
201                 loop_ctx = talloc_named(mem_ctx, 0, "torture_rpc_mgmt loop context");
202                 
203                 /* some interfaces are not mappable */
204                 if (l->table->num_calls == 0 ||
205                     strcmp(l->table->name, "mgmt") == 0) {
206                         talloc_free(loop_ctx);
207                         continue;
208                 }
209
210                 printf("\nTesting pipe '%s'\n", l->table->name);
211
212                 if (b->transport == NCACN_IP_TCP) {
213                         status = dcerpc_epm_map_binding(loop_ctx, b, 
214                                                         l->table->uuid,
215                                                         l->table->if_version, NULL);
216                         if (!NT_STATUS_IS_OK(status)) {
217                                 talloc_free(loop_ctx);
218                                 printf("Failed to map port for uuid %s\n", l->table->uuid);
219                                 continue;
220                         }
221                 } else {
222                         b->endpoint = talloc_strdup(b, l->table->name);
223                 }
224
225                 lp_set_cmdline("torture:binding", dcerpc_binding_string(loop_ctx, b));
226
227                 status = torture_rpc_connection(loop_ctx, 
228                                                 &p, 
229                                                 l->table->name,
230                                                 DCERPC_MGMT_UUID,
231                                                 DCERPC_MGMT_VERSION);
232                 if (!NT_STATUS_IS_OK(status)) {
233                         talloc_free(loop_ctx);
234                         ret = False;
235                         continue;
236                 }
237         
238                 if (!test_is_server_listening(p, loop_ctx)) {
239                         ret = False;
240                 }
241
242                 if (!test_stop_server_listening(p, loop_ctx)) {
243                         ret = False;
244                 }
245
246                 if (!test_inq_stats(p, loop_ctx)) {
247                         ret = False;
248                 }
249
250                 if (!test_inq_princ_name(p, loop_ctx)) {
251                         ret = False;
252                 }
253
254                 if (!test_inq_if_ids(p, loop_ctx)) {
255                         ret = False;
256                 }
257
258         }
259
260         return ret;
261 }