2 Unix SMB/CIFS implementation.
3 test suite for various RAP operations
4 Copyright (C) Volker Lendecke 2004
5 Copyright (C) Tim Potter 2005
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.
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.
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.
33 uint16 rcv_paramlen
, rcv_datalen
;
35 struct ndr_push
*ndr_push_param
;
36 struct ndr_push
*ndr_push_data
;
37 struct ndr_pull
*ndr_pull_param
;
38 struct ndr_pull
*ndr_pull_data
;
41 #define RAPNDR_FLAGS (LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM);
43 static struct rap_call
*new_rap_cli_call(TALLOC_CTX
*mem_ctx
, uint16 callno
)
45 struct rap_call
*call
;
47 call
= talloc(mem_ctx
, struct rap_call
);
52 call
->callno
= callno
;
53 call
->rcv_paramlen
= 4;
55 call
->paramdesc
= NULL
;
56 call
->datadesc
= NULL
;
58 call
->ndr_push_param
= ndr_push_init_ctx(mem_ctx
);
59 call
->ndr_push_param
->flags
= RAPNDR_FLAGS
;
61 call
->ndr_push_data
= ndr_push_init_ctx(mem_ctx
);
62 call
->ndr_push_data
->flags
= RAPNDR_FLAGS
;
67 static void rap_cli_push_paramdesc(struct rap_call
*call
, char desc
)
71 if (call
->paramdesc
!= NULL
)
72 len
= strlen(call
->paramdesc
);
74 call
->paramdesc
= talloc_realloc(call
,
79 call
->paramdesc
[len
] = desc
;
80 call
->paramdesc
[len
+1] = '\0';
83 static void rap_cli_push_word(struct rap_call
*call
, uint16 val
)
85 rap_cli_push_paramdesc(call
, 'W');
86 ndr_push_uint16(call
->ndr_push_param
, NDR_SCALARS
, val
);
89 static void rap_cli_push_dword(struct rap_call
*call
, uint32 val
)
91 rap_cli_push_paramdesc(call
, 'D');
92 ndr_push_uint32(call
->ndr_push_param
, NDR_SCALARS
, val
);
95 static void rap_cli_push_rcvbuf(struct rap_call
*call
, int len
)
97 rap_cli_push_paramdesc(call
, 'r');
98 rap_cli_push_paramdesc(call
, 'L');
99 ndr_push_uint16(call
->ndr_push_param
, NDR_SCALARS
, len
);
100 call
->rcv_datalen
= len
;
103 static void rap_cli_expect_multiple_entries(struct rap_call
*call
)
105 rap_cli_push_paramdesc(call
, 'e');
106 rap_cli_push_paramdesc(call
, 'h');
107 call
->rcv_paramlen
+= 4; /* uint16 entry count, uint16 total */
110 static void rap_cli_push_string(struct rap_call
*call
, const char *str
)
113 rap_cli_push_paramdesc(call
, 'O');
116 rap_cli_push_paramdesc(call
, 'z');
117 ndr_push_string(call
->ndr_push_param
, NDR_SCALARS
, str
);
120 static void rap_cli_expect_format(struct rap_call
*call
, const char *format
)
122 call
->datadesc
= format
;
125 static NTSTATUS
rap_pull_string(TALLOC_CTX
*mem_ctx
, struct ndr_pull
*ndr
,
126 uint16 convert
, char **dest
)
128 uint16 string_offset
;
133 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &string_offset
));
134 NDR_CHECK(ndr_pull_uint16(ndr
, NDR_SCALARS
, &ignore
));
136 string_offset
-= convert
;
138 if (string_offset
+1 > ndr
->data_size
)
139 return NT_STATUS_INVALID_PARAMETER
;
141 p
= (const char *)(ndr
->data
+ string_offset
);
142 len
= strnlen(p
, ndr
->data_size
-string_offset
);
144 if ( string_offset
+ len
+ 1 > ndr
->data_size
)
145 return NT_STATUS_INVALID_PARAMETER
;
147 *dest
= talloc_zero_size(mem_ctx
, len
+1);
148 pull_ascii(*dest
, p
, len
+1, len
, 0);
153 static NTSTATUS
rap_cli_do_call(struct smbcli_state
*cli
, struct rap_call
*call
)
156 DATA_BLOB param_blob
;
157 struct ndr_push
*params
;
158 struct smb_trans2 trans
;
160 params
= ndr_push_init_ctx(call
);
163 return NT_STATUS_NO_MEMORY
;
165 params
->flags
= RAPNDR_FLAGS
;
167 trans
.in
.max_param
= call
->rcv_paramlen
;
168 trans
.in
.max_data
= smb_raw_max_trans_data(cli
->tree
, call
->rcv_paramlen
);
169 trans
.in
.max_setup
= 0;
171 trans
.in
.timeout
= 0;
172 trans
.in
.setup_count
= 0;
173 trans
.in
.setup
= NULL
;
174 trans
.in
.trans_name
= "\\PIPE\\LANMAN";
176 NDR_CHECK(ndr_push_uint16(params
, NDR_SCALARS
, call
->callno
));
178 NDR_CHECK(ndr_push_string(params
, NDR_SCALARS
, call
->paramdesc
));
180 NDR_CHECK(ndr_push_string(params
, NDR_SCALARS
, call
->datadesc
));
182 param_blob
= ndr_push_blob(call
->ndr_push_param
);
183 NDR_CHECK(ndr_push_bytes(params
, param_blob
.data
,
186 trans
.in
.params
= ndr_push_blob(params
);
187 trans
.in
.data
= data_blob(NULL
, 0);
189 result
= smb_raw_trans(cli
->tree
, call
, &trans
);
191 if (!NT_STATUS_IS_OK(result
))
194 call
->ndr_pull_param
= ndr_pull_init_blob(&trans
.out
.params
, call
);
195 call
->ndr_pull_param
->flags
= RAPNDR_FLAGS
;
197 call
->ndr_pull_data
= ndr_pull_init_blob(&trans
.out
.data
, call
);
198 call
->ndr_pull_data
->flags
= RAPNDR_FLAGS
;
203 #define NDR_OK(call) do { NTSTATUS _status; \
205 if (!NT_STATUS_IS_OK(_status)) \
209 static NTSTATUS
smbcli_rap_netshareenum(struct smbcli_state
*cli
,
210 struct rap_NetShareEnum
*r
)
212 struct rap_call
*call
;
213 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
216 call
= new_rap_cli_call(NULL
, RAP_WshareEnum
);
219 return NT_STATUS_NO_MEMORY
;
221 rap_cli_push_word(call
, r
->in
.level
); /* Level */
222 rap_cli_push_rcvbuf(call
, r
->in
.bufsize
);
223 rap_cli_expect_multiple_entries(call
);
225 switch(r
->in
.level
) {
227 rap_cli_expect_format(call
, "B13");
230 rap_cli_expect_format(call
, "B13BWz");
234 result
= rap_cli_do_call(cli
, call
);
236 if (!NT_STATUS_IS_OK(result
))
239 NDR_OK(ndr_pull_uint16(call
->ndr_pull_param
, NDR_SCALARS
, &r
->out
.status
));
240 NDR_OK(ndr_pull_uint16(call
->ndr_pull_param
, NDR_SCALARS
, &r
->out
.convert
));
241 NDR_OK(ndr_pull_uint16(call
->ndr_pull_param
, NDR_SCALARS
, &r
->out
.count
));
242 NDR_OK(ndr_pull_uint16(call
->ndr_pull_param
, NDR_SCALARS
, &r
->out
.available
));
244 r
->out
.info
= talloc_array(call
, union rap_shareenum_info
,
247 if (r
->out
.info
== NULL
) {
248 result
= NT_STATUS_NO_MEMORY
;
252 for (i
=0; i
<r
->out
.count
; i
++) {
253 switch(r
->in
.level
) {
255 NDR_OK(ndr_pull_bytes(call
->ndr_pull_data
,
256 (uint8_t *)r
->out
.info
[i
].info0
.name
, 13));
259 NDR_OK(ndr_pull_bytes(call
->ndr_pull_data
,
260 (uint8_t *)r
->out
.info
[i
].info1
.name
, 13));
261 NDR_OK(ndr_pull_bytes(call
->ndr_pull_data
,
262 (uint8_t *)&r
->out
.info
[i
].info1
.pad
, 1));
263 NDR_OK(ndr_pull_uint16(call
->ndr_pull_data
,
264 NDR_SCALARS
, &r
->out
.info
[i
].info1
.type
));
265 NDR_OK(rap_pull_string(call
, call
->ndr_pull_data
,
267 &r
->out
.info
[i
].info1
.comment
));
272 result
= NT_STATUS_OK
;
279 static BOOL
test_netshareenum(struct smbcli_state
*cli
)
281 struct rap_NetShareEnum r
;
287 if (!NT_STATUS_IS_OK(smbcli_rap_netshareenum(cli
, &r
)))
290 for (i
=0; i
<r
.out
.count
; i
++) {
291 printf("%s %d %s\n", r
.out
.info
[i
].info1
.name
,
292 r
.out
.info
[i
].info1
.type
,
293 r
.out
.info
[i
].info1
.comment
);
299 static NTSTATUS
smbcli_rap_netserverenum2(struct smbcli_state
*cli
,
300 struct rap_NetServerEnum2
*r
)
302 struct rap_call
*call
;
303 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
306 call
= new_rap_cli_call(NULL
, RAP_NetServerEnum2
);
309 return NT_STATUS_NO_MEMORY
;
311 rap_cli_push_word(call
, r
->in
.level
);
312 rap_cli_push_rcvbuf(call
, r
->in
.bufsize
);
313 rap_cli_expect_multiple_entries(call
);
314 rap_cli_push_dword(call
, r
->in
.servertype
);
315 rap_cli_push_string(call
, r
->in
.domain
);
317 switch(r
->in
.level
) {
319 rap_cli_expect_format(call
, "B16");
322 rap_cli_expect_format(call
, "B16BBDz");
326 result
= rap_cli_do_call(cli
, call
);
328 if (!NT_STATUS_IS_OK(result
))
331 result
= NT_STATUS_INVALID_PARAMETER
;
333 NDR_OK(ndr_pull_uint16(call
->ndr_pull_param
, NDR_SCALARS
, &r
->out
.status
));
334 NDR_OK(ndr_pull_uint16(call
->ndr_pull_param
, NDR_SCALARS
, &r
->out
.convert
));
335 NDR_OK(ndr_pull_uint16(call
->ndr_pull_param
, NDR_SCALARS
, &r
->out
.count
));
336 NDR_OK(ndr_pull_uint16(call
->ndr_pull_param
, NDR_SCALARS
, &r
->out
.available
));
338 r
->out
.info
= talloc_array(call
, union rap_server_info
,
341 if (r
->out
.info
== NULL
) {
342 result
= NT_STATUS_NO_MEMORY
;
346 for (i
=0; i
<r
->out
.count
; i
++) {
347 switch(r
->in
.level
) {
349 NDR_OK(ndr_pull_bytes(call
->ndr_pull_data
,
350 (uint8_t *)r
->out
.info
[i
].info0
.name
, 16));
353 NDR_OK(ndr_pull_bytes(call
->ndr_pull_data
,
354 (uint8_t *)r
->out
.info
[i
].info1
.name
, 16));
355 NDR_OK(ndr_pull_bytes(call
->ndr_pull_data
,
356 &r
->out
.info
[i
].info1
.version_major
, 1));
357 NDR_OK(ndr_pull_bytes(call
->ndr_pull_data
,
358 &r
->out
.info
[i
].info1
.version_minor
, 1));
359 NDR_OK(ndr_pull_uint32(call
->ndr_pull_data
,
360 NDR_SCALARS
, &r
->out
.info
[i
].info1
.servertype
));
361 NDR_OK(rap_pull_string(call
, call
->ndr_pull_data
,
363 &r
->out
.info
[i
].info1
.comment
));
367 result
= NT_STATUS_OK
;
374 static BOOL
test_netserverenum(struct smbcli_state
*cli
)
376 struct rap_NetServerEnum2 r
;
381 r
.in
.servertype
= 0xffffffff;
382 r
.in
.servertype
= 0x80000000;
385 if (!NT_STATUS_IS_OK(smbcli_rap_netserverenum2(cli
, &r
)))
388 for (i
=0; i
<r
.out
.count
; i
++) {
389 switch (r
.in
.level
) {
391 printf("%s\n", r
.out
.info
[i
].info0
.name
);
394 printf("%s %x %s\n", r
.out
.info
[i
].info1
.name
,
395 r
.out
.info
[i
].info1
.servertype
,
396 r
.out
.info
[i
].info1
.comment
);
406 static BOOL
test_rap(struct smbcli_state
*cli
)
410 if (!test_netserverenum(cli
))
413 if (!test_netshareenum(cli
))
419 BOOL
torture_raw_rap(void)
421 struct smbcli_state
*cli
;
425 if (!torture_open_connection(&cli
)) {
429 mem_ctx
= talloc_init("torture_raw_rap");
431 if (!test_rap(cli
)) {
435 torture_close_connection(cli
);
436 talloc_free(mem_ctx
);
441 BOOL
torture_rap_scan(void)
444 struct smbcli_state
*cli
;
447 mem_ctx
= talloc_init("torture_rap_scan");
449 if (!torture_open_connection(&cli
)) {
453 for (callno
= 0; callno
< 0xffff; callno
++) {
454 struct rap_call
*call
= new_rap_cli_call(mem_ctx
, callno
);
457 result
= rap_cli_do_call(cli
, call
);
459 if (!NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_PARAMETER
))
462 printf("callno %d is RAP call\n", callno
);
465 torture_close_connection(cli
);