258450ada1bfac2ecdfe3fafa8788c726d2fd386
[gd/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 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 "torture/torture.h"
23 #include "librpc/gen_ndr/ndr_mgmt_c.h"
24 #include "auth/gensec/gensec.h"
25 #include "librpc/ndr/ndr_table.h"
26 #include "torture/rpc/rpc.h"
27 #include "param/param.h"
28
29
30 /*
31   ask the server what interface IDs are available on this endpoint
32 */
33 bool test_inq_if_ids(struct torture_context *tctx, 
34                      struct dcerpc_pipe *p, 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(p, 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 dcerpc_pipe *p, 
83                            TALLOC_CTX *mem_ctx)
84 {
85         NTSTATUS status;
86         struct mgmt_inq_stats r;
87         struct mgmt_statistics statistics;
88
89         r.in.max_count = MGMT_STATS_ARRAY_MAX_SIZE;
90         r.in.unknown = 0;
91         r.out.statistics = &statistics;
92
93         status = dcerpc_mgmt_inq_stats(p, mem_ctx, &r);
94         if (!NT_STATUS_IS_OK(status)) {
95                 printf("inq_stats failed - %s\n", nt_errstr(status));
96                 return false;
97         }
98
99         if (statistics.count != MGMT_STATS_ARRAY_MAX_SIZE) {
100                 printf("Unexpected array size %d\n", statistics.count);
101                 return false;
102         }
103
104         printf("\tcalls_in %6d  calls_out %6d\n\tpkts_in  %6d  pkts_out  %6d\n",
105                statistics.statistics[MGMT_STATS_CALLS_IN],
106                statistics.statistics[MGMT_STATS_CALLS_OUT],
107                statistics.statistics[MGMT_STATS_PKTS_IN],
108                statistics.statistics[MGMT_STATS_PKTS_OUT]);
109
110         return true;
111 }
112
113 static bool test_inq_princ_name(struct dcerpc_pipe *p, 
114                                 TALLOC_CTX *mem_ctx)
115 {
116         NTSTATUS status;
117         struct mgmt_inq_princ_name r;
118         int i;
119         bool ret = false;
120
121         for (i=0;i<100;i++) {
122                 r.in.authn_proto = i;  /* DCERPC_AUTH_TYPE_* */
123                 r.in.princ_name_size = 100;
124
125                 status = dcerpc_mgmt_inq_princ_name(p, mem_ctx, &r);
126                 if (!NT_STATUS_IS_OK(status)) {
127                         continue;
128                 }
129                 if (W_ERROR_IS_OK(r.out.result)) {
130                         const char *name = gensec_get_name_by_authtype(i);
131                         ret = true;
132                         if (name) {
133                                 printf("\tprinciple name for proto %u (%s) is '%s'\n", 
134                                        i, name, r.out.princ_name);
135                         } else {
136                                 printf("\tprinciple name for proto %u is '%s'\n", 
137                                        i, r.out.princ_name);
138                         }
139                 }
140         }
141
142         if (!ret) {
143                 printf("\tno principle names?\n");
144         }
145
146         return true;
147 }
148
149 static bool test_is_server_listening(struct dcerpc_pipe *p, 
150                                      TALLOC_CTX *mem_ctx)
151 {
152         NTSTATUS status;
153         struct mgmt_is_server_listening r;
154         r.out.status = talloc(mem_ctx, uint32_t);
155
156         status = dcerpc_mgmt_is_server_listening(p, mem_ctx, &r);
157         if (!NT_STATUS_IS_OK(status)) {
158                 printf("is_server_listening failed - %s\n", nt_errstr(status));
159                 return false;
160         }
161
162         if (*r.out.status != 0 || r.out.result == 0) {
163                 printf("\tserver is NOT listening\n");
164         } else {
165                 printf("\tserver is listening\n");
166         }
167
168         return true;
169 }
170
171 static bool test_stop_server_listening(struct dcerpc_pipe *p, 
172                                        TALLOC_CTX *mem_ctx)
173 {
174         NTSTATUS status;
175         struct mgmt_stop_server_listening r;
176
177         status = dcerpc_mgmt_stop_server_listening(p, mem_ctx, &r);
178         if (!NT_STATUS_IS_OK(status)) {
179                 printf("stop_server_listening failed - %s\n", nt_errstr(status));
180                 return false;
181         }
182
183         if (!W_ERROR_IS_OK(r.out.result)) {
184                 printf("\tserver refused to stop listening - %s\n", win_errstr(r.out.result));
185         } else {
186                 printf("\tserver allowed a stop_server_listening request\n");
187                 return false;
188         }
189
190         return true;
191 }
192
193
194 bool torture_rpc_mgmt(struct torture_context *torture)
195 {
196         NTSTATUS status;
197         struct dcerpc_pipe *p;
198         TALLOC_CTX *mem_ctx, *loop_ctx;
199         bool ret = true;
200         const struct ndr_interface_list *l;
201         struct dcerpc_binding *b;
202
203         mem_ctx = talloc_init("torture_rpc_mgmt");
204
205         status = torture_rpc_binding(torture, &b);
206         if (!NT_STATUS_IS_OK(status)) {
207                 talloc_free(mem_ctx);
208                 return false;
209         }
210
211         for (l=ndr_table_list();l;l=l->next) {          
212                 loop_ctx = talloc_named(mem_ctx, 0, "torture_rpc_mgmt loop context");
213                 
214                 /* some interfaces are not mappable */
215                 if (l->table->num_calls == 0 ||
216                     strcmp(l->table->name, "mgmt") == 0) {
217                         talloc_free(loop_ctx);
218                         continue;
219                 }
220
221                 printf("\nTesting pipe '%s'\n", l->table->name);
222
223                 status = dcerpc_epm_map_binding(loop_ctx, b, l->table, NULL);
224                 if (!NT_STATUS_IS_OK(status)) {
225                         printf("Failed to map port for uuid %s\n", 
226                                    GUID_string(loop_ctx, &l->table->syntax_id.uuid));
227                         talloc_free(loop_ctx);
228                         continue;
229                 }
230
231                 lp_set_cmdline(global_loadparm, "torture:binding", dcerpc_binding_string(loop_ctx, b));
232
233                 status = torture_rpc_connection(torture, &p, &ndr_table_mgmt);
234                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
235                         printf("Interface not available - skipping\n");
236                         talloc_free(loop_ctx);
237                         continue;
238                 }
239
240                 if (!NT_STATUS_IS_OK(status)) {
241                         talloc_free(loop_ctx);
242                         ret = false;
243                         continue;
244                 }
245
246                 if (!test_is_server_listening(p, loop_ctx)) {
247                         ret = false;
248                 }
249
250                 if (!test_stop_server_listening(p, loop_ctx)) {
251                         ret = false;
252                 }
253
254                 if (!test_inq_stats(p, loop_ctx)) {
255                         ret = false;
256                 }
257
258                 if (!test_inq_princ_name(p, loop_ctx)) {
259                         ret = false;
260                 }
261
262                 if (!test_inq_if_ids(torture, p, loop_ctx, NULL, NULL)) {
263                         ret = false;
264                 }
265
266         }
267
268         return ret;
269 }