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 + -
显示快捷键?