1/* 2 Unix SMB/CIFS implementation. 3 4 dcerpc torture tests, designed to walk Samba3 code paths 5 6 Copyright (C) Volker Lendecke 2006 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "libcli/raw/libcliraw.h" 24#include "libcli/raw/raw_proto.h" 25#include "libcli/rap/rap.h" 26#include "torture/torture.h" 27#include "torture/util.h" 28#include "torture/rap/proto.h" 29#include "librpc/gen_ndr/ndr_lsa.h" 30#include "librpc/gen_ndr/ndr_lsa_c.h" 31#include "librpc/gen_ndr/ndr_samr.h" 32#include "librpc/gen_ndr/ndr_samr_c.h" 33#include "librpc/gen_ndr/ndr_netlogon.h" 34#include "librpc/gen_ndr/ndr_netlogon_c.h" 35#include "librpc/gen_ndr/ndr_srvsvc.h" 36#include "librpc/gen_ndr/ndr_srvsvc_c.h" 37#include "librpc/gen_ndr/ndr_spoolss.h" 38#include "librpc/gen_ndr/ndr_spoolss_c.h" 39#include "librpc/gen_ndr/ndr_winreg.h" 40#include "librpc/gen_ndr/ndr_winreg_c.h" 41#include "librpc/gen_ndr/ndr_wkssvc.h" 42#include "librpc/gen_ndr/ndr_wkssvc_c.h" 43#include "lib/cmdline/popt_common.h" 44#include "librpc/rpc/dcerpc.h" 45#include "torture/rpc/rpc.h" 46#include "libcli/libcli.h" 47#include "libcli/composite/composite.h" 48#include "libcli/smb_composite/smb_composite.h" 49#include "libcli/auth/libcli_auth.h" 50#include "../lib/crypto/crypto.h" 51#include "auth/ntlmssp/ntlmssp.h" 52#include "libcli/security/security.h" 53#include "param/param.h" 54#include "lib/registry/registry.h" 55#include "libcli/resolve/resolve.h" 56 57/* 58 * This tests a RPC call using an invalid vuid 59 */ 60 61bool torture_bind_authcontext(struct torture_context *torture) 62{ 63 TALLOC_CTX *mem_ctx; 64 NTSTATUS status; 65 bool ret = false; 66 struct lsa_ObjectAttribute objectattr; 67 struct lsa_OpenPolicy2 openpolicy; 68 struct policy_handle handle; 69 struct lsa_Close close_handle; 70 struct smbcli_session *tmp; 71 struct smbcli_session *session2; 72 struct smbcli_state *cli; 73 struct dcerpc_pipe *lsa_pipe; 74 struct cli_credentials *anon_creds; 75 struct smb_composite_sesssetup setup; 76 struct smbcli_options options; 77 struct smbcli_session_options session_options; 78 79 mem_ctx = talloc_init("torture_bind_authcontext"); 80 81 if (mem_ctx == NULL) { 82 d_printf("talloc_init failed\n"); 83 return false; 84 } 85 86 lp_smbcli_options(torture->lp_ctx, &options); 87 lp_smbcli_session_options(torture->lp_ctx, &session_options); 88 89 status = smbcli_full_connection(mem_ctx, &cli, 90 torture_setting_string(torture, "host", NULL), 91 lp_smb_ports(torture->lp_ctx), 92 "IPC$", NULL, 93 lp_socket_options(torture->lp_ctx), 94 cmdline_credentials, 95 lp_resolve_context(torture->lp_ctx), 96 torture->ev, &options, &session_options, 97 lp_iconv_convenience(torture->lp_ctx), 98 lp_gensec_settings(torture, torture->lp_ctx)); 99 if (!NT_STATUS_IS_OK(status)) { 100 d_printf("smbcli_full_connection failed: %s\n", 101 nt_errstr(status)); 102 goto done; 103 } 104 105 lsa_pipe = dcerpc_pipe_init(mem_ctx, cli->transport->socket->event.ctx, 106 lp_iconv_convenience(torture->lp_ctx)); 107 if (lsa_pipe == NULL) { 108 d_printf("dcerpc_pipe_init failed\n"); 109 goto done; 110 } 111 112 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc"); 113 if (!NT_STATUS_IS_OK(status)) { 114 d_printf("dcerpc_pipe_open_smb failed: %s\n", 115 nt_errstr(status)); 116 goto done; 117 } 118 119 status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc); 120 if (!NT_STATUS_IS_OK(status)) { 121 d_printf("dcerpc_bind_auth_none failed: %s\n", 122 nt_errstr(status)); 123 goto done; 124 } 125 126 openpolicy.in.system_name =talloc_asprintf( 127 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe)); 128 ZERO_STRUCT(objectattr); 129 openpolicy.in.attr = &objectattr; 130 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 131 openpolicy.out.handle = &handle; 132 133 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy); 134 135 if (!NT_STATUS_IS_OK(status)) { 136 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n", 137 nt_errstr(status)); 138 goto done; 139 } 140 141 close_handle.in.handle = &handle; 142 close_handle.out.handle = &handle; 143 144 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle); 145 if (!NT_STATUS_IS_OK(status)) { 146 d_printf("dcerpc_lsa_Close failed: %s\n", 147 nt_errstr(status)); 148 goto done; 149 } 150 151 session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options); 152 if (session2 == NULL) { 153 d_printf("smbcli_session_init failed\n"); 154 goto done; 155 } 156 157 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) { 158 d_printf("create_anon_creds failed\n"); 159 goto done; 160 } 161 162 setup.in.sesskey = cli->transport->negotiate.sesskey; 163 setup.in.capabilities = cli->transport->negotiate.capabilities; 164 setup.in.workgroup = ""; 165 setup.in.credentials = anon_creds; 166 setup.in.gensec_settings = lp_gensec_settings(torture, torture->lp_ctx); 167 168 status = smb_composite_sesssetup(session2, &setup); 169 if (!NT_STATUS_IS_OK(status)) { 170 d_printf("anon session setup failed: %s\n", 171 nt_errstr(status)); 172 goto done; 173 } 174 session2->vuid = setup.out.vuid; 175 176 tmp = cli->tree->session; 177 cli->tree->session = session2; 178 179 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy); 180 181 cli->tree->session = tmp; 182 talloc_free(lsa_pipe); 183 lsa_pipe = NULL; 184 185 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { 186 d_printf("dcerpc_lsa_OpenPolicy2 with wrong vuid gave %s, " 187 "expected NT_STATUS_INVALID_HANDLE\n", 188 nt_errstr(status)); 189 goto done; 190 } 191 192 ret = true; 193 done: 194 talloc_free(mem_ctx); 195 return ret; 196} 197 198/* 199 * Bind to lsa using a specific auth method 200 */ 201 202static bool bindtest(struct smbcli_state *cli, 203 struct cli_credentials *credentials, 204 struct loadparm_context *lp_ctx, 205 uint8_t auth_type, uint8_t auth_level) 206{ 207 TALLOC_CTX *mem_ctx; 208 bool ret = false; 209 NTSTATUS status; 210 211 struct dcerpc_pipe *lsa_pipe; 212 struct lsa_ObjectAttribute objectattr; 213 struct lsa_OpenPolicy2 openpolicy; 214 struct lsa_QueryInfoPolicy query; 215 union lsa_PolicyInformation *info = NULL; 216 struct policy_handle handle; 217 struct lsa_Close close_handle; 218 219 if ((mem_ctx = talloc_init("bindtest")) == NULL) { 220 d_printf("talloc_init failed\n"); 221 return false; 222 } 223 224 lsa_pipe = dcerpc_pipe_init(mem_ctx, 225 cli->transport->socket->event.ctx, 226 lp_iconv_convenience(lp_ctx)); 227 if (lsa_pipe == NULL) { 228 d_printf("dcerpc_pipe_init failed\n"); 229 goto done; 230 } 231 232 status = dcerpc_pipe_open_smb(lsa_pipe, cli->tree, "\\lsarpc"); 233 if (!NT_STATUS_IS_OK(status)) { 234 d_printf("dcerpc_pipe_open_smb failed: %s\n", 235 nt_errstr(status)); 236 goto done; 237 } 238 239 status = dcerpc_bind_auth(lsa_pipe, &ndr_table_lsarpc, 240 credentials, lp_gensec_settings(lp_ctx, lp_ctx), auth_type, auth_level, 241 NULL); 242 if (!NT_STATUS_IS_OK(status)) { 243 d_printf("dcerpc_bind_auth failed: %s\n", nt_errstr(status)); 244 goto done; 245 } 246 247 openpolicy.in.system_name =talloc_asprintf( 248 mem_ctx, "\\\\%s", dcerpc_server_name(lsa_pipe)); 249 ZERO_STRUCT(objectattr); 250 openpolicy.in.attr = &objectattr; 251 openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 252 openpolicy.out.handle = &handle; 253 254 status = dcerpc_lsa_OpenPolicy2(lsa_pipe, mem_ctx, &openpolicy); 255 256 if (!NT_STATUS_IS_OK(status)) { 257 d_printf("dcerpc_lsa_OpenPolicy2 failed: %s\n", 258 nt_errstr(status)); 259 goto done; 260 } 261 262 query.in.handle = &handle; 263 query.in.level = LSA_POLICY_INFO_DOMAIN; 264 query.out.info = &info; 265 266 status = dcerpc_lsa_QueryInfoPolicy(lsa_pipe, mem_ctx, &query); 267 if (!NT_STATUS_IS_OK(status)) { 268 d_printf("dcerpc_lsa_QueryInfoPolicy failed: %s\n", 269 nt_errstr(status)); 270 goto done; 271 } 272 273 close_handle.in.handle = &handle; 274 close_handle.out.handle = &handle; 275 276 status = dcerpc_lsa_Close(lsa_pipe, mem_ctx, &close_handle); 277 if (!NT_STATUS_IS_OK(status)) { 278 d_printf("dcerpc_lsa_Close failed: %s\n", 279 nt_errstr(status)); 280 goto done; 281 } 282 283 ret = true; 284 done: 285 talloc_free(mem_ctx); 286 return ret; 287} 288 289/* 290 * test authenticated RPC binds with the variants Samba3 does support 291 */ 292 293bool torture_bind_samba3(struct torture_context *torture) 294{ 295 TALLOC_CTX *mem_ctx; 296 NTSTATUS status; 297 bool ret = false; 298 struct smbcli_state *cli; 299 struct smbcli_options options; 300 struct smbcli_session_options session_options; 301 302 mem_ctx = talloc_init("torture_bind_authcontext"); 303 304 if (mem_ctx == NULL) { 305 d_printf("talloc_init failed\n"); 306 return false; 307 } 308 309 lp_smbcli_options(torture->lp_ctx, &options); 310 lp_smbcli_session_options(torture->lp_ctx, &session_options); 311 312 status = smbcli_full_connection(mem_ctx, &cli, 313 torture_setting_string(torture, "host", NULL), 314 lp_smb_ports(torture->lp_ctx), 315 "IPC$", NULL, 316 lp_socket_options(torture->lp_ctx), 317 cmdline_credentials, 318 lp_resolve_context(torture->lp_ctx), 319 torture->ev, &options, &session_options, 320 lp_iconv_convenience(torture->lp_ctx), 321 lp_gensec_settings(torture, torture->lp_ctx)); 322 if (!NT_STATUS_IS_OK(status)) { 323 d_printf("smbcli_full_connection failed: %s\n", 324 nt_errstr(status)); 325 goto done; 326 } 327 328 ret = true; 329 330 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_NTLMSSP, 331 DCERPC_AUTH_LEVEL_INTEGRITY); 332 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_NTLMSSP, 333 DCERPC_AUTH_LEVEL_PRIVACY); 334 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO, 335 DCERPC_AUTH_LEVEL_INTEGRITY); 336 ret &= bindtest(cli, cmdline_credentials, torture->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO, 337 DCERPC_AUTH_LEVEL_PRIVACY); 338 339 done: 340 talloc_free(mem_ctx); 341 return ret; 342} 343 344/* 345 * Lookup or create a user and return all necessary info 346 */ 347 348static NTSTATUS get_usr_handle(struct smbcli_state *cli, 349 TALLOC_CTX *mem_ctx, 350 struct loadparm_context *lp_ctx, 351 struct cli_credentials *admin_creds, 352 uint8_t auth_type, 353 uint8_t auth_level, 354 const char *username, 355 char **domain, 356 struct dcerpc_pipe **result_pipe, 357 struct policy_handle **result_handle, 358 struct dom_sid **sid_p) 359{ 360 struct dcerpc_pipe *samr_pipe; 361 NTSTATUS status; 362 struct policy_handle conn_handle; 363 struct policy_handle domain_handle; 364 struct policy_handle *user_handle; 365 struct samr_Connect2 conn; 366 struct samr_EnumDomains enumdom; 367 uint32_t resume_handle = 0; 368 uint32_t num_entries = 0; 369 struct samr_SamArray *sam = NULL; 370 struct samr_LookupDomain l; 371 struct dom_sid2 *sid = NULL; 372 int dom_idx; 373 struct lsa_String domain_name; 374 struct lsa_String user_name; 375 struct samr_OpenDomain o; 376 struct samr_CreateUser2 c; 377 uint32_t user_rid,access_granted; 378 379 samr_pipe = dcerpc_pipe_init(mem_ctx, 380 cli->transport->socket->event.ctx, 381 lp_iconv_convenience(lp_ctx)); 382 if (samr_pipe == NULL) { 383 d_printf("dcerpc_pipe_init failed\n"); 384 status = NT_STATUS_NO_MEMORY; 385 goto fail; 386 } 387 388 status = dcerpc_pipe_open_smb(samr_pipe, cli->tree, "\\samr"); 389 if (!NT_STATUS_IS_OK(status)) { 390 d_printf("dcerpc_pipe_open_smb failed: %s\n", 391 nt_errstr(status)); 392 goto fail; 393 } 394 395 if (admin_creds != NULL) { 396 status = dcerpc_bind_auth(samr_pipe, &ndr_table_samr, 397 admin_creds, lp_gensec_settings(lp_ctx, lp_ctx), auth_type, auth_level, 398 NULL); 399 if (!NT_STATUS_IS_OK(status)) { 400 d_printf("dcerpc_bind_auth failed: %s\n", 401 nt_errstr(status)); 402 goto fail; 403 } 404 } else { 405 /* We must have an authenticated SMB connection */ 406 status = dcerpc_bind_auth_none(samr_pipe, &ndr_table_samr); 407 if (!NT_STATUS_IS_OK(status)) { 408 d_printf("dcerpc_bind_auth_none failed: %s\n", 409 nt_errstr(status)); 410 goto fail; 411 } 412 } 413 414 conn.in.system_name = talloc_asprintf( 415 mem_ctx, "\\\\%s", dcerpc_server_name(samr_pipe)); 416 conn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 417 conn.out.connect_handle = &conn_handle; 418 419 status = dcerpc_samr_Connect2(samr_pipe, mem_ctx, &conn); 420 if (!NT_STATUS_IS_OK(status)) { 421 d_printf("samr_Connect2 failed: %s\n", nt_errstr(status)); 422 goto fail; 423 } 424 425 enumdom.in.connect_handle = &conn_handle; 426 enumdom.in.resume_handle = &resume_handle; 427 enumdom.in.buf_size = (uint32_t)-1; 428 enumdom.out.resume_handle = &resume_handle; 429 enumdom.out.num_entries = &num_entries; 430 enumdom.out.sam = &sam; 431 432 status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom); 433 if (!NT_STATUS_IS_OK(status)) { 434 d_printf("samr_EnumDomains failed: %s\n", nt_errstr(status)); 435 goto fail; 436 } 437 438 if (*enumdom.out.num_entries != 2) { 439 d_printf("samr_EnumDomains returned %d entries, expected 2\n", 440 *enumdom.out.num_entries); 441 status = NT_STATUS_UNSUCCESSFUL; 442 goto fail; 443 } 444 445 dom_idx = strequal(sam->entries[0].name.string, 446 "builtin") ? 1:0; 447 448 l.in.connect_handle = &conn_handle; 449 domain_name.string = sam->entries[dom_idx].name.string; 450 *domain = talloc_strdup(mem_ctx, domain_name.string); 451 l.in.domain_name = &domain_name; 452 l.out.sid = &sid; 453 454 status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l); 455 if (!NT_STATUS_IS_OK(status)) { 456 d_printf("samr_LookupDomain failed: %s\n", nt_errstr(status)); 457 goto fail; 458 } 459 460 o.in.connect_handle = &conn_handle; 461 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 462 o.in.sid = *l.out.sid; 463 o.out.domain_handle = &domain_handle; 464 465 status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o); 466 if (!NT_STATUS_IS_OK(status)) { 467 d_printf("samr_OpenDomain failed: %s\n", nt_errstr(status)); 468 goto fail; 469 } 470 471 c.in.domain_handle = &domain_handle; 472 user_name.string = username; 473 c.in.account_name = &user_name; 474 c.in.acct_flags = ACB_NORMAL; 475 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 476 user_handle = talloc(mem_ctx, struct policy_handle); 477 c.out.user_handle = user_handle; 478 c.out.access_granted = &access_granted; 479 c.out.rid = &user_rid; 480 481 status = dcerpc_samr_CreateUser2(samr_pipe, mem_ctx, &c); 482 483 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { 484 struct samr_LookupNames ln; 485 struct samr_OpenUser ou; 486 struct samr_Ids rids, types; 487 488 ln.in.domain_handle = &domain_handle; 489 ln.in.num_names = 1; 490 ln.in.names = &user_name; 491 ln.out.rids = &rids; 492 ln.out.types = &types; 493 494 status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln); 495 if (!NT_STATUS_IS_OK(status)) { 496 d_printf("samr_LookupNames failed: %s\n", 497 nt_errstr(status)); 498 goto fail; 499 } 500 501 ou.in.domain_handle = &domain_handle; 502 ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 503 user_rid = ou.in.rid = ln.out.rids->ids[0]; 504 ou.out.user_handle = user_handle; 505 506 status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou); 507 if (!NT_STATUS_IS_OK(status)) { 508 d_printf("samr_OpenUser failed: %s\n", 509 nt_errstr(status)); 510 goto fail; 511 } 512 } 513 514 if (!NT_STATUS_IS_OK(status)) { 515 d_printf("samr_CreateUser failed: %s\n", nt_errstr(status)); 516 goto fail; 517 } 518 519 *result_pipe = samr_pipe; 520 *result_handle = user_handle; 521 if (sid_p != NULL) { 522 *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid); 523 } 524 return NT_STATUS_OK; 525 526 fail: 527 return status; 528} 529 530/* 531 * Create a test user 532 */ 533 534static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, 535 struct loadparm_context *lp_ctx, 536 struct cli_credentials *admin_creds, 537 const char *username, const char *password, 538 char **domain_name, 539 struct dom_sid **user_sid) 540{ 541 TALLOC_CTX *tmp_ctx; 542 NTSTATUS status; 543 struct dcerpc_pipe *samr_pipe; 544 struct policy_handle *wks_handle; 545 bool ret = false; 546 547 if (!(tmp_ctx = talloc_new(mem_ctx))) { 548 d_printf("talloc_init failed\n"); 549 return false; 550 } 551 552 status = get_usr_handle(cli, tmp_ctx, lp_ctx, admin_creds, 553 DCERPC_AUTH_TYPE_NTLMSSP, 554 DCERPC_AUTH_LEVEL_INTEGRITY, 555 username, domain_name, &samr_pipe, &wks_handle, 556 user_sid); 557 if (!NT_STATUS_IS_OK(status)) { 558 d_printf("get_usr_handle failed: %s\n", nt_errstr(status)); 559 goto done; 560 } 561 562 { 563 struct samr_SetUserInfo2 sui2; 564 struct samr_SetUserInfo sui; 565 struct samr_QueryUserInfo qui; 566 union samr_UserInfo u_info; 567 union samr_UserInfo *info; 568 DATA_BLOB session_key; 569 570 571 ZERO_STRUCT(u_info); 572 encode_pw_buffer(u_info.info23.password.data, password, 573 STR_UNICODE); 574 575 status = dcerpc_fetch_session_key(samr_pipe, &session_key); 576 if (!NT_STATUS_IS_OK(status)) { 577 d_printf("dcerpc_fetch_session_key failed\n"); 578 goto done; 579 } 580 arcfour_crypt_blob(u_info.info23.password.data, 516, 581 &session_key); 582 u_info.info23.info.password_expired = 0; 583 u_info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT | 584 SAMR_FIELD_LM_PASSWORD_PRESENT | 585 SAMR_FIELD_EXPIRED_FLAG; 586 sui2.in.user_handle = wks_handle; 587 sui2.in.info = &u_info; 588 sui2.in.level = 23; 589 590 status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2); 591 if (!NT_STATUS_IS_OK(status)) { 592 d_printf("samr_SetUserInfo(23) failed: %s\n", 593 nt_errstr(status)); 594 goto done; 595 } 596 597 u_info.info16.acct_flags = ACB_NORMAL; 598 sui.in.user_handle = wks_handle; 599 sui.in.info = &u_info; 600 sui.in.level = 16; 601 602 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui); 603 if (!NT_STATUS_IS_OK(status)) { 604 d_printf("samr_SetUserInfo(16) failed\n"); 605 goto done; 606 } 607 608 qui.in.user_handle = wks_handle; 609 qui.in.level = 21; 610 qui.out.info = &info; 611 612 status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui); 613 if (!NT_STATUS_IS_OK(status)) { 614 d_printf("samr_QueryUserInfo(21) failed\n"); 615 goto done; 616 } 617 618 info->info21.allow_password_change = 0; 619 info->info21.force_password_change = 0; 620 info->info21.account_name.string = NULL; 621 info->info21.rid = 0; 622 info->info21.acct_expiry = 0; 623 info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */ 624 625 u_info.info21 = info->info21; 626 sui.in.user_handle = wks_handle; 627 sui.in.info = &u_info; 628 sui.in.level = 21; 629 630 status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui); 631 if (!NT_STATUS_IS_OK(status)) { 632 d_printf("samr_SetUserInfo(21) failed\n"); 633 goto done; 634 } 635 } 636 637 *domain_name= talloc_steal(mem_ctx, *domain_name); 638 *user_sid = talloc_steal(mem_ctx, *user_sid); 639 ret = true; 640 done: 641 talloc_free(tmp_ctx); 642 return ret; 643} 644 645/* 646 * Delete a test user 647 */ 648 649static bool delete_user(struct smbcli_state *cli, 650 struct loadparm_context *lp_ctx, 651 struct cli_credentials *admin_creds, 652 const char *username) 653{ 654 TALLOC_CTX *mem_ctx; 655 NTSTATUS status; 656 char *dom_name; 657 struct dcerpc_pipe *samr_pipe; 658 struct policy_handle *user_handle; 659 bool ret = false; 660 661 if ((mem_ctx = talloc_init("leave")) == NULL) { 662 d_printf("talloc_init failed\n"); 663 return false; 664 } 665 666 status = get_usr_handle(cli, mem_ctx, lp_ctx, admin_creds, 667 DCERPC_AUTH_TYPE_NTLMSSP, 668 DCERPC_AUTH_LEVEL_INTEGRITY, 669 username, &dom_name, &samr_pipe, 670 &user_handle, NULL); 671 672 if (!NT_STATUS_IS_OK(status)) { 673 d_printf("get_wks_handle failed: %s\n", nt_errstr(status)); 674 goto done; 675 } 676 677 { 678 struct samr_DeleteUser d; 679 680 d.in.user_handle = user_handle; 681 d.out.user_handle = user_handle; 682 683 status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d); 684 if (!NT_STATUS_IS_OK(status)) { 685 d_printf("samr_DeleteUser failed %s\n", nt_errstr(status)); 686 goto done; 687 } 688 } 689 690 ret = true; 691 692 done: 693 talloc_free(mem_ctx); 694 return ret; 695} 696 697/* 698 * Do a Samba3-style join 699 */ 700 701static bool join3(struct smbcli_state *cli, 702 struct loadparm_context *lp_ctx, 703 bool use_level25, 704 struct cli_credentials *admin_creds, 705 struct cli_credentials *wks_creds) 706{ 707 TALLOC_CTX *mem_ctx; 708 NTSTATUS status; 709 char *dom_name; 710 struct dcerpc_pipe *samr_pipe; 711 struct policy_handle *wks_handle; 712 bool ret = false; 713 NTTIME last_password_change; 714 715 if ((mem_ctx = talloc_init("join3")) == NULL) { 716 d_printf("talloc_init failed\n"); 717 return false; 718 } 719 720 status = get_usr_handle( 721 cli, mem_ctx, lp_ctx, admin_creds, 722 DCERPC_AUTH_TYPE_NTLMSSP, 723 DCERPC_AUTH_LEVEL_PRIVACY, 724 talloc_asprintf(mem_ctx, "%s$", 725 cli_credentials_get_workstation(wks_creds)), 726 &dom_name, &samr_pipe, &wks_handle, NULL); 727 728 if (!NT_STATUS_IS_OK(status)) { 729 d_printf("get_wks_handle failed: %s\n", nt_errstr(status)); 730 goto done; 731 } 732 733 { 734 struct samr_QueryUserInfo q; 735 union samr_UserInfo *info; 736 737 q.in.user_handle = wks_handle; 738 q.in.level = 21; 739 q.out.info = &info; 740 741 status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q); 742 if (!NT_STATUS_IS_OK(status)) { 743 d_printf("(%s) QueryUserInfo failed: %s\n", 744 __location__, nt_errstr(status)); 745 goto done; 746 } 747 748 last_password_change = info->info21.last_password_change; 749 } 750 751 cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED); 752 753 if (use_level25) { 754 struct samr_SetUserInfo2 sui2; 755 union samr_UserInfo u_info; 756 struct samr_UserInfo21 *i21 = &u_info.info25.info; 757 DATA_BLOB session_key; 758 DATA_BLOB confounded_session_key = data_blob_talloc( 759 mem_ctx, NULL, 16); 760 struct MD5Context ctx; 761 uint8_t confounder[16]; 762 763 ZERO_STRUCT(u_info); 764 765 i21->full_name.string = talloc_asprintf( 766 mem_ctx, "%s$", 767 cli_credentials_get_workstation(wks_creds)); 768 i21->acct_flags = ACB_WSTRUST; 769 i21->fields_present = SAMR_FIELD_FULL_NAME | 770 SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_NT_PASSWORD_PRESENT; 771 /* this would break the test result expectations 772 i21->fields_present |= SAMR_FIELD_EXPIRED_FLAG; 773 i21->password_expired = 1; 774 */ 775 776 encode_pw_buffer(u_info.info25.password.data, 777 cli_credentials_get_password(wks_creds), 778 STR_UNICODE); 779 status = dcerpc_fetch_session_key(samr_pipe, &session_key); 780 if (!NT_STATUS_IS_OK(status)) { 781 d_printf("dcerpc_fetch_session_key failed: %s\n", 782 nt_errstr(status)); 783 goto done; 784 } 785 generate_random_buffer((uint8_t *)confounder, 16); 786 787 MD5Init(&ctx); 788 MD5Update(&ctx, confounder, 16); 789 MD5Update(&ctx, session_key.data, session_key.length); 790 MD5Final(confounded_session_key.data, &ctx); 791 792 arcfour_crypt_blob(u_info.info25.password.data, 516, 793 &confounded_session_key); 794 memcpy(&u_info.info25.password.data[516], confounder, 16); 795 796 sui2.in.user_handle = wks_handle; 797 sui2.in.level = 25; 798 sui2.in.info = &u_info; 799 800 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2); 801 if (!NT_STATUS_IS_OK(status)) { 802 d_printf("samr_SetUserInfo2(25) failed: %s\n", 803 nt_errstr(status)); 804 goto done; 805 } 806 } else { 807 struct samr_SetUserInfo2 sui2; 808 struct samr_SetUserInfo sui; 809 union samr_UserInfo u_info; 810 DATA_BLOB session_key; 811 812 encode_pw_buffer(u_info.info24.password.data, 813 cli_credentials_get_password(wks_creds), 814 STR_UNICODE); 815 /* just to make this test pass */ 816 u_info.info24.password_expired = 1; 817 818 status = dcerpc_fetch_session_key(samr_pipe, &session_key); 819 if (!NT_STATUS_IS_OK(status)) { 820 d_printf("dcerpc_fetch_session_key failed\n"); 821 goto done; 822 } 823 arcfour_crypt_blob(u_info.info24.password.data, 516, 824 &session_key); 825 sui2.in.user_handle = wks_handle; 826 sui2.in.info = &u_info; 827 sui2.in.level = 24; 828 829 status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2); 830 if (!NT_STATUS_IS_OK(status)) { 831 d_printf("samr_SetUserInfo(24) failed: %s\n", 832 nt_errstr(status)); 833 goto done; 834 } 835 836 u_info.info16.acct_flags = ACB_WSTRUST; 837 sui.in.user_handle = wks_handle; 838 sui.in.info = &u_info; 839 sui.in.level = 16; 840 841 status = dcerpc_samr_SetUserInfo(samr_pipe, mem_ctx, &sui); 842 if (!NT_STATUS_IS_OK(status)) { 843 d_printf("samr_SetUserInfo(16) failed\n"); 844 goto done; 845 } 846 } 847 848 { 849 struct samr_QueryUserInfo q; 850 union samr_UserInfo *info; 851 852 q.in.user_handle = wks_handle; 853 q.in.level = 21; 854 q.out.info = &info; 855 856 status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q); 857 if (!NT_STATUS_IS_OK(status)) { 858 d_printf("(%s) QueryUserInfo failed: %s\n", 859 __location__, nt_errstr(status)); 860 goto done; 861 } 862 863 if (use_level25) { 864 if (last_password_change 865 == info->info21.last_password_change) { 866 d_printf("(%s) last_password_change unchanged " 867 "during join, level25 must change " 868 "it\n", __location__); 869 goto done; 870 } 871 } 872 else { 873 if (last_password_change 874 != info->info21.last_password_change) { 875 d_printf("(%s) last_password_change changed " 876 "during join, level24 doesn't " 877 "change it\n", __location__); 878 goto done; 879 } 880 } 881 } 882 883 ret = true; 884 885 done: 886 talloc_free(mem_ctx); 887 return ret; 888} 889 890/* 891 * Do a ReqChallenge/Auth2 and get the wks creds 892 */ 893 894static bool auth2(struct smbcli_state *cli, 895 struct loadparm_context *lp_ctx, 896 struct cli_credentials *wks_cred) 897{ 898 TALLOC_CTX *mem_ctx; 899 struct dcerpc_pipe *net_pipe; 900 bool result = false; 901 NTSTATUS status; 902 struct netr_ServerReqChallenge r; 903 struct netr_Credential netr_cli_creds; 904 struct netr_Credential netr_srv_creds; 905 uint32_t negotiate_flags; 906 struct netr_ServerAuthenticate2 a; 907 struct netlogon_creds_CredentialState *creds_state; 908 struct netr_Credential netr_cred; 909 struct samr_Password mach_pw; 910 911 mem_ctx = talloc_new(NULL); 912 if (mem_ctx == NULL) { 913 d_printf("talloc_new failed\n"); 914 return false; 915 } 916 917 net_pipe = dcerpc_pipe_init(mem_ctx, 918 cli->transport->socket->event.ctx, 919 lp_iconv_convenience(lp_ctx)); 920 if (net_pipe == NULL) { 921 d_printf("dcerpc_pipe_init failed\n"); 922 goto done; 923 } 924 925 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon"); 926 if (!NT_STATUS_IS_OK(status)) { 927 d_printf("dcerpc_pipe_open_smb failed: %s\n", 928 nt_errstr(status)); 929 goto done; 930 } 931 932 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon); 933 if (!NT_STATUS_IS_OK(status)) { 934 d_printf("dcerpc_bind_auth_none failed: %s\n", 935 nt_errstr(status)); 936 goto done; 937 } 938 939 r.in.computer_name = cli_credentials_get_workstation(wks_cred); 940 r.in.server_name = talloc_asprintf( 941 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); 942 if (r.in.server_name == NULL) { 943 d_printf("talloc_asprintf failed\n"); 944 goto done; 945 } 946 generate_random_buffer(netr_cli_creds.data, 947 sizeof(netr_cli_creds.data)); 948 r.in.credentials = &netr_cli_creds; 949 r.out.return_credentials = &netr_srv_creds; 950 951 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r); 952 if (!NT_STATUS_IS_OK(status)) { 953 d_printf("netr_ServerReqChallenge failed: %s\n", 954 nt_errstr(status)); 955 goto done; 956 } 957 958 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; 959 E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash); 960 961 a.in.server_name = talloc_asprintf( 962 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); 963 a.in.account_name = talloc_asprintf( 964 mem_ctx, "%s$", cli_credentials_get_workstation(wks_cred)); 965 a.in.computer_name = cli_credentials_get_workstation(wks_cred); 966 a.in.secure_channel_type = SEC_CHAN_WKSTA; 967 a.in.negotiate_flags = &negotiate_flags; 968 a.out.negotiate_flags = &negotiate_flags; 969 a.in.credentials = &netr_cred; 970 a.out.return_credentials = &netr_cred; 971 972 creds_state = netlogon_creds_client_init(mem_ctx, 973 a.in.account_name, 974 a.in.computer_name, 975 r.in.credentials, 976 r.out.return_credentials, &mach_pw, 977 &netr_cred, negotiate_flags); 978 979 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a); 980 if (!NT_STATUS_IS_OK(status)) { 981 d_printf("netr_ServerServerAuthenticate2 failed: %s\n", 982 nt_errstr(status)); 983 goto done; 984 } 985 986 if (!netlogon_creds_client_check(creds_state, a.out.return_credentials)) { 987 d_printf("creds_client_check failed\n"); 988 goto done; 989 } 990 991 cli_credentials_set_netlogon_creds(wks_cred, creds_state); 992 993 result = true; 994 995 done: 996 talloc_free(mem_ctx); 997 return result; 998} 999 1000/* 1001 * Do a couple of schannel protected Netlogon ops: Interactive and Network 1002 * login, and change the wks password 1003 */ 1004 1005static bool schan(struct smbcli_state *cli, 1006 struct loadparm_context *lp_ctx, 1007 struct cli_credentials *wks_creds, 1008 struct cli_credentials *user_creds) 1009{ 1010 TALLOC_CTX *mem_ctx; 1011 NTSTATUS status; 1012 bool ret = false; 1013 struct dcerpc_pipe *net_pipe; 1014 int i; 1015 1016 mem_ctx = talloc_new(NULL); 1017 if (mem_ctx == NULL) { 1018 d_printf("talloc_new failed\n"); 1019 return false; 1020 } 1021 1022 net_pipe = dcerpc_pipe_init(mem_ctx, 1023 cli->transport->socket->event.ctx, 1024 lp_iconv_convenience(lp_ctx)); 1025 if (net_pipe == NULL) { 1026 d_printf("dcerpc_pipe_init failed\n"); 1027 goto done; 1028 } 1029 1030 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon"); 1031 if (!NT_STATUS_IS_OK(status)) { 1032 d_printf("dcerpc_pipe_open_smb failed: %s\n", 1033 nt_errstr(status)); 1034 goto done; 1035 } 1036 1037#if 0 1038 net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN | 1039 DCERPC_DEBUG_PRINT_OUT; 1040#endif 1041#if 1 1042 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); 1043 status = dcerpc_bind_auth(net_pipe, &ndr_table_netlogon, 1044 wks_creds, lp_gensec_settings(lp_ctx, lp_ctx), DCERPC_AUTH_TYPE_SCHANNEL, 1045 DCERPC_AUTH_LEVEL_PRIVACY, 1046 NULL); 1047#else 1048 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon); 1049#endif 1050 if (!NT_STATUS_IS_OK(status)) { 1051 d_printf("schannel bind failed: %s\n", nt_errstr(status)); 1052 goto done; 1053 } 1054 1055 1056 for (i=2; i<4; i++) { 1057 int flags; 1058 DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key; 1059 struct netlogon_creds_CredentialState *creds_state; 1060 struct netr_Authenticator netr_auth, netr_auth2; 1061 struct netr_NetworkInfo ninfo; 1062 struct netr_PasswordInfo pinfo; 1063 struct netr_LogonSamLogon r; 1064 union netr_LogonLevel logon; 1065 union netr_Validation validation; 1066 uint8_t authoritative; 1067 struct netr_Authenticator return_authenticator; 1068 1069 flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH | 1070 CLI_CRED_NTLMv2_AUTH; 1071 1072 chal = data_blob_talloc(mem_ctx, NULL, 8); 1073 if (chal.data == NULL) { 1074 d_printf("data_blob_talloc failed\n"); 1075 goto done; 1076 } 1077 1078 generate_random_buffer(chal.data, chal.length); 1079 names_blob = NTLMv2_generate_names_blob( 1080 mem_ctx, 1081 cli_credentials_get_workstation(user_creds), 1082 cli_credentials_get_domain(user_creds)); 1083 status = cli_credentials_get_ntlm_response( 1084 user_creds, mem_ctx, &flags, chal, names_blob, 1085 &lm_resp, &nt_resp, NULL, NULL); 1086 if (!NT_STATUS_IS_OK(status)) { 1087 d_printf("cli_credentials_get_ntlm_response failed:" 1088 " %s\n", nt_errstr(status)); 1089 goto done; 1090 } 1091 1092 creds_state = cli_credentials_get_netlogon_creds(wks_creds); 1093 netlogon_creds_client_authenticator(creds_state, &netr_auth); 1094 1095 ninfo.identity_info.account_name.string = 1096 cli_credentials_get_username(user_creds); 1097 ninfo.identity_info.domain_name.string = 1098 cli_credentials_get_domain(user_creds); 1099 ninfo.identity_info.parameter_control = 0; 1100 ninfo.identity_info.logon_id_low = 0; 1101 ninfo.identity_info.logon_id_high = 0; 1102 ninfo.identity_info.workstation.string = 1103 cli_credentials_get_workstation(user_creds); 1104 memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge)); 1105 ninfo.nt.length = nt_resp.length; 1106 ninfo.nt.data = nt_resp.data; 1107 ninfo.lm.length = lm_resp.length; 1108 ninfo.lm.data = lm_resp.data; 1109 1110 logon.network = &ninfo; 1111 1112 r.in.server_name = talloc_asprintf( 1113 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); 1114 ZERO_STRUCT(netr_auth2); 1115 r.in.computer_name = 1116 cli_credentials_get_workstation(wks_creds); 1117 r.in.credential = &netr_auth; 1118 r.in.return_authenticator = &netr_auth2; 1119 r.in.logon_level = 2; 1120 r.in.validation_level = i; 1121 r.in.logon = &logon; 1122 r.out.validation = &validation; 1123 r.out.authoritative = &authoritative; 1124 r.out.return_authenticator = &return_authenticator; 1125 1126 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r); 1127 if (!NT_STATUS_IS_OK(status)) { 1128 d_printf("netr_LogonSamLogon failed: %s\n", 1129 nt_errstr(status)); 1130 goto done; 1131 } 1132 1133 if ((r.out.return_authenticator == NULL) || 1134 (!netlogon_creds_client_check(creds_state, 1135 &r.out.return_authenticator->cred))) { 1136 d_printf("Credentials check failed!\n"); 1137 goto done; 1138 } 1139 1140 netlogon_creds_client_authenticator(creds_state, &netr_auth); 1141 1142 pinfo.identity_info = ninfo.identity_info; 1143 ZERO_STRUCT(pinfo.lmpassword.hash); 1144 E_md4hash(cli_credentials_get_password(user_creds), 1145 pinfo.ntpassword.hash); 1146 session_key = data_blob_talloc(mem_ctx, 1147 creds_state->session_key, 16); 1148 arcfour_crypt_blob(pinfo.ntpassword.hash, 1149 sizeof(pinfo.ntpassword.hash), 1150 &session_key); 1151 1152 logon.password = &pinfo; 1153 1154 r.in.logon_level = 1; 1155 r.in.logon = &logon; 1156 r.out.return_authenticator = &return_authenticator; 1157 1158 status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r); 1159 if (!NT_STATUS_IS_OK(status)) { 1160 d_printf("netr_LogonSamLogon failed: %s\n", 1161 nt_errstr(status)); 1162 goto done; 1163 } 1164 1165 if ((r.out.return_authenticator == NULL) || 1166 (!netlogon_creds_client_check(creds_state, 1167 &r.out.return_authenticator->cred))) { 1168 d_printf("Credentials check failed!\n"); 1169 goto done; 1170 } 1171 } 1172 1173 { 1174 struct netr_ServerPasswordSet s; 1175 char *password = generate_random_str(wks_creds, 8); 1176 struct netlogon_creds_CredentialState *creds_state; 1177 struct netr_Authenticator credential, return_authenticator; 1178 struct samr_Password new_password; 1179 1180 s.in.server_name = talloc_asprintf( 1181 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); 1182 s.in.computer_name = cli_credentials_get_workstation(wks_creds); 1183 s.in.account_name = talloc_asprintf( 1184 mem_ctx, "%s$", s.in.computer_name); 1185 s.in.secure_channel_type = SEC_CHAN_WKSTA; 1186 s.in.credential = &credential; 1187 s.in.new_password = &new_password; 1188 s.out.return_authenticator = &return_authenticator; 1189 1190 E_md4hash(password, new_password.hash); 1191 1192 creds_state = cli_credentials_get_netlogon_creds(wks_creds); 1193 netlogon_creds_des_encrypt(creds_state, &new_password); 1194 netlogon_creds_client_authenticator(creds_state, &credential); 1195 1196 status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s); 1197 if (!NT_STATUS_IS_OK(status)) { 1198 printf("ServerPasswordSet - %s\n", nt_errstr(status)); 1199 goto done; 1200 } 1201 1202 if (!netlogon_creds_client_check(creds_state, 1203 &s.out.return_authenticator->cred)) { 1204 printf("Credential chaining failed\n"); 1205 } 1206 1207 cli_credentials_set_password(wks_creds, password, 1208 CRED_SPECIFIED); 1209 } 1210 1211 ret = true; 1212 done: 1213 talloc_free(mem_ctx); 1214 return ret; 1215} 1216 1217/* 1218 * Delete the wks account again 1219 */ 1220 1221static bool leave(struct smbcli_state *cli, 1222 struct loadparm_context *lp_ctx, 1223 struct cli_credentials *admin_creds, 1224 struct cli_credentials *wks_creds) 1225{ 1226 char *wks_name = talloc_asprintf( 1227 NULL, "%s$", cli_credentials_get_workstation(wks_creds)); 1228 bool ret; 1229 1230 ret = delete_user(cli, lp_ctx, admin_creds, wks_name); 1231 talloc_free(wks_name); 1232 return ret; 1233} 1234 1235/* 1236 * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave 1237 */ 1238 1239bool torture_netlogon_samba3(struct torture_context *torture) 1240{ 1241 TALLOC_CTX *mem_ctx; 1242 NTSTATUS status; 1243 bool ret = false; 1244 struct smbcli_state *cli; 1245 struct cli_credentials *anon_creds; 1246 struct cli_credentials *wks_creds; 1247 const char *wks_name; 1248 int i; 1249 struct smbcli_options options; 1250 struct smbcli_session_options session_options; 1251 1252 wks_name = torture_setting_string(torture, "wksname", NULL); 1253 if (wks_name == NULL) { 1254 wks_name = get_myname(torture); 1255 } 1256 1257 mem_ctx = talloc_init("torture_netlogon_samba3"); 1258 1259 if (mem_ctx == NULL) { 1260 d_printf("talloc_init failed\n"); 1261 return false; 1262 } 1263 1264 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) { 1265 d_printf("create_anon_creds failed\n"); 1266 goto done; 1267 } 1268 1269 lp_smbcli_options(torture->lp_ctx, &options); 1270 lp_smbcli_session_options(torture->lp_ctx, &session_options); 1271 1272 status = smbcli_full_connection(mem_ctx, &cli, 1273 torture_setting_string(torture, "host", NULL), 1274 lp_smb_ports(torture->lp_ctx), 1275 "IPC$", NULL, 1276 lp_socket_options(torture->lp_ctx), 1277 anon_creds, 1278 lp_resolve_context(torture->lp_ctx), 1279 torture->ev, &options, &session_options, 1280 lp_iconv_convenience(torture->lp_ctx), 1281 lp_gensec_settings(torture, torture->lp_ctx)); 1282 if (!NT_STATUS_IS_OK(status)) { 1283 d_printf("smbcli_full_connection failed: %s\n", 1284 nt_errstr(status)); 1285 goto done; 1286 } 1287 1288 wks_creds = cli_credentials_init(mem_ctx); 1289 if (wks_creds == NULL) { 1290 d_printf("cli_credentials_init failed\n"); 1291 goto done; 1292 } 1293 1294 cli_credentials_set_conf(wks_creds, torture->lp_ctx); 1295 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA); 1296 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED); 1297 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED); 1298 cli_credentials_set_password(wks_creds, 1299 generate_random_str(wks_creds, 8), 1300 CRED_SPECIFIED); 1301 1302 if (!join3(cli, torture->lp_ctx, false, cmdline_credentials, wks_creds)) { 1303 d_printf("join failed\n"); 1304 goto done; 1305 } 1306 1307 cli_credentials_set_domain( 1308 cmdline_credentials, cli_credentials_get_domain(wks_creds), 1309 CRED_SPECIFIED); 1310 1311 for (i=0; i<2; i++) { 1312 1313 /* Do this more than once, the routine "schan" changes 1314 * the workstation password using the netlogon 1315 * password change routine */ 1316 1317 int j; 1318 1319 if (!auth2(cli, torture->lp_ctx, wks_creds)) { 1320 d_printf("auth2 failed\n"); 1321 goto done; 1322 } 1323 1324 for (j=0; j<2; j++) { 1325 if (!schan(cli, torture->lp_ctx, wks_creds, cmdline_credentials)) { 1326 d_printf("schan failed\n"); 1327 goto done; 1328 } 1329 } 1330 } 1331 1332 if (!leave(cli, torture->lp_ctx, cmdline_credentials, wks_creds)) { 1333 d_printf("leave failed\n"); 1334 goto done; 1335 } 1336 1337 ret = true; 1338 1339 done: 1340 talloc_free(mem_ctx); 1341 return ret; 1342} 1343 1344/* 1345 * Do a simple join, testjoin and leave using specified smb and samr 1346 * credentials 1347 */ 1348 1349static bool test_join3(struct torture_context *tctx, 1350 bool use_level25, 1351 struct cli_credentials *smb_creds, 1352 struct cli_credentials *samr_creds, 1353 const char *wks_name) 1354{ 1355 NTSTATUS status; 1356 bool ret = false; 1357 struct smbcli_state *cli; 1358 struct cli_credentials *wks_creds; 1359 struct smbcli_options options; 1360 struct smbcli_session_options session_options; 1361 1362 lp_smbcli_options(tctx->lp_ctx, &options); 1363 lp_smbcli_session_options(tctx->lp_ctx, &session_options); 1364 1365 status = smbcli_full_connection(tctx, &cli, 1366 torture_setting_string(tctx, "host", NULL), 1367 lp_smb_ports(tctx->lp_ctx), 1368 "IPC$", NULL, lp_socket_options(tctx->lp_ctx), 1369 smb_creds, lp_resolve_context(tctx->lp_ctx), 1370 tctx->ev, &options, &session_options, 1371 lp_iconv_convenience(tctx->lp_ctx), 1372 lp_gensec_settings(tctx, tctx->lp_ctx)); 1373 if (!NT_STATUS_IS_OK(status)) { 1374 d_printf("smbcli_full_connection failed: %s\n", 1375 nt_errstr(status)); 1376 goto done; 1377 } 1378 1379 wks_creds = cli_credentials_init(cli); 1380 if (wks_creds == NULL) { 1381 d_printf("cli_credentials_init failed\n"); 1382 goto done; 1383 } 1384 1385 cli_credentials_set_conf(wks_creds, tctx->lp_ctx); 1386 cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA); 1387 cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED); 1388 cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED); 1389 cli_credentials_set_password(wks_creds, 1390 generate_random_str(wks_creds, 8), 1391 CRED_SPECIFIED); 1392 1393 if (!join3(cli, tctx->lp_ctx, use_level25, samr_creds, wks_creds)) { 1394 d_printf("join failed\n"); 1395 goto done; 1396 } 1397 1398 cli_credentials_set_domain( 1399 cmdline_credentials, cli_credentials_get_domain(wks_creds), 1400 CRED_SPECIFIED); 1401 1402 if (!auth2(cli, tctx->lp_ctx, wks_creds)) { 1403 d_printf("auth2 failed\n"); 1404 goto done; 1405 } 1406 1407 if (!leave(cli, tctx->lp_ctx, samr_creds, wks_creds)) { 1408 d_printf("leave failed\n"); 1409 goto done; 1410 } 1411 1412 talloc_free(cli); 1413 1414 ret = true; 1415 1416 done: 1417 return ret; 1418} 1419 1420/* 1421 * Test the different session key variants. Do it by joining, this uses the 1422 * session key in the setpassword routine. Test the join by doing the auth2. 1423 */ 1424 1425bool torture_samba3_sessionkey(struct torture_context *torture) 1426{ 1427 bool ret = false; 1428 struct cli_credentials *anon_creds; 1429 const char *wks_name; 1430 1431 wks_name = torture_setting_string(torture, "wksname", get_myname(torture)); 1432 1433 if (!(anon_creds = cli_credentials_init_anon(torture))) { 1434 d_printf("create_anon_creds failed\n"); 1435 goto done; 1436 } 1437 1438 cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED); 1439 1440 ret = true; 1441 1442 if (!torture_setting_bool(torture, "samba3", false)) { 1443 1444 /* Samba3 in the build farm right now does this happily. Need 1445 * to fix :-) */ 1446 1447 if (test_join3(torture, false, anon_creds, NULL, wks_name)) { 1448 d_printf("join using anonymous bind on an anonymous smb " 1449 "connection succeeded -- HUH??\n"); 1450 ret = false; 1451 } 1452 } 1453 1454 if (!test_join3(torture, false, anon_creds, cmdline_credentials, 1455 wks_name)) { 1456 d_printf("join using ntlmssp bind on an anonymous smb " 1457 "connection failed\n"); 1458 ret = false; 1459 } 1460 1461 if (!test_join3(torture, false, cmdline_credentials, NULL, wks_name)) { 1462 d_printf("join using anonymous bind on an authenticated smb " 1463 "connection failed\n"); 1464 ret = false; 1465 } 1466 1467 if (!test_join3(torture, false, cmdline_credentials, 1468 cmdline_credentials, 1469 wks_name)) { 1470 d_printf("join using ntlmssp bind on an authenticated smb " 1471 "connection failed\n"); 1472 ret = false; 1473 } 1474 1475 /* 1476 * The following two are tests for setuserinfolevel 25 1477 */ 1478 1479 if (!test_join3(torture, true, anon_creds, cmdline_credentials, 1480 wks_name)) { 1481 d_printf("join using ntlmssp bind on an anonymous smb " 1482 "connection failed\n"); 1483 ret = false; 1484 } 1485 1486 if (!test_join3(torture, true, cmdline_credentials, NULL, wks_name)) { 1487 d_printf("join using anonymous bind on an authenticated smb " 1488 "connection failed\n"); 1489 ret = false; 1490 } 1491 1492 done: 1493 1494 return ret; 1495} 1496 1497/* 1498 * open pipe and bind, given an IPC$ context 1499 */ 1500 1501static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx, 1502 struct loadparm_context *lp_ctx, 1503 struct smbcli_tree *tree, 1504 const char *pipe_name, 1505 const struct ndr_interface_table *iface, 1506 struct dcerpc_pipe **p) 1507{ 1508 struct dcerpc_pipe *result; 1509 NTSTATUS status; 1510 1511 if (!(result = dcerpc_pipe_init( 1512 mem_ctx, tree->session->transport->socket->event.ctx, 1513 lp_iconv_convenience(lp_ctx)))) { 1514 return NT_STATUS_NO_MEMORY; 1515 } 1516 1517 status = dcerpc_pipe_open_smb(result, tree, pipe_name); 1518 if (!NT_STATUS_IS_OK(status)) { 1519 d_printf("dcerpc_pipe_open_smb failed: %s\n", 1520 nt_errstr(status)); 1521 talloc_free(result); 1522 return status; 1523 } 1524 1525 status = dcerpc_bind_auth_none(result, iface); 1526 if (!NT_STATUS_IS_OK(status)) { 1527 d_printf("schannel bind failed: %s\n", nt_errstr(status)); 1528 talloc_free(result); 1529 return status; 1530 } 1531 1532 *p = result; 1533 return NT_STATUS_OK; 1534} 1535 1536/* 1537 * Sane wrapper around lsa_LookupNames 1538 */ 1539 1540static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx, 1541 struct dcerpc_pipe *p, 1542 const char *name, 1543 const char *domain) 1544{ 1545 struct lsa_ObjectAttribute attr; 1546 struct lsa_QosInfo qos; 1547 struct lsa_OpenPolicy2 r; 1548 struct lsa_Close c; 1549 NTSTATUS status; 1550 struct policy_handle handle; 1551 struct lsa_LookupNames l; 1552 struct lsa_TransSidArray sids; 1553 struct lsa_RefDomainList *domains = NULL; 1554 struct lsa_String lsa_name; 1555 uint32_t count = 0; 1556 struct dom_sid *result; 1557 TALLOC_CTX *tmp_ctx; 1558 1559 if (!(tmp_ctx = talloc_new(mem_ctx))) { 1560 return NULL; 1561 } 1562 1563 qos.len = 0; 1564 qos.impersonation_level = 2; 1565 qos.context_mode = 1; 1566 qos.effective_only = 0; 1567 1568 attr.len = 0; 1569 attr.root_dir = NULL; 1570 attr.object_name = NULL; 1571 attr.attributes = 0; 1572 attr.sec_desc = NULL; 1573 attr.sec_qos = &qos; 1574 1575 r.in.system_name = "\\"; 1576 r.in.attr = &attr; 1577 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 1578 r.out.handle = &handle; 1579 1580 status = dcerpc_lsa_OpenPolicy2(p, tmp_ctx, &r); 1581 if (!NT_STATUS_IS_OK(status)) { 1582 printf("OpenPolicy2 failed - %s\n", nt_errstr(status)); 1583 talloc_free(tmp_ctx); 1584 return NULL; 1585 } 1586 1587 sids.count = 0; 1588 sids.sids = NULL; 1589 1590 lsa_name.string = talloc_asprintf(tmp_ctx, "%s\\%s", domain, name); 1591 1592 l.in.handle = &handle; 1593 l.in.num_names = 1; 1594 l.in.names = &lsa_name; 1595 l.in.sids = &sids; 1596 l.in.level = 1; 1597 l.in.count = &count; 1598 l.out.count = &count; 1599 l.out.sids = &sids; 1600 l.out.domains = &domains; 1601 1602 status = dcerpc_lsa_LookupNames(p, tmp_ctx, &l); 1603 if (!NT_STATUS_IS_OK(status)) { 1604 printf("LookupNames of %s failed - %s\n", lsa_name.string, 1605 nt_errstr(status)); 1606 talloc_free(tmp_ctx); 1607 return NULL; 1608 } 1609 1610 result = dom_sid_add_rid(mem_ctx, domains->domains[0].sid, 1611 l.out.sids->sids[0].rid); 1612 1613 c.in.handle = &handle; 1614 c.out.handle = &handle; 1615 1616 status = dcerpc_lsa_Close(p, tmp_ctx, &c); 1617 if (!NT_STATUS_IS_OK(status)) { 1618 printf("dcerpc_lsa_Close failed - %s\n", nt_errstr(status)); 1619 talloc_free(tmp_ctx); 1620 return NULL; 1621 } 1622 1623 talloc_free(tmp_ctx); 1624 return result; 1625} 1626 1627/* 1628 * Find out the user SID on this connection 1629 */ 1630 1631static struct dom_sid *whoami(TALLOC_CTX *mem_ctx, 1632 struct loadparm_context *lp_ctx, 1633 struct smbcli_tree *tree) 1634{ 1635 struct dcerpc_pipe *lsa; 1636 struct lsa_GetUserName r; 1637 NTSTATUS status; 1638 struct lsa_String *authority_name_p = NULL; 1639 struct lsa_String *account_name_p = NULL; 1640 struct dom_sid *result; 1641 1642 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\lsarpc", 1643 &ndr_table_lsarpc, &lsa); 1644 if (!NT_STATUS_IS_OK(status)) { 1645 d_printf("(%s) Could not bind to LSA: %s\n", 1646 __location__, nt_errstr(status)); 1647 return NULL; 1648 } 1649 1650 r.in.system_name = "\\"; 1651 r.in.account_name = &account_name_p; 1652 r.in.authority_name = &authority_name_p; 1653 r.out.account_name = &account_name_p; 1654 1655 status = dcerpc_lsa_GetUserName(lsa, mem_ctx, &r); 1656 1657 authority_name_p = *r.out.authority_name; 1658 1659 if (!NT_STATUS_IS_OK(status)) { 1660 printf("(%s) GetUserName failed - %s\n", 1661 __location__, nt_errstr(status)); 1662 talloc_free(lsa); 1663 return NULL; 1664 } 1665 1666 result = name2sid(mem_ctx, lsa, account_name_p->string, 1667 authority_name_p->string); 1668 1669 talloc_free(lsa); 1670 return result; 1671} 1672 1673static int destroy_tree(struct smbcli_tree *tree) 1674{ 1675 smb_tree_disconnect(tree); 1676 return 0; 1677} 1678 1679/* 1680 * Do a tcon, given a session 1681 */ 1682 1683NTSTATUS secondary_tcon(TALLOC_CTX *mem_ctx, 1684 struct smbcli_session *session, 1685 const char *sharename, 1686 struct smbcli_tree **res) 1687{ 1688 struct smbcli_tree *result; 1689 TALLOC_CTX *tmp_ctx; 1690 union smb_tcon tcon; 1691 NTSTATUS status; 1692 1693 if (!(tmp_ctx = talloc_new(mem_ctx))) { 1694 return NT_STATUS_NO_MEMORY; 1695 } 1696 1697 if (!(result = smbcli_tree_init(session, mem_ctx, false))) { 1698 talloc_free(tmp_ctx); 1699 return NT_STATUS_NO_MEMORY; 1700 } 1701 1702 tcon.generic.level = RAW_TCON_TCONX; 1703 tcon.tconx.in.flags = 0; 1704 tcon.tconx.in.password = data_blob(NULL, 0); 1705 tcon.tconx.in.path = sharename; 1706 tcon.tconx.in.device = "?????"; 1707 1708 status = smb_raw_tcon(result, tmp_ctx, &tcon); 1709 if (!NT_STATUS_IS_OK(status)) { 1710 d_printf("(%s) smb_raw_tcon failed: %s\n", __location__, 1711 nt_errstr(status)); 1712 talloc_free(tmp_ctx); 1713 return status; 1714 } 1715 1716 result->tid = tcon.tconx.out.tid; 1717 result = talloc_steal(mem_ctx, result); 1718 talloc_set_destructor(result, destroy_tree); 1719 talloc_free(tmp_ctx); 1720 *res = result; 1721 return NT_STATUS_OK; 1722} 1723 1724/* 1725 * Test the getusername behaviour 1726 */ 1727 1728bool torture_samba3_rpc_getusername(struct torture_context *torture) 1729{ 1730 NTSTATUS status; 1731 struct smbcli_state *cli; 1732 TALLOC_CTX *mem_ctx; 1733 bool ret = true; 1734 struct dom_sid *user_sid; 1735 struct dom_sid *created_sid; 1736 struct cli_credentials *anon_creds; 1737 struct cli_credentials *user_creds; 1738 char *domain_name; 1739 struct smbcli_options options; 1740 struct smbcli_session_options session_options; 1741 1742 if (!(mem_ctx = talloc_new(torture))) { 1743 return false; 1744 } 1745 1746 lp_smbcli_options(torture->lp_ctx, &options); 1747 lp_smbcli_session_options(torture->lp_ctx, &session_options); 1748 1749 status = smbcli_full_connection( 1750 mem_ctx, &cli, torture_setting_string(torture, "host", NULL), 1751 lp_smb_ports(torture->lp_ctx), 1752 "IPC$", NULL, lp_socket_options(torture->lp_ctx), cmdline_credentials, 1753 lp_resolve_context(torture->lp_ctx), 1754 torture->ev, &options, &session_options, 1755 lp_iconv_convenience(torture->lp_ctx), 1756 lp_gensec_settings(torture, torture->lp_ctx)); 1757 if (!NT_STATUS_IS_OK(status)) { 1758 d_printf("(%s) smbcli_full_connection failed: %s\n", 1759 __location__, nt_errstr(status)); 1760 ret = false; 1761 goto done; 1762 } 1763 1764 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) { 1765 d_printf("(%s) whoami on auth'ed connection failed\n", 1766 __location__); 1767 ret = false; 1768 } 1769 1770 talloc_free(cli); 1771 1772 if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) { 1773 d_printf("(%s) create_anon_creds failed\n", __location__); 1774 ret = false; 1775 goto done; 1776 } 1777 1778 status = smbcli_full_connection( 1779 mem_ctx, &cli, torture_setting_string(torture, "host", NULL), 1780 lp_smb_ports(torture->lp_ctx), "IPC$", NULL, 1781 lp_socket_options(torture->lp_ctx), anon_creds, 1782 lp_resolve_context(torture->lp_ctx), 1783 torture->ev, &options, &session_options, 1784 lp_iconv_convenience(torture->lp_ctx), 1785 lp_gensec_settings(torture, torture->lp_ctx)); 1786 if (!NT_STATUS_IS_OK(status)) { 1787 d_printf("(%s) anon smbcli_full_connection failed: %s\n", 1788 __location__, nt_errstr(status)); 1789 ret = false; 1790 goto done; 1791 } 1792 1793 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) { 1794 d_printf("(%s) whoami on anon connection failed\n", 1795 __location__); 1796 ret = false; 1797 goto done; 1798 } 1799 1800 if (!dom_sid_equal(user_sid, 1801 dom_sid_parse_talloc(mem_ctx, "s-1-5-7"))) { 1802 d_printf("(%s) Anon lsa_GetUserName returned %s, expected " 1803 "S-1-5-7", __location__, 1804 dom_sid_string(mem_ctx, user_sid)); 1805 ret = false; 1806 } 1807 1808 if (!(user_creds = cli_credentials_init(mem_ctx))) { 1809 d_printf("(%s) cli_credentials_init failed\n", __location__); 1810 ret = false; 1811 goto done; 1812 } 1813 1814 cli_credentials_set_conf(user_creds, torture->lp_ctx); 1815 cli_credentials_set_username(user_creds, "torture_username", 1816 CRED_SPECIFIED); 1817 cli_credentials_set_password(user_creds, 1818 generate_random_str(user_creds, 8), 1819 CRED_SPECIFIED); 1820 1821 if (!create_user(mem_ctx, cli, torture->lp_ctx, cmdline_credentials, 1822 cli_credentials_get_username(user_creds), 1823 cli_credentials_get_password(user_creds), 1824 &domain_name, &created_sid)) { 1825 d_printf("(%s) create_user failed\n", __location__); 1826 ret = false; 1827 goto done; 1828 } 1829 1830 cli_credentials_set_domain(user_creds, domain_name, 1831 CRED_SPECIFIED); 1832 1833 { 1834 struct smbcli_session *session2; 1835 struct smb_composite_sesssetup setup; 1836 struct smbcli_tree *tree; 1837 1838 session2 = smbcli_session_init(cli->transport, mem_ctx, false, session_options); 1839 if (session2 == NULL) { 1840 d_printf("(%s) smbcli_session_init failed\n", 1841 __location__); 1842 goto done; 1843 } 1844 1845 setup.in.sesskey = cli->transport->negotiate.sesskey; 1846 setup.in.capabilities = cli->transport->negotiate.capabilities; 1847 setup.in.workgroup = ""; 1848 setup.in.credentials = user_creds; 1849 setup.in.gensec_settings = lp_gensec_settings(torture, torture->lp_ctx); 1850 1851 status = smb_composite_sesssetup(session2, &setup); 1852 if (!NT_STATUS_IS_OK(status)) { 1853 d_printf("(%s) session setup with new user failed: " 1854 "%s\n", __location__, nt_errstr(status)); 1855 ret = false; 1856 goto done; 1857 } 1858 session2->vuid = setup.out.vuid; 1859 1860 if (!NT_STATUS_IS_OK(secondary_tcon(mem_ctx, session2, 1861 "IPC$", &tree))) { 1862 d_printf("(%s) secondary_tcon failed\n", 1863 __location__); 1864 ret = false; 1865 goto done; 1866 } 1867 1868 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, tree))) { 1869 d_printf("(%s) whoami on user connection failed\n", 1870 __location__); 1871 ret = false; 1872 goto del; 1873 } 1874 1875 talloc_free(tree); 1876 } 1877 1878 d_printf("Created %s, found %s\n", 1879 dom_sid_string(mem_ctx, created_sid), 1880 dom_sid_string(mem_ctx, user_sid)); 1881 1882 if (!dom_sid_equal(created_sid, user_sid)) { 1883 ret = false; 1884 } 1885 1886 del: 1887 if (!delete_user(cli, torture->lp_ctx, 1888 cmdline_credentials, 1889 cli_credentials_get_username(user_creds))) { 1890 d_printf("(%s) delete_user failed\n", __location__); 1891 ret = false; 1892 } 1893 1894 done: 1895 talloc_free(mem_ctx); 1896 return ret; 1897} 1898 1899static bool test_NetShareGetInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 1900 const char *sharename) 1901{ 1902 NTSTATUS status; 1903 struct srvsvc_NetShareGetInfo r; 1904 union srvsvc_NetShareInfo info; 1905 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007, 1501 }; 1906 int i; 1907 bool ret = true; 1908 1909 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", 1910 dcerpc_server_name(p)); 1911 r.in.share_name = sharename; 1912 r.out.info = &info; 1913 1914 for (i=0;i<ARRAY_SIZE(levels);i++) { 1915 r.in.level = levels[i]; 1916 1917 printf("testing NetShareGetInfo level %u on share '%s'\n", 1918 r.in.level, r.in.share_name); 1919 1920 status = dcerpc_srvsvc_NetShareGetInfo(p, mem_ctx, &r); 1921 if (!NT_STATUS_IS_OK(status)) { 1922 printf("NetShareGetInfo level %u on share '%s' failed" 1923 " - %s\n", r.in.level, r.in.share_name, 1924 nt_errstr(status)); 1925 ret = false; 1926 continue; 1927 } 1928 if (!W_ERROR_IS_OK(r.out.result)) { 1929 printf("NetShareGetInfo level %u on share '%s' failed " 1930 "- %s\n", r.in.level, r.in.share_name, 1931 win_errstr(r.out.result)); 1932 ret = false; 1933 continue; 1934 } 1935 } 1936 1937 return ret; 1938} 1939 1940static bool test_NetShareEnum(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 1941 const char **one_sharename) 1942{ 1943 NTSTATUS status; 1944 struct srvsvc_NetShareEnum r; 1945 struct srvsvc_NetShareInfoCtr info_ctr; 1946 struct srvsvc_NetShareCtr0 c0; 1947 struct srvsvc_NetShareCtr1 c1; 1948 struct srvsvc_NetShareCtr2 c2; 1949 struct srvsvc_NetShareCtr501 c501; 1950 struct srvsvc_NetShareCtr502 c502; 1951 struct srvsvc_NetShareCtr1004 c1004; 1952 struct srvsvc_NetShareCtr1005 c1005; 1953 struct srvsvc_NetShareCtr1006 c1006; 1954 struct srvsvc_NetShareCtr1007 c1007; 1955 uint32_t totalentries = 0; 1956 uint32_t levels[] = { 0, 1, 2, 501, 502, 1004, 1005, 1006, 1007 }; 1957 int i; 1958 bool ret = true; 1959 1960 ZERO_STRUCT(info_ctr); 1961 1962 r.in.server_unc = talloc_asprintf(mem_ctx,"\\\\%s",dcerpc_server_name(p)); 1963 r.in.info_ctr = &info_ctr; 1964 r.in.max_buffer = (uint32_t)-1; 1965 r.in.resume_handle = NULL; 1966 r.out.totalentries = &totalentries; 1967 r.out.info_ctr = &info_ctr; 1968 1969 for (i=0;i<ARRAY_SIZE(levels);i++) { 1970 info_ctr.level = levels[i]; 1971 1972 switch (info_ctr.level) { 1973 case 0: 1974 ZERO_STRUCT(c0); 1975 info_ctr.ctr.ctr0 = &c0; 1976 break; 1977 case 1: 1978 ZERO_STRUCT(c1); 1979 info_ctr.ctr.ctr1 = &c1; 1980 break; 1981 case 2: 1982 ZERO_STRUCT(c2); 1983 info_ctr.ctr.ctr2 = &c2; 1984 break; 1985 case 501: 1986 ZERO_STRUCT(c501); 1987 info_ctr.ctr.ctr501 = &c501; 1988 break; 1989 case 502: 1990 ZERO_STRUCT(c502); 1991 info_ctr.ctr.ctr502 = &c502; 1992 break; 1993 case 1004: 1994 ZERO_STRUCT(c1004); 1995 info_ctr.ctr.ctr1004 = &c1004; 1996 break; 1997 case 1005: 1998 ZERO_STRUCT(c1005); 1999 info_ctr.ctr.ctr1005 = &c1005; 2000 break; 2001 case 1006: 2002 ZERO_STRUCT(c1006); 2003 info_ctr.ctr.ctr1006 = &c1006; 2004 break; 2005 case 1007: 2006 ZERO_STRUCT(c1007); 2007 info_ctr.ctr.ctr1007 = &c1007; 2008 break; 2009 } 2010 2011 printf("testing NetShareEnum level %u\n", info_ctr.level); 2012 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r); 2013 if (!NT_STATUS_IS_OK(status)) { 2014 printf("NetShareEnum level %u failed - %s\n", 2015 info_ctr.level, nt_errstr(status)); 2016 ret = false; 2017 continue; 2018 } 2019 if (!W_ERROR_IS_OK(r.out.result)) { 2020 printf("NetShareEnum level %u failed - %s\n", 2021 info_ctr.level, win_errstr(r.out.result)); 2022 continue; 2023 } 2024 if (info_ctr.level == 0) { 2025 struct srvsvc_NetShareCtr0 *ctr = r.out.info_ctr->ctr.ctr0; 2026 if (ctr->count > 0) { 2027 *one_sharename = ctr->array[0].name; 2028 } 2029 } 2030 } 2031 2032 return ret; 2033} 2034 2035bool torture_samba3_rpc_srvsvc(struct torture_context *torture) 2036{ 2037 struct dcerpc_pipe *p; 2038 TALLOC_CTX *mem_ctx; 2039 bool ret = true; 2040 const char *sharename = NULL; 2041 struct smbcli_state *cli; 2042 NTSTATUS status; 2043 2044 if (!(mem_ctx = talloc_new(torture))) { 2045 return false; 2046 } 2047 2048 if (!(torture_open_connection_share( 2049 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL), 2050 "IPC$", torture->ev))) { 2051 talloc_free(mem_ctx); 2052 return false; 2053 } 2054 2055 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, 2056 "\\pipe\\srvsvc", &ndr_table_srvsvc, &p); 2057 if (!NT_STATUS_IS_OK(status)) { 2058 d_printf("(%s) could not bind to srvsvc pipe: %s\n", 2059 __location__, nt_errstr(status)); 2060 ret = false; 2061 goto done; 2062 } 2063 2064 ret &= test_NetShareEnum(p, mem_ctx, &sharename); 2065 if (sharename == NULL) { 2066 printf("did not get sharename\n"); 2067 } else { 2068 ret &= test_NetShareGetInfo(p, mem_ctx, sharename); 2069 } 2070 2071 done: 2072 talloc_free(mem_ctx); 2073 return ret; 2074} 2075 2076/* 2077 * Do a ReqChallenge/Auth2 with a random wks name, make sure it returns 2078 * NT_STATUS_NO_SAM_ACCOUNT 2079 */ 2080 2081bool torture_samba3_rpc_randomauth2(struct torture_context *torture) 2082{ 2083 TALLOC_CTX *mem_ctx; 2084 struct dcerpc_pipe *net_pipe; 2085 char *wksname; 2086 bool result = false; 2087 NTSTATUS status; 2088 struct netr_ServerReqChallenge r; 2089 struct netr_Credential netr_cli_creds; 2090 struct netr_Credential netr_srv_creds; 2091 uint32_t negotiate_flags; 2092 struct netr_ServerAuthenticate2 a; 2093 struct netlogon_creds_CredentialState *creds_state; 2094 struct netr_Credential netr_cred; 2095 struct samr_Password mach_pw; 2096 struct smbcli_state *cli; 2097 2098 if (!(mem_ctx = talloc_new(torture))) { 2099 d_printf("talloc_new failed\n"); 2100 return false; 2101 } 2102 2103 if (!(wksname = generate_random_str_list( 2104 mem_ctx, 14, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"))) { 2105 d_printf("generate_random_str_list failed\n"); 2106 goto done; 2107 } 2108 2109 if (!(torture_open_connection_share( 2110 mem_ctx, &cli, 2111 torture, torture_setting_string(torture, "host", NULL), 2112 "IPC$", torture->ev))) { 2113 d_printf("IPC$ connection failed\n"); 2114 goto done; 2115 } 2116 2117 if (!(net_pipe = dcerpc_pipe_init( 2118 mem_ctx, cli->transport->socket->event.ctx, 2119 lp_iconv_convenience(torture->lp_ctx)))) { 2120 d_printf("dcerpc_pipe_init failed\n"); 2121 goto done; 2122 } 2123 2124 status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon"); 2125 if (!NT_STATUS_IS_OK(status)) { 2126 d_printf("dcerpc_pipe_open_smb failed: %s\n", 2127 nt_errstr(status)); 2128 goto done; 2129 } 2130 2131 status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon); 2132 if (!NT_STATUS_IS_OK(status)) { 2133 d_printf("dcerpc_bind_auth_none failed: %s\n", 2134 nt_errstr(status)); 2135 goto done; 2136 } 2137 2138 r.in.computer_name = wksname; 2139 r.in.server_name = talloc_asprintf( 2140 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); 2141 if (r.in.server_name == NULL) { 2142 d_printf("talloc_asprintf failed\n"); 2143 goto done; 2144 } 2145 generate_random_buffer(netr_cli_creds.data, 2146 sizeof(netr_cli_creds.data)); 2147 r.in.credentials = &netr_cli_creds; 2148 r.out.return_credentials = &netr_srv_creds; 2149 2150 status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r); 2151 if (!NT_STATUS_IS_OK(status)) { 2152 d_printf("netr_ServerReqChallenge failed: %s\n", 2153 nt_errstr(status)); 2154 goto done; 2155 } 2156 2157 negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; 2158 E_md4hash("foobar", mach_pw.hash); 2159 2160 a.in.server_name = talloc_asprintf( 2161 mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); 2162 a.in.account_name = talloc_asprintf( 2163 mem_ctx, "%s$", wksname); 2164 a.in.computer_name = wksname; 2165 a.in.secure_channel_type = SEC_CHAN_WKSTA; 2166 a.in.negotiate_flags = &negotiate_flags; 2167 a.out.negotiate_flags = &negotiate_flags; 2168 a.in.credentials = &netr_cred; 2169 a.out.return_credentials = &netr_cred; 2170 2171 creds_state = netlogon_creds_client_init(mem_ctx, 2172 a.in.account_name, 2173 a.in.computer_name, 2174 r.in.credentials, 2175 r.out.return_credentials, &mach_pw, 2176 &netr_cred, negotiate_flags); 2177 2178 2179 status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a); 2180 2181 if (!NT_STATUS_EQUAL(status, NT_STATUS_NO_TRUST_SAM_ACCOUNT)) { 2182 d_printf("dcerpc_netr_ServerAuthenticate2 returned %s, " 2183 "expected NT_STATUS_NO_TRUST_SAM_ACCOUNT\n", 2184 nt_errstr(status)); 2185 goto done; 2186 } 2187 2188 result = true; 2189 done: 2190 talloc_free(mem_ctx); 2191 return result; 2192} 2193 2194static struct security_descriptor *get_sharesec(TALLOC_CTX *mem_ctx, 2195 struct loadparm_context *lp_ctx, 2196 struct smbcli_session *sess, 2197 const char *sharename) 2198{ 2199 struct smbcli_tree *tree; 2200 TALLOC_CTX *tmp_ctx; 2201 struct dcerpc_pipe *p; 2202 NTSTATUS status; 2203 struct srvsvc_NetShareGetInfo r; 2204 union srvsvc_NetShareInfo info; 2205 struct security_descriptor *result; 2206 2207 if (!(tmp_ctx = talloc_new(mem_ctx))) { 2208 d_printf("talloc_new failed\n"); 2209 return NULL; 2210 } 2211 2212 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) { 2213 d_printf("secondary_tcon failed\n"); 2214 talloc_free(tmp_ctx); 2215 return NULL; 2216 } 2217 2218 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\srvsvc", 2219 &ndr_table_srvsvc, &p); 2220 if (!NT_STATUS_IS_OK(status)) { 2221 d_printf("(%s) could not bind to srvsvc pipe: %s\n", 2222 __location__, nt_errstr(status)); 2223 talloc_free(tmp_ctx); 2224 return NULL; 2225 } 2226 2227#if 0 2228 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT; 2229#endif 2230 2231 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s", 2232 dcerpc_server_name(p)); 2233 r.in.share_name = sharename; 2234 r.in.level = 502; 2235 r.out.info = &info; 2236 2237 status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r); 2238 if (!NT_STATUS_IS_OK(status)) { 2239 d_printf("srvsvc_NetShareGetInfo failed: %s\n", 2240 nt_errstr(status)); 2241 talloc_free(tmp_ctx); 2242 return NULL; 2243 } 2244 2245 result = talloc_steal(mem_ctx, info.info502->sd_buf.sd); 2246 talloc_free(tmp_ctx); 2247 return result; 2248} 2249 2250static NTSTATUS set_sharesec(TALLOC_CTX *mem_ctx, 2251 struct loadparm_context *lp_ctx, 2252 struct smbcli_session *sess, 2253 const char *sharename, 2254 struct security_descriptor *sd) 2255{ 2256 struct smbcli_tree *tree; 2257 TALLOC_CTX *tmp_ctx; 2258 struct dcerpc_pipe *p; 2259 NTSTATUS status; 2260 struct sec_desc_buf i; 2261 struct srvsvc_NetShareSetInfo r; 2262 union srvsvc_NetShareInfo info; 2263 uint32_t error = 0; 2264 2265 if (!(tmp_ctx = talloc_new(mem_ctx))) { 2266 d_printf("talloc_new failed\n"); 2267 return NT_STATUS_NO_MEMORY; 2268 } 2269 2270 if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) { 2271 d_printf("secondary_tcon failed\n"); 2272 talloc_free(tmp_ctx); 2273 return NT_STATUS_UNSUCCESSFUL; 2274 } 2275 2276 status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\srvsvc", 2277 &ndr_table_srvsvc, &p); 2278 if (!NT_STATUS_IS_OK(status)) { 2279 d_printf("(%s) could not bind to srvsvc pipe: %s\n", 2280 __location__, nt_errstr(status)); 2281 talloc_free(tmp_ctx); 2282 return NT_STATUS_UNSUCCESSFUL; 2283 } 2284 2285#if 0 2286 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT; 2287#endif 2288 2289 r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s", 2290 dcerpc_server_name(p)); 2291 r.in.share_name = sharename; 2292 r.in.level = 1501; 2293 i.sd = sd; 2294 info.info1501 = &i; 2295 r.in.info = &info; 2296 r.in.parm_error = &error; 2297 2298 status = dcerpc_srvsvc_NetShareSetInfo(p, tmp_ctx, &r); 2299 if (!NT_STATUS_IS_OK(status)) { 2300 d_printf("srvsvc_NetShareSetInfo failed: %s\n", 2301 nt_errstr(status)); 2302 } 2303 2304 talloc_free(tmp_ctx); 2305 return status; 2306} 2307 2308bool try_tcon(TALLOC_CTX *mem_ctx, 2309 struct loadparm_context *lp_ctx, 2310 struct security_descriptor *orig_sd, 2311 struct smbcli_session *session, 2312 const char *sharename, const struct dom_sid *user_sid, 2313 unsigned int access_mask, NTSTATUS expected_tcon, 2314 NTSTATUS expected_mkdir) 2315{ 2316 TALLOC_CTX *tmp_ctx; 2317 struct smbcli_tree *rmdir_tree, *tree; 2318 struct dom_sid *domain_sid; 2319 uint32_t rid; 2320 struct security_descriptor *sd; 2321 NTSTATUS status; 2322 bool ret = true; 2323 2324 if (!(tmp_ctx = talloc_new(mem_ctx))) { 2325 d_printf("talloc_new failed\n"); 2326 return false; 2327 } 2328 2329 status = secondary_tcon(tmp_ctx, session, sharename, &rmdir_tree); 2330 if (!NT_STATUS_IS_OK(status)) { 2331 d_printf("first tcon to delete dir failed\n"); 2332 talloc_free(tmp_ctx); 2333 return false; 2334 } 2335 2336 smbcli_rmdir(rmdir_tree, "sharesec_testdir"); 2337 2338 if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid, 2339 &domain_sid, &rid))) { 2340 d_printf("dom_sid_split_rid failed\n"); 2341 talloc_free(tmp_ctx); 2342 return false; 2343 } 2344 2345 sd = security_descriptor_dacl_create( 2346 tmp_ctx, 0, "S-1-5-32-544", 2347 dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid, 2348 DOMAIN_RID_USERS)), 2349 dom_sid_string(mem_ctx, user_sid), 2350 SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL); 2351 if (sd == NULL) { 2352 d_printf("security_descriptor_dacl_create failed\n"); 2353 talloc_free(tmp_ctx); 2354 return false; 2355 } 2356 2357 status = set_sharesec(mem_ctx, lp_ctx, session, sharename, sd); 2358 if (!NT_STATUS_IS_OK(status)) { 2359 d_printf("custom set_sharesec failed: %s\n", 2360 nt_errstr(status)); 2361 talloc_free(tmp_ctx); 2362 return false; 2363 } 2364 2365 status = secondary_tcon(tmp_ctx, session, sharename, &tree); 2366 if (!NT_STATUS_EQUAL(status, expected_tcon)) { 2367 d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon), 2368 nt_errstr(status)); 2369 ret = false; 2370 goto done; 2371 } 2372 2373 if (!NT_STATUS_IS_OK(status)) { 2374 /* An expected non-access, no point in trying to write */ 2375 goto done; 2376 } 2377 2378 status = smbcli_mkdir(tree, "sharesec_testdir"); 2379 if (!NT_STATUS_EQUAL(status, expected_mkdir)) { 2380 d_printf("(%s) Expected %s, got %s\n", __location__, 2381 nt_errstr(expected_mkdir), nt_errstr(status)); 2382 ret = false; 2383 } 2384 2385 done: 2386 smbcli_rmdir(rmdir_tree, "sharesec_testdir"); 2387 2388 status = set_sharesec(mem_ctx, lp_ctx, session, sharename, orig_sd); 2389 if (!NT_STATUS_IS_OK(status)) { 2390 d_printf("custom set_sharesec failed: %s\n", 2391 nt_errstr(status)); 2392 talloc_free(tmp_ctx); 2393 return false; 2394 } 2395 2396 talloc_free(tmp_ctx); 2397 return ret; 2398} 2399 2400bool torture_samba3_rpc_sharesec(struct torture_context *torture) 2401{ 2402 TALLOC_CTX *mem_ctx; 2403 bool ret = true; 2404 struct smbcli_state *cli; 2405 struct security_descriptor *sd; 2406 struct dom_sid *user_sid; 2407 2408 if (!(mem_ctx = talloc_new(torture))) { 2409 return false; 2410 } 2411 2412 if (!(torture_open_connection_share( 2413 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL), 2414 "IPC$", torture->ev))) { 2415 d_printf("IPC$ connection failed\n"); 2416 talloc_free(mem_ctx); 2417 return false; 2418 } 2419 2420 if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) { 2421 d_printf("whoami failed\n"); 2422 talloc_free(mem_ctx); 2423 return false; 2424 } 2425 2426 sd = get_sharesec(mem_ctx, torture->lp_ctx, cli->session, 2427 torture_setting_string(torture, "share", NULL)); 2428 2429 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session, 2430 torture_setting_string(torture, "share", NULL), 2431 user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK); 2432 2433 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session, 2434 torture_setting_string(torture, "share", NULL), 2435 user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK, 2436 NT_STATUS_MEDIA_WRITE_PROTECTED); 2437 2438 ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session, 2439 torture_setting_string(torture, "share", NULL), 2440 user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK); 2441 2442 talloc_free(mem_ctx); 2443 return ret; 2444} 2445 2446bool torture_samba3_rpc_lsa(struct torture_context *torture) 2447{ 2448 TALLOC_CTX *mem_ctx; 2449 bool ret = true; 2450 struct smbcli_state *cli; 2451 struct dcerpc_pipe *p; 2452 struct policy_handle lsa_handle; 2453 NTSTATUS status; 2454 struct dom_sid *domain_sid; 2455 2456 if (!(mem_ctx = talloc_new(torture))) { 2457 return false; 2458 } 2459 2460 if (!(torture_open_connection_share( 2461 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL), 2462 "IPC$", torture->ev))) { 2463 d_printf("IPC$ connection failed\n"); 2464 talloc_free(mem_ctx); 2465 return false; 2466 } 2467 2468 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\lsarpc", 2469 &ndr_table_lsarpc, &p); 2470 if (!NT_STATUS_IS_OK(status)) { 2471 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__, 2472 nt_errstr(status)); 2473 talloc_free(mem_ctx); 2474 return false; 2475 } 2476 2477 { 2478 struct lsa_ObjectAttribute attr; 2479 struct lsa_OpenPolicy2 o; 2480 o.in.system_name = talloc_asprintf( 2481 mem_ctx, "\\\\%s", dcerpc_server_name(p)); 2482 ZERO_STRUCT(attr); 2483 o.in.attr = &attr; 2484 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 2485 o.out.handle = &lsa_handle; 2486 status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &o); 2487 if (!NT_STATUS_IS_OK(status)) { 2488 d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n", 2489 __location__, nt_errstr(status)); 2490 talloc_free(mem_ctx); 2491 return false; 2492 } 2493 } 2494 2495#if 0 2496 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT; 2497#endif 2498 2499 { 2500 int i; 2501 int levels[] = { 2,3,5,6 }; 2502 2503 for (i=0; i<ARRAY_SIZE(levels); i++) { 2504 struct lsa_QueryInfoPolicy r; 2505 union lsa_PolicyInformation *info = NULL; 2506 r.in.handle = &lsa_handle; 2507 r.in.level = levels[i]; 2508 r.out.info = &info; 2509 status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r); 2510 if (!NT_STATUS_IS_OK(status)) { 2511 d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d " 2512 "failed: %s\n", __location__, 2513 levels[i], nt_errstr(status)); 2514 talloc_free(mem_ctx); 2515 return false; 2516 } 2517 if (levels[i] == 5) { 2518 domain_sid = info->account_domain.sid; 2519 } 2520 } 2521 } 2522 2523 return ret; 2524} 2525 2526static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree, 2527 struct smb_iconv_convenience *iconv_convenience, 2528 char **name) 2529{ 2530 struct rap_WserverGetInfo r; 2531 NTSTATUS status; 2532 char servername[17]; 2533 2534 r.in.level = 0; 2535 r.in.bufsize = 0xffff; 2536 2537 status = smbcli_rap_netservergetinfo(tree, iconv_convenience, mem_ctx, &r); 2538 if (!NT_STATUS_IS_OK(status)) { 2539 return status; 2540 } 2541 2542 memcpy(servername, r.out.info.info0.name, 16); 2543 servername[16] = '\0'; 2544 2545 if (!pull_ascii_talloc(mem_ctx, name, servername, NULL)) { 2546 return NT_STATUS_NO_MEMORY; 2547 } 2548 2549 return NT_STATUS_OK; 2550} 2551 2552 2553static NTSTATUS find_printers(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx, 2554 struct smbcli_tree *tree, 2555 const char ***printers, int *num_printers) 2556{ 2557 TALLOC_CTX *mem_ctx; 2558 NTSTATUS status; 2559 struct dcerpc_pipe *p; 2560 struct srvsvc_NetShareEnum r; 2561 struct srvsvc_NetShareInfoCtr info_ctr; 2562 struct srvsvc_NetShareCtr1 c1_in; 2563 struct srvsvc_NetShareCtr1 *c1; 2564 uint32_t totalentries = 0; 2565 int i; 2566 2567 mem_ctx = talloc_new(ctx); 2568 if (mem_ctx == NULL) { 2569 return NT_STATUS_NO_MEMORY; 2570 } 2571 2572 status = pipe_bind_smb(mem_ctx, lp_ctx, 2573 tree, "\\srvsvc", &ndr_table_srvsvc, 2574 &p); 2575 if (!NT_STATUS_IS_OK(status)) { 2576 d_printf("could not bind to srvsvc pipe\n"); 2577 talloc_free(mem_ctx); 2578 return status; 2579 } 2580 2581 ZERO_STRUCT(c1_in); 2582 info_ctr.level = 1; 2583 info_ctr.ctr.ctr1 = &c1_in; 2584 2585 r.in.server_unc = talloc_asprintf( 2586 mem_ctx, "\\\\%s", dcerpc_server_name(p)); 2587 r.in.info_ctr = &info_ctr; 2588 r.in.max_buffer = (uint32_t)-1; 2589 r.in.resume_handle = NULL; 2590 r.out.totalentries = &totalentries; 2591 r.out.info_ctr = &info_ctr; 2592 2593 status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r); 2594 if (!NT_STATUS_IS_OK(status)) { 2595 d_printf("NetShareEnum level %u failed - %s\n", 2596 info_ctr.level, nt_errstr(status)); 2597 talloc_free(mem_ctx); 2598 return status; 2599 } 2600 2601 *printers = NULL; 2602 *num_printers = 0; 2603 c1 = r.out.info_ctr->ctr.ctr1; 2604 for (i=0; i<c1->count; i++) { 2605 if (c1->array[i].type != STYPE_PRINTQ) { 2606 continue; 2607 } 2608 if (!add_string_to_array(ctx, c1->array[i].name, 2609 printers, num_printers)) { 2610 talloc_free(ctx); 2611 return NT_STATUS_NO_MEMORY; 2612 } 2613 } 2614 2615 talloc_free(mem_ctx); 2616 return NT_STATUS_OK; 2617} 2618 2619static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe, 2620 const char *servername, int level, int *num_printers) 2621{ 2622 struct spoolss_EnumPrinters r; 2623 NTSTATUS status; 2624 DATA_BLOB blob; 2625 uint32_t needed; 2626 uint32_t count; 2627 union spoolss_PrinterInfo *info; 2628 2629 r.in.flags = PRINTER_ENUM_LOCAL; 2630 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername); 2631 r.in.level = level; 2632 r.in.buffer = NULL; 2633 r.in.offered = 0; 2634 r.out.needed = &needed; 2635 r.out.count = &count; 2636 r.out.info = &info; 2637 2638 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r); 2639 if (!NT_STATUS_IS_OK(status)) { 2640 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n", 2641 __location__, nt_errstr(status)); 2642 return false; 2643 } 2644 2645 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { 2646 d_printf("(%s) EnumPrinters unexpected return code %s, should " 2647 "be WERR_INSUFFICIENT_BUFFER\n", __location__, 2648 win_errstr(r.out.result)); 2649 return false; 2650 } 2651 2652 blob = data_blob_talloc_zero(mem_ctx, needed); 2653 if (blob.data == NULL) { 2654 d_printf("(%s) data_blob_talloc failed\n", __location__); 2655 return false; 2656 } 2657 2658 r.in.buffer = &blob; 2659 r.in.offered = needed; 2660 2661 status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r); 2662 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 2663 d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s, " 2664 "%s\n", __location__, nt_errstr(status), 2665 win_errstr(r.out.result)); 2666 return false; 2667 } 2668 2669 *num_printers = count; 2670 2671 return true; 2672} 2673 2674static NTSTATUS getprinterinfo(TALLOC_CTX *ctx, struct dcerpc_pipe *pipe, 2675 struct policy_handle *handle, int level, 2676 union spoolss_PrinterInfo **res) 2677{ 2678 TALLOC_CTX *mem_ctx; 2679 struct spoolss_GetPrinter r; 2680 DATA_BLOB blob; 2681 NTSTATUS status; 2682 uint32_t needed; 2683 2684 mem_ctx = talloc_new(ctx); 2685 if (mem_ctx == NULL) { 2686 return NT_STATUS_NO_MEMORY; 2687 } 2688 2689 r.in.handle = handle; 2690 r.in.level = level; 2691 r.in.buffer = NULL; 2692 r.in.offered = 0; 2693 r.out.needed = &needed; 2694 2695 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r); 2696 if (!NT_STATUS_IS_OK(status)) { 2697 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s\n", 2698 __location__, nt_errstr(status)); 2699 talloc_free(mem_ctx); 2700 return status; 2701 } 2702 2703 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { 2704 printf("GetPrinter unexpected return code %s, should " 2705 "be WERR_INSUFFICIENT_BUFFER\n", 2706 win_errstr(r.out.result)); 2707 talloc_free(mem_ctx); 2708 return NT_STATUS_UNSUCCESSFUL; 2709 } 2710 2711 r.in.handle = handle; 2712 r.in.level = level; 2713 blob = data_blob_talloc(mem_ctx, NULL, needed); 2714 if (blob.data == NULL) { 2715 talloc_free(mem_ctx); 2716 return NT_STATUS_NO_MEMORY; 2717 } 2718 memset(blob.data, 0, blob.length); 2719 r.in.buffer = &blob; 2720 r.in.offered = needed; 2721 2722 status = dcerpc_spoolss_GetPrinter(pipe, mem_ctx, &r); 2723 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 2724 d_printf("(%s) dcerpc_spoolss_GetPrinter failed: %s, " 2725 "%s\n", __location__, nt_errstr(status), 2726 win_errstr(r.out.result)); 2727 talloc_free(mem_ctx); 2728 return NT_STATUS_IS_OK(status) ? 2729 NT_STATUS_UNSUCCESSFUL : status; 2730 } 2731 2732 if (res != NULL) { 2733 *res = talloc_steal(ctx, r.out.info); 2734 } 2735 2736 talloc_free(mem_ctx); 2737 return NT_STATUS_OK; 2738} 2739 2740bool torture_samba3_rpc_spoolss(struct torture_context *torture) 2741{ 2742 TALLOC_CTX *mem_ctx; 2743 bool ret = true; 2744 struct smbcli_state *cli; 2745 struct dcerpc_pipe *p; 2746 NTSTATUS status; 2747 struct policy_handle server_handle, printer_handle; 2748 const char **printers; 2749 int num_printers; 2750 struct spoolss_UserLevel1 userlevel1; 2751 char *servername; 2752 2753 if (!(mem_ctx = talloc_new(torture))) { 2754 return false; 2755 } 2756 2757 if (!(torture_open_connection_share( 2758 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL), 2759 "IPC$", torture->ev))) { 2760 d_printf("IPC$ connection failed\n"); 2761 talloc_free(mem_ctx); 2762 return false; 2763 } 2764 2765 status = get_servername(mem_ctx, cli->tree, lp_iconv_convenience(torture->lp_ctx), &servername); 2766 if (!NT_STATUS_IS_OK(status)) { 2767 d_fprintf(stderr, "(%s) get_servername returned %s\n", 2768 __location__, nt_errstr(status)); 2769 talloc_free(mem_ctx); 2770 return false; 2771 } 2772 2773 if (!NT_STATUS_IS_OK(find_printers(mem_ctx, torture->lp_ctx, cli->tree, 2774 &printers, &num_printers))) { 2775 talloc_free(mem_ctx); 2776 return false; 2777 } 2778 2779 if (num_printers == 0) { 2780 d_printf("Did not find printers\n"); 2781 talloc_free(mem_ctx); 2782 return true; 2783 } 2784 2785 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\spoolss", 2786 &ndr_table_spoolss, &p); 2787 if (!NT_STATUS_IS_OK(status)) { 2788 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__, 2789 nt_errstr(status)); 2790 talloc_free(mem_ctx); 2791 return false; 2792 } 2793 2794 ZERO_STRUCT(userlevel1); 2795 userlevel1.client = talloc_asprintf( 2796 mem_ctx, "\\\\%s", lp_netbios_name(torture->lp_ctx)); 2797 userlevel1.user = cli_credentials_get_username(cmdline_credentials); 2798 userlevel1.build = 2600; 2799 userlevel1.major = 3; 2800 userlevel1.minor = 0; 2801 userlevel1.processor = 0; 2802 2803 { 2804 struct spoolss_OpenPrinterEx r; 2805 2806 ZERO_STRUCT(r); 2807 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s", 2808 servername); 2809 r.in.datatype = NULL; 2810 r.in.access_mask = 0; 2811 r.in.level = 1; 2812 r.in.userlevel.level1 = &userlevel1; 2813 r.out.handle = &server_handle; 2814 2815 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r); 2816 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 2817 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: " 2818 "%s, %s\n", __location__, nt_errstr(status), 2819 win_errstr(r.out.result)); 2820 talloc_free(mem_ctx); 2821 return false; 2822 } 2823 } 2824 2825 { 2826 struct spoolss_ClosePrinter r; 2827 2828 r.in.handle = &server_handle; 2829 r.out.handle = &server_handle; 2830 2831 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r); 2832 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 2833 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: " 2834 "%s, %s\n", __location__, nt_errstr(status), 2835 win_errstr(r.out.result)); 2836 talloc_free(mem_ctx); 2837 return false; 2838 } 2839 } 2840 2841 { 2842 struct spoolss_OpenPrinterEx r; 2843 2844 ZERO_STRUCT(r); 2845 r.in.printername = talloc_asprintf( 2846 mem_ctx, "\\\\%s\\%s", servername, printers[0]); 2847 r.in.datatype = NULL; 2848 r.in.access_mask = 0; 2849 r.in.level = 1; 2850 r.in.userlevel.level1 = &userlevel1; 2851 r.out.handle = &printer_handle; 2852 2853 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r); 2854 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 2855 d_printf("(%s) dcerpc_spoolss_OpenPrinterEx failed: " 2856 "%s, %s\n", __location__, nt_errstr(status), 2857 win_errstr(r.out.result)); 2858 talloc_free(mem_ctx); 2859 return false; 2860 } 2861 } 2862 2863 { 2864 int i; 2865 2866 for (i=0; i<8; i++) { 2867 status = getprinterinfo(mem_ctx, p, &printer_handle, 2868 i, NULL); 2869 if (!NT_STATUS_IS_OK(status)) { 2870 d_printf("(%s) getprinterinfo %d failed: %s\n", 2871 __location__, i, nt_errstr(status)); 2872 ret = false; 2873 } 2874 } 2875 } 2876 2877 { 2878 struct spoolss_ClosePrinter r; 2879 2880 r.in.handle = &printer_handle; 2881 r.out.handle = &printer_handle; 2882 2883 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r); 2884 if (!NT_STATUS_IS_OK(status)) { 2885 d_printf("(%s) dcerpc_spoolss_ClosePrinter failed: " 2886 "%s\n", __location__, nt_errstr(status)); 2887 talloc_free(mem_ctx); 2888 return false; 2889 } 2890 } 2891 2892 { 2893 int num_enumerated; 2894 if (!enumprinters(mem_ctx, p, servername, 1, 2895 &num_enumerated)) { 2896 d_printf("(%s) enumprinters failed\n", __location__); 2897 talloc_free(mem_ctx); 2898 return false; 2899 } 2900 if (num_printers != num_enumerated) { 2901 d_printf("(%s) netshareenum gave %d printers, " 2902 "enumprinters lvl 1 gave %d\n", __location__, 2903 num_printers, num_enumerated); 2904 talloc_free(mem_ctx); 2905 return false; 2906 } 2907 } 2908 2909 { 2910 int num_enumerated; 2911 if (!enumprinters(mem_ctx, p, servername, 2, 2912 &num_enumerated)) { 2913 d_printf("(%s) enumprinters failed\n", __location__); 2914 talloc_free(mem_ctx); 2915 return false; 2916 } 2917 if (num_printers != num_enumerated) { 2918 d_printf("(%s) netshareenum gave %d printers, " 2919 "enumprinters lvl 2 gave %d\n", __location__, 2920 num_printers, num_enumerated); 2921 talloc_free(mem_ctx); 2922 return false; 2923 } 2924 } 2925 2926 talloc_free(mem_ctx); 2927 2928 return ret; 2929} 2930 2931bool torture_samba3_rpc_wkssvc(struct torture_context *torture) 2932{ 2933 TALLOC_CTX *mem_ctx; 2934 struct smbcli_state *cli; 2935 struct dcerpc_pipe *p; 2936 NTSTATUS status; 2937 char *servername; 2938 2939 if (!(mem_ctx = talloc_new(torture))) { 2940 return false; 2941 } 2942 2943 if (!(torture_open_connection_share( 2944 mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL), 2945 "IPC$", torture->ev))) { 2946 d_printf("IPC$ connection failed\n"); 2947 talloc_free(mem_ctx); 2948 return false; 2949 } 2950 2951 status = get_servername(mem_ctx, cli->tree, lp_iconv_convenience(torture->lp_ctx), &servername); 2952 if (!NT_STATUS_IS_OK(status)) { 2953 d_fprintf(stderr, "(%s) get_servername returned %s\n", 2954 __location__, nt_errstr(status)); 2955 talloc_free(mem_ctx); 2956 return false; 2957 } 2958 2959 status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\wkssvc", 2960 &ndr_table_wkssvc, &p); 2961 if (!NT_STATUS_IS_OK(status)) { 2962 d_printf("(%s) pipe_bind_smb failed: %s\n", __location__, 2963 nt_errstr(status)); 2964 talloc_free(mem_ctx); 2965 return false; 2966 } 2967 2968 { 2969 struct wkssvc_NetWkstaInfo100 wks100; 2970 union wkssvc_NetWkstaInfo info; 2971 struct wkssvc_NetWkstaGetInfo r; 2972 2973 r.in.server_name = "\\foo"; 2974 r.in.level = 100; 2975 info.info100 = &wks100; 2976 r.out.info = &info; 2977 2978 status = dcerpc_wkssvc_NetWkstaGetInfo(p, mem_ctx, &r); 2979 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 2980 d_printf("(%s) dcerpc_wkssvc_NetWksGetInfo failed: " 2981 "%s, %s\n", __location__, nt_errstr(status), 2982 win_errstr(r.out.result)); 2983 talloc_free(mem_ctx); 2984 return false; 2985 } 2986 2987 if (strcmp(servername, 2988 r.out.info->info100->server_name) != 0) { 2989 d_printf("(%s) servername inconsistency: RAP=%s, " 2990 "dcerpc_wkssvc_NetWksGetInfo=%s", 2991 __location__, servername, 2992 r.out.info->info100->server_name); 2993 talloc_free(mem_ctx); 2994 return false; 2995 } 2996 } 2997 2998 talloc_free(mem_ctx); 2999 return true; 3000} 3001 3002static NTSTATUS winreg_close(struct dcerpc_pipe *p, 3003 struct policy_handle *handle) 3004{ 3005 struct winreg_CloseKey c; 3006 NTSTATUS status; 3007 TALLOC_CTX *mem_ctx; 3008 3009 c.in.handle = c.out.handle = handle; 3010 3011 if (!(mem_ctx = talloc_new(p))) { 3012 return NT_STATUS_NO_MEMORY; 3013 } 3014 3015 status = dcerpc_winreg_CloseKey(p, mem_ctx, &c); 3016 talloc_free(mem_ctx); 3017 3018 if (!NT_STATUS_IS_OK(status)) { 3019 return status; 3020 } 3021 3022 if (!W_ERROR_IS_OK(c.out.result)) { 3023 return werror_to_ntstatus(c.out.result); 3024 } 3025 3026 return NT_STATUS_OK; 3027} 3028 3029static NTSTATUS enumvalues(struct dcerpc_pipe *p, struct policy_handle *handle, 3030 TALLOC_CTX *mem_ctx) 3031{ 3032 uint32_t enum_index = 0; 3033 3034 while (1) { 3035 struct winreg_EnumValue r; 3036 struct winreg_ValNameBuf name; 3037 enum winreg_Type type = 0; 3038 uint8_t buf8[1024]; 3039 NTSTATUS status; 3040 uint32_t size, length; 3041 3042 r.in.handle = handle; 3043 r.in.enum_index = enum_index; 3044 name.name = ""; 3045 name.size = 1024; 3046 r.in.name = r.out.name = &name; 3047 size = 1024; 3048 length = 5; 3049 r.in.type = &type; 3050 r.in.value = buf8; 3051 r.in.size = &size; 3052 r.in.length = &length; 3053 3054 status = dcerpc_winreg_EnumValue(p, mem_ctx, &r); 3055 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 3056 return NT_STATUS_OK; 3057 } 3058 enum_index += 1; 3059 } 3060} 3061 3062static NTSTATUS enumkeys(struct dcerpc_pipe *p, struct policy_handle *handle, 3063 TALLOC_CTX *mem_ctx, int depth) 3064{ 3065 struct winreg_EnumKey r; 3066 struct winreg_StringBuf kclass, name; 3067 NTSTATUS status; 3068 NTTIME t = 0; 3069 3070 if (depth <= 0) { 3071 return NT_STATUS_OK; 3072 } 3073 3074 kclass.name = ""; 3075 kclass.size = 1024; 3076 3077 r.in.handle = handle; 3078 r.in.enum_index = 0; 3079 r.in.name = &name; 3080 r.in.keyclass = &kclass; 3081 r.out.name = &name; 3082 r.in.last_changed_time = &t; 3083 3084 do { 3085 TALLOC_CTX *tmp_ctx; 3086 struct winreg_OpenKey o; 3087 struct policy_handle key_handle; 3088 int i; 3089 3090 if (!(tmp_ctx = talloc_new(mem_ctx))) { 3091 return NT_STATUS_NO_MEMORY; 3092 } 3093 3094 name.name = NULL; 3095 name.size = 1024; 3096 3097 status = dcerpc_winreg_EnumKey(p, tmp_ctx, &r); 3098 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 3099 /* We're done enumerating */ 3100 talloc_free(tmp_ctx); 3101 return NT_STATUS_OK; 3102 } 3103 3104 for (i=0; i<10-depth; i++) 3105 printf(" "); 3106 printf("%s\n", r.out.name->name); 3107 3108 3109 o.in.parent_handle = handle; 3110 o.in.keyname.name = r.out.name->name; 3111 o.in.unknown = 0; 3112 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 3113 o.out.handle = &key_handle; 3114 3115 status = dcerpc_winreg_OpenKey(p, tmp_ctx, &o); 3116 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(o.out.result)) { 3117 enumkeys(p, &key_handle, tmp_ctx, depth-1); 3118 enumvalues(p, &key_handle, tmp_ctx); 3119 status = winreg_close(p, &key_handle); 3120 if (!NT_STATUS_IS_OK(status)) { 3121 return status; 3122 } 3123 } 3124 3125 talloc_free(tmp_ctx); 3126 3127 r.in.enum_index += 1; 3128 } while(true); 3129 3130 return NT_STATUS_OK; 3131} 3132 3133typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *); 3134 3135static bool test_Open3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 3136 const char *name, winreg_open_fn open_fn) 3137{ 3138 struct policy_handle handle; 3139 struct winreg_OpenHKLM r; 3140 NTSTATUS status; 3141 3142 r.in.system_name = 0; 3143 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 3144 r.out.handle = &handle; 3145 3146 status = open_fn(p, mem_ctx, &r); 3147 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 3148 d_printf("(%s) %s failed: %s, %s\n", __location__, name, 3149 nt_errstr(status), win_errstr(r.out.result)); 3150 return false; 3151 } 3152 3153 enumkeys(p, &handle, mem_ctx, 4); 3154 3155 status = winreg_close(p, &handle); 3156 if (!NT_STATUS_IS_OK(status)) { 3157 d_printf("(%s) dcerpc_CloseKey failed: %s\n", 3158 __location__, nt_errstr(status)); 3159 return false; 3160 } 3161 3162 return true; 3163} 3164 3165bool torture_samba3_rpc_winreg(struct torture_context *torture) 3166{ 3167 NTSTATUS status; 3168 struct dcerpc_pipe *p; 3169 TALLOC_CTX *mem_ctx; 3170 bool ret = true; 3171 struct { 3172 const char *name; 3173 winreg_open_fn fn; 3174 } open_fns[] = { 3175 {"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM }, 3176 {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU }, 3177 {"OpenHKPD", (winreg_open_fn)dcerpc_winreg_OpenHKPD }, 3178 {"OpenHKPT", (winreg_open_fn)dcerpc_winreg_OpenHKPT }, 3179 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR }}; 3180#if 0 3181 int i; 3182#endif 3183 3184 mem_ctx = talloc_init("torture_rpc_winreg"); 3185 3186 status = torture_rpc_connection(torture, &p, &ndr_table_winreg); 3187 3188 if (!NT_STATUS_IS_OK(status)) { 3189 talloc_free(mem_ctx); 3190 return false; 3191 } 3192 3193#if 1 3194 ret = test_Open3(p, mem_ctx, open_fns[0].name, open_fns[0].fn); 3195#else 3196 for (i = 0; i < ARRAY_SIZE(open_fns); i++) { 3197 if (!test_Open3(p, mem_ctx, open_fns[i].name, open_fns[i].fn)) 3198 ret = false; 3199 } 3200#endif 3201 3202 talloc_free(mem_ctx); 3203 3204 return ret; 3205} 3206 3207static NTSTATUS get_shareinfo(TALLOC_CTX *mem_ctx, 3208 struct loadparm_context *lp_ctx, 3209 struct smbcli_state *cli, 3210 const char *share, 3211 struct srvsvc_NetShareInfo502 **info502) 3212{ 3213 struct smbcli_tree *ipc; 3214 struct dcerpc_pipe *p; 3215 struct srvsvc_NetShareGetInfo r; 3216 union srvsvc_NetShareInfo info; 3217 NTSTATUS status; 3218 3219 if (!(p = dcerpc_pipe_init(cli, 3220 cli->transport->socket->event.ctx, 3221 lp_iconv_convenience(lp_ctx)))) { 3222 status = NT_STATUS_NO_MEMORY; 3223 goto fail; 3224 } 3225 3226 status = secondary_tcon(p, cli->session, "IPC$", &ipc); 3227 if (!NT_STATUS_IS_OK(status)) { 3228 goto fail; 3229 } 3230 3231 status = dcerpc_pipe_open_smb(p, ipc, "\\pipe\\srvsvc"); 3232 if (!NT_STATUS_IS_OK(status)) { 3233 d_printf("dcerpc_pipe_open_smb failed: %s\n", 3234 nt_errstr(status)); 3235 goto fail; 3236 } 3237 3238 status = dcerpc_bind_auth_none(p, &ndr_table_srvsvc); 3239 if (!NT_STATUS_IS_OK(status)) { 3240 d_printf("dcerpc_bind_auth_none failed: %s\n", 3241 nt_errstr(status)); 3242 goto fail; 3243 } 3244 3245 r.in.server_unc = talloc_asprintf(mem_ctx, "\\\\%s", 3246 dcerpc_server_name(p)); 3247 r.in.share_name = share; 3248 r.in.level = 502; 3249 r.out.info = &info; 3250 3251 status = dcerpc_srvsvc_NetShareGetInfo(p, p, &r); 3252 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 3253 d_printf("(%s) srvsvc_NetShareGetInfo failed: %s, %s\n", __location__, 3254 nt_errstr(status), win_errstr(r.out.result)); 3255 status = NT_STATUS_IS_OK(status) ? werror_to_ntstatus(r.out.result) : status; 3256 goto fail; 3257 } 3258 3259 *info502 = talloc_move(mem_ctx, &info.info502); 3260 return NT_STATUS_OK; 3261 3262fail: 3263 talloc_free(p); 3264 return status; 3265} 3266 3267/* 3268 * Get us a handle on HKLM\ 3269 */ 3270 3271static NTSTATUS get_hklm_handle(TALLOC_CTX *mem_ctx, 3272 struct smbcli_state *cli, 3273 struct smb_iconv_convenience *iconv_convenience, 3274 struct dcerpc_pipe **pipe_p, 3275 struct policy_handle **handle) 3276{ 3277 struct smbcli_tree *ipc; 3278 struct dcerpc_pipe *p; 3279 struct winreg_OpenHKLM r; 3280 NTSTATUS status; 3281 struct policy_handle *result; 3282 3283 result = talloc(mem_ctx, struct policy_handle); 3284 3285 if (result == NULL) { 3286 return NT_STATUS_NO_MEMORY; 3287 } 3288 3289 if (!(p = dcerpc_pipe_init(result, 3290 cli->transport->socket->event.ctx, 3291 iconv_convenience))) { 3292 status = NT_STATUS_NO_MEMORY; 3293 goto fail; 3294 } 3295 3296 status = secondary_tcon(p, cli->session, "IPC$", &ipc); 3297 if (!NT_STATUS_IS_OK(status)) { 3298 goto fail; 3299 } 3300 3301 status = dcerpc_pipe_open_smb(p, ipc, "\\winreg"); 3302 if (!NT_STATUS_IS_OK(status)) { 3303 d_printf("dcerpc_pipe_open_smb failed: %s\n", 3304 nt_errstr(status)); 3305 goto fail; 3306 } 3307 3308 status = dcerpc_bind_auth_none(p, &ndr_table_winreg); 3309 if (!NT_STATUS_IS_OK(status)) { 3310 d_printf("dcerpc_bind_auth_none failed: %s\n", 3311 nt_errstr(status)); 3312 goto fail; 3313 } 3314 3315 r.in.system_name = 0; 3316 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 3317 r.out.handle = result; 3318 3319 status = dcerpc_winreg_OpenHKLM(p, p, &r); 3320 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) { 3321 d_printf("(%s) OpenHKLM failed: %s, %s\n", __location__, 3322 nt_errstr(status), win_errstr(r.out.result)); 3323 status = NT_STATUS_IS_OK(status) ? werror_to_ntstatus(r.out.result) : status; 3324 goto fail; 3325 } 3326 3327 *pipe_p = p; 3328 *handle = result; 3329 return NT_STATUS_OK; 3330 3331 fail: 3332 talloc_free(result); 3333 return status; 3334} 3335 3336static NTSTATUS torture_samba3_createshare(struct smbcli_state *cli, 3337 struct smb_iconv_convenience *iconv_convenience, 3338 const char *sharename) 3339{ 3340 struct dcerpc_pipe *p; 3341 struct policy_handle *hklm = NULL; 3342 struct policy_handle new_handle; 3343 struct winreg_CreateKey c; 3344 struct winreg_CloseKey cl; 3345 enum winreg_CreateAction action_taken; 3346 NTSTATUS status; 3347 TALLOC_CTX *mem_ctx; 3348 3349 mem_ctx = talloc_new(cli); 3350 NT_STATUS_HAVE_NO_MEMORY(mem_ctx); 3351 3352 status = get_hklm_handle(mem_ctx, cli, iconv_convenience, &p, &hklm); 3353 if (!NT_STATUS_IS_OK(status)) { 3354 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status)); 3355 goto fail; 3356 } 3357 3358 c.in.handle = hklm; 3359 c.in.name.name = talloc_asprintf( 3360 mem_ctx, "software\\samba\\smbconf\\%s", sharename); 3361 if (c.in.name.name == NULL) { 3362 d_printf("talloc_asprintf failed\n"); 3363 status = NT_STATUS_NO_MEMORY; 3364 goto fail; 3365 } 3366 c.in.keyclass.name = ""; 3367 c.in.options = 0; 3368 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 3369 c.in.secdesc = NULL; 3370 c.in.action_taken = &action_taken; 3371 c.out.new_handle = &new_handle; 3372 c.out.action_taken = &action_taken; 3373 3374 status = dcerpc_winreg_CreateKey(p, p, &c); 3375 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(c.out.result)) { 3376 d_printf("(%s) OpenKey failed: %s, %s\n", __location__, 3377 nt_errstr(status), win_errstr(c.out.result)); 3378 status = NT_STATUS_IS_OK(status) ? werror_to_ntstatus(c.out.result) : status; 3379 goto fail; 3380 } 3381 3382 cl.in.handle = &new_handle; 3383 cl.out.handle = &new_handle; 3384 status = dcerpc_winreg_CloseKey(p, p, &cl); 3385 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(cl.out.result)) { 3386 d_printf("(%s) OpenKey failed: %s, %s\n", __location__, 3387 nt_errstr(status), win_errstr(cl.out.result)); 3388 status = NT_STATUS_IS_OK(status) ? werror_to_ntstatus(cl.out.result) : status; 3389 goto fail; 3390 } 3391 3392 3393fail: 3394 talloc_free(mem_ctx); 3395 return status; 3396} 3397 3398static NTSTATUS torture_samba3_deleteshare(struct torture_context *torture, 3399 struct smbcli_state *cli, 3400 const char *sharename) 3401{ 3402 struct dcerpc_pipe *p; 3403 struct policy_handle *hklm = NULL; 3404 struct winreg_DeleteKey d; 3405 NTSTATUS status; 3406 TALLOC_CTX *mem_ctx; 3407 3408 mem_ctx = talloc_new(cli); 3409 NT_STATUS_HAVE_NO_MEMORY(mem_ctx); 3410 3411 status = get_hklm_handle(cli, cli, lp_iconv_convenience(torture->lp_ctx), 3412 &p, &hklm); 3413 if (!NT_STATUS_IS_OK(status)) { 3414 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status)); 3415 goto fail; 3416 } 3417 3418 d.in.handle = hklm; 3419 d.in.key.name = talloc_asprintf( 3420 mem_ctx, "software\\samba\\smbconf\\%s", sharename); 3421 if (d.in.key.name == NULL) { 3422 d_printf("talloc_asprintf failed\n"); 3423 status = NT_STATUS_NO_MEMORY; 3424 goto fail; 3425 } 3426 status = dcerpc_winreg_DeleteKey(p, p, &d); 3427 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(d.out.result)) { 3428 d_printf("(%s) OpenKey failed: %s, %s\n", __location__, 3429 nt_errstr(status), win_errstr(d.out.result)); 3430 status = NT_STATUS_IS_OK(status) ? werror_to_ntstatus(d.out.result) : status; 3431 goto fail; 3432 } 3433 3434fail: 3435 talloc_free(mem_ctx); 3436 return status; 3437} 3438 3439static NTSTATUS torture_samba3_setconfig(struct smbcli_state *cli, 3440 struct loadparm_context *lp_ctx, 3441 const char *sharename, 3442 const char *parameter, 3443 const char *value) 3444{ 3445 struct dcerpc_pipe *p = NULL; 3446 struct policy_handle *hklm = NULL, key_handle; 3447 struct winreg_OpenKey o; 3448 struct winreg_SetValue s; 3449 uint32_t type; 3450 DATA_BLOB val; 3451 NTSTATUS status; 3452 3453 status = get_hklm_handle(cli, cli, lp_iconv_convenience(lp_ctx), &p, &hklm); 3454 if (!NT_STATUS_IS_OK(status)) { 3455 d_printf("get_hklm_handle failed: %s\n", nt_errstr(status)); 3456 return status;; 3457 } 3458 3459 o.in.parent_handle = hklm; 3460 o.in.keyname.name = talloc_asprintf( 3461 hklm, "software\\samba\\smbconf\\%s", sharename); 3462 if (o.in.keyname.name == NULL) { 3463 d_printf("talloc_asprintf failed\n"); 3464 status = NT_STATUS_NO_MEMORY; 3465 goto done; 3466 } 3467 o.in.unknown = 0; 3468 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 3469 o.out.handle = &key_handle; 3470 3471 status = dcerpc_winreg_OpenKey(p, p, &o); 3472 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(o.out.result)) { 3473 d_printf("(%s) OpenKey failed: %s, %s\n", __location__, 3474 nt_errstr(status), win_errstr(o.out.result)); 3475 status = NT_STATUS_IS_OK(status) ? werror_to_ntstatus(o.out.result) : status; 3476 goto done; 3477 } 3478 3479 if (!reg_string_to_val(hklm, lp_iconv_convenience(lp_ctx), "REG_SZ", 3480 value, &type, &val)) { 3481 d_printf("(%s) reg_string_to_val failed\n", __location__); 3482 goto done; 3483 } 3484 3485 s.in.handle = &key_handle; 3486 s.in.name.name = parameter; 3487 s.in.type = type; 3488 s.in.data = val.data; 3489 s.in.size = val.length; 3490 3491 status = dcerpc_winreg_SetValue(p, p, &s); 3492 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(s.out.result)) { 3493 d_printf("(%s) SetValue failed: %s, %s\n", __location__, 3494 nt_errstr(status), win_errstr(s.out.result)); 3495 status = NT_STATUS_IS_OK(status) ? werror_to_ntstatus(s.out.result) : status; 3496 goto done; 3497 } 3498 3499done: 3500 talloc_free(hklm); 3501 return status; 3502} 3503 3504bool torture_samba3_regconfig(struct torture_context *torture) 3505{ 3506 struct smbcli_state *cli; 3507 struct srvsvc_NetShareInfo502 *i = NULL; 3508 NTSTATUS status; 3509 bool ret = false; 3510 const char *comment = "Dummer Kommentar"; 3511 3512 if (!(torture_open_connection(&cli, torture, 0))) { 3513 return false; 3514 } 3515 3516 status = torture_samba3_createshare(cli, lp_iconv_convenience(torture->lp_ctx), "blubber"); 3517 if (!NT_STATUS_IS_OK(status)) { 3518 torture_warning(torture, "torture_samba3_createshare failed: " 3519 "%s\n", nt_errstr(status)); 3520 goto done; 3521 } 3522 3523 status = torture_samba3_setconfig(cli, torture->lp_ctx, "blubber", "comment", comment); 3524 if (!NT_STATUS_IS_OK(status)) { 3525 torture_warning(torture, "torture_samba3_setconfig failed: " 3526 "%s\n", nt_errstr(status)); 3527 goto done; 3528 } 3529 3530 status = get_shareinfo(torture, torture->lp_ctx, cli, "blubber", &i); 3531 if (!NT_STATUS_IS_OK(status)) { 3532 torture_warning(torture, "get_shareinfo failed: " 3533 "%s\n", nt_errstr(status)); 3534 goto done; 3535 } 3536 3537 if (strcmp(comment, i->comment) != 0) { 3538 torture_warning(torture, "Expected comment [%s], got [%s]\n", 3539 comment, i->comment); 3540 goto done; 3541 } 3542 3543 status = torture_samba3_deleteshare(torture, cli, "blubber"); 3544 if (!NT_STATUS_IS_OK(status)) { 3545 torture_warning(torture, "torture_samba3_deleteshare failed: " 3546 "%s\n", nt_errstr(status)); 3547 goto done; 3548 } 3549 3550 ret = true; 3551 done: 3552 talloc_free(cli); 3553 return ret; 3554} 3555