mirror of
https://github.com/samba-team/samba.git
synced 2025-11-11 00:23:51 +03:00
r1952: change the _RPC levels into _SAMR
because we may have other rpc levels in future add more comments about what's going on check the rsult of samr_OpenUser metze
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
b660e5b9e6
commit
741f95909b
@@ -79,7 +79,7 @@ union libnet_rpc_connect {
|
||||
/* struct and enum for doing a remote password change */
|
||||
enum libnet_ChangePassword_level {
|
||||
LIBNET_CHANGE_PASSWORD_GENERIC,
|
||||
LIBNET_CHANGE_PASSWORD_RPC,
|
||||
LIBNET_CHANGE_PASSWORD_SAMR,
|
||||
LIBNET_CHANGE_PASSWORD_KRB5,
|
||||
LIBNET_CHANGE_PASSWORD_LDAP,
|
||||
LIBNET_CHANGE_PASSWORD_RAP
|
||||
@@ -105,7 +105,7 @@ union libnet_ChangePassword {
|
||||
enum libnet_ChangePassword_level level;
|
||||
struct _libnet_ChangePassword_in in;
|
||||
struct _libnet_ChangePassword_out out;
|
||||
} rpc;
|
||||
} samr;
|
||||
|
||||
struct {
|
||||
enum libnet_ChangePassword_level level;
|
||||
@@ -129,7 +129,7 @@ union libnet_ChangePassword {
|
||||
/* struct and enum for doing a remote password set */
|
||||
enum libnet_SetPassword_level {
|
||||
LIBNET_SET_PASSWORD_GENERIC,
|
||||
LIBNET_SET_PASSWORD_RPC,
|
||||
LIBNET_SET_PASSWORD_SAMR,
|
||||
LIBNET_SET_PASSWORD_KRB5,
|
||||
LIBNET_SET_PASSWORD_LDAP,
|
||||
LIBNET_SET_PASSWORD_RAP
|
||||
@@ -154,7 +154,7 @@ union libnet_SetPassword {
|
||||
enum libnet_SetPassword_level level;
|
||||
struct _libnet_SetPassword_in in;
|
||||
struct _libnet_SetPassword_out out;
|
||||
} rpc;
|
||||
} samr;
|
||||
|
||||
struct {
|
||||
enum libnet_SetPassword_level level;
|
||||
|
||||
@@ -23,9 +23,12 @@
|
||||
/*
|
||||
* do a password change using DCERPC/SAMR calls
|
||||
* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation)
|
||||
* 2. try samr_ChangePassword3
|
||||
* 2. try samr_ChangePasswordUser3
|
||||
* 3. try samr_ChangePasswordUser2
|
||||
* 4. try samr_OemChangePasswordUser2
|
||||
* (not yet: 5. try samr_ChangePasswordUser)
|
||||
*/
|
||||
static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_ChangePassword *r)
|
||||
static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_ChangePassword *r)
|
||||
{
|
||||
NTSTATUS status;
|
||||
union libnet_rpc_connect c;
|
||||
@@ -44,37 +47,38 @@ static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX
|
||||
uint8_t old_nt_hash[16], new_nt_hash[16];
|
||||
uint8_t old_lm_hash[16], new_lm_hash[16];
|
||||
|
||||
/* prepare connect to the SAMR pipe of the */
|
||||
/* prepare connect to the SAMR pipe of the users domain PDC */
|
||||
c.pdc.level = LIBNET_RPC_CONNECT_PDC;
|
||||
c.pdc.in.domain_name = r->rpc.in.domain_name;
|
||||
c.pdc.in.domain_name = r->samr.in.domain_name;
|
||||
c.pdc.in.dcerpc_iface_name = DCERPC_SAMR_NAME;
|
||||
c.pdc.in.dcerpc_iface_uuid = DCERPC_SAMR_UUID;
|
||||
c.pdc.in.dcerpc_iface_version = DCERPC_SAMR_VERSION;
|
||||
|
||||
/* do connect to the SAMR pipe of the */
|
||||
/* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */
|
||||
status = libnet_rpc_connect(ctx, mem_ctx, &c);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"Connection to SAMR pipe of PDC of domain '%s' failed: %s\n",
|
||||
r->rpc.in.domain_name, nt_errstr(status));
|
||||
r->samr.in.domain_name, nt_errstr(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
/* prepare password change for account */
|
||||
server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(c.pdc.out.dcerpc_pipe));
|
||||
account.name = r->rpc.in.account_name;
|
||||
account.name = r->samr.in.account_name;
|
||||
|
||||
E_md4hash(r->rpc.in.oldpassword, old_nt_hash);
|
||||
E_md4hash(r->rpc.in.newpassword, new_nt_hash);
|
||||
E_md4hash(r->samr.in.oldpassword, old_nt_hash);
|
||||
E_md4hash(r->samr.in.newpassword, new_nt_hash);
|
||||
|
||||
E_deshash(r->rpc.in.oldpassword, old_lm_hash);
|
||||
E_deshash(r->rpc.in.newpassword, new_lm_hash);
|
||||
E_deshash(r->samr.in.oldpassword, old_lm_hash);
|
||||
E_deshash(r->samr.in.newpassword, new_lm_hash);
|
||||
|
||||
encode_pw_buffer(lm_pass.data, r->rpc.in.newpassword, STR_UNICODE);
|
||||
/* prepare samr_ChangePasswordUser3 */
|
||||
encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_UNICODE);
|
||||
arcfour_crypt(lm_pass.data, old_nt_hash, 516);
|
||||
E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
|
||||
|
||||
encode_pw_buffer(nt_pass.data, r->rpc.in.newpassword, STR_UNICODE);
|
||||
encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE);
|
||||
arcfour_crypt(nt_pass.data, old_nt_hash, 516);
|
||||
E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
|
||||
|
||||
@@ -87,20 +91,20 @@ static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX
|
||||
pw3.in.lm_verifier = &lm_verifier;
|
||||
pw3.in.password3 = NULL;
|
||||
|
||||
/* do password change for account */
|
||||
/* 2. try samr_ChangePasswordUser3 */
|
||||
status = dcerpc_samr_ChangePasswordUser3(c.pdc.out.dcerpc_pipe, mem_ctx, &pw3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_ChangePasswordUser3 failed: %s\n",
|
||||
nt_errstr(status));
|
||||
goto ChangePasswordUser2;
|
||||
}
|
||||
|
||||
/* check result of password change */
|
||||
/* check result of samr_ChangePasswordUser3 */
|
||||
if (!NT_STATUS_IS_OK(pw3.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_ChangePasswordUser3 for '%s\\%s' failed: %s\n",
|
||||
r->rpc.in.domain_name, r->rpc.in.account_name,
|
||||
r->samr.in.domain_name, r->samr.in.account_name,
|
||||
nt_errstr(pw3.out.result));
|
||||
/* TODO: give the reason of the reject */
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
|
||||
@@ -112,12 +116,12 @@ static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX
|
||||
goto disconnect;
|
||||
|
||||
ChangePasswordUser2:
|
||||
|
||||
encode_pw_buffer(lm_pass.data, r->rpc.in.newpassword, STR_ASCII|STR_TERMINATE);
|
||||
/* prepare samr_ChangePasswordUser2 */
|
||||
encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_ASCII|STR_TERMINATE);
|
||||
arcfour_crypt(lm_pass.data, old_lm_hash, 516);
|
||||
E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
|
||||
|
||||
encode_pw_buffer(nt_pass.data, r->rpc.in.newpassword, STR_UNICODE);
|
||||
encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE);
|
||||
arcfour_crypt(nt_pass.data, old_nt_hash, 516);
|
||||
E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
|
||||
|
||||
@@ -129,19 +133,20 @@ ChangePasswordUser2:
|
||||
pw2.in.lm_password = &lm_pass;
|
||||
pw2.in.lm_verifier = &lm_verifier;
|
||||
|
||||
/* 3. try samr_ChangePasswordUser2 */
|
||||
status = dcerpc_samr_ChangePasswordUser2(c.pdc.out.dcerpc_pipe, mem_ctx, &pw2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_ChangePasswordUser2 failed: %s\n",
|
||||
nt_errstr(status));
|
||||
goto OemChangePasswordUser2;
|
||||
}
|
||||
|
||||
/* check result of password change */
|
||||
/* check result of samr_ChangePasswordUser2 */
|
||||
if (!NT_STATUS_IS_OK(pw2.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_ChangePasswordUser2 for '%s\\%s' failed: %s\n",
|
||||
r->rpc.in.domain_name, r->rpc.in.account_name,
|
||||
r->samr.in.domain_name, r->samr.in.account_name,
|
||||
nt_errstr(pw2.out.result));
|
||||
goto OemChangePasswordUser2;
|
||||
}
|
||||
@@ -149,11 +154,11 @@ ChangePasswordUser2:
|
||||
goto disconnect;
|
||||
|
||||
OemChangePasswordUser2:
|
||||
|
||||
/* prepare samr_OemChangePasswordUser2 */
|
||||
a_server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(c.pdc.out.dcerpc_pipe));
|
||||
a_account.name = r->rpc.in.account_name;
|
||||
a_account.name = r->samr.in.account_name;
|
||||
|
||||
encode_pw_buffer(lm_pass.data, r->rpc.in.newpassword, STR_ASCII);
|
||||
encode_pw_buffer(lm_pass.data, r->samr.in.newpassword, STR_ASCII);
|
||||
arcfour_crypt(lm_pass.data, old_lm_hash, 516);
|
||||
E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
|
||||
|
||||
@@ -162,19 +167,20 @@ OemChangePasswordUser2:
|
||||
oe2.in.password = &lm_pass;
|
||||
oe2.in.hash = &lm_verifier;
|
||||
|
||||
/* 4. try samr_OemChangePasswordUser2 */
|
||||
status = dcerpc_samr_OemChangePasswordUser2(c.pdc.out.dcerpc_pipe, mem_ctx, &oe2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_OemChangePasswordUser2 failed: %s\n",
|
||||
nt_errstr(status));
|
||||
goto ChangePasswordUser;
|
||||
}
|
||||
|
||||
/* check result of password change */
|
||||
/* check result of samr_OemChangePasswordUser2 */
|
||||
if (!NT_STATUS_IS_OK(oe2.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_OemChangePasswordUser2 for '%s\\%s' failed: %s\n",
|
||||
r->rpc.in.domain_name, r->rpc.in.account_name,
|
||||
r->samr.in.domain_name, r->samr.in.account_name,
|
||||
nt_errstr(oe2.out.result));
|
||||
goto ChangePasswordUser;
|
||||
}
|
||||
@@ -183,6 +189,7 @@ OemChangePasswordUser2:
|
||||
|
||||
ChangePasswordUser:
|
||||
#if 0
|
||||
/* prepare samr_ChangePasswordUser */
|
||||
E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
|
||||
E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
|
||||
E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
|
||||
@@ -203,19 +210,20 @@ ChangePasswordUser:
|
||||
pw.in.cross2_present = 1;
|
||||
pw.in.lm_cross = &hash6;
|
||||
|
||||
/* 5. try samr_ChangePasswordUser */
|
||||
status = dcerpc_samr_ChangePasswordUser(c.pdc.out.dcerpc_pipe, mem_ctx, &pw);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_ChangePasswordUser failed: %s\n",
|
||||
nt_errstr(status));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* check result of password change */
|
||||
/* check result of samr_ChangePasswordUser */
|
||||
if (!NT_STATUS_IS_OK(pw.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_ChangePasswordUser for '%s\\%s' failed: %s\n",
|
||||
r->rpc.in.domain_name, r->rpc.in.account_name,
|
||||
r->samr.in.domain_name, r->samr.in.account_name,
|
||||
nt_errstr(pw.out.result));
|
||||
goto disconnect;
|
||||
}
|
||||
@@ -232,15 +240,15 @@ static NTSTATUS libnet_ChangePassword_generic(struct libnet_context *ctx, TALLOC
|
||||
NTSTATUS status;
|
||||
union libnet_ChangePassword r2;
|
||||
|
||||
r2.rpc.level = LIBNET_CHANGE_PASSWORD_RPC;
|
||||
r2.rpc.in.account_name = r->generic.in.account_name;
|
||||
r2.rpc.in.domain_name = r->generic.in.domain_name;
|
||||
r2.rpc.in.oldpassword = r->generic.in.oldpassword;
|
||||
r2.rpc.in.newpassword = r->generic.in.newpassword;
|
||||
r2.samr.level = LIBNET_CHANGE_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.oldpassword = r->generic.in.oldpassword;
|
||||
r2.samr.in.newpassword = r->generic.in.newpassword;
|
||||
|
||||
status = libnet_ChangePassword(ctx, mem_ctx, &r2);
|
||||
|
||||
r->generic.out.error_string = r2.rpc.out.error_string;
|
||||
r->generic.out.error_string = r2.samr.out.error_string;
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -250,8 +258,8 @@ NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
|
||||
switch (r->generic.level) {
|
||||
case LIBNET_CHANGE_PASSWORD_GENERIC:
|
||||
return libnet_ChangePassword_generic(ctx, mem_ctx, r);
|
||||
case LIBNET_CHANGE_PASSWORD_RPC:
|
||||
return libnet_ChangePassword_rpc(ctx, mem_ctx, r);
|
||||
case LIBNET_CHANGE_PASSWORD_SAMR:
|
||||
return libnet_ChangePassword_samr(ctx, mem_ctx, r);
|
||||
case LIBNET_CHANGE_PASSWORD_KRB5:
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
case LIBNET_CHANGE_PASSWORD_LDAP:
|
||||
@@ -265,10 +273,16 @@ NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
|
||||
|
||||
/*
|
||||
* 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. try samr_SetUserInfo level 26 to set the password
|
||||
*/
|
||||
static NTSTATUS libnet_SetPassword_rpc(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
|
||||
static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
|
||||
{
|
||||
NTSTATUS status;
|
||||
union libnet_rpc_connect c;
|
||||
@@ -288,138 +302,157 @@ static NTSTATUS libnet_SetPassword_rpc(struct libnet_context *ctx, TALLOC_CTX *m
|
||||
uint8_t confounder[16];
|
||||
struct MD5Context md5;
|
||||
|
||||
/* prepare connect to the SAMR pipe of the */
|
||||
/* prepare connect to the SAMR pipe of users domain PDC */
|
||||
c.pdc.level = LIBNET_RPC_CONNECT_PDC;
|
||||
c.pdc.in.domain_name = r->rpc.in.domain_name;
|
||||
c.pdc.in.domain_name = r->samr.in.domain_name;
|
||||
c.pdc.in.dcerpc_iface_name = DCERPC_SAMR_NAME;
|
||||
c.pdc.in.dcerpc_iface_uuid = DCERPC_SAMR_UUID;
|
||||
c.pdc.in.dcerpc_iface_version = DCERPC_SAMR_VERSION;
|
||||
|
||||
/* do connect to the SAMR pipe of the */
|
||||
/* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */
|
||||
status = libnet_rpc_connect(ctx, mem_ctx, &c);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"Connection to SAMR pipe of PDC of domain '%s' failed: %s\n",
|
||||
r->rpc.in.domain_name, nt_errstr(status));
|
||||
r->samr.in.domain_name, nt_errstr(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
/* do a samr_Connect to get a policy handle */
|
||||
/* prepare samr_Connect */
|
||||
ZERO_STRUCT(p_handle);
|
||||
sc.in.system_name = 0;
|
||||
sc.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
|
||||
sc.out.handle = &p_handle;
|
||||
|
||||
/* 2. do a samr_Connect to get a policy handle */
|
||||
status = dcerpc_samr_Connect(c.pdc.out.dcerpc_pipe, mem_ctx, &sc);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_Connect failed: %s\n",
|
||||
nt_errstr(status));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* check result of samr_connect */
|
||||
/* check result of samr_Connect */
|
||||
if (!NT_STATUS_IS_OK(sc.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_Connect failed: %s\n",
|
||||
nt_errstr(sc.out.result));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* do a samr_LookupDomain */
|
||||
d_name.name = r->rpc.in.domain_name;
|
||||
/* prepare samr_LookupDomain */
|
||||
d_name.name = r->samr.in.domain_name;
|
||||
ld.in.handle = &p_handle;
|
||||
ld.in.domain = &d_name;
|
||||
|
||||
/* 3. do a samr_LookupDomain to get the domain sid */
|
||||
status = dcerpc_samr_LookupDomain(c.pdc.out.dcerpc_pipe, mem_ctx, &ld);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_LookupDomain for [%s] failed: %s\n",
|
||||
r->rpc.in.domain_name, nt_errstr(status));
|
||||
r->samr.in.domain_name, nt_errstr(status));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* check result of samr_LookupDomain */
|
||||
if (!NT_STATUS_IS_OK(ld.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_LookupDomain for [%s] failed: %s\n",
|
||||
r->rpc.in.domain_name, nt_errstr(ld.out.result));
|
||||
r->samr.in.domain_name, nt_errstr(ld.out.result));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* do a samr_OpenDomain to get a domain handle */
|
||||
/* prepare samr_OpenDomain */
|
||||
ZERO_STRUCT(d_handle);
|
||||
od.in.handle = &p_handle;
|
||||
od.in.access_mask = SEC_RIGHTS_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.pdc.out.dcerpc_pipe, mem_ctx, &od);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_OpenDomain for [%s] failed: %s\n",
|
||||
r->rpc.in.domain_name, nt_errstr(status));
|
||||
r->samr.in.domain_name, nt_errstr(status));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* check result of samr_LookupDomain */
|
||||
/* check result of samr_OpenDomain */
|
||||
if (!NT_STATUS_IS_OK(od.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_OpenDomain for [%s] failed: %s\n",
|
||||
r->rpc.in.domain_name, nt_errstr(od.out.result));
|
||||
r->samr.in.domain_name, nt_errstr(od.out.result));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* do a samr_LookupNames for the account_name to get the RID */
|
||||
/* prepare samr_LookupNames */
|
||||
ln.in.handle = &d_handle;
|
||||
ln.in.num_names = 1;
|
||||
ln.in.names = talloc_array_p(mem_ctx, struct samr_Name, 1);
|
||||
if (!ln.in.names) {
|
||||
r->rpc.out.error_string = "Out of Memory";
|
||||
r->samr.out.error_string = "Out of Memory";
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
ln.in.names[0].name = r->rpc.in.account_name;
|
||||
ln.in.names[0].name = r->samr.in.account_name;
|
||||
|
||||
/* 5. do a samr_LookupNames to get the users rid */
|
||||
status = dcerpc_samr_LookupNames(c.pdc.out.dcerpc_pipe, mem_ctx, &ln);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_LookupNames for [%s] failed: %s\n",
|
||||
r->rpc.in.account_name, nt_errstr(status));
|
||||
r->samr.in.account_name, nt_errstr(status));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* check result of samr_LookupDomain */
|
||||
/* check result of samr_LookupNames */
|
||||
if (!NT_STATUS_IS_OK(ln.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_LookupNames for [%s] failed: %s\n",
|
||||
r->rpc.in.account_name, nt_errstr(ln.out.result));
|
||||
r->samr.in.account_name, nt_errstr(ln.out.result));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* check if we got one RID for the user */
|
||||
if (ln.out.rids.count != 1) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_LookupNames for [%s] returns %d RIDs\n",
|
||||
r->rpc.in.account_name, ln.out.rids.count);
|
||||
r->samr.in.account_name, ln.out.rids.count);
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* do samr_OpenUser to get the user handle */
|
||||
/* prepare samr_OpenUser */
|
||||
ZERO_STRUCT(u_handle);
|
||||
ou.in.handle = &d_handle;
|
||||
ou.in.access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
|
||||
ou.in.rid = ln.out.rids.ids[0];
|
||||
ou.out.acct_handle = &u_handle;
|
||||
|
||||
/* 6. do a samr_OpenUser to get a user handle */
|
||||
status = dcerpc_samr_OpenUser(c.pdc.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\n",
|
||||
r->samr.in.account_name, nt_errstr(status));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* prepare password set with samr_UserInfo26 */
|
||||
encode_pw_buffer(u_info.info26.password.data, r->rpc.in.newpassword, STR_UNICODE);
|
||||
u_info.info26.pw_len = strlen(r->rpc.in.newpassword);
|
||||
/* check result of samr_OpenUser */
|
||||
if (!NT_STATUS_IS_OK(ou.out.result)) {
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"samr_OpenUser for [%s] failed: %s\n",
|
||||
r->samr.in.account_name, nt_errstr(ou.out.result));
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
/* prepare samr_SetUserInfo level 26 */
|
||||
encode_pw_buffer(u_info.info26.password.data, r->samr.in.newpassword, STR_UNICODE);
|
||||
u_info.info26.pw_len = strlen(r->samr.in.newpassword);
|
||||
|
||||
status = dcerpc_fetch_session_key(c.pdc.out.dcerpc_pipe, &session_key);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"dcerpc_fetch_session_key failed: %s\n",
|
||||
nt_errstr(status));
|
||||
goto disconnect;
|
||||
@@ -439,19 +472,20 @@ static NTSTATUS libnet_SetPassword_rpc(struct libnet_context *ctx, TALLOC_CTX *m
|
||||
sui.in.info = &u_info;
|
||||
sui.in.level = 26;
|
||||
|
||||
/* 7. try samr_SetUserInfo level 26 to set the password */
|
||||
status = dcerpc_samr_SetUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &sui);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"SetUserInfo level 26 for [%s] failed: %s\n",
|
||||
r->rpc.in.account_name, nt_errstr(status));
|
||||
r->samr.in.account_name, nt_errstr(status));
|
||||
goto UserInfo25;
|
||||
}
|
||||
|
||||
/* check result of samr_LookupDomain */
|
||||
/* check result of samr_SetUserInfo level 26 */
|
||||
if (!NT_STATUS_IS_OK(sui.out.result)) {
|
||||
r->rpc.out.error_string = talloc_asprintf(mem_ctx,
|
||||
r->samr.out.error_string = talloc_asprintf(mem_ctx,
|
||||
"SetUserInfo level 26 for [%s] failed: %s\n",
|
||||
r->rpc.in.account_name, nt_errstr(sui.out.result));
|
||||
r->samr.in.account_name, nt_errstr(sui.out.result));
|
||||
goto UserInfo25;
|
||||
}
|
||||
|
||||
@@ -469,14 +503,14 @@ static NTSTATUS libnet_SetPassword_generic(struct libnet_context *ctx, TALLOC_CT
|
||||
NTSTATUS status;
|
||||
union libnet_SetPassword r2;
|
||||
|
||||
r2.rpc.level = LIBNET_SET_PASSWORD_RPC;
|
||||
r2.rpc.in.account_name = r->generic.in.account_name;
|
||||
r2.rpc.in.domain_name = r->generic.in.domain_name;
|
||||
r2.rpc.in.newpassword = r->generic.in.newpassword;
|
||||
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;
|
||||
|
||||
status = libnet_SetPassword(ctx, mem_ctx, &r2);
|
||||
|
||||
r->generic.out.error_string = r2.rpc.out.error_string;
|
||||
r->generic.out.error_string = r2.samr.out.error_string;
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -486,8 +520,8 @@ NTSTATUS libnet_SetPassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, uni
|
||||
switch (r->generic.level) {
|
||||
case LIBNET_SET_PASSWORD_GENERIC:
|
||||
return libnet_SetPassword_generic(ctx, mem_ctx, r);
|
||||
case LIBNET_SET_PASSWORD_RPC:
|
||||
return libnet_SetPassword_rpc(ctx, mem_ctx, r);
|
||||
case LIBNET_SET_PASSWORD_SAMR:
|
||||
return libnet_SetPassword_samr(ctx, mem_ctx, r);
|
||||
case LIBNET_SET_PASSWORD_KRB5:
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
case LIBNET_SET_PASSWORD_LDAP:
|
||||
|
||||
Reference in New Issue
Block a user