s4-torture: pass down struct torture_context to some more calls in mgmt test.
[samba.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 3 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, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "librpc/gen_ndr/ndr_mgmt_c.h"
23 #include "auth/gensec/gensec.h"
24 #include "librpc/ndr/ndr_table.h"
25 #include "torture/rpc/torture_rpc.h"
26 #include "param/param.h"
27
28
29 /*
30   ask the server what interface IDs are available on this endpoint
31 */
32 bool test_inq_if_ids(struct torture_context *tctx,
33                      struct dcerpc_binding_handle *b,
34                      TALLOC_CTX *mem_ctx,
35                      bool (*per_id_test)(struct torture_context *,
36                                          const struct ndr_interface_table *iface,
37                                          TALLOC_CTX *mem_ctx,
38                                          struct ndr_syntax_id *id),
39                      const void *priv)
40 {
41         NTSTATUS status;
42         struct mgmt_inq_if_ids r;
43         struct rpc_if_id_vector_t *vector;
44         int i;
45
46         vector = talloc(mem_ctx, struct rpc_if_id_vector_t);
47         r.out.if_id_vector = &vector;
48
49         status = dcerpc_mgmt_inq_if_ids_r(b, mem_ctx, &r);
50         if (!NT_STATUS_IS_OK(status)) {
51                 printf("inq_if_ids failed - %s\n", nt_errstr(status));
52                 return false;
53         }
54
55         if (!W_ERROR_IS_OK(r.out.result)) {
56                 printf("inq_if_ids gave error code %s\n", win_errstr(r.out.result));
57                 return false;
58         }
59
60         if (!vector) {
61                 printf("inq_if_ids gave NULL if_id_vector\n");
62                 return false;
63         }
64
65         for (i=0;i<vector->count;i++) {
66                 struct ndr_syntax_id *id = vector->if_id[i].id;
67                 if (!id) continue;
68
69                 printf("\tuuid %s  version 0x%08x  '%s'\n",
70                        GUID_string(mem_ctx, &id->uuid),
71                        id->if_version,
72                        ndr_interface_name(&id->uuid, id->if_version));
73
74                 if (per_id_test) {
75                         per_id_test(tctx, priv, mem_ctx, id);
76                 }
77         }
78
79         return true;
80 }
81
82 static bool test_inq_stats(struct torture_context *tctx,
83                            struct dcerpc_binding_handle *b,
84                            TALLOC_CTX *mem_ctx)
85 {
86         NTSTATUS status;
87         struct mgmt_inq_stats r;
88         struct mgmt_statistics statistics;
89
90         r.in.max_count = MGMT_STATS_ARRAY_MAX_SIZE;
91         r.in.unknown = 0;
92         r.out.statistics = &statistics;
93
94         status = dcerpc_mgmt_inq_stats_r(b, mem_ctx, &r);
95         if (!NT_STATUS_IS_OK(status)) {
96                 printf("inq_stats failed - %s\n", nt_errstr(status));
97                 return false;
98         }
99
100         if (statistics.count != MGMT_STATS_ARRAY_MAX_SIZE) {
101                 printf("Unexpected array size %d\n", statistics.count);
102                 return false;
103         }
104
105         printf("\tcalls_in %6d  calls_out %6d\n\tpkts_in  %6d  pkts_out  %6d\n",
106                statistics.statistics[MGMT_STATS_CALLS_IN],
107                statistics.statistics[MGMT_STATS_CALLS_OUT],
108                statistics.statistics[MGMT_STATS_PKTS_IN],
109                statistics.statistics[MGMT_STATS_PKTS_OUT]);
110
111         return true;
112 }
113
114 static bool test_inq_princ_name(struct torture_context *tctx,
115                                 struct dcerpc_binding_handle *b,
116                                 TALLOC_CTX *mem_ctx)
117 {
118         NTSTATUS status;
119         struct mgmt_inq_princ_name r;
120         int i;
121         bool ret = false;
122
123         for (i=0;i<256;i++) {
124                 r.in.authn_proto = i;  /* DCERPC_AUTH_TYPE_* */
125                 r.in.princ_name_size = 100;
126
127                 status = dcerpc_mgmt_inq_princ_name_r(b, mem_ctx, &r);
128                 if (!NT_STATUS_IS_OK(status)) {
129                         continue;
130                 }
131                 if (W_ERROR_IS_OK(r.out.result)) {
132                         const char *name = gensec_get_name_by_authtype(NULL, i);
133                         ret = true;
134                         if (name) {
135                                 printf("\tprinciple name for proto %u (%s) is '%s'\n",
136                                        i, name, r.out.princ_name);
137                         } else {
138                                 printf("\tprinciple name for proto %u is '%s'\n",
139                                        i, r.out.princ_name);
140                         }
141                 }
142         }
143
144         if (!ret) {
145                 printf("\tno principle names?\n");
146         }
147
148         return true;
149 }
150
151 static bool test_is_server_listening(struct torture_context *tctx,
152                                      struct dcerpc_binding_handle *b,
153                                      TALLOC_CTX *mem_ctx)
154 {
155         NTSTATUS status;
156         struct mgmt_is_server_listening r;
157         r.out.status = talloc(mem_ctx, uint32_t);
158
159         status = dcerpc_mgmt_is_server_listening_r(b, mem_ctx, &r);
160         if (!NT_STATUS_IS_OK(status)) {
161                 printf("is_server_listening failed - %s\n", nt_errstr(status));
162                 return false;
163         }
164
165         if (*r.out.status != 0 || r.out.result == 0) {
166                 printf("\tserver is NOT listening\n");
167         } else {
168                 printf("\tserver is listening\n");
169         }
170
171         return true;
172 }
173
174 static bool test_stop_server_listening(struct torture_context *tctx,
175                                        struct dcerpc_binding_handle *b,
176                                        TALLOC_CTX *mem_ctx)
177 {
178         NTSTATUS status;
179         struct mgmt_stop_server_listening r;
180
181         status = dcerpc_mgmt_stop_server_listening_r(b, mem_ctx, &r);
182         if (!NT_STATUS_IS_OK(status)) {
183                 printf("stop_server_listening failed - %s\n", nt_errstr(status));
184                 return false;
185         }
186
187         if (!W_ERROR_IS_OK(r.out.result)) {
188                 printf("\tserver refused to stop listening - %s\n", win_errstr(r.out.result));
189         } else {
190                 printf("\tserver allowed a stop_server_listening request\n");
191                 return false;
192         }
193
194         return true;
195 }
196
197
198 bool torture_rpc_mgmt(struct torture_context *tctx)
199 {
200         NTSTATUS status;
201         struct dcerpc_pipe *p;
202         TALLOC_CTX *mem_ctx, *loop_ctx;
203         bool ret = true;
204         const struct ndr_interface_list *l;
205         struct dcerpc_binding *b;
206
207         mem_ctx = talloc_init("torture_rpc_mgmt");
208
209         status = torture_rpc_binding(tctx, &b);
210         if (!NT_STATUS_IS_OK(status)) {
211                 talloc_free(mem_ctx);
212                 return false;
213         }
214
215         for (l=ndr_table_list();l;l=l->next) {
216                 struct dcerpc_binding_handle *bh;
217
218                 loop_ctx = talloc_named(mem_ctx, 0, "torture_rpc_mgmt loop context");
219
220                 /* some interfaces are not mappable */
221                 if (l->table->num_calls == 0 ||
222                     strcmp(l->table->name, "mgmt") == 0) {
223                         talloc_free(loop_ctx);
224                         continue;
225                 }
226
227                 printf("\nTesting pipe '%s'\n", l->table->name);
228
229                 status = dcerpc_epm_map_binding(loop_ctx, b, l->table,
230                                                 tctx->ev, tctx->lp_ctx);
231                 if (!NT_STATUS_IS_OK(status)) {
232                         printf("Failed to map port for uuid %s\n",
233                                    GUID_string(loop_ctx, &l->table->syntax_id.uuid));
234                         talloc_free(loop_ctx);
235                         continue;
236                 }
237
238                 lpcfg_set_cmdline(tctx->lp_ctx, "torture:binding", dcerpc_binding_string(loop_ctx, b));
239
240                 status = torture_rpc_connection(tctx, &p, &ndr_table_mgmt);
241                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
242                         printf("Interface not available - skipping\n");
243                         talloc_free(loop_ctx);
244                         continue;
245                 }
246                 bh = p->binding_handle;
247
248                 if (!NT_STATUS_IS_OK(status)) {
249                         talloc_free(loop_ctx);
250                         ret = false;
251                         continue;
252                 }
253
254                 if (!test_is_server_listening(tctx, bh, loop_ctx)) {
255                         ret = false;
256                 }
257
258                 if (!test_stop_server_listening(tctx, bh, loop_ctx)) {
259                         ret = false;
260                 }
261
262                 if (!test_inq_stats(tctx, bh, loop_ctx)) {
263                         ret = false;
264                 }
265
266                 if (!test_inq_princ_name(tctx, bh, loop_ctx)) {
267                         ret = false;
268                 }
269
270                 if (!test_inq_if_ids(tctx, bh, loop_ctx, NULL, NULL)) {
271                         ret = false;
272                 }
273
274         }
275
276         return ret;
277 }