libnet_passwd.c

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

C
704
字号
		return NT_STATUS_INVALID_PARAMETER_MIX;	}	/* prepare samr_SetUserInfo2 level 25 */	ZERO_STRUCT(u_info);	u_info.info25.info = *r->samr_handle.in.info21;	u_info.info25.info.fields_present |= SAMR_FIELD_PASSWORD;	encode_pw_buffer(u_info.info25.password.data, r->samr_handle.in.newpassword, STR_UNICODE);	status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);	if (!NT_STATUS_IS_OK(status)) {		r->samr_handle.out.error_string = talloc_asprintf(mem_ctx,						"dcerpc_fetch_session_key failed: %s",						nt_errstr(status));		return status;	}	generate_random_buffer((uint8_t *)confounder, 16);	MD5Init(&md5);	MD5Update(&md5, confounder, 16);	MD5Update(&md5, session_key.data, session_key.length);	MD5Final(confounded_session_key.data, &md5);	arcfour_crypt_blob(u_info.info25.password.data, 516, &confounded_session_key);	memcpy(&u_info.info25.password.data[516], confounder, 16);	sui.in.user_handle = r->samr_handle.in.user_handle;	sui.in.info = &u_info;	sui.in.level = 25;	/* 8. try samr_SetUserInfo2 level 25 to set the password */	status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);	if (!NT_STATUS_IS_OK(status)) {		r->samr_handle.out.error_string			= talloc_asprintf(mem_ctx,					  "SetUserInfo2 level 25 for [%s] failed: %s",					  r->samr_handle.in.account_name, nt_errstr(status));	}	return status;}static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){	NTSTATUS status;	struct samr_SetUserInfo2 sui;	union samr_UserInfo u_info;	DATA_BLOB session_key;	if (r->samr_handle.in.info21) {		return NT_STATUS_INVALID_PARAMETER_MIX;	}	/* prepare samr_SetUserInfo2 level 24 */	ZERO_STRUCT(u_info);	encode_pw_buffer(u_info.info24.password.data, r->samr_handle.in.newpassword, STR_UNICODE);	/* w2k3 ignores this length */	u_info.info24.pw_len = strlen_m(r->samr_handle.in.newpassword)*2;	status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);	if (!NT_STATUS_IS_OK(status)) {		r->samr_handle.out.error_string = talloc_asprintf(mem_ctx,						"dcerpc_fetch_session_key failed: %s",						nt_errstr(status));		return status;	}	arcfour_crypt_blob(u_info.info24.password.data, 516, &session_key);	sui.in.user_handle = r->samr_handle.in.user_handle;	sui.in.info = &u_info;	sui.in.level = 24;	/* 9. try samr_SetUserInfo2 level 24 to set the password */	status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);	if (!NT_STATUS_IS_OK(status)) {		r->samr_handle.out.error_string			= talloc_asprintf(mem_ctx,					  "SetUserInfo2 level 24 for [%s] failed: %s",					  r->samr_handle.in.account_name, nt_errstr(status));	}	return status;}static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){	NTSTATUS status;	struct samr_SetUserInfo2 sui;	union samr_UserInfo u_info;	DATA_BLOB session_key;	if (!r->samr_handle.in.info21) {		return NT_STATUS_INVALID_PARAMETER_MIX;	}	/* prepare samr_SetUserInfo2 level 23 */	ZERO_STRUCT(u_info);	u_info.info23.info = *r->samr_handle.in.info21;	u_info.info23.info.fields_present |= SAMR_FIELD_PASSWORD;	encode_pw_buffer(u_info.info23.password.data, r->samr_handle.in.newpassword, STR_UNICODE);	status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);	if (!NT_STATUS_IS_OK(status)) {		r->samr_handle.out.error_string			= talloc_asprintf(mem_ctx,					  "dcerpc_fetch_session_key failed: %s",					  nt_errstr(status));		return status;	}	arcfour_crypt_blob(u_info.info23.password.data, 516, &session_key);	sui.in.user_handle = r->samr_handle.in.user_handle;	sui.in.info = &u_info;	sui.in.level = 23;	/* 10. try samr_SetUserInfo2 level 23 to set the password */	status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui);	if (!NT_STATUS_IS_OK(status)) {		r->samr_handle.out.error_string			= talloc_asprintf(mem_ctx,					  "SetUserInfo2 level 23 for [%s] failed: %s",					  r->samr_handle.in.account_name, nt_errstr(status));	}	return status;}/* * 1. try samr_SetUserInfo2 level 26 to set the password * 2. try samr_SetUserInfo2 level 25 to set the password * 3. try samr_SetUserInfo2 level 24 to set the password * 4. try samr_SetUserInfo2 level 23 to set the password*/static NTSTATUS libnet_SetPassword_samr_handle(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){	NTSTATUS status;	enum libnet_SetPassword_level levels[] = {		LIBNET_SET_PASSWORD_SAMR_HANDLE_26,		LIBNET_SET_PASSWORD_SAMR_HANDLE_25,		LIBNET_SET_PASSWORD_SAMR_HANDLE_24,		LIBNET_SET_PASSWORD_SAMR_HANDLE_23,	};	int i;	for (i=0; i < ARRAY_SIZE(levels); i++) {		r->generic.level = levels[i];		status = libnet_SetPassword(ctx, mem_ctx, r);		if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)		    || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER_MIX)		    || NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {			/* Try another password set mechanism */			continue;		}		break;	}		return status;}/* * set a password with DCERPC/SAMR calls * 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) *    is it correct to contact the the pdc of the domain of the user who's password should be set? * 2. do a samr_Connect to get a policy handle * 3. do a samr_LookupDomain to get the domain sid * 4. do a samr_OpenDomain to get a domain handle * 5. do a samr_LookupNames to get the users rid * 6. do a samr_OpenUser to get a user handle * 7  call libnet_SetPassword_samr_handle to set the password */static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){	NTSTATUS status;	struct libnet_RpcConnect c;	struct samr_Connect sc;	struct policy_handle p_handle;	struct samr_LookupDomain ld;	struct lsa_String d_name;	struct samr_OpenDomain od;	struct policy_handle d_handle;	struct samr_LookupNames ln;	struct samr_OpenUser ou;	struct policy_handle u_handle;	union libnet_SetPassword r2;	/* prepare connect to the SAMR pipe of users domain PDC */	c.level               = LIBNET_RPC_CONNECT_PDC;	c.in.name             = r->samr.in.domain_name;	c.in.dcerpc_iface     = &ndr_table_samr;	/* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */	status = libnet_RpcConnect(ctx, mem_ctx, &c);	if (!NT_STATUS_IS_OK(status)) {		r->samr.out.error_string = talloc_asprintf(mem_ctx,							   "Connection to SAMR pipe of PDC of domain '%s' failed: %s",							   r->samr.in.domain_name, nt_errstr(status));		return status;	}	/* prepare samr_Connect */	ZERO_STRUCT(p_handle);	sc.in.system_name = NULL;	sc.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;	sc.out.connect_handle = &p_handle;	/* 2. do a samr_Connect to get a policy handle */	status = dcerpc_samr_Connect(c.out.dcerpc_pipe, mem_ctx, &sc);	if (!NT_STATUS_IS_OK(status)) {		r->samr.out.error_string = talloc_asprintf(mem_ctx,						"samr_Connect failed: %s",						nt_errstr(status));		goto disconnect;	}	/* prepare samr_LookupDomain */	d_name.string = r->samr.in.domain_name;	ld.in.connect_handle = &p_handle;	ld.in.domain_name = &d_name;	/* 3. do a samr_LookupDomain to get the domain sid */	status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld);	if (!NT_STATUS_IS_OK(status)) {		r->samr.out.error_string = talloc_asprintf(mem_ctx,						"samr_LookupDomain for [%s] failed: %s",						r->samr.in.domain_name, nt_errstr(status));		goto disconnect;	}	/* prepare samr_OpenDomain */	ZERO_STRUCT(d_handle);	od.in.connect_handle = &p_handle;	od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;	od.in.sid = ld.out.sid;	od.out.domain_handle = &d_handle;	/* 4. do a samr_OpenDomain to get a domain handle */	status = dcerpc_samr_OpenDomain(c.out.dcerpc_pipe, mem_ctx, &od);	if (!NT_STATUS_IS_OK(status)) {		r->samr.out.error_string = talloc_asprintf(mem_ctx,						"samr_OpenDomain for [%s] failed: %s",						r->samr.in.domain_name, nt_errstr(status));		goto disconnect;	}	/* prepare samr_LookupNames */	ln.in.domain_handle = &d_handle;	ln.in.num_names = 1;	ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1);	if (!ln.in.names) {		r->samr.out.error_string = "Out of Memory";		return NT_STATUS_NO_MEMORY;	}	ln.in.names[0].string = r->samr.in.account_name;	/* 5. do a samr_LookupNames to get the users rid */	status = dcerpc_samr_LookupNames(c.out.dcerpc_pipe, mem_ctx, &ln);	if (!NT_STATUS_IS_OK(status)) {		r->samr.out.error_string = talloc_asprintf(mem_ctx,						"samr_LookupNames for [%s] failed: %s",						r->samr.in.account_name, nt_errstr(status));		goto disconnect;	}	/* check if we got one RID for the user */	if (ln.out.rids.count != 1) {		r->samr.out.error_string = talloc_asprintf(mem_ctx,						"samr_LookupNames for [%s] returns %d RIDs",						r->samr.in.account_name, ln.out.rids.count);		status = NT_STATUS_INVALID_PARAMETER;		goto disconnect;		}	/* prepare samr_OpenUser */	ZERO_STRUCT(u_handle);	ou.in.domain_handle = &d_handle;	ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;	ou.in.rid = ln.out.rids.ids[0];	ou.out.user_handle = &u_handle;	/* 6. do a samr_OpenUser to get a user handle */	status = dcerpc_samr_OpenUser(c.out.dcerpc_pipe, mem_ctx, &ou);	if (!NT_STATUS_IS_OK(status)) {		r->samr.out.error_string = talloc_asprintf(mem_ctx,						"samr_OpenUser for [%s] failed: %s",						r->samr.in.account_name, nt_errstr(status));		goto disconnect;	}	r2.samr_handle.level		= LIBNET_SET_PASSWORD_SAMR_HANDLE;	r2.samr_handle.in.account_name	= r->samr.in.account_name;	r2.samr_handle.in.newpassword	= r->samr.in.newpassword;	r2.samr_handle.in.user_handle   = &u_handle;	r2.samr_handle.in.dcerpc_pipe   = c.out.dcerpc_pipe;	r2.samr_handle.in.info21	= NULL;	status = libnet_SetPassword(ctx, mem_ctx, &r2);	r->generic.out.error_string = r2.samr_handle.out.error_string;disconnect:	/* close connection */	talloc_free(c.out.dcerpc_pipe);	return status;}static NTSTATUS libnet_SetPassword_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){	NTSTATUS status;	union libnet_SetPassword r2;	r2.samr.level		= LIBNET_SET_PASSWORD_SAMR;	r2.samr.in.account_name	= r->generic.in.account_name;	r2.samr.in.domain_name	= r->generic.in.domain_name;	r2.samr.in.newpassword	= r->generic.in.newpassword;	r->generic.out.error_string = "Unknown Error";	status = libnet_SetPassword(ctx, mem_ctx, &r2);	r->generic.out.error_string = r2.samr.out.error_string;	return status;}NTSTATUS libnet_SetPassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){	switch (r->generic.level) {		case LIBNET_SET_PASSWORD_GENERIC:			return libnet_SetPassword_generic(ctx, mem_ctx, r);		case LIBNET_SET_PASSWORD_SAMR:			return libnet_SetPassword_samr(ctx, mem_ctx, r);		case LIBNET_SET_PASSWORD_SAMR_HANDLE:			return libnet_SetPassword_samr_handle(ctx, mem_ctx, r);		case LIBNET_SET_PASSWORD_SAMR_HANDLE_26:			return libnet_SetPassword_samr_handle_26(ctx, mem_ctx, r);		case LIBNET_SET_PASSWORD_SAMR_HANDLE_25:			return libnet_SetPassword_samr_handle_25(ctx, mem_ctx, r);		case LIBNET_SET_PASSWORD_SAMR_HANDLE_24:			return libnet_SetPassword_samr_handle_24(ctx, mem_ctx, r);		case LIBNET_SET_PASSWORD_SAMR_HANDLE_23:			return libnet_SetPassword_samr_handle_23(ctx, mem_ctx, r);		case LIBNET_SET_PASSWORD_KRB5:			return NT_STATUS_NOT_IMPLEMENTED;		case LIBNET_SET_PASSWORD_LDAP:			return NT_STATUS_NOT_IMPLEMENTED;		case LIBNET_SET_PASSWORD_RAP:			return NT_STATUS_NOT_IMPLEMENTED;	}	return NT_STATUS_INVALID_LEVEL;}

⌨️ 快捷键说明

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