samba3rpc.c

来自「samba最新软件」· C语言 代码 · 共 2,504 行 · 第 1/5 页

C
2,504
字号
		DCERPC_DEBUG_PRINT_OUT;#endif#if 1	net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);	status = dcerpc_bind_auth(net_pipe, &ndr_table_netlogon,				  wks_creds, lp_ctx, DCERPC_AUTH_TYPE_SCHANNEL,				  DCERPC_AUTH_LEVEL_PRIVACY,				  NULL);#else	status = dcerpc_bind_auth_none(net_pipe, &ndr_table_netlogon);#endif	if (!NT_STATUS_IS_OK(status)) {		d_printf("schannel bind failed: %s\n", nt_errstr(status));		goto done;	}	for (i=2; i<4; i++) {		int flags;		DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key;		struct creds_CredentialState *creds_state;		struct netr_Authenticator netr_auth, netr_auth2;		struct netr_NetworkInfo ninfo;		struct netr_PasswordInfo pinfo;		struct netr_LogonSamLogon r;		flags = CLI_CRED_LANMAN_AUTH | CLI_CRED_NTLM_AUTH |			CLI_CRED_NTLMv2_AUTH;		chal = data_blob_talloc(mem_ctx, NULL, 8);		if (chal.data == NULL) {			d_printf("data_blob_talloc failed\n");			goto done;		}		generate_random_buffer(chal.data, chal.length);		names_blob = NTLMv2_generate_names_blob(			mem_ctx, lp_iconv_convenience(lp_ctx), 			cli_credentials_get_workstation(user_creds),			cli_credentials_get_domain(user_creds));		status = cli_credentials_get_ntlm_response(			user_creds, mem_ctx, &flags, chal, names_blob,			&lm_resp, &nt_resp, NULL, NULL);		if (!NT_STATUS_IS_OK(status)) {			d_printf("cli_credentials_get_ntlm_response failed:"				 " %s\n", nt_errstr(status));			goto done;		}		creds_state = cli_credentials_get_netlogon_creds(wks_creds);		creds_client_authenticator(creds_state, &netr_auth);		ninfo.identity_info.account_name.string =			cli_credentials_get_username(user_creds);		ninfo.identity_info.domain_name.string =			cli_credentials_get_domain(user_creds);		ninfo.identity_info.parameter_control = 0;		ninfo.identity_info.logon_id_low = 0;		ninfo.identity_info.logon_id_high = 0;		ninfo.identity_info.workstation.string =			cli_credentials_get_workstation(user_creds);		memcpy(ninfo.challenge, chal.data, sizeof(ninfo.challenge));		ninfo.nt.length = nt_resp.length;		ninfo.nt.data = nt_resp.data;		ninfo.lm.length = lm_resp.length;		ninfo.lm.data = lm_resp.data;		r.in.server_name = talloc_asprintf(			mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));		ZERO_STRUCT(netr_auth2);		r.in.computer_name =			cli_credentials_get_workstation(wks_creds);		r.in.credential = &netr_auth;		r.in.return_authenticator = &netr_auth2;		r.in.logon_level = 2;		r.in.validation_level = i;		r.in.logon.network = &ninfo;		r.out.return_authenticator = NULL;		status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);		if (!NT_STATUS_IS_OK(status)) {			d_printf("netr_LogonSamLogon failed: %s\n",				 nt_errstr(status));			goto done;		}		if ((r.out.return_authenticator == NULL) ||		    (!creds_client_check(creds_state,					 &r.out.return_authenticator->cred))) {			d_printf("Credentials check failed!\n");			goto done;		}		creds_client_authenticator(creds_state, &netr_auth);		pinfo.identity_info = ninfo.identity_info;		ZERO_STRUCT(pinfo.lmpassword.hash);		E_md4hash(cli_credentials_get_password(user_creds),			  pinfo.ntpassword.hash);		session_key = data_blob_talloc(mem_ctx,					       creds_state->session_key, 16);		arcfour_crypt_blob(pinfo.ntpassword.hash,				   sizeof(pinfo.ntpassword.hash),				   &session_key);		r.in.logon_level = 1;		r.in.logon.password = &pinfo;		r.out.return_authenticator = NULL;		status = dcerpc_netr_LogonSamLogon(net_pipe, mem_ctx, &r);		if (!NT_STATUS_IS_OK(status)) {			d_printf("netr_LogonSamLogon failed: %s\n",				 nt_errstr(status));			goto done;		}		if ((r.out.return_authenticator == NULL) ||		    (!creds_client_check(creds_state,					 &r.out.return_authenticator->cred))) {			d_printf("Credentials check failed!\n");			goto done;		}	}	{		struct netr_ServerPasswordSet s;		char *password = generate_random_str(wks_creds, 8);		struct creds_CredentialState *creds_state;		s.in.server_name = talloc_asprintf(			mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe));		s.in.computer_name = cli_credentials_get_workstation(wks_creds);		s.in.account_name = talloc_asprintf(			mem_ctx, "%s$", s.in.computer_name);		s.in.secure_channel_type = SEC_CHAN_WKSTA;		E_md4hash(password, s.in.new_password.hash);		creds_state = cli_credentials_get_netlogon_creds(wks_creds);		creds_des_encrypt(creds_state, &s.in.new_password);		creds_client_authenticator(creds_state, &s.in.credential);		status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s);		if (!NT_STATUS_IS_OK(status)) {			printf("ServerPasswordSet - %s\n", nt_errstr(status));			goto done;		}		if (!creds_client_check(creds_state,					&s.out.return_authenticator.cred)) {			printf("Credential chaining failed\n");		}		cli_credentials_set_password(wks_creds, password,					     CRED_SPECIFIED);	}	ret = true; done:	talloc_free(mem_ctx);	return ret;}/* * Delete the wks account again */static bool leave(struct smbcli_state *cli,		  struct loadparm_context *lp_ctx,		  struct cli_credentials *admin_creds,		  struct cli_credentials *wks_creds){	char *wks_name = talloc_asprintf(		NULL, "%s$", cli_credentials_get_workstation(wks_creds));	bool ret;	ret = delete_user(cli, lp_ctx, admin_creds, wks_name);	talloc_free(wks_name);	return ret;}/* * Test the Samba3 DC code a bit. Join, do some schan netlogon ops, leave */bool torture_netlogon_samba3(struct torture_context *torture){	TALLOC_CTX *mem_ctx;	NTSTATUS status;	bool ret = false;	struct smbcli_state *cli;	struct cli_credentials *anon_creds;	struct cli_credentials *wks_creds;	const char *wks_name;	int i;	struct smbcli_options options;	wks_name = torture_setting_string(torture, "wksname", NULL);	if (wks_name == NULL) {		wks_name = get_myname();	}	mem_ctx = talloc_init("torture_netlogon_samba3");	if (mem_ctx == NULL) {		d_printf("talloc_init failed\n");		return false;	}	if (!(anon_creds = cli_credentials_init_anon(mem_ctx))) {		d_printf("create_anon_creds failed\n");		goto done;	}	lp_smbcli_options(torture->lp_ctx, &options);	status = smbcli_full_connection(mem_ctx, &cli,					torture_setting_string(torture, "host", NULL),					lp_smb_ports(torture->lp_ctx),					"IPC$", NULL, anon_creds, 					lp_resolve_context(torture->lp_ctx),					torture->ev, &options);	if (!NT_STATUS_IS_OK(status)) {		d_printf("smbcli_full_connection failed: %s\n",			 nt_errstr(status));		goto done;	}	wks_creds = cli_credentials_init(mem_ctx);	if (wks_creds == NULL) {		d_printf("cli_credentials_init failed\n");		goto done;	}	cli_credentials_set_conf(wks_creds, torture->lp_ctx);	cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);	cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);	cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);	cli_credentials_set_password(wks_creds,				     generate_random_str(wks_creds, 8),				     CRED_SPECIFIED);	if (!join3(cli, torture->lp_ctx, false, cmdline_credentials, wks_creds)) {		d_printf("join failed\n");		goto done;	}	cli_credentials_set_domain(		cmdline_credentials, cli_credentials_get_domain(wks_creds),		CRED_SPECIFIED);	for (i=0; i<2; i++) {		/* Do this more than once, the routine "schan" changes		 * the workstation password using the netlogon		 * password change routine */		int j;		if (!auth2(cli, torture->lp_ctx, wks_creds)) {			d_printf("auth2 failed\n");			goto done;		}		for (j=0; j<2; j++) {			if (!schan(cli, torture->lp_ctx, wks_creds, cmdline_credentials)) {				d_printf("schan failed\n");				goto done;			}		}	}	if (!leave(cli, torture->lp_ctx, cmdline_credentials, wks_creds)) {		d_printf("leave failed\n");		goto done;	}	ret = true; done:	talloc_free(mem_ctx);	return ret;}/* * Do a simple join, testjoin and leave using specified smb and samr * credentials */static bool test_join3(struct torture_context *tctx,		       bool use_level25,		       struct cli_credentials *smb_creds,		       struct cli_credentials *samr_creds,		       const char *wks_name){	NTSTATUS status;	bool ret = false;	struct smbcli_state *cli;	struct cli_credentials *wks_creds;	struct smbcli_options options;	lp_smbcli_options(tctx->lp_ctx, &options);	status = smbcli_full_connection(tctx, &cli,					torture_setting_string(tctx, "host", NULL),					lp_smb_ports(tctx->lp_ctx),					"IPC$", NULL, smb_creds, 					lp_resolve_context(tctx->lp_ctx),					tctx->ev, &options);	if (!NT_STATUS_IS_OK(status)) {		d_printf("smbcli_full_connection failed: %s\n",			 nt_errstr(status));		goto done;	}	wks_creds = cli_credentials_init(cli);	if (wks_creds == NULL) {		d_printf("cli_credentials_init failed\n");		goto done;	}	cli_credentials_set_conf(wks_creds, tctx->lp_ctx);	cli_credentials_set_secure_channel_type(wks_creds, SEC_CHAN_WKSTA);	cli_credentials_set_username(wks_creds, wks_name, CRED_SPECIFIED);	cli_credentials_set_workstation(wks_creds, wks_name, CRED_SPECIFIED);	cli_credentials_set_password(wks_creds,				     generate_random_str(wks_creds, 8),				     CRED_SPECIFIED);	if (!join3(cli, tctx->lp_ctx, use_level25, samr_creds, wks_creds)) {		d_printf("join failed\n");		goto done;	}	cli_credentials_set_domain(		cmdline_credentials, cli_credentials_get_domain(wks_creds),		CRED_SPECIFIED);	if (!auth2(cli, tctx->lp_ctx, wks_creds)) {		d_printf("auth2 failed\n");		goto done;	}	if (!leave(cli, tctx->lp_ctx, samr_creds, wks_creds)) {		d_printf("leave failed\n");		goto done;	}	talloc_free(cli);	ret = true; done:	return ret;}/* * Test the different session key variants. Do it by joining, this uses the * session key in the setpassword routine. Test the join by doing the auth2. */bool torture_samba3_sessionkey(struct torture_context *torture){	bool ret = false;	struct cli_credentials *anon_creds;	const char *wks_name;	wks_name = torture_setting_string(torture, "wksname", get_myname());	if (!(anon_creds = cli_credentials_init_anon(torture))) {		d_printf("create_anon_creds failed\n");		goto done;	}	cli_credentials_set_workstation(anon_creds, wks_name, CRED_SPECIFIED);	ret = true;	if (!torture_setting_bool(torture, "samba3", false)) {		/* Samba3 in the build farm right now does this happily. Need		 * to fix :-) */		if (test_join3(torture, false, anon_creds, NULL, wks_name)) {			d_printf("join using anonymous bind on an anonymous smb "				 "connection succeeded -- HUH??\n");			ret = false;		}	}	if (!test_join3(torture, false, anon_creds, cmdline_credentials,			wks_name)) {		d_printf("join using ntlmssp bind on an anonymous smb "			 "connection failed\n");		ret = false;	}	if (!test_join3(torture, false, cmdline_credentials, NULL, wks_name)) {		d_printf("join using anonymous bind on an authenticated smb "			 "connection failed\n");		ret = false;	}	if (!test_join3(torture, false, cmdline_credentials,			cmdline_credentials,			wks_name)) {		d_printf("join using ntlmssp bind on an authenticated smb "			 "connection failed\n");		ret = false;	}	/*	 * The following two are tests for setuserinfolevel 25	 */	if (!test_join3(torture, true, anon_creds, cmdline_credentials,			wks_name)) {		d_printf("join using ntlmssp bind on an anonymous smb "			 "connection failed\n");		ret = false;	}	if (!test_join3(torture, true, cmdline_credentials, NULL, wks_name)) {		d_printf("join using anonymous bind on an authenticated smb "			 "connection failed\n");		ret = false;	} done:	return ret;}/* * open pipe and bind, given an IPC$ context */static NTSTATUS pipe_bind_smb(TALLOC_CTX *mem_ctx,			      struct loadparm_context *lp_ctx,			      struct smbcli_tree *tree,			      const char *pipe_name,			      const struct ndr_interface_table *iface,			      struct dcerpc_pipe **p){	struct dcerpc_pipe *result;	NTSTATUS status;	if (!(result = dcerpc_pipe_init(		      mem_ctx, tree->session->transport->socket->event.ctx, 		      lp_iconv_convenience(lp_ctx)))) {		return NT_STATUS_NO_MEMORY;	}	status = dcerpc_pipe_open_smb(result, tree, pipe_name);	if (!NT_STATUS_IS_OK(status)) {		d_printf("dcerpc_pipe_open_smb failed: %s\n",			 nt_errstr(status));		talloc_free(result);		return status;	}	status = dcerpc_bind_auth_none(result, iface);	if (!NT_STATUS_IS_OK(status)) {		d_printf("schannel bind failed: %s\n", nt_errstr(status));		talloc_free(result);		return status;	}	*p = result;	return NT_STATUS_OK;}/* * Sane wrapper around lsa_LookupNames */static struct dom_sid *name2sid(TALLOC_CTX *mem_ctx,				struct dcerpc_pipe *p,				const char *name,				const char *domain){	struct lsa_ObjectAttribute attr;	struct lsa_QosInfo qos;	struct lsa_OpenPolicy2 r;	struct lsa_Close c;	NTSTATUS status;	struct policy_handle handle;	struct lsa_LookupNames l;	struct lsa_TransSidArray sids;	struct lsa_String lsa_name;	uint32_t count = 0;	struct dom_sid *result;	TALLOC_CTX *tmp_ctx;	if (!(tmp_ctx = talloc_new(mem_ctx))) {		return NULL;	}	qos.len = 0;	qos.impersonation_level = 2;	qos.context_mode = 1;	qos.effective_only = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?