1 /* 2 Unix SMB/CIFS implementation. 3 test suite for srvsvc rpc operations 4 5 Copyright (C) Stefan (metze) Metzmacher 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_srvsvc_c.h" 23 #include "torture/rpc/torture_rpc.h" 24 25 /**************************/ 26 /* srvsvc_NetCharDev */ 27 /**************************/ 28 static bool test_NetCharDevGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx, 29 const char *devname) 30 { 31 NTSTATUS status; 32 struct srvsvc_NetCharDevGetInfo r; 33 union srvsvc_NetCharDevInfo info; 34 uint32_t levels[] = {0, 1}; 35 int i; 36 struct dcerpc_binding_handle *b = p->binding_handle; 37 38 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 39 r.in.device_name = devname; 40 r.out.info = &info; 41 42 for (i=0;i<ARRAY_SIZE(levels);i++) { 43 r.in.level = levels[i]; 44 torture_comment(tctx, "Testing NetCharDevGetInfo level %u on device '%s'\n", 45 r.in.level, r.in.device_name); 46 status = dcerpc_srvsvc_NetCharDevGetInfo_r(b, tctx, &r); 47 torture_assert_ntstatus_ok(tctx, status, "NetCharDevGetInfo failed"); 48 torture_assert_werr_ok(tctx, r.out.result, "NetCharDevGetInfo failed"); 49 } 50 51 return true; 52 } 53 54 static bool test_NetCharDevControl(struct dcerpc_pipe *p, struct torture_context *tctx, 55 const char *devname) 56 { 57 NTSTATUS status; 58 struct srvsvc_NetCharDevControl r; 59 uint32_t opcodes[] = {0, 1}; 60 int i; 61 struct dcerpc_binding_handle *b = p->binding_handle; 62 63 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 64 r.in.device_name = devname; 65 66 for (i=0;i<ARRAY_SIZE(opcodes);i++) { 67 ZERO_STRUCT(r.out); 68 r.in.opcode = opcodes[i]; 69 torture_comment(tctx, "Testing NetCharDevControl opcode %u on device '%s'\n", 70 r.in.opcode, r.in.device_name); 71 status = dcerpc_srvsvc_NetCharDevControl_r(b, tctx, &r); 72 torture_assert_ntstatus_ok(tctx, status, "NetCharDevControl failed"); 73 torture_assert_werr_ok(tctx, r.out.result, "NetCharDevControl failed"); 74 } 75 76 return true; 77 } 78 79 static bool test_NetCharDevEnum(struct torture_context *tctx, 80 struct dcerpc_pipe *p) 81 { 82 NTSTATUS status; 83 struct srvsvc_NetCharDevEnum r; 84 struct srvsvc_NetCharDevInfoCtr info_ctr; 85 struct srvsvc_NetCharDevCtr0 c0; 86 struct srvsvc_NetCharDevCtr0 c1; 87 uint32_t totalentries = 0; 88 uint32_t levels[] = {0, 1}; 89 int i; 90 struct dcerpc_binding_handle *b = p->binding_handle; 91 92 ZERO_STRUCT(info_ctr); 93 94 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 95 r.in.info_ctr = &info_ctr; 96 r.in.max_buffer = (uint32_t)-1; 97 r.in.resume_handle = NULL; 98 r.out.info_ctr = &info_ctr; 99 r.out.totalentries = &totalentries; 100 101 for (i=0;i<ARRAY_SIZE(levels);i++) { 102 int j; 103 104 info_ctr.level = levels[i]; 105 106 switch(info_ctr.level) { 107 case 0: 108 ZERO_STRUCT(c0); 109 info_ctr.ctr.ctr0 = &c0; 110 break; 111 case 1: 112 ZERO_STRUCT(c1); 113 info_ctr.ctr.ctr0 = &c1; 114 break; 115 } 116 117 torture_comment(tctx, "Testing NetCharDevEnum level %u\n", info_ctr.level); 118 status = dcerpc_srvsvc_NetCharDevEnum_r(b, tctx, &r); 119 torture_assert_ntstatus_ok(tctx, status, "NetCharDevEnum failed"); 120 if (!W_ERROR_IS_OK(r.out.result)) { 121 torture_comment(tctx, "NetCharDevEnum failed: %s\n", win_errstr(r.out.result)); 122 continue; 123 } 124 125 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */ 126 if (info_ctr.level == 1) { 127 for (j=0;j<r.out.info_ctr->ctr.ctr1->count;j++) { 128 const char *device; 129 device = r.out.info_ctr->ctr.ctr1->array[j].device; 130 if (!test_NetCharDevGetInfo(p, tctx, device)) { 131 return false; 132 } 133 if (!test_NetCharDevControl(p, tctx, device)) { 134 return false; 135 } 136 } 137 } 138 } 139 140 return true; 141 } 142 143 /**************************/ 144 /* srvsvc_NetCharDevQ */ 145 /**************************/ 146 static bool test_NetCharDevQGetInfo(struct dcerpc_pipe *p, struct torture_context *tctx, 147 const char *devicequeue) 148 { 149 NTSTATUS status; 150 struct srvsvc_NetCharDevQGetInfo r; 151 union srvsvc_NetCharDevQInfo info; 152 uint32_t levels[] = {0, 1}; 153 int i; 154 struct dcerpc_binding_handle *b = p->binding_handle; 155 156 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 157 r.in.queue_name = devicequeue; 158 r.in.user = talloc_asprintf(tctx,"Administrator"); 159 r.out.info = &info; 160 161 for (i=0;i<ARRAY_SIZE(levels);i++) { 162 r.in.level = levels[i]; 163 torture_comment(tctx, "Testing NetCharDevQGetInfo level %u on devicequeue '%s'\n", 164 r.in.level, r.in.queue_name); 165 status = dcerpc_srvsvc_NetCharDevQGetInfo_r(b, tctx, &r); 166 torture_assert_ntstatus_ok(tctx, status, "NetCharDevQGetInfo failed"); 167 torture_assert_werr_ok(tctx, r.out.result, "NetCharDevQGetInfo failed"); 168 } 169 170 return true; 171 } 172 173 #if 0 174 static bool test_NetCharDevQSetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 175 const char *devicequeue) 176 { 177 NTSTATUS status; 178 struct srvsvc_NetCharDevQSetInfo r; 179 uint32_t parm_error; 180 uint32_t levels[] = {0, 1}; 181 int i; 182 bool ret = true; 183 struct dcerpc_binding_handle *b = p->binding_handle; 184 185 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p)); 186 r.in.queue_name = devicequeue; 187 188 for (i=0;i<ARRAY_SIZE(levels);i++) { 189 ZERO_STRUCT(r.out); 190 parm_error = 0; 191 r.in.level = levels[i]; 192 d_printf("testing NetCharDevQSetInfo level %u on devicequeue '%s'\n", 193 r.in.level, devicequeue); 194 switch (r.in.level) { 195 case 0: 196 r.in.info.info0 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo0); 197 r.in.info.info0->device = r.in.queue_name; 198 break; 199 case 1: 200 r.in.info.info1 = talloc(mem_ctx, struct srvsvc_NetCharDevQInfo1); 201 r.in.info.info1->device = r.in.queue_name; 202 r.in.info.info1->priority = 0x000; 203 r.in.info.info1->devices = r.in.queue_name; 204 r.in.info.info1->users = 0x000; 205 r.in.info.info1->num_ahead = 0x000; 206 break; 207 default: 208 break; 209 } 210 r.in.parm_error = &parm_error; 211 status = dcerpc_srvsvc_NetCharDevQSetInfo_r(b, mem_ctx, &r); 212 if (!NT_STATUS_IS_OK(status)) { 213 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n", 214 r.in.level, r.in.queue_name, nt_errstr(status)); 215 ret = false; 216 continue; 217 } 218 if (!W_ERROR_IS_OK(r.out.result)) { 219 d_printf("NetCharDevQSetInfo level %u on devicequeue '%s' failed - %s\n", 220 r.in.level, r.in.queue_name, win_errstr(r.out.result)); 221 continue; 222 } 223 } 224 225 return ret; 226 } 227 #endif 228 229 static bool test_NetCharDevQEnum(struct torture_context *tctx, 230 struct dcerpc_pipe *p) 231 { 232 NTSTATUS status; 233 struct srvsvc_NetCharDevQEnum r; 234 struct srvsvc_NetCharDevQInfoCtr info_ctr; 235 struct srvsvc_NetCharDevQCtr0 c0; 236 struct srvsvc_NetCharDevQCtr1 c1; 237 uint32_t totalentries = 0; 238 uint32_t levels[] = {0, 1}; 239 int i; 240 struct dcerpc_binding_handle *b = p->binding_handle; 241 242 ZERO_STRUCT(info_ctr); 243 244 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 245 r.in.user = talloc_asprintf(tctx,"%s","Administrator"); 246 r.in.info_ctr = &info_ctr; 247 r.in.max_buffer = (uint32_t)-1; 248 r.in.resume_handle = NULL; 249 r.out.totalentries = &totalentries; 250 r.out.info_ctr = &info_ctr; 251 252 for (i=0;i<ARRAY_SIZE(levels);i++) { 253 int j; 254 255 info_ctr.level = levels[i]; 256 257 switch (info_ctr.level) { 258 case 0: 259 ZERO_STRUCT(c0); 260 info_ctr.ctr.ctr0 = &c0; 261 break; 262 case 1: 263 ZERO_STRUCT(c1); 264 info_ctr.ctr.ctr1 = &c1; 265 break; 266 } 267 torture_comment(tctx, "Testing NetCharDevQEnum level %u\n", info_ctr.level); 268 status = dcerpc_srvsvc_NetCharDevQEnum_r(b, tctx, &r); 269 torture_assert_ntstatus_ok(tctx, status, "NetCharDevQEnum failed"); 270 if (!W_ERROR_IS_OK(r.out.result)) { 271 torture_comment(tctx, "NetCharDevQEnum failed: %s\n", win_errstr(r.out.result)); 272 continue; 273 } 274 275 /* call test_NetCharDevGetInfo and test_NetCharDevControl for each returned share */ 276 if (info_ctr.level == 1) { 277 for (j=0;j<r.out.info_ctr->ctr.ctr1->count;j++) { 278 const char *device; 279 device = r.out.info_ctr->ctr.ctr1->array[j].device; 280 if (!test_NetCharDevQGetInfo(p, tctx, device)) { 281 return false; 282 } 283 } 284 } 285 } 286 287 return true; 288 } 289 290 /**************************/ 291 /* srvsvc_NetConn */ 292 /**************************/ 293 static bool test_NetConnEnum(struct torture_context *tctx, 294 struct dcerpc_pipe *p) 295 { 296 NTSTATUS status; 297 struct srvsvc_NetConnEnum r; 298 struct srvsvc_NetConnInfoCtr info_ctr; 299 struct srvsvc_NetConnCtr0 c0; 300 struct srvsvc_NetConnCtr1 c1; 301 uint32_t totalentries = 0; 302 uint32_t levels[] = {0, 1}; 303 int i; 304 struct dcerpc_binding_handle *b = p->binding_handle; 305 306 ZERO_STRUCT(info_ctr); 307 308 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 309 r.in.path = talloc_asprintf(tctx,"%s","IPC$"); 310 r.in.info_ctr = &info_ctr; 311 r.in.max_buffer = (uint32_t)-1; 312 r.in.resume_handle = NULL; 313 r.out.totalentries = &totalentries; 314 r.out.info_ctr = &info_ctr; 315 316 for (i=0;i<ARRAY_SIZE(levels);i++) { 317 info_ctr.level = levels[i]; 318 319 switch (info_ctr.level) { 320 case 0: 321 ZERO_STRUCT(c0); 322 info_ctr.ctr.ctr0 = &c0; 323 break; 324 case 1: 325 ZERO_STRUCT(c1); 326 info_ctr.ctr.ctr1 = &c1; 327 break; 328 } 329 330 torture_comment(tctx, "Testing NetConnEnum level %u\n", info_ctr.level); 331 status = dcerpc_srvsvc_NetConnEnum_r(b, tctx, &r); 332 torture_assert_ntstatus_ok(tctx, status, "NetConnEnum failed"); 333 if (!W_ERROR_IS_OK(r.out.result)) { 334 torture_comment(tctx, "NetConnEnum failed: %s\n", win_errstr(r.out.result)); 335 } 336 } 337 338 return true; 339 } 340 341 /**************************/ 342 /* srvsvc_NetFile */ 343 /**************************/ 344 static bool test_NetFileEnum(struct torture_context *tctx, 345 struct dcerpc_pipe *p) 346 { 347 NTSTATUS status; 348 struct srvsvc_NetFileEnum r; 349 struct srvsvc_NetFileInfoCtr info_ctr; 350 struct srvsvc_NetFileCtr2 c2; 351 struct srvsvc_NetFileCtr3 c3; 352 uint32_t totalentries = 0; 353 uint32_t levels[] = {2, 3}; 354 int i; 355 struct dcerpc_binding_handle *b = p->binding_handle; 356 357 ZERO_STRUCT(info_ctr); 358 359 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 360 r.in.path = NULL; 361 r.in.user = NULL; 362 r.in.info_ctr = &info_ctr; 363 r.in.max_buffer = (uint32_t)4096; 364 r.in.resume_handle = NULL; 365 r.out.totalentries = &totalentries; 366 r.out.info_ctr = &info_ctr; 367 368 for (i=0;i<ARRAY_SIZE(levels);i++) { 369 info_ctr.level = levels[i]; 370 371 switch (info_ctr.level) { 372 case 2: 373 ZERO_STRUCT(c2); 374 info_ctr.ctr.ctr2 = &c2; 375 break; 376 case 3: 377 ZERO_STRUCT(c3); 378 info_ctr.ctr.ctr3 = &c3; 379 break; 380 } 381 torture_comment(tctx, "Testing NetFileEnum level %u\n", info_ctr.level); 382 status = dcerpc_srvsvc_NetFileEnum_r(b, tctx, &r); 383 torture_assert_ntstatus_ok(tctx, status, "NetFileEnum failed"); 384 if (!W_ERROR_IS_OK(r.out.result)) { 385 torture_comment(tctx, "NetFileEnum failed: %s\n", win_errstr(r.out.result)); 386 } 387 } 388 389 return true; 390 } 391 392 /**************************/ 393 /* srvsvc_NetSess */ 394 /**************************/ 395 static bool test_NetSessEnum(struct torture_context *tctx, 396 struct dcerpc_pipe *p) 397 { 398 NTSTATUS status; 399 struct srvsvc_NetSessEnum r; 400 struct srvsvc_NetSessInfoCtr info_ctr; 401 struct srvsvc_NetSessCtr0 c0; 402 struct srvsvc_NetSessCtr1 c1; 403 struct srvsvc_NetSessCtr2 c2; 404 struct srvsvc_NetSessCtr10 c10; 405 struct srvsvc_NetSessCtr502 c502; 406 uint32_t totalentries = 0; 407 uint32_t levels[] = {0, 1, 2, 10, 502}; 408 int i; 409 struct dcerpc_binding_handle *b = p->binding_handle; 410 411 ZERO_STRUCT(info_ctr); 412 413 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 414 r.in.client = NULL; 415 r.in.user = NULL; 416 r.in.info_ctr = &info_ctr; 417 r.in.max_buffer = (uint32_t)-1; 418 r.in.resume_handle = NULL; 419 r.out.totalentries = &totalentries; 420 r.out.info_ctr = &info_ctr; 421 422 for (i=0;i<ARRAY_SIZE(levels);i++) { 423 info_ctr.level = levels[i]; 424 425 switch (info_ctr.level) { 426 case 0: 427 ZERO_STRUCT(c0); 428 info_ctr.ctr.ctr0 = &c0; 429 break; 430 case 1: 431 ZERO_STRUCT(c1); 432 info_ctr.ctr.ctr1 = &c1; 433 break; 434 case 2: 435 ZERO_STRUCT(c2); 436 info_ctr.ctr.ctr2 = &c2; 437 break; 438 case 10: 439 ZERO_STRUCT(c10); 440 info_ctr.ctr.ctr10 = &c10; 441 break; 442 case 502: 443 ZERO_STRUCT(c502); 444 info_ctr.ctr.ctr502 = &c502; 445 break; 446 } 447 448 torture_comment(tctx, "Testing NetSessEnum level %u\n", info_ctr.level); 449 status = dcerpc_srvsvc_NetSessEnum_r(b, tctx, &r); 450 torture_assert_ntstatus_ok(tctx, status, "NetSessEnum failed"); 451 if (!W_ERROR_IS_OK(r.out.result)) { 452 torture_comment(tctx, "NetSessEnum failed: %s\n", win_errstr(r.out.result)); 453 } 454 } 455 456 return true; 457 } 458 459 /**************************/ 460 /* srvsvc_NetShare */ 461 /**************************/ 462 static bool test_NetShareCheck(struct dcerpc_pipe *p, struct torture_context *tctx, 463 const char *device_name) 464 { 465 NTSTATUS status; 466 struct srvsvc_NetShareCheck r; 467 enum srvsvc_ShareType type; 468 struct dcerpc_binding_handle *b = p->binding_handle; 469 470 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); 471 r.in.device_name = device_name; 472 r.out.type = &type; 473 474 torture_comment(tctx, 475 "Testing NetShareCheck on device '%s'\n", r.in.device_name); 476 477 status = dcerpc_srvsvc_NetShareCheck_r(b, tctx, &r); 478 torture_assert_ntstatus_ok(tctx, status, "dcerpc_srvsvc_NetShareCheck failed"); 479 torture_assert_werr_ok(tctx, r.out.result, "NetShareCheck failed"); 480 481 return true; 482 } 483 484 static bool test_NetShareGetInfo(struct torture_context *tctx, 485 struct dcerpc_pipe *p, 486 const char *sharename, bool admin) 487 { 488 NTSTATUS status; 489 struct srvsvc_NetShareGetInfo r; 490 union srvsvc_NetShareInfo info; 491 struct { 492 uint32_t level; 493 WERROR anon_status; 494 WERROR admin_status; 495 } levels[] = { 496 { 0, WERR_OK, WERR_OK }, 497 { 1, WERR_OK, WERR_OK }, 498 { 2, WERR_ACCESS_DENIED, WERR_OK }, 499 { 501, WERR_OK, WERR_OK }, 500 { 502, WERR_ACCESS_DENIED, WERR_OK }, 501 { 1005, WERR_OK, WERR_OK }, 502 }; 503 int i; 504 struct dcerpc_binding_handle *b = p->binding_handle; 505 506 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); 507 r.in.share_name = sharename; 508 r.out.info = &info; 509 510 for (i=0;i<ARRAY_SIZE(levels);i++) { 511 WERROR expected; 512 513 r.in.level = levels[i].level; 514 expected = levels[i].anon_status; 515 if (admin) expected = levels[i].admin_status; 516 517 torture_comment(tctx, "Testing NetShareGetInfo level %u on share '%s'\n", 518 r.in.level, r.in.share_name); 519 520 status = dcerpc_srvsvc_NetShareGetInfo_r(b, tctx, &r); 521 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed"); 522 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareGetInfo failed"); 523 524 if (r.in.level != 2) continue; 525 if (!r.out.info->info2 || !r.out.info->info2->path) continue; 526 if (!test_NetShareCheck(p, tctx, r.out.info->info2->path)) { 527 return false; 528 } 529 } 530 531 return true; 532 } 533 534 static bool test_NetShareGetInfoAdminFull(struct torture_context *tctx, 535 struct dcerpc_pipe *p) 536 { 537 return test_NetShareGetInfo(tctx, p, "IPC$", true); 538 } 539 540 static bool test_NetShareGetInfoAdminAnon(struct torture_context *tctx, 541 struct dcerpc_pipe *p) 542 { 543 return test_NetShareGetInfo(tctx, p, "IPC$", false); 544 } 545 546 static bool test_NetShareAddSetDel(struct torture_context *tctx, 547 struct dcerpc_pipe *p) 548 { 549 NTSTATUS status; 550 struct srvsvc_NetShareAdd a; 551 struct srvsvc_NetShareSetInfo r; 552 struct srvsvc_NetShareGetInfo q; 553 struct srvsvc_NetShareDel d; 554 struct sec_desc_buf sd_buf; 555 union srvsvc_NetShareInfo info; 556 struct { 557 uint32_t level; 558 WERROR expected; 559 } levels[] = { 560 { 0, WERR_INVALID_LEVEL }, 561 { 1, WERR_OK }, 562 { 2, WERR_OK }, 563 { 501, WERR_INVALID_LEVEL }, 564 { 502, WERR_OK }, 565 { 1004, WERR_OK }, 566 { 1005, WERR_OK }, 567 { 1006, WERR_OK }, 568 /* { 1007, WERR_OK }, */ 569 { 1501, WERR_OK }, 570 }; 571 int i; 572 struct dcerpc_binding_handle *b = p->binding_handle; 573 574 a.in.server_unc = r.in.server_unc = q.in.server_unc = d.in.server_unc = 575 talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); 576 r.in.share_name = talloc_strdup(tctx, "testshare"); 577 578 info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2); 579 info.info2->name = r.in.share_name; 580 info.info2->type = STYPE_DISKTREE; 581 info.info2->comment = talloc_strdup(tctx, "test comment"); 582 info.info2->permissions = 123434566; 583 info.info2->max_users = -1; 584 info.info2->current_users = 0; 585 info.info2->path = talloc_strdup(tctx, "C:\\"); 586 info.info2->password = NULL; 587 588 a.in.info = &info; 589 a.in.level = 2; 590 a.in.parm_error = NULL; 591 592 status = dcerpc_srvsvc_NetShareAdd_r(b, tctx, &a); 593 torture_assert_ntstatus_ok(tctx, status, "NetShareAdd level 2 on share 'testshare' failed"); 594 torture_assert_werr_ok(tctx, a.out.result, "NetShareAdd level 2 on share 'testshare' failed"); 595 596 r.in.parm_error = NULL; 597 598 q.in.level = 502; 599 600 for (i = 0; i < ARRAY_SIZE(levels); i++) { 601 602 r.in.level = levels[i].level; 603 ZERO_STRUCT(r.out); 604 605 torture_comment(tctx, "Testing NetShareSetInfo level %u on share '%s'\n", 606 r.in.level, r.in.share_name); 607 608 switch (levels[i].level) { 609 case 0: 610 info.info0 = talloc(tctx, struct srvsvc_NetShareInfo0); 611 info.info0->name = r.in.share_name; 612 break; 613 case 1: 614 info.info1 = talloc(tctx, struct srvsvc_NetShareInfo1); 615 info.info1->name = r.in.share_name; 616 info.info1->type = STYPE_DISKTREE; 617 info.info1->comment = talloc_strdup(tctx, "test comment 1"); 618 break; 619 case 2: 620 info.info2 = talloc(tctx, struct srvsvc_NetShareInfo2); 621 info.info2->name = r.in.share_name; 622 info.info2->type = STYPE_DISKTREE; 623 info.info2->comment = talloc_strdup(tctx, "test comment 2"); 624 info.info2->permissions = 0; 625 info.info2->max_users = 2; 626 info.info2->current_users = 1; 627 info.info2->path = talloc_strdup(tctx, "::BLaH::"); /* "C:\\"); */ 628 info.info2->password = NULL; 629 break; 630 case 501: 631 info.info501 = talloc(tctx, struct srvsvc_NetShareInfo501); 632 info.info501->name = r.in.share_name; 633 info.info501->type = STYPE_DISKTREE; 634 info.info501->comment = talloc_strdup(tctx, "test comment 501"); 635 info.info501->csc_policy = 0; 636 break; 637 case 502: 638 ZERO_STRUCT(sd_buf); 639 info.info502 = talloc(tctx, struct srvsvc_NetShareInfo502); 640 info.info502->name = r.in.share_name; 641 info.info502->type = STYPE_DISKTREE; 642 info.info502->comment = talloc_strdup(tctx, "test comment 502"); 643 info.info502->permissions = 0; 644 info.info502->max_users = 502; 645 info.info502->current_users = 1; 646 info.info502->path = talloc_strdup(tctx, "C:\\"); 647 info.info502->password = NULL; 648 info.info502->sd_buf = sd_buf; 649 break; 650 case 1004: 651 info.info1004 = talloc(tctx, struct srvsvc_NetShareInfo1004); 652 info.info1004->comment = talloc_strdup(tctx, "test comment 1004"); 653 break; 654 case 1005: 655 info.info1005 = talloc(tctx, struct srvsvc_NetShareInfo1005); 656 info.info1005->dfs_flags = 0; 657 break; 658 case 1006: 659 info.info1006 = talloc(tctx, struct srvsvc_NetShareInfo1006); 660 info.info1006->max_users = 1006; 661 break; 662 /* case 1007: 663 info.info1007 = talloc(tctx, struct srvsvc_NetShareInfo1007); 664 info.info1007->flags = 0; 665 info.info1007->alternate_directory_name = talloc_strdup(tctx, "test"); 666 break; 667 */ 668 case 1501: 669 info.info1501 = talloc_zero(tctx, struct sec_desc_buf); 670 break; 671 } 672 673 r.in.info = &info; 674 675 status = dcerpc_srvsvc_NetShareSetInfo_r(b, tctx, &r); 676 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed"); 677 torture_assert_werr_equal(tctx, r.out.result, levels[i].expected, "NetShareSetInfo failed"); 678 679 q.in.share_name = r.in.share_name; 680 q.out.info = &info; 681 682 status = dcerpc_srvsvc_NetShareGetInfo_r(b, tctx, &q); 683 torture_assert_ntstatus_ok(tctx, status, "NetShareGetInfo failed"); 684 torture_assert_werr_ok(tctx, q.out.result, "NetShareGetInfo failed"); 685 686 torture_assert_str_equal(tctx, q.out.info->info502->name, r.in.share_name, 687 "share name invalid"); 688 689 switch (levels[i].level) { 690 case 0: 691 break; 692 case 1: 693 torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 1", "comment"); 694 break; 695 case 2: 696 torture_assert_str_equal(tctx, q.out.info->info2->comment, "test comment 2", "comment"); 697 torture_assert_int_equal(tctx, q.out.info->info2->max_users, 2, "max users"); 698 torture_assert_str_equal(tctx, q.out.info->info2->path, "C:\\", "path"); 699 break; 700 case 501: 701 torture_assert_str_equal(tctx, q.out.info->info501->comment, "test comment 501", "comment"); 702 break; 703 case 502: 704 torture_assert_str_equal(tctx, q.out.info->info502->comment, "test comment 502", "comment"); 705 torture_assert_int_equal(tctx, q.out.info->info502->max_users, 502, "max users"); 706 torture_assert_str_equal(tctx, q.out.info->info502->path, "C:\\", "path"); 707 break; 708 case 1004: 709 torture_assert_str_equal(tctx, q.out.info->info1004->comment, "test comment 1004", 710 "comment"); 711 break; 712 case 1005: 713 break; 714 case 1006: 715 torture_assert_int_equal(tctx, q.out.info->info1006->max_users, 1006, "Max users"); 716 break; 717 /* case 1007: 718 break; 719 */ 720 case 1501: 721 break; 722 } 723 } 724 725 d.in.share_name = r.in.share_name; 726 d.in.reserved = 0; 727 728 status = dcerpc_srvsvc_NetShareDel_r(b, tctx, &d); 729 torture_assert_ntstatus_ok(tctx, status, "NetShareDel on share 'testshare502' failed"); 730 torture_assert_werr_ok(tctx, a.out.result, "NetShareDel on share 'testshare502' failed"); 731 732 return true; 733 } 734 735 /**************************/ 736 /* srvsvc_NetShare */ 737 /**************************/ 738 static bool test_NetShareEnumAll(struct torture_context *tctx, 739 struct dcerpc_pipe *p, 740 bool admin) 741 { 742 NTSTATUS status; 743 struct srvsvc_NetShareEnumAll r; 744 struct srvsvc_NetShareInfoCtr info_ctr; 745 struct srvsvc_NetShareCtr0 c0; 746 struct srvsvc_NetShareCtr1 c1; 747 struct srvsvc_NetShareCtr2 c2; 748 struct srvsvc_NetShareCtr501 c501; 749 struct srvsvc_NetShareCtr502 c502; 750 uint32_t totalentries = 0; 751 struct { 752 uint32_t level; 753 WERROR anon_status; 754 WERROR admin_status; 755 } levels[] = { 756 { 0, WERR_OK, WERR_OK }, 757 { 1, WERR_OK, WERR_OK }, 758 { 2, WERR_ACCESS_DENIED, WERR_OK }, 759 { 501, WERR_ACCESS_DENIED, WERR_OK }, 760 { 502, WERR_ACCESS_DENIED, WERR_OK }, 761 }; 762 int i; 763 uint32_t resume_handle; 764 struct dcerpc_binding_handle *b = p->binding_handle; 765 766 ZERO_STRUCT(info_ctr); 767 768 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 769 r.in.info_ctr = &info_ctr; 770 r.in.max_buffer = (uint32_t)-1; 771 r.in.resume_handle = &resume_handle; 772 r.out.resume_handle = &resume_handle; 773 r.out.totalentries = &totalentries; 774 r.out.info_ctr = &info_ctr; 775 776 for (i=0;i<ARRAY_SIZE(levels);i++) { 777 778 int j; 779 WERROR expected; 780 781 info_ctr.level = levels[i].level; 782 783 switch (info_ctr.level) { 784 case 0: 785 ZERO_STRUCT(c0); 786 info_ctr.ctr.ctr0 = &c0; 787 break; 788 case 1: 789 ZERO_STRUCT(c1); 790 info_ctr.ctr.ctr1 = &c1; 791 break; 792 case 2: 793 ZERO_STRUCT(c2); 794 info_ctr.ctr.ctr2 = &c2; 795 break; 796 case 501: 797 ZERO_STRUCT(c501); 798 info_ctr.ctr.ctr501 = &c501; 799 break; 800 case 502: 801 ZERO_STRUCT(c502); 802 info_ctr.ctr.ctr502 = &c502; 803 break; 804 } 805 806 expected = levels[i].anon_status; 807 if (admin) expected = levels[i].admin_status; 808 809 resume_handle = 0; 810 811 torture_comment(tctx, "Testing NetShareEnumAll level %u\n", info_ctr.level); 812 status = dcerpc_srvsvc_NetShareEnumAll_r(b, tctx, &r); 813 torture_assert_ntstatus_ok(tctx, status, "NetShareEnumAll failed"); 814 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareEnumAll failed"); 815 816 /* call srvsvc_NetShareGetInfo for each returned share */ 817 if (info_ctr.level == 2 && r.out.info_ctr->ctr.ctr2) { 818 for (j=0;j<r.out.info_ctr->ctr.ctr2->count;j++) { 819 const char *name; 820 name = r.out.info_ctr->ctr.ctr2->array[j].name; 821 if (!test_NetShareGetInfo(tctx, p, name, admin)) { 822 return false; 823 } 824 } 825 } 826 } 827 828 return true; 829 } 830 831 static bool test_NetShareEnumAllFull(struct torture_context *tctx, 832 struct dcerpc_pipe *p) 833 { 834 return test_NetShareEnumAll(tctx, p, true); 835 } 836 837 static bool test_NetShareEnumAllAnon(struct torture_context *tctx, 838 struct dcerpc_pipe *p) 839 { 840 return test_NetShareEnumAll(tctx, p, false); 841 } 842 843 static bool test_NetShareEnum(struct torture_context *tctx, 844 struct dcerpc_pipe *p, bool admin) 845 { 846 NTSTATUS status; 847 struct srvsvc_NetShareEnum r; 848 struct srvsvc_NetShareInfoCtr info_ctr; 849 struct srvsvc_NetShareCtr0 c0; 850 struct srvsvc_NetShareCtr1 c1; 851 struct srvsvc_NetShareCtr2 c2; 852 struct srvsvc_NetShareCtr501 c501; 853 struct srvsvc_NetShareCtr502 c502; 854 uint32_t totalentries = 0; 855 struct { 856 uint32_t level; 857 WERROR anon_status; 858 WERROR admin_status; 859 } levels[] = { 860 { 0, WERR_OK, WERR_OK }, 861 { 1, WERR_OK, WERR_OK }, 862 { 2, WERR_ACCESS_DENIED, WERR_OK }, 863 { 501, WERR_INVALID_LEVEL, WERR_INVALID_LEVEL }, 864 { 502, WERR_ACCESS_DENIED, WERR_OK }, 865 }; 866 int i; 867 struct dcerpc_binding_handle *b = p->binding_handle; 868 869 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 870 r.in.info_ctr = &info_ctr; 871 r.in.max_buffer = (uint32_t)-1; 872 r.in.resume_handle = NULL; 873 r.out.totalentries = &totalentries; 874 r.out.info_ctr = &info_ctr; 875 876 for (i=0;i<ARRAY_SIZE(levels);i++) { 877 WERROR expected; 878 879 info_ctr.level = levels[i].level; 880 881 switch (info_ctr.level) { 882 case 0: 883 ZERO_STRUCT(c0); 884 info_ctr.ctr.ctr0 = &c0; 885 break; 886 case 1: 887 ZERO_STRUCT(c1); 888 info_ctr.ctr.ctr1 = &c1; 889 break; 890 case 2: 891 ZERO_STRUCT(c2); 892 info_ctr.ctr.ctr2 = &c2; 893 break; 894 case 501: 895 ZERO_STRUCT(c501); 896 info_ctr.ctr.ctr501 = &c501; 897 break; 898 case 502: 899 ZERO_STRUCT(c502); 900 info_ctr.ctr.ctr502 = &c502; 901 break; 902 } 903 904 expected = levels[i].anon_status; 905 if (admin) expected = levels[i].admin_status; 906 907 torture_comment(tctx, "Testing NetShareEnum level %u\n", info_ctr.level); 908 status = dcerpc_srvsvc_NetShareEnum_r(b, tctx, &r); 909 torture_assert_ntstatus_ok(tctx, status, "NetShareEnum failed"); 910 torture_assert_werr_equal(tctx, r.out.result, expected, "NetShareEnum failed"); 911 } 912 913 return true; 914 } 915 916 static bool test_NetShareEnumFull(struct torture_context *tctx, 917 struct dcerpc_pipe *p) 918 { 919 return test_NetShareEnum(tctx, p, true); 920 } 921 922 static bool test_NetShareEnumAnon(struct torture_context *tctx, 923 struct dcerpc_pipe *p) 924 { 925 return test_NetShareEnum(tctx, p, false); 926 } 927 928 /**************************/ 929 /* srvsvc_NetSrv */ 930 /**************************/ 931 static bool test_NetSrvGetInfo(struct torture_context *tctx, 932 struct dcerpc_pipe *p) 933 { 934 NTSTATUS status; 935 struct srvsvc_NetSrvGetInfo r; 936 union srvsvc_NetSrvInfo info; 937 uint32_t levels[] = {100, 101, 102, 502, 503}; 938 int i; 939 struct dcerpc_binding_handle *b = p->binding_handle; 940 941 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 942 943 for (i=0;i<ARRAY_SIZE(levels);i++) { 944 r.in.level = levels[i]; 945 r.out.info = &info; 946 torture_comment(tctx, "Testing NetSrvGetInfo level %u\n", r.in.level); 947 status = dcerpc_srvsvc_NetSrvGetInfo_r(b, tctx, &r); 948 torture_assert_ntstatus_ok(tctx, status, "NetSrvGetInfo failed"); 949 if (!W_ERROR_IS_OK(r.out.result)) { 950 torture_comment(tctx, "NetSrvGetInfo failed: %s\n", win_errstr(r.out.result)); 951 } 952 } 953 954 return true; 955 } 956 957 /**************************/ 958 /* srvsvc_NetDisk */ 959 /**************************/ 960 static bool test_NetDiskEnum(struct torture_context *tctx, 961 struct dcerpc_pipe *p) 962 { 963 NTSTATUS status; 964 struct srvsvc_NetDiskEnum r; 965 struct srvsvc_NetDiskInfo info; 966 uint32_t totalentries = 0; 967 uint32_t levels[] = {0}; 968 int i; 969 uint32_t resume_handle=0; 970 struct dcerpc_binding_handle *b = p->binding_handle; 971 972 ZERO_STRUCT(info); 973 ZERO_STRUCT(r); 974 975 r.in.server_unc = NULL; 976 r.in.resume_handle = &resume_handle; 977 r.in.info = &info; 978 r.out.info = &info; 979 r.out.totalentries = &totalentries; 980 r.out.resume_handle = &resume_handle; 981 982 for (i=0;i<ARRAY_SIZE(levels);i++) { 983 ZERO_STRUCTP(r.out.info); 984 r.in.level = levels[i]; 985 torture_comment(tctx, "Testing NetDiskEnum level %u\n", r.in.level); 986 status = dcerpc_srvsvc_NetDiskEnum_r(b, tctx, &r); 987 torture_assert_ntstatus_ok(tctx, status, "NetDiskEnum failed"); 988 torture_assert_werr_ok(tctx, r.out.result, "NetDiskEnum failed"); 989 } 990 991 return true; 992 } 993 994 /**************************/ 995 /* srvsvc_NetTransport */ 996 /**************************/ 997 static bool test_NetTransportEnum(struct torture_context *tctx, 998 struct dcerpc_pipe *p) 999 { 1000 NTSTATUS status; 1001 struct srvsvc_NetTransportEnum r; 1002 struct srvsvc_NetTransportInfoCtr transports; 1003 struct srvsvc_NetTransportCtr0 ctr0; 1004 struct srvsvc_NetTransportCtr1 ctr1; 1005 1006 uint32_t totalentries = 0; 1007 uint32_t levels[] = {0, 1}; 1008 int i; 1009 struct dcerpc_binding_handle *b = p->binding_handle; 1010 1011 ZERO_STRUCT(transports); 1012 1013 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s", dcerpc_server_name(p)); 1014 r.in.transports = &transports; 1015 r.in.max_buffer = (uint32_t)-1; 1016 r.in.resume_handle = NULL; 1017 r.out.totalentries = &totalentries; 1018 r.out.transports = &transports; 1019 1020 for (i=0;i<ARRAY_SIZE(levels);i++) { 1021 transports.level = levels[i]; 1022 switch (transports.level) { 1023 case 0: 1024 ZERO_STRUCT(ctr0); 1025 transports.ctr.ctr0 = &ctr0; 1026 break; 1027 case 1: 1028 ZERO_STRUCT(ctr1); 1029 transports.ctr.ctr1 = &ctr1; 1030 break; 1031 } 1032 torture_comment(tctx, "Testing NetTransportEnum level %u\n", transports.level); 1033 status = dcerpc_srvsvc_NetTransportEnum_r(b, tctx, &r); 1034 torture_assert_ntstatus_ok(tctx, status, "NetTransportEnum failed"); 1035 if (!W_ERROR_IS_OK(r.out.result)) { 1036 torture_comment(tctx, "unexpected result: %s\n", win_errstr(r.out.result)); 1037 } 1038 } 1039 1040 return true; 1041 } 1042 1043 /**************************/ 1044 /* srvsvc_NetRemoteTOD */ 1045 /**************************/ 1046 static bool test_NetRemoteTOD(struct torture_context *tctx, 1047 struct dcerpc_pipe *p) 1048 { 1049 NTSTATUS status; 1050 struct srvsvc_NetRemoteTOD r; 1051 struct srvsvc_NetRemoteTODInfo *info = NULL; 1052 struct dcerpc_binding_handle *b = p->binding_handle; 1053 1054 r.in.server_unc = talloc_asprintf(tctx,"\\\\%s",dcerpc_server_name(p)); 1055 r.out.info = &info; 1056 1057 torture_comment(tctx, "Testing NetRemoteTOD\n"); 1058 status = dcerpc_srvsvc_NetRemoteTOD_r(b, tctx, &r); 1059 torture_assert_ntstatus_ok(tctx, status, "NetRemoteTOD failed"); 1060 torture_assert_werr_ok(tctx, r.out.result, "NetRemoteTOD failed"); 1061 1062 return true; 1063 } 1064 1065 /**************************/ 1066 /* srvsvc_NetName */ 1067 /**************************/ 1068 1069 static bool test_NetNameValidate(struct torture_context *tctx, 1070 struct dcerpc_pipe *p) 1071 { 1072 NTSTATUS status; 1073 struct srvsvc_NetNameValidate r; 1074 char *invalidc; 1075 char *name; 1076 int i, n, min, max; 1077 struct dcerpc_binding_handle *b = p->binding_handle; 1078 1079 r.in.server_unc = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); 1080 r.in.flags = 0x0; 1081 1082 d_printf("Testing NetNameValidate\n"); 1083 1084 /* valid path types only between 1 and 13 */ 1085 for (i = 1; i < 14; i++) { 1086 1087 again: 1088 /* let's limit ourselves to a maximum of 4096 bytes */ 1089 r.in.name = name = talloc_array(tctx, char, 4097); 1090 max = 4096; 1091 min = 0; 1092 n = max; 1093 1094 while (1) { 1095 1096 /* Find maximum length accepted by this type */ 1097 ZERO_STRUCT(r.out); 1098 r.in.name_type = i; 1099 memset(name, 'A', n); 1100 name[n] = '\0'; 1101 1102 status = dcerpc_srvsvc_NetNameValidate_r(b, tctx, &r); 1103 if (!NT_STATUS_IS_OK(status)) { 1104 d_printf("NetNameValidate failed while checking maximum size (%s)\n", 1105 nt_errstr(status)); 1106 break; 1107 } 1108 1109 if (W_ERROR_IS_OK(r.out.result)) { 1110 min = n; 1111 n += (max - min + 1)/2; 1112 if (n == min) { 1113 /* 1114 * We did not move, so 1115 * do not loop forever 1116 */ 1117 break; 1118 } 1119 continue; 1120 1121 } else { 1122 if ((min + 1) >= max) break; /* found it */ 1123 1124 max = n; 1125 n -= (max - min)/2; 1126 continue; 1127 } 1128 } 1129 1130 talloc_free(name); 1131 1132 d_printf("Maximum length for type %2d, flags %08x: %d\n", i, r.in.flags, max); 1133 1134 /* find invalid chars for this type check only ASCII between 0x20 and 0x7e */ 1135 1136 invalidc = talloc_strdup(tctx, ""); 1137 1138 for (n = 0x20; n < 0x7e; n++) { 1139 r.in.name = name = talloc_asprintf(tctx, "%c", (char)n); 1140 1141 status = dcerpc_srvsvc_NetNameValidate_r(b, tctx, &r); 1142 if (!NT_STATUS_IS_OK(status)) { 1143 d_printf("NetNameValidate failed while checking valid chars (%s)\n", 1144 nt_errstr(status)); 1145 break; 1146 } 1147 1148 if (!W_ERROR_IS_OK(r.out.result)) { 1149 invalidc = talloc_asprintf_append_buffer(invalidc, "%c", (char)n); 1150 } 1151 1152 talloc_free(name); 1153 } 1154 1155 d_printf(" Invalid chars for type %2d, flags %08x: \"%s\"\n", i, r.in.flags, invalidc); 1156 1157 /* only two values are accepted for flags: 0x0 and 0x80000000 */ 1158 if (r.in.flags == 0x0) { 1159 r.in.flags = 0x80000000; 1160 goto again; 1161 } 1162 1163 r.in.flags = 0x0; 1164 } 1165 1166 return true; 1167 } 1168 1169 struct torture_suite *torture_rpc_srvsvc(TALLOC_CTX *mem_ctx) 1170 { 1171 struct torture_suite *suite = torture_suite_create(mem_ctx, "srvsvc"); 1172 struct torture_rpc_tcase *tcase; 1173 struct torture_test *test; 1174 1175 tcase = torture_suite_add_rpc_iface_tcase(suite, "srvsvc (admin access)", &ndr_table_srvsvc); 1176 1177 torture_rpc_tcase_add_test(tcase, "NetCharDevEnum", test_NetCharDevEnum); 1178 torture_rpc_tcase_add_test(tcase, "NetCharDevQEnum", test_NetCharDevQEnum); 1179 torture_rpc_tcase_add_test(tcase, "NetConnEnum", test_NetConnEnum); 1180 torture_rpc_tcase_add_test(tcase, "NetFileEnum", test_NetFileEnum); 1181 torture_rpc_tcase_add_test(tcase, "NetSessEnum", test_NetSessEnum); 1182 torture_rpc_tcase_add_test(tcase, "NetShareEnumAll", test_NetShareEnumAllFull); 1183 torture_rpc_tcase_add_test(tcase, "NetSrvGetInfo", test_NetSrvGetInfo); 1184 torture_rpc_tcase_add_test(tcase, "NetDiskEnum", test_NetDiskEnum); 1185 torture_rpc_tcase_add_test(tcase, "NetTransportEnum", test_NetTransportEnum); 1186 torture_rpc_tcase_add_test(tcase, "NetRemoteTOD", test_NetRemoteTOD); 1187 torture_rpc_tcase_add_test(tcase, "NetShareEnum", test_NetShareEnumFull); 1188 torture_rpc_tcase_add_test(tcase, "NetShareGetInfo", test_NetShareGetInfoAdminFull); 1189 test = torture_rpc_tcase_add_test(tcase, "NetShareAddSetDel", 1190 test_NetShareAddSetDel); 1191 test->dangerous = true; 1192 torture_rpc_tcase_add_test(tcase, "NetNameValidate", test_NetNameValidate); 1193 1194 tcase = torture_suite_add_anon_rpc_iface_tcase(suite, 1195 "srvsvc anonymous access", 1196 &ndr_table_srvsvc); 1197 1198 torture_rpc_tcase_add_test(tcase, "NetShareEnumAll", 1199 test_NetShareEnumAllAnon); 1200 torture_rpc_tcase_add_test(tcase, "NetShareEnum", 1201 test_NetShareEnumAnon); 1202 torture_rpc_tcase_add_test(tcase, "NetShareGetInfo", 1203 test_NetShareGetInfoAdminAnon); 1204 1205 return suite; 1206 } 1207