samba3rpc.c

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

C
2,504
字号
 fail:	return status;}/* * Create a test user */static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,			struct loadparm_context *lp_ctx,			struct cli_credentials *admin_creds,			const char *username, const char *password,			char **domain_name,			struct dom_sid **user_sid){	TALLOC_CTX *tmp_ctx;	NTSTATUS status;	struct dcerpc_pipe *samr_pipe;	struct policy_handle *wks_handle;	bool ret = false;	if (!(tmp_ctx = talloc_new(mem_ctx))) {		d_printf("talloc_init failed\n");		return false;	}	status = get_usr_handle(cli, tmp_ctx, lp_ctx, admin_creds,				DCERPC_AUTH_TYPE_NTLMSSP,				DCERPC_AUTH_LEVEL_INTEGRITY,				username, domain_name, &samr_pipe, &wks_handle,				user_sid);	if (!NT_STATUS_IS_OK(status)) {		d_printf("get_usr_handle failed: %s\n", nt_errstr(status));		goto done;	}	{		struct samr_SetUserInfo2 sui2;		struct samr_SetUserInfo sui;		struct samr_QueryUserInfo qui;		union samr_UserInfo u_info;		DATA_BLOB session_key;		ZERO_STRUCT(u_info);		encode_pw_buffer(u_info.info23.password.data, password,				 STR_UNICODE);		status = dcerpc_fetch_session_key(samr_pipe, &session_key);		if (!NT_STATUS_IS_OK(status)) {			d_printf("dcerpc_fetch_session_key failed\n");			goto done;		}		arcfour_crypt_blob(u_info.info23.password.data, 516,				   &session_key);		u_info.info23.info.password_expired = 0;		u_info.info23.info.fields_present = SAMR_FIELD_PASSWORD | 						    SAMR_FIELD_PASSWORD2 |						    SAMR_FIELD_EXPIRED_FLAG;		sui2.in.user_handle = wks_handle;		sui2.in.info = &u_info;		sui2.in.level = 23;		status = dcerpc_samr_SetUserInfo2(samr_pipe, tmp_ctx, &sui2);		if (!NT_STATUS_IS_OK(status)) {			d_printf("samr_SetUserInfo(23) failed: %s\n",				 nt_errstr(status));			goto done;		}		u_info.info16.acct_flags = ACB_NORMAL;		sui.in.user_handle = wks_handle;		sui.in.info = &u_info;		sui.in.level = 16;		status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);		if (!NT_STATUS_IS_OK(status)) {			d_printf("samr_SetUserInfo(16) failed\n");			goto done;		}		qui.in.user_handle = wks_handle;		qui.in.level = 21;		status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);		if (!NT_STATUS_IS_OK(status)) {			d_printf("samr_QueryUserInfo(21) failed\n");			goto done;		}		qui.out.info->info21.allow_password_change = 0;		qui.out.info->info21.force_password_change = 0;		qui.out.info->info21.account_name.string = NULL;		qui.out.info->info21.rid = 0;		qui.out.info->info21.acct_expiry = 0;		qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */		u_info.info21 = qui.out.info->info21;		sui.in.user_handle = wks_handle;		sui.in.info = &u_info;		sui.in.level = 21;		status = dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui);		if (!NT_STATUS_IS_OK(status)) {			d_printf("samr_SetUserInfo(21) failed\n");			goto done;		}	}	*domain_name= talloc_steal(mem_ctx, *domain_name);	*user_sid = talloc_steal(mem_ctx, *user_sid);	ret = true; done:	talloc_free(tmp_ctx);	return ret;}/* * Delete a test user */static bool delete_user(struct smbcli_state *cli,			struct loadparm_context *lp_ctx,			struct cli_credentials *admin_creds,			const char *username){	TALLOC_CTX *mem_ctx;	NTSTATUS status;	char *dom_name;	struct dcerpc_pipe *samr_pipe;	struct policy_handle *user_handle;	bool ret = false;	if ((mem_ctx = talloc_init("leave")) == NULL) {		d_printf("talloc_init failed\n");		return false;	}	status = get_usr_handle(cli, mem_ctx, lp_ctx, admin_creds,				DCERPC_AUTH_TYPE_NTLMSSP,				DCERPC_AUTH_LEVEL_INTEGRITY,				username, &dom_name, &samr_pipe,				&user_handle, NULL);	if (!NT_STATUS_IS_OK(status)) {		d_printf("get_wks_handle failed: %s\n", nt_errstr(status));		goto done;	}	{		struct samr_DeleteUser d;		d.in.user_handle = user_handle;		d.out.user_handle = user_handle;		status = dcerpc_samr_DeleteUser(samr_pipe, mem_ctx, &d);		if (!NT_STATUS_IS_OK(status)) {			d_printf("samr_DeleteUser failed %s\n", nt_errstr(status));			goto done;		}	}	ret = true; done:	talloc_free(mem_ctx);	return ret;}/* * Do a Samba3-style join */static bool join3(struct smbcli_state *cli,		  struct loadparm_context *lp_ctx,		  bool use_level25,		  struct cli_credentials *admin_creds,		  struct cli_credentials *wks_creds){	TALLOC_CTX *mem_ctx;	NTSTATUS status;	char *dom_name;	struct dcerpc_pipe *samr_pipe;	struct policy_handle *wks_handle;	bool ret = false;	NTTIME last_password_change;	if ((mem_ctx = talloc_init("join3")) == NULL) {		d_printf("talloc_init failed\n");		return false;	}	status = get_usr_handle(		cli, mem_ctx, lp_ctx, admin_creds,		DCERPC_AUTH_TYPE_NTLMSSP,		DCERPC_AUTH_LEVEL_PRIVACY,		talloc_asprintf(mem_ctx, "%s$",				cli_credentials_get_workstation(wks_creds)),		&dom_name, &samr_pipe, &wks_handle, NULL);	if (!NT_STATUS_IS_OK(status)) {		d_printf("get_wks_handle failed: %s\n", nt_errstr(status));		goto done;	}	{		struct samr_QueryUserInfo q;		q.in.user_handle = wks_handle;		q.in.level = 21;		status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);		if (!NT_STATUS_IS_OK(status)) {			d_printf("(%s) QueryUserInfo failed: %s\n",				  __location__, nt_errstr(status));			goto done;		}		last_password_change = q.out.info->info21.last_password_change;	}	cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);	if (use_level25) {		struct samr_SetUserInfo2 sui2;		union samr_UserInfo u_info;		struct samr_UserInfo21 *i21 = &u_info.info25.info;		DATA_BLOB session_key;		DATA_BLOB confounded_session_key = data_blob_talloc(			mem_ctx, NULL, 16);		struct MD5Context ctx;		uint8_t confounder[16];		ZERO_STRUCT(u_info);		i21->full_name.string = talloc_asprintf(			mem_ctx, "%s$",			cli_credentials_get_workstation(wks_creds));		i21->acct_flags = ACB_WSTRUST;		i21->fields_present = SAMR_FIELD_FULL_NAME |			SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;		encode_pw_buffer(u_info.info25.password.data,				 cli_credentials_get_password(wks_creds),				 STR_UNICODE);		status = dcerpc_fetch_session_key(samr_pipe, &session_key);		if (!NT_STATUS_IS_OK(status)) {			d_printf("dcerpc_fetch_session_key failed: %s\n",				 nt_errstr(status));			goto done;		}		generate_random_buffer((uint8_t *)confounder, 16);		MD5Init(&ctx);		MD5Update(&ctx, confounder, 16);		MD5Update(&ctx, session_key.data, session_key.length);		MD5Final(confounded_session_key.data, &ctx);		arcfour_crypt_blob(u_info.info25.password.data, 516,				   &confounded_session_key);		memcpy(&u_info.info25.password.data[516], confounder, 16);		sui2.in.user_handle = wks_handle;		sui2.in.level = 25;		sui2.in.info = &u_info;		status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);		if (!NT_STATUS_IS_OK(status)) {			d_printf("samr_SetUserInfo2(25) failed: %s\n",				 nt_errstr(status));			goto done;		}	} else {		struct samr_SetUserInfo2 sui2;		struct samr_SetUserInfo sui;		union samr_UserInfo u_info;		DATA_BLOB session_key;		encode_pw_buffer(u_info.info24.password.data,				 cli_credentials_get_password(wks_creds),				 STR_UNICODE);		u_info.info24.pw_len =			strlen_m(cli_credentials_get_password(wks_creds))*2;		status = dcerpc_fetch_session_key(samr_pipe, &session_key);		if (!NT_STATUS_IS_OK(status)) {			d_printf("dcerpc_fetch_session_key failed\n");			goto done;		}		arcfour_crypt_blob(u_info.info24.password.data, 516,				   &session_key);		sui2.in.user_handle = wks_handle;		sui2.in.info = &u_info;		sui2.in.level = 24;		status = dcerpc_samr_SetUserInfo2(samr_pipe, mem_ctx, &sui2);		if (!NT_STATUS_IS_OK(status)) {			d_printf("samr_SetUserInfo(24) failed: %s\n",				 nt_errstr(status));			goto done;		}		u_info.info16.acct_flags = ACB_WSTRUST;		sui.in.user_handle = wks_handle;		sui.in.info = &u_info;		sui.in.level = 16;		status = dcerpc_samr_SetUserInfo(samr_pipe, mem_ctx, &sui);		if (!NT_STATUS_IS_OK(status)) {			d_printf("samr_SetUserInfo(16) failed\n");			goto done;		}	}	{		struct samr_QueryUserInfo q;		q.in.user_handle = wks_handle;		q.in.level = 21;		status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);		if (!NT_STATUS_IS_OK(status)) {			d_printf("(%s) QueryUserInfo failed: %s\n",				  __location__, nt_errstr(status));			goto done;		}		if (use_level25) {			if (last_password_change			    == q.out.info->info21.last_password_change) {				d_printf("(%s) last_password_change unchanged "					 "during join, level25 must change "					 "it\n", __location__);				goto done;			}		}		else {			if (last_password_change			    != q.out.info->info21.last_password_change) {				d_printf("(%s) last_password_change changed "					 "during join, level24 doesn't "					 "change it\n", __location__);				goto done;			}		}	}	ret = true; done:	talloc_free(mem_ctx);	return ret;}/* * Do a ReqChallenge/Auth2 and get the wks creds */static bool auth2(struct smbcli_state *cli,		  struct loadparm_context *lp_ctx,		  struct cli_credentials *wks_cred){	TALLOC_CTX *mem_ctx;	struct dcerpc_pipe *net_pipe;	bool result = false;	NTSTATUS status;	struct netr_ServerReqChallenge r;	struct netr_Credential netr_cli_creds;	struct netr_Credential netr_srv_creds;	uint32_t negotiate_flags;	struct netr_ServerAuthenticate2 a;	struct creds_CredentialState *creds_state;	struct netr_Credential netr_cred;	struct samr_Password mach_pw;	mem_ctx = talloc_new(NULL);	if (mem_ctx == NULL) {		d_printf("talloc_new failed\n");		return false;	}	net_pipe = dcerpc_pipe_init(mem_ctx,				    cli->transport->socket->event.ctx,				    lp_iconv_convenience(lp_ctx));	if (net_pipe == NULL) {		d_printf("dcerpc_pipe_init failed\n");		goto done;	}	status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");	if (!NT_STATUS_IS_OK(status)) {		d_printf("dcerpc_pipe_open_smb failed: %s\n",			 nt_errstr(status));		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 = cli_credentials_get_workstation(wks_cred);	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(cli_credentials_get_password(wks_cred), 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$", cli_credentials_get_workstation(wks_cred));	a.in.computer_name = cli_credentials_get_workstation(wks_cred);	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_IS_OK(status)) {		d_printf("netr_ServerServerAuthenticate2 failed: %s\n",			 nt_errstr(status));		goto done;	}	if (!creds_client_check(creds_state, a.out.credentials)) {		d_printf("creds_client_check failed\n");		goto done;	}	cli_credentials_set_netlogon_creds(wks_cred, creds_state);	result = true; done:	talloc_free(mem_ctx);	return result;}/* * Do a couple of schannel protected Netlogon ops: Interactive and Network * login, and change the wks password */static bool schan(struct smbcli_state *cli,		  struct loadparm_context *lp_ctx,		  struct cli_credentials *wks_creds,		  struct cli_credentials *user_creds){	TALLOC_CTX *mem_ctx;	NTSTATUS status;	bool ret = false;	struct dcerpc_pipe *net_pipe;	int i;		mem_ctx = talloc_new(NULL);	if (mem_ctx == NULL) {		d_printf("talloc_new failed\n");		return false;	}	net_pipe = dcerpc_pipe_init(mem_ctx,				    cli->transport->socket->event.ctx,				    lp_iconv_convenience(lp_ctx));	if (net_pipe == NULL) {		d_printf("dcerpc_pipe_init failed\n");		goto done;	}	status = dcerpc_pipe_open_smb(net_pipe, cli->tree, "\\netlogon");	if (!NT_STATUS_IS_OK(status)) {		d_printf("dcerpc_pipe_open_smb failed: %s\n",			 nt_errstr(status));		goto done;	}#if 0	net_pipe->conn->flags |= DCERPC_DEBUG_PRINT_IN |

⌨️ 快捷键说明

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