samba3rpc.c
来自「samba最新软件」· C语言 代码 · 共 2,504 行 · 第 1/5 页
C
2,504 行
goto done; } status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon); if (!NT_STATUS_IS_OK(status)) { d_printf("dcerpc_bind_auth_none failed: %s\n", nt_errstr(status)); goto done; } r.in.computer_name = wksname; r.in.server_name = talloc_asprintf( mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); if (r.in.server_name == NULL) { d_printf("talloc_asprintf failed\n"); goto done; } generate_random_buffer(netr_cli_creds.data, sizeof(netr_cli_creds.data)); r.in.credentials = &netr_cli_creds; r.out.credentials = &netr_srv_creds; status = dcerpc_netr_ServerReqChallenge(net_pipe, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { d_printf("netr_ServerReqChallenge failed: %s\n", nt_errstr(status)); goto done; } negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; E_md4hash("foobar", mach_pw.hash); creds_state = talloc(mem_ctx, struct creds_CredentialState); creds_client_init(creds_state, r.in.credentials, r.out.credentials, &mach_pw, &netr_cred, negotiate_flags); a.in.server_name = talloc_asprintf( mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); a.in.account_name = talloc_asprintf( mem_ctx, "%s$", wksname); a.in.computer_name = wksname; a.in.secure_channel_type = SEC_CHAN_WKSTA; a.in.negotiate_flags = &negotiate_flags; a.out.negotiate_flags = &negotiate_flags; a.in.credentials = &netr_cred; a.out.credentials = &netr_cred; status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a); if (!NT_STATUS_EQUAL(status, NT_STATUS_NO_TRUST_SAM_ACCOUNT)) { d_printf("dcerpc_netr_ServerAuthenticate2 returned %s, " "expected NT_STATUS_NO_TRUST_SAM_ACCOUNT\n", nt_errstr(status)); goto done; } result = true; done: talloc_free(mem_ctx); return result;}static struct security_descriptor *get_sharesec(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct smbcli_session *sess, const char *sharename){ struct smbcli_tree *tree; TALLOC_CTX *tmp_ctx; struct dcerpc_pipe *p; NTSTATUS status; struct srvsvc_NetShareGetInfo r; struct security_descriptor *result; if (!(tmp_ctx = talloc_new(mem_ctx))) { d_printf("talloc_new failed\n"); return NULL; } if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) { d_printf("secondary_tcon failed\n"); talloc_free(tmp_ctx); return NULL; } status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\srvsvc", &ndr_table_srvsvc, &p); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) could not bind to srvsvc pipe: %s\n", __location__, nt_errstr(status)); talloc_free(tmp_ctx); return NULL; }#if 0 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;#endif r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.share_name = sharename; r.in.level = 502; status = dcerpc_srvsvc_NetShareGetInfo(p, tmp_ctx, &r); if (!NT_STATUS_IS_OK(status)) { d_printf("srvsvc_NetShareGetInfo failed: %s\n", nt_errstr(status)); talloc_free(tmp_ctx); return NULL; } result = talloc_steal(mem_ctx, r.out.info.info502->sd); talloc_free(tmp_ctx); return result;}static NTSTATUS set_sharesec(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct smbcli_session *sess, const char *sharename, struct security_descriptor *sd){ struct smbcli_tree *tree; TALLOC_CTX *tmp_ctx; struct dcerpc_pipe *p; NTSTATUS status; struct sec_desc_buf i; struct srvsvc_NetShareSetInfo r; uint32_t error = 0; if (!(tmp_ctx = talloc_new(mem_ctx))) { d_printf("talloc_new failed\n"); return NT_STATUS_NO_MEMORY; } if (!NT_STATUS_IS_OK(secondary_tcon(tmp_ctx, sess, "IPC$", &tree))) { d_printf("secondary_tcon failed\n"); talloc_free(tmp_ctx); return NT_STATUS_UNSUCCESSFUL; } status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\pipe\\srvsvc", &ndr_table_srvsvc, &p); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) could not bind to srvsvc pipe: %s\n", __location__, nt_errstr(status)); talloc_free(tmp_ctx); return NT_STATUS_UNSUCCESSFUL; }#if 0 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;#endif r.in.server_unc = talloc_asprintf(tmp_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.share_name = sharename; r.in.level = 1501; i.sd = sd; r.in.info.info1501 = &i; r.in.parm_error = &error; status = dcerpc_srvsvc_NetShareSetInfo(p, tmp_ctx, &r); if (!NT_STATUS_IS_OK(status)) { d_printf("srvsvc_NetShareGetInfo failed: %s\n", nt_errstr(status)); } talloc_free(tmp_ctx); return status;}bool try_tcon(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct security_descriptor *orig_sd, struct smbcli_session *session, const char *sharename, const struct dom_sid *user_sid, unsigned int access_mask, NTSTATUS expected_tcon, NTSTATUS expected_mkdir){ TALLOC_CTX *tmp_ctx; struct smbcli_tree *rmdir_tree, *tree; struct dom_sid *domain_sid; uint32_t rid; struct security_descriptor *sd; NTSTATUS status; bool ret = true; if (!(tmp_ctx = talloc_new(mem_ctx))) { d_printf("talloc_new failed\n"); return false; } status = secondary_tcon(tmp_ctx, session, sharename, &rmdir_tree); if (!NT_STATUS_IS_OK(status)) { d_printf("first tcon to delete dir failed\n"); talloc_free(tmp_ctx); return false; } smbcli_rmdir(rmdir_tree, "sharesec_testdir"); if (!NT_STATUS_IS_OK(dom_sid_split_rid(tmp_ctx, user_sid, &domain_sid, &rid))) { d_printf("dom_sid_split_rid failed\n"); talloc_free(tmp_ctx); return false; } sd = security_descriptor_dacl_create( tmp_ctx, 0, "S-1-5-32-544", dom_sid_string(mem_ctx, dom_sid_add_rid(mem_ctx, domain_sid, DOMAIN_RID_USERS)), dom_sid_string(mem_ctx, user_sid), SEC_ACE_TYPE_ACCESS_ALLOWED, access_mask, 0, NULL); if (sd == NULL) { d_printf("security_descriptor_dacl_create failed\n"); talloc_free(tmp_ctx); return false; } status = set_sharesec(mem_ctx, lp_ctx, session, sharename, sd); if (!NT_STATUS_IS_OK(status)) { d_printf("custom set_sharesec failed: %s\n", nt_errstr(status)); talloc_free(tmp_ctx); return false; } status = secondary_tcon(tmp_ctx, session, sharename, &tree); if (!NT_STATUS_EQUAL(status, expected_tcon)) { d_printf("Expected %s, got %s\n", nt_errstr(expected_tcon), nt_errstr(status)); ret = false; goto done; } if (!NT_STATUS_IS_OK(status)) { /* An expected non-access, no point in trying to write */ goto done; } status = smbcli_mkdir(tree, "sharesec_testdir"); if (!NT_STATUS_EQUAL(status, expected_mkdir)) { d_printf("(%s) Expected %s, got %s\n", __location__, nt_errstr(expected_mkdir), nt_errstr(status)); ret = false; } done: smbcli_rmdir(rmdir_tree, "sharesec_testdir"); status = set_sharesec(mem_ctx, lp_ctx, session, sharename, orig_sd); if (!NT_STATUS_IS_OK(status)) { d_printf("custom set_sharesec failed: %s\n", nt_errstr(status)); talloc_free(tmp_ctx); return false; } talloc_free(tmp_ctx); return ret;}bool torture_samba3_rpc_sharesec(struct torture_context *torture){ TALLOC_CTX *mem_ctx; bool ret = true; struct smbcli_state *cli; struct security_descriptor *sd; struct dom_sid *user_sid; if (!(mem_ctx = talloc_new(torture))) { return false; } if (!(torture_open_connection_share( mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL), "IPC$", torture->ev))) { d_printf("IPC$ connection failed\n"); talloc_free(mem_ctx); return false; } if (!(user_sid = whoami(mem_ctx, torture->lp_ctx, cli->tree))) { d_printf("whoami failed\n"); talloc_free(mem_ctx); return false; } sd = get_sharesec(mem_ctx, torture->lp_ctx, cli->session, torture_setting_string(torture, "share", NULL)); ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session, torture_setting_string(torture, "share", NULL), user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK); ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session, torture_setting_string(torture, "share", NULL), user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK, NT_STATUS_MEDIA_WRITE_PROTECTED); ret &= try_tcon(mem_ctx, torture->lp_ctx, sd, cli->session, torture_setting_string(torture, "share", NULL), user_sid, SEC_FILE_ALL, NT_STATUS_OK, NT_STATUS_OK); talloc_free(mem_ctx); return ret;}bool torture_samba3_rpc_lsa(struct torture_context *torture){ TALLOC_CTX *mem_ctx; bool ret = true; struct smbcli_state *cli; struct dcerpc_pipe *p; struct policy_handle lsa_handle; NTSTATUS status; struct dom_sid *domain_sid; if (!(mem_ctx = talloc_new(torture))) { return false; } if (!(torture_open_connection_share( mem_ctx, &cli, torture, torture_setting_string(torture, "host", NULL), "IPC$", torture->ev))) { d_printf("IPC$ connection failed\n"); talloc_free(mem_ctx); return false; } status = pipe_bind_smb(mem_ctx, torture->lp_ctx, cli->tree, "\\lsarpc", &ndr_table_lsarpc, &p); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) pipe_bind_smb failed: %s\n", __location__, nt_errstr(status)); talloc_free(mem_ctx); return false; } { struct lsa_ObjectAttribute attr; struct lsa_OpenPolicy2 o; o.in.system_name = talloc_asprintf( mem_ctx, "\\\\%s", dcerpc_server_name(p)); ZERO_STRUCT(attr); o.in.attr = &attr; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; o.out.handle = &lsa_handle; status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &o); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) dcerpc_lsa_OpenPolicy2 failed: %s\n", __location__, nt_errstr(status)); talloc_free(mem_ctx); return false; } }#if 0 p->conn->flags |= DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT;#endif { int i; int levels[] = { 2,3,5,6 }; for (i=0; i<ARRAY_SIZE(levels); i++) { struct lsa_QueryInfoPolicy r; r.in.handle = &lsa_handle; r.in.level = levels[i]; status = dcerpc_lsa_QueryInfoPolicy(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) dcerpc_lsa_QueryInfoPolicy %d " "failed: %s\n", __location__, levels[i], nt_errstr(status)); talloc_free(mem_ctx); return false; } if (levels[i] == 5) { domain_sid = r.out.info->account_domain.sid; } } } return ret;}static NTSTATUS get_servername(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree, struct smb_iconv_convenience *iconv_convenience, char **name){ struct rap_WserverGetInfo r; NTSTATUS status; char servername[17]; r.in.level = 0; r.in.bufsize = 0xffff; status = smbcli_rap_netservergetinfo(tree, iconv_convenience, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { return status; } memcpy(servername, r.out.info.info0.name, 16); servername[16] = '\0'; if (pull_ascii_talloc(mem_ctx, iconv_convenience, name, servername) < 0) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK;}static NTSTATUS find_printers(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx, struct smbcli_tree *tree, const char ***printers, int *num_printers){ TALLOC_CTX *mem_ctx; NTSTATUS status; struct dcerpc_pipe *p; struct srvsvc_NetShareEnum r; struct srvsvc_NetShareCtr1 c1_in; struct srvsvc_NetShareCtr1 *c1; int i; mem_ctx = talloc_new(ctx); if (mem_ctx == NULL) { return NT_STATUS_NO_MEMORY; } status = pipe_bind_smb(mem_ctx, lp_ctx, tree, "\\srvsvc", &ndr_table_srvsvc, &p); if (!NT_STATUS_IS_OK(status)) { d_printf("could not bind to srvsvc pipe\n"); talloc_free(mem_ctx); return status; } r.in.server_unc = talloc_asprintf( mem_ctx, "\\\\%s", dcerpc_server_name(p)); r.in.level = 1; ZERO_STRUCT(c1_in); r.in.ctr.ctr1 = &c1_in; r.in.max_buffer = (uint32_t)-1; r.in.resume_handle = NULL; status = dcerpc_srvsvc_NetShareEnum(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { d_printf("NetShareEnum level %u failed - %s\n", r.in.level, nt_errstr(status)); talloc_free(mem_ctx); return status; } *printers = NULL; *num_printers = 0; c1 = r.out.ctr.ctr1; for (i=0; i<c1->count; i++) { if (c1->array[i].type != STYPE_PRINTQ) { continue; } if (!add_string_to_array(ctx, c1->array[i].name, printers, num_printers)) { talloc_free(ctx); return NT_STATUS_NO_MEMORY; } } talloc_free(mem_ctx); return NT_STATUS_OK;}static bool enumprinters(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *pipe, const char *servername, int level, int *num_printers){ struct spoolss_EnumPrinters r; NTSTATUS status; DATA_BLOB blob; r.in.flags = PRINTER_ENUM_LOCAL; r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", servername); r.in.level = level; r.in.buffer = NULL; r.in.offered = 0; status = dcerpc_spoolss_EnumPrinters(pipe, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) dcerpc_spoolss_EnumPrinters failed: %s\n", __location__, nt_errstr(status)); return false; } if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { d_printf("(%s) EnumPrinters unexpected return code %s, should " "be WERR_INSUFFICIENT_BUFFE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?