summaryrefslogtreecommitdiff
path: root/source3/rpcclient/cmd_samr.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpcclient/cmd_samr.c')
-rw-r--r--source3/rpcclient/cmd_samr.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index 979941193f..426e7e9744 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -2617,6 +2617,241 @@ static NTSTATUS cmd_samr_chgpasswd3(struct rpc_pipe_client *cli,
return result;
}
+static NTSTATUS cmd_samr_setuserinfo_int(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv,
+ int opcode)
+{
+ POLICY_HND connect_pol, domain_pol, user_pol;
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ const char *user, *param;
+ uint32_t access_mask = MAXIMUM_ALLOWED_ACCESS;
+ uint32_t level;
+ uint32_t user_rid;
+ union samr_UserInfo info;
+ struct samr_CryptPassword pwd_buf;
+ struct samr_CryptPasswordEx pwd_buf_ex;
+ uint8_t nt_hash[16];
+ uint8_t lm_hash[16];
+ DATA_BLOB session_key;
+ uint8_t password_expired = 0;
+
+ if (argc < 4) {
+ printf("Usage: %s username level password [password_expired]\n",
+ argv[0]);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ user = argv[1];
+ level = atoi(argv[2]);
+ param = argv[3];
+
+ if (argc >= 5) {
+ password_expired = atoi(argv[4]);
+ }
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_samr_CryptPassword(param, &session_key, &pwd_buf);
+ init_samr_CryptPasswordEx(param, &session_key, &pwd_buf_ex);
+ nt_lm_owf_gen(param, nt_hash, lm_hash);
+
+ switch (level) {
+ case 18:
+ {
+ DATA_BLOB in,out;
+ in = data_blob_const(nt_hash, 16);
+ out = data_blob_talloc_zero(mem_ctx, 16);
+ sess_crypt_blob(&out, &in, &session_key, true);
+ memcpy(nt_hash, out.data, out.length);
+ }
+ {
+ DATA_BLOB in,out;
+ in = data_blob_const(lm_hash, 16);
+ out = data_blob_talloc_zero(mem_ctx, 16);
+ sess_crypt_blob(&out, &in, &session_key, true);
+ memcpy(lm_hash, out.data, out.length);
+ }
+
+ init_samr_user_info18(&info.info18,
+ lm_hash,
+ nt_hash,
+ password_expired);
+ break;
+ case 21:
+ ZERO_STRUCT(info.info21);
+
+ info.info21.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
+ SAMR_FIELD_LM_PASSWORD_PRESENT;
+ if (argc >= 5) {
+ info.info21.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
+ info.info21.password_expired = password_expired;
+ }
+
+ info.info21.lm_password_set = true;
+ info.info21.lm_owf_password.length = 16;
+ info.info21.lm_owf_password.size = 16;
+
+ info.info21.nt_password_set = true;
+ info.info21.nt_owf_password.length = 16;
+ info.info21.nt_owf_password.size = 16;
+
+ {
+ DATA_BLOB in,out;
+ in = data_blob_const(nt_hash, 16);
+ out = data_blob_talloc_zero(mem_ctx, 16);
+ sess_crypt_blob(&out, &in, &session_key, true);
+ info.info21.nt_owf_password.array =
+ (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
+ }
+ {
+ DATA_BLOB in,out;
+ in = data_blob_const(lm_hash, 16);
+ out = data_blob_talloc_zero(mem_ctx, 16);
+ sess_crypt_blob(&out, &in, &session_key, true);
+ info.info21.lm_owf_password.array =
+ (uint16_t *)talloc_memdup(mem_ctx, out.data, 16);
+ }
+
+ break;
+ case 23:
+ ZERO_STRUCT(info.info23);
+
+ info.info23.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
+ SAMR_FIELD_LM_PASSWORD_PRESENT;
+ if (argc >= 5) {
+ info.info23.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
+ info.info23.info.password_expired = password_expired;
+ }
+
+ info.info23.password = pwd_buf;
+
+ break;
+ case 24:
+ init_samr_user_info24(&info.info24,
+ &pwd_buf,
+ password_expired);
+ break;
+ case 25:
+ ZERO_STRUCT(info.info25);
+
+ info.info25.info.fields_present = SAMR_FIELD_NT_PASSWORD_PRESENT |
+ SAMR_FIELD_LM_PASSWORD_PRESENT;
+ if (argc >= 5) {
+ info.info25.info.fields_present |= SAMR_FIELD_EXPIRED_FLAG;
+ info.info25.info.password_expired = password_expired;
+ }
+
+ info.info25.password = pwd_buf_ex;
+
+ break;
+ case 26:
+ init_samr_user_info26(&info.info26,
+ &pwd_buf_ex,
+ password_expired);
+ break;
+ default:
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ /* Get sam policy handle */
+
+ status = rpccli_try_samr_connects(cli, mem_ctx,
+ MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+
+ if (!NT_STATUS_IS_OK(status))
+ goto done;
+
+ /* Get domain policy handle */
+
+ status = rpccli_samr_OpenDomain(cli, mem_ctx,
+ &connect_pol,
+ access_mask,
+ &domain_sid,
+ &domain_pol);
+
+ if (!NT_STATUS_IS_OK(status))
+ goto done;
+
+ user_rid = strtol(user, NULL, 0);
+ if (user_rid) {
+ status = rpccli_samr_OpenUser(cli, mem_ctx,
+ &domain_pol,
+ access_mask,
+ user_rid,
+ &user_pol);
+ }
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) ||
+ (user_rid == 0)) {
+
+ /* Probably this was a user name, try lookupnames */
+ struct samr_Ids rids, types;
+ struct lsa_String lsa_acct_name;
+
+ init_lsa_String(&lsa_acct_name, user);
+
+ status = rpccli_samr_LookupNames(cli, mem_ctx,
+ &domain_pol,
+ 1,
+ &lsa_acct_name,
+ &rids,
+ &types);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = rpccli_samr_OpenUser(cli, mem_ctx,
+ &domain_pol,
+ access_mask,
+ rids.ids[0],
+ &user_pol);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ switch (opcode) {
+ case NDR_SAMR_SETUSERINFO:
+ status = rpccli_samr_SetUserInfo(cli, mem_ctx,
+ &user_pol,
+ level,
+ &info);
+ break;
+ case NDR_SAMR_SETUSERINFO2:
+ status = rpccli_samr_SetUserInfo2(cli, mem_ctx,
+ &user_pol,
+ level,
+ &info);
+ break;
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ done:
+ return status;
+}
+
+static NTSTATUS cmd_samr_setuserinfo(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
+ NDR_SAMR_SETUSERINFO);
+}
+
+static NTSTATUS cmd_samr_setuserinfo2(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ return cmd_samr_setuserinfo_int(cli, mem_ctx, argc, argv,
+ NDR_SAMR_SETUSERINFO2);
+}
+
static NTSTATUS cmd_samr_get_dispinfo_idx(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
@@ -2718,5 +2953,7 @@ struct cmd_set samr_commands[] = {
{ "chgpasswd2", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd2, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
{ "chgpasswd3", RPC_RTYPE_NTSTATUS, cmd_samr_chgpasswd3, NULL, &ndr_table_samr.syntax_id, NULL, "Change user password", "" },
{ "getdispinfoidx", RPC_RTYPE_NTSTATUS, cmd_samr_get_dispinfo_idx, NULL, &ndr_table_samr.syntax_id, NULL, "Get Display Information Index", "" },
+ { "setuserinfo", RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo, NULL, &ndr_table_samr.syntax_id, NULL, "Set user info", "" },
+ { "setuserinfo2", RPC_RTYPE_NTSTATUS, cmd_samr_setuserinfo2, NULL, &ndr_table_samr.syntax_id, NULL, "Set user info2", "" },
{ NULL }
};