NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *username, DATA_BLOB new_nt_password_blob, DATA_BLOB old_nt_hash_enc_blob, DATA_BLOB new_lm_password_blob, DATA_BLOB old_lm_hash_enc_blob) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct samr_CryptPassword new_nt_password; struct samr_CryptPassword new_lm_password; struct samr_Password old_nt_hash_enc; struct samr_Password old_lm_hash_enc; struct lsa_String server, account; DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n")); init_lsa_String(&server, cli->srv_name_slash); init_lsa_String(&account, username); memcpy(&new_nt_password.data, new_nt_password_blob.data, 516); memcpy(&new_lm_password.data, new_lm_password_blob.data, 516); memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16); memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16); result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx, &server, &account, &new_nt_password, &old_nt_hash_enc, true, &new_lm_password, &old_lm_hash_enc); return result; }
NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *username, const char *newpassword, const char *oldpassword) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct samr_CryptPassword new_nt_password; struct samr_CryptPassword new_lm_password; struct samr_Password old_nt_hash_enc; struct samr_Password old_lanman_hash_enc; uchar old_nt_hash[16]; uchar old_lanman_hash[16]; uchar new_nt_hash[16]; uchar new_lanman_hash[16]; struct lsa_String server, account; DEBUG(10,("rpccli_samr_chgpasswd_user2\n")); init_lsa_String(&server, cli->srv_name_slash); init_lsa_String(&account, username); /* Calculate the MD4 hash (NT compatible) of the password */ E_md4hash(oldpassword, old_nt_hash); E_md4hash(newpassword, new_nt_hash); if (lp_client_lanman_auth() && E_deshash(newpassword, new_lanman_hash) && E_deshash(oldpassword, old_lanman_hash)) { /* E_deshash returns false for 'long' passwords (> 14 DOS chars). This allows us to match Win2k, which does not store a LM hash for these passwords (which would reduce the effective password length to 14) */ encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE); arcfour_crypt(new_lm_password.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); } else { ZERO_STRUCT(new_lm_password); ZERO_STRUCT(old_lanman_hash_enc); } encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE); arcfour_crypt(new_nt_password.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx, &server, &account, &new_nt_password, &old_nt_hash_enc, true, &new_lm_password, &old_lanman_hash_enc); return result; }
static bool get_policy_handle(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) { struct eventlog_OpenEventLogW r; struct eventlog_OpenUnknown0 unknown0; unknown0.unknown0 = 0x005c; unknown0.unknown1 = 0x0001; r.in.unknown0 = &unknown0; init_lsa_String(&r.in.logname, "dns server"); init_lsa_String(&r.in.servername, NULL); r.in.unknown2 = 0x00000001; r.in.unknown3 = 0x00000001; r.out.handle = handle; torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_OpenEventLogW(p, tctx, &r), "OpenEventLog failed"); torture_assert_ntstatus_ok(tctx, r.out.result, "OpenEventLog failed"); return true; }
static NTSTATUS get_eventlog_handle(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *log, struct policy_handle *handle) { NTSTATUS status, result; struct eventlog_OpenUnknown0 unknown0; struct lsa_String logname, servername; struct dcerpc_binding_handle *b = cli->binding_handle; unknown0.unknown0 = 0x005c; unknown0.unknown1 = 0x0001; init_lsa_String(&logname, log); init_lsa_String(&servername, NULL); status = dcerpc_eventlog_OpenEventLogW(b, mem_ctx, &unknown0, &logname, &servername, 0x00000001, /* major */ 0x00000001, /* minor */ handle, &result); if (!NT_STATUS_IS_OK(status)) { return status; } return result; }
NTSTATUS dcerpc_samr_chng_pswd_auth_crap(struct dcerpc_binding_handle *h, TALLOC_CTX *mem_ctx, const char *srv_name_slash, const char *username, DATA_BLOB new_nt_password_blob, DATA_BLOB old_nt_hash_enc_blob, DATA_BLOB new_lm_password_blob, DATA_BLOB old_lm_hash_enc_blob, NTSTATUS *presult) { NTSTATUS status; struct samr_CryptPassword new_nt_password; struct samr_CryptPassword new_lm_password; struct samr_Password old_nt_hash_enc; struct samr_Password old_lm_hash_enc; struct lsa_String server, account; DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n")); ZERO_STRUCT(new_nt_password); ZERO_STRUCT(new_lm_password); ZERO_STRUCT(old_nt_hash_enc); ZERO_STRUCT(old_lm_hash_enc); init_lsa_String(&server, srv_name_slash); init_lsa_String(&account, username); if (new_nt_password_blob.data && new_nt_password_blob.length >= 516) { memcpy(&new_nt_password.data, new_nt_password_blob.data, 516); } if (new_lm_password_blob.data && new_lm_password_blob.length >= 516) { memcpy(&new_lm_password.data, new_lm_password_blob.data, 516); } if (old_nt_hash_enc_blob.data && old_nt_hash_enc_blob.length >= 16) { memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16); } if (old_lm_hash_enc_blob.data && old_lm_hash_enc_blob.length >= 16) { memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16); } status = dcerpc_samr_ChangePasswordUser2(h, mem_ctx, &server, &account, &new_nt_password, &old_nt_hash_enc, true, &new_lm_password, &old_lm_hash_enc, presult); return status; }
void init_netr_IdentityInfo(struct netr_IdentityInfo *r, const char *domain_name, uint32_t parameter_control, uint32_t logon_id_low, uint32_t logon_id_high, const char *account_name, const char *workstation) { init_lsa_String(&r->domain_name, domain_name); r->parameter_control = parameter_control; r->logon_id_low = logon_id_low; r->logon_id_high = logon_id_high; init_lsa_String(&r->account_name, account_name); init_lsa_String(&r->workstation, workstation); }
static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx, struct netr_SamInfo3 *info3) { NTSTATUS status; struct dom_sid *system_sid; /* Set account name */ init_lsa_String(&info3->base.account_name, "SYSTEM"); /* Set domain name */ init_lsa_StringLarge(&info3->base.logon_domain, "NT AUTHORITY"); /* The SID set here will be overwirtten anyway, but try and make it SID_NT_SYSTEM anyway */ /* Domain sid is NT_AUTHORITY */ system_sid = dom_sid_parse_talloc(mem_ctx, SID_NT_SYSTEM); if (system_sid == NULL) { return NT_STATUS_NO_MEMORY; } status = dom_sid_split_rid(mem_ctx, system_sid, &info3->base.domain_sid, &info3->base.rid); TALLOC_FREE(system_sid); if (!NT_STATUS_IS_OK(status)) { return status; } /* Primary gid is the same */ info3->base.primary_gid = info3->base.rid; return NT_STATUS_OK; }
bool torture_setup_privs(struct torture_context *tctx, struct dcerpc_pipe *p, uint32_t num_privs, const char **privs, const struct dom_sid *user_sid) { struct dcerpc_binding_handle *b = p->binding_handle; struct policy_handle *handle; int i; torture_assert(tctx, test_lsa_OpenPolicy2(b, tctx, &handle), "failed to open policy"); for (i=0; i < num_privs; i++) { struct lsa_LookupPrivValue r; struct lsa_LUID luid; struct lsa_String name; init_lsa_String(&name, privs[i]); r.in.handle = handle; r.in.name = &name; r.out.luid = &luid; torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupPrivValue_r(b, tctx, &r), "lsa_LookupPrivValue failed"); if (!NT_STATUS_IS_OK(r.out.result)) { torture_comment(tctx, "lsa_LookupPrivValue failed for '%s' with %s\n", privs[i], nt_errstr(r.out.result)); return false; } } { struct lsa_AddAccountRights r; struct lsa_RightSet rights; rights.count = num_privs; rights.names = talloc_zero_array(tctx, struct lsa_StringLarge, rights.count); for (i=0; i < rights.count; i++) { init_lsa_StringLarge(&rights.names[i], privs[i]); } r.in.handle = handle; r.in.sid = discard_const_p(struct dom_sid, user_sid); r.in.rights = &rights; torture_assert_ntstatus_ok(tctx, dcerpc_lsa_AddAccountRights_r(b, tctx, &r), "lsa_AddAccountRights failed"); torture_assert_ntstatus_ok(tctx, r.out.result, "lsa_AddAccountRights failed"); } test_lsa_Close(b, tctx, handle); return true; }
static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status; struct policy_handle handle; struct lsa_String name; struct lsa_DATA_BUF *val; DATA_BLOB session_key; DATA_BLOB blob = data_blob_null; char *secret; if (argc < 2) { printf("Usage: %s name\n", argv[0]); return NT_STATUS_OK; } status = rpccli_lsa_open_policy2(cli, mem_ctx, true, SEC_FLAG_MAXIMUM_ALLOWED, &handle); if (!NT_STATUS_IS_OK(status)) { return status; } init_lsa_String(&name, argv[1]); ZERO_STRUCT(val); status = rpccli_lsa_RetrievePrivateData(cli, mem_ctx, &handle, &name, &val); if (!NT_STATUS_IS_OK(status)) { goto done; } status = cli_get_session_key(mem_ctx, cli, &session_key); if (!NT_STATUS_IS_OK(status)) { goto done; } if (val) { blob = data_blob_const(val->data, val->length); } secret = sess_decrypt_string(mem_ctx, &blob, &session_key); if (secret) { d_printf("secret: %s\n", secret); } done: if (is_valid_policy_hnd(&handle)) { rpccli_lsa_Close(cli, mem_ctx, &handle); } return status; }
static NTSTATUS cmd_eventlog_registerevsource(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status, result; struct policy_handle log_handle; struct lsa_String module_name, reg_module_name; struct eventlog_OpenUnknown0 unknown0; struct dcerpc_binding_handle *b = cli->binding_handle; unknown0.unknown0 = 0x005c; unknown0.unknown1 = 0x0001; if (argc != 2) { printf("Usage: %s logname\n", argv[0]); return NT_STATUS_OK; } init_lsa_String(&module_name, "rpcclient"); init_lsa_String(®_module_name, NULL); status = dcerpc_eventlog_RegisterEventSourceW(b, mem_ctx, &unknown0, &module_name, ®_module_name, 1, /* major_version */ 1, /* minor_version */ &log_handle, &result); if (!NT_STATUS_IS_OK(status)) { goto done; } if (!NT_STATUS_IS_OK(result)) { status = result; goto done; } done: dcerpc_eventlog_DeregisterEventSource(b, mem_ctx, &log_handle, &result); return status; }
static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_cli, struct policy_handle *domain_handle, const char *group_name, uint32_t access_rights, struct policy_handle *alias_handle) { NTSTATUS status, result; struct lsa_String lsa_account_name; struct samr_Ids user_rids, name_types; struct dcerpc_binding_handle *b = pipe_cli->binding_handle; init_lsa_String(&lsa_account_name, group_name); status = dcerpc_samr_LookupNames(b, mem_ctx, domain_handle, 1, &lsa_account_name, &user_rids, &name_types, &result); if (!NT_STATUS_IS_OK(status)) { return status; } if (!NT_STATUS_IS_OK(result)) { return result; } if (user_rids.count != 1) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } if (name_types.count != 1) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } switch (name_types.ids[0]) { case SID_NAME_ALIAS: case SID_NAME_WKN_GRP: break; default: return NT_STATUS_INVALID_SID; } status = dcerpc_samr_OpenAlias(b, mem_ctx, domain_handle, access_rights, user_rids.ids[0], alias_handle, &result); if (!NT_STATUS_IS_OK(status)) { return status; } return result; }
static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *ctx, struct policy_handle *pol ) { NTSTATUS result; uint32 enum_context = 0; uint32 pref_max_length=0x1000; int i; uint16 lang_id=0; uint16 lang_id_sys=0; uint16 lang_id_desc; struct lsa_StringLarge *description = NULL; struct lsa_PrivArray priv_array; result = rpccli_lsa_EnumPrivs(pipe_hnd, ctx, pol, &enum_context, &priv_array, pref_max_length); if ( !NT_STATUS_IS_OK(result) ) return result; /* Print results */ for (i = 0; i < priv_array.count; i++) { struct lsa_String lsa_name; d_printf("%30s ", priv_array.privs[i].name.string ? priv_array.privs[i].name.string : "*unknown*" ); /* try to get the description */ init_lsa_String(&lsa_name, priv_array.privs[i].name.string); result = rpccli_lsa_LookupPrivDisplayName(pipe_hnd, ctx, pol, &lsa_name, lang_id, lang_id_sys, &description, &lang_id_desc); if (!NT_STATUS_IS_OK(result)) { d_printf("??????\n"); continue; } d_printf("%s\n", description->string); } return NT_STATUS_OK; }
static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status; struct policy_handle handle; struct lsa_String name; struct lsa_DATA_BUF val; DATA_BLOB session_key; DATA_BLOB enc_key; if (argc < 3) { printf("Usage: %s name secret\n", argv[0]); return NT_STATUS_OK; } status = rpccli_lsa_open_policy2(cli, mem_ctx, true, SEC_FLAG_MAXIMUM_ALLOWED, &handle); if (!NT_STATUS_IS_OK(status)) { return status; } init_lsa_String(&name, argv[1]); ZERO_STRUCT(val); status = cli_get_session_key(mem_ctx, cli, &session_key); if (!NT_STATUS_IS_OK(status)) { goto done; } enc_key = sess_encrypt_string(argv[2], &session_key); val.length = enc_key.length; val.size = enc_key.length; val.data = enc_key.data; status = rpccli_lsa_StorePrivateData(cli, mem_ctx, &handle, &name, &val); if (!NT_STATUS_IS_OK(status)) { goto done; } done: if (is_valid_policy_hnd(&handle)) { rpccli_lsa_Close(cli, mem_ctx, &handle); } return status; }
static NTSTATUS libnetapi_lsa_lookup_names3(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *lsa_pipe, const char *name, struct dom_sid *sid) { NTSTATUS status, result; struct policy_handle lsa_handle; struct dcerpc_binding_handle *b = lsa_pipe->binding_handle; struct lsa_RefDomainList *domains = NULL; struct lsa_TransSidArray3 sids; uint32_t count = 0; struct lsa_String names; uint32_t num_names = 1; if (!sid || !name) { return NT_STATUS_INVALID_PARAMETER; } ZERO_STRUCT(sids); init_lsa_String(&names, name); status = rpccli_lsa_open_policy2(lsa_pipe, mem_ctx, false, SEC_STD_READ_CONTROL | LSA_POLICY_VIEW_LOCAL_INFORMATION | LSA_POLICY_LOOKUP_NAMES, &lsa_handle); NT_STATUS_NOT_OK_RETURN(status); status = dcerpc_lsa_LookupNames3(b, mem_ctx, &lsa_handle, num_names, &names, &domains, &sids, LSA_LOOKUP_NAMES_ALL, /* sure ? */ &count, 0, 0, &result); NT_STATUS_NOT_OK_RETURN(status); NT_STATUS_NOT_OK_RETURN(result); if (count != 1 || sids.count != 1) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } sid_copy(sid, sids.sids[0].sid); return NT_STATUS_OK; }
static NTSTATUS cmd_lsa_lookup_names4(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32_t num_names; struct lsa_String *names; struct lsa_RefDomainList *domains; struct lsa_TransSidArray3 sids; uint32_t count = 0; int i; if (argc == 1) { printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]); return NT_STATUS_OK; } ZERO_STRUCT(sids); num_names = argc-1; names = talloc_array(mem_ctx, struct lsa_String, num_names); NT_STATUS_HAVE_NO_MEMORY(names); for (i=0; i < num_names; i++) { init_lsa_String(&names[i], argv[i+1]); } result = rpccli_lsa_LookupNames4(cli, mem_ctx, num_names, names, &domains, &sids, 1, &count, 0, 0); if (!NT_STATUS_IS_OK(result)) { return result; } for (i = 0; i < sids.count; i++) { fstring sid_str; sid_to_fstring(sid_str, sids.sids[i].sid); printf("%s %s (%s: %d)\n", argv[i+1], sid_str, sid_type_lookup(sids.sids[i].sid_type), sids.sids[i].sid_type); } return result; }
static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx, uint32_t level, uint8_t *buffer, enum samr_AliasInfoEnum *alias_level, union samr_AliasInfo **alias_info) { struct LOCALGROUP_INFO_0 *info0; struct LOCALGROUP_INFO_1 *info1; struct LOCALGROUP_INFO_1002 *info1002; union samr_AliasInfo *info = NULL; info = talloc_zero(mem_ctx, union samr_AliasInfo); W_ERROR_HAVE_NO_MEMORY(info); switch (level) { case 0: info0 = (struct LOCALGROUP_INFO_0 *)buffer; init_lsa_String(&info->name, info0->lgrpi0_name); *alias_level = ALIASINFONAME; break; case 1: info1 = (struct LOCALGROUP_INFO_1 *)buffer; /* group name will be ignored */ init_lsa_String(&info->description, info1->lgrpi1_comment); *alias_level = ALIASINFODESCRIPTION; break; case 1002: info1002 = (struct LOCALGROUP_INFO_1002 *)buffer; init_lsa_String(&info->description, info1002->lgrpi1002_comment); *alias_level = ALIASINFODESCRIPTION; break; } *alias_info = info; return WERR_OK; }
static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx, struct netr_SamInfo3 *info3) { const char *guest_account = lp_guestaccount(); struct dom_sid domain_sid; struct passwd *pwd; const char *tmp; pwd = Get_Pwnam_alloc(mem_ctx, guest_account); if (pwd == NULL) { DEBUG(0,("SamInfo3_for_guest: Unable to locate guest " "account [%s]!\n", guest_account)); return NT_STATUS_NO_SUCH_USER; } /* Set account name */ tmp = talloc_strdup(mem_ctx, pwd->pw_name); if (tmp == NULL) { return NT_STATUS_NO_MEMORY; } init_lsa_String(&info3->base.account_name, tmp); /* Set domain name */ tmp = talloc_strdup(mem_ctx, get_global_sam_name()); if (tmp == NULL) { return NT_STATUS_NO_MEMORY; } init_lsa_StringLarge(&info3->base.logon_domain, tmp); /* Domain sid */ sid_copy(&domain_sid, get_global_sam_sid()); info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid); if (info3->base.domain_sid == NULL) { return NT_STATUS_NO_MEMORY; } /* Guest rid */ info3->base.rid = DOMAIN_RID_GUEST; /* Primary gid */ info3->base.primary_gid = DOMAIN_RID_GUESTS; /* Set as guest */ info3->base.user_flags = NETLOGON_GUEST; TALLOC_FREE(pwd); return NT_STATUS_OK; }
static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status; struct policy_handle handle, sec_handle; struct lsa_String name; if (argc < 2) { printf("Usage: %s name\n", argv[0]); return NT_STATUS_OK; } status = rpccli_lsa_open_policy2(cli, mem_ctx, true, SEC_FLAG_MAXIMUM_ALLOWED, &handle); if (!NT_STATUS_IS_OK(status)) { return status; } init_lsa_String(&name, argv[1]); status = rpccli_lsa_OpenSecret(cli, mem_ctx, &handle, name, SEC_FLAG_MAXIMUM_ALLOWED, &sec_handle); if (!NT_STATUS_IS_OK(status)) { goto done; } status = rpccli_lsa_DeleteObject(cli, mem_ctx, &sec_handle); if (!NT_STATUS_IS_OK(status)) { goto done; } done: if (is_valid_policy_hnd(&sec_handle)) { rpccli_lsa_Close(cli, mem_ctx, &sec_handle); } if (is_valid_policy_hnd(&handle)) { rpccli_lsa_Close(cli, mem_ctx, &handle); } return status; }
static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED; union lsa_TrustedDomainInfo *info = NULL; enum lsa_TrustDomInfoEnum info_class = 1; struct lsa_String trusted_domain; uint8_t nt_hash[16]; if (argc > 3 || argc < 2) { printf("Usage: %s [name] [info_class]\n", argv[0]); return NT_STATUS_OK; } if (argc == 3) info_class = atoi(argv[2]); result = rpccli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol); if (!NT_STATUS_IS_OK(result)) goto done; init_lsa_String(&trusted_domain, argv[1]); result = rpccli_lsa_QueryTrustedDomainInfoByName(cli, mem_ctx, &pol, &trusted_domain, info_class, &info); if (!NT_STATUS_IS_OK(result)) goto done; if (!rpccli_get_pwd_hash(cli, nt_hash)) { d_fprintf(stderr, "Could not get pwd hash\n"); goto done; } display_trust_dom_info(mem_ctx, info, info_class, nt_hash); done: rpccli_lsa_Close(cli, mem_ctx, &pol); return result; }
static NTSTATUS cmd_eventlog_backuplog(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status, result; struct policy_handle handle; struct lsa_String backup_filename; const char *tmp; struct dcerpc_binding_handle *b = cli->binding_handle; if (argc != 3) { printf("Usage: %s logname backupname\n", argv[0]); return NT_STATUS_OK; } status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle); if (!NT_STATUS_IS_OK(status)) { return status; } tmp = talloc_asprintf(mem_ctx, "\\??\\%s", argv[2]); if (!tmp) { status = NT_STATUS_NO_MEMORY; goto done; } init_lsa_String(&backup_filename, tmp); status = dcerpc_eventlog_BackupEventLogW(b, mem_ctx, &handle, &backup_filename, &result); if (!NT_STATUS_IS_OK(status)) { goto done; } if (!NT_STATUS_IS_OK(result)) { status = result; goto done; } done: dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result); return status; }
static NTSTATUS cmd_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint16 lang_id=0; uint16 lang_id_sys=0; uint16 lang_id_desc; struct lsa_String lsa_name; struct lsa_StringLarge *description = NULL; if (argc != 2) { printf("Usage: %s privilege name\n", argv[0]); return NT_STATUS_OK; } result = rpccli_lsa_open_policy(cli, mem_ctx, True, SEC_FLAG_MAXIMUM_ALLOWED, &pol); if (!NT_STATUS_IS_OK(result)) goto done; init_lsa_String(&lsa_name, argv[1]); result = rpccli_lsa_LookupPrivDisplayName(cli, mem_ctx, &pol, &lsa_name, lang_id, lang_id_sys, &description, &lang_id_desc); if (!NT_STATUS_IS_OK(result)) goto done; /* Print results */ printf("%s -> %s (language: 0x%x)\n", argv[1], description->string, lang_id_desc); rpccli_lsa_Close(cli, mem_ctx, &pol); done: return result; }
void init_netr_SamBaseInfo(struct netr_SamBaseInfo *r, NTTIME last_logon, NTTIME last_logoff, NTTIME acct_expiry, NTTIME last_password_change, NTTIME allow_password_change, NTTIME force_password_change, const char *account_name, const char *full_name, const char *logon_script, const char *profile_path, const char *home_directory, const char *home_drive, uint16_t logon_count, uint16_t bad_password_count, uint32_t rid, uint32_t primary_gid, struct samr_RidWithAttributeArray groups, uint32_t user_flags, struct netr_UserSessionKey key, const char *logon_server, const char *domain, struct dom_sid2 *domain_sid, struct netr_LMSessionKey LMSessKey, uint32_t acct_flags) { r->last_logon = last_logon; r->last_logoff = last_logoff; r->acct_expiry = acct_expiry; r->last_password_change = last_password_change; r->allow_password_change = allow_password_change; r->force_password_change = force_password_change; init_lsa_String(&r->account_name, account_name); init_lsa_String(&r->full_name, full_name); init_lsa_String(&r->logon_script, logon_script); init_lsa_String(&r->profile_path, profile_path); init_lsa_String(&r->home_directory, home_directory); init_lsa_String(&r->home_drive, home_drive); r->logon_count = logon_count; r->bad_password_count = bad_password_count; r->rid = rid; r->primary_gid = primary_gid; r->groups = groups; r->user_flags = user_flags; r->key = key; init_lsa_StringLarge(&r->logon_server, logon_server); init_lsa_StringLarge(&r->domain, domain); r->domain_sid = domain_sid; r->LMSessKey = LMSessKey; r->acct_flags = acct_flags; }
static NTSTATUS cmd_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_LUID luid; struct lsa_String name; if (argc != 2 ) { printf("Usage: %s name\n", argv[0]); return NT_STATUS_OK; } result = rpccli_lsa_open_policy2(cli, mem_ctx, True, SEC_FLAG_MAXIMUM_ALLOWED, &pol); if (!NT_STATUS_IS_OK(result)) goto done; init_lsa_String(&name, argv[1]); result = rpccli_lsa_LookupPrivValue(cli, mem_ctx, &pol, &name, &luid); if (!NT_STATUS_IS_OK(result)) goto done; /* Print results */ printf("%u:%u (0x%x:0x%x)\n", luid.high, luid.low, luid.high, luid.low); rpccli_lsa_Close(cli, mem_ctx, &pol); done: return result; }
static NTSTATUS get_system_info3(TALLOC_CTX *mem_ctx, struct passwd *pwd, struct netr_SamInfo3 *info3) { struct dom_sid domain_sid; const char *tmp; /* Set account name */ tmp = talloc_strdup(mem_ctx, pwd->pw_name); if (tmp == NULL) { return NT_STATUS_NO_MEMORY; } init_lsa_String(&info3->base.account_name, tmp); /* Set domain name */ tmp = talloc_strdup(mem_ctx, get_global_sam_name()); if (tmp == NULL) { return NT_STATUS_NO_MEMORY; } init_lsa_StringLarge(&info3->base.domain, tmp); /* Domain sid */ sid_copy(&domain_sid, get_global_sam_sid()); info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid); if (info3->base.domain_sid == NULL) { return NT_STATUS_NO_MEMORY; } /* Admin rid */ info3->base.rid = DOMAIN_RID_ADMINISTRATOR; /* Primary gid */ info3->base.primary_gid = BUILTIN_RID_ADMINISTRATORS; return NT_STATUS_OK; }
static NTSTATUS cmd_lsa_delete_trusted_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status; struct policy_handle handle, trustdom_handle; struct lsa_String name; struct dom_sid *sid = NULL; if (argc < 2) { printf("Usage: %s name\n", argv[0]); return NT_STATUS_OK; } status = rpccli_lsa_open_policy2(cli, mem_ctx, true, SEC_FLAG_MAXIMUM_ALLOWED, &handle); if (!NT_STATUS_IS_OK(status)) { return status; } init_lsa_String(&name, argv[1]); status = rpccli_lsa_OpenTrustedDomainByName(cli, mem_ctx, &handle, name, SEC_FLAG_MAXIMUM_ALLOWED, &trustdom_handle); if (NT_STATUS_IS_OK(status)) { goto delete_object; } { uint32_t resume_handle = 0; struct lsa_DomainList domains; int i; status = rpccli_lsa_EnumTrustDom(cli, mem_ctx, &handle, &resume_handle, &domains, 0xffff); if (!NT_STATUS_IS_OK(status)) { goto done; } for (i=0; i < domains.count; i++) { if (strequal(domains.domains[i].name.string, argv[1])) { sid = domains.domains[i].sid; break; } } if (!sid) { return NT_STATUS_INVALID_SID; } } status = rpccli_lsa_OpenTrustedDomain(cli, mem_ctx, &handle, sid, SEC_FLAG_MAXIMUM_ALLOWED, &trustdom_handle); if (!NT_STATUS_IS_OK(status)) { goto done; } delete_object: status = rpccli_lsa_DeleteObject(cli, mem_ctx, &trustdom_handle); if (!NT_STATUS_IS_OK(status)) { goto done; } done: if (is_valid_policy_hnd(&trustdom_handle)) { rpccli_lsa_Close(cli, mem_ctx, &trustdom_handle); } if (is_valid_policy_hnd(&handle)) { rpccli_lsa_Close(cli, mem_ctx, &handle); } return status; }
static NTSTATUS cmd_eventlog_reporteventsource(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status, result; struct policy_handle handle; struct dcerpc_binding_handle *b = cli->binding_handle; uint16_t num_of_strings = 1; uint32_t data_size = 0; struct lsa_String servername, sourcename; struct lsa_String *strings; uint8_t *data = NULL; uint32_t record_number = 0; time_t time_written = 0; if (argc != 2) { printf("Usage: %s logname\n", argv[0]); return NT_STATUS_OK; } status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle); if (!NT_STATUS_IS_OK(status)) { return status; } strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings); if (!strings) { return NT_STATUS_NO_MEMORY; } init_lsa_String(&strings[0], "test event written by rpcclient\n"); init_lsa_String(&servername, NULL); init_lsa_String(&sourcename, "rpcclient"); status = dcerpc_eventlog_ReportEventAndSourceW(b, mem_ctx, &handle, time(NULL), EVENTLOG_INFORMATION_TYPE, 0, /* event_category */ 0, /* event_id */ &sourcename, num_of_strings, data_size, &servername, NULL, /* user_sid */ &strings, data, 0, /* flags */ &record_number, &time_written, &result); if (!NT_STATUS_IS_OK(status)) { goto done; } if (!NT_STATUS_IS_OK(result)) { status = result; goto done; } printf("entry: %d written at %s\n", record_number, http_timestring(talloc_tos(), time_written)); done: dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result); return status; }
NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, TALLOC_CTX *mem_ctx, const char *srv_name_slash, const char *username, const char *newpassword, const char *oldpassword, struct samr_DomInfo1 **dominfo1, struct userPwdChangeFailureInformation **reject, NTSTATUS *presult) { NTSTATUS status; struct samr_CryptPassword new_nt_password; struct samr_CryptPassword new_lm_password; struct samr_Password old_nt_hash_enc; struct samr_Password old_lanman_hash_enc; uint8_t old_nt_hash[16]; uint8_t old_lanman_hash[16]; uint8_t new_nt_hash[16]; uint8_t new_lanman_hash[16]; struct lsa_String server, account; DEBUG(10,("rpccli_samr_chgpasswd_user3\n")); init_lsa_String(&server, srv_name_slash); init_lsa_String(&account, username); /* Calculate the MD4 hash (NT compatible) of the password */ E_md4hash(oldpassword, old_nt_hash); E_md4hash(newpassword, new_nt_hash); if (lp_client_lanman_auth() && E_deshash(newpassword, new_lanman_hash) && E_deshash(oldpassword, old_lanman_hash)) { /* E_deshash returns false for 'long' passwords (> 14 DOS chars). This allows us to match Win2k, which does not store a LM hash for these passwords (which would reduce the effective password length to 14) */ encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE); arcfour_crypt(new_lm_password.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); } else { ZERO_STRUCT(new_lm_password); ZERO_STRUCT(old_lanman_hash_enc); } encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE); arcfour_crypt(new_nt_password.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); status = dcerpc_samr_ChangePasswordUser3(h, mem_ctx, &server, &account, &new_nt_password, &old_nt_hash_enc, true, &new_lm_password, &old_lanman_hash_enc, NULL, dominfo1, reject, presult); return status; }
static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { struct policy_handle dom_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct lsa_PrivilegeSet privs; struct lsa_LUIDAttribute *set = NULL; DOM_SID sid; int i; ZERO_STRUCT(privs); if (argc < 3 ) { printf("Usage: %s SID [rights...]\n", argv[0]); return NT_STATUS_OK; } result = name_to_sid(cli, mem_ctx, &sid, argv[1]); if (!NT_STATUS_IS_OK(result)) { goto done; } result = rpccli_lsa_open_policy2(cli, mem_ctx, True, SEC_FLAG_MAXIMUM_ALLOWED, &dom_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } result = rpccli_lsa_OpenAccount(cli, mem_ctx, &dom_pol, &sid, SEC_FLAG_MAXIMUM_ALLOWED, &user_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } for (i=2; i<argc; i++) { struct lsa_String priv_name; struct lsa_LUID luid; init_lsa_String(&priv_name, argv[i]); result = rpccli_lsa_LookupPrivValue(cli, mem_ctx, &dom_pol, &priv_name, &luid); if (!NT_STATUS_IS_OK(result)) { continue; } privs.count++; set = TALLOC_REALLOC_ARRAY(mem_ctx, set, struct lsa_LUIDAttribute, privs.count); if (!set) { return NT_STATUS_NO_MEMORY; } set[privs.count-1].luid = luid; set[privs.count-1].attribute = 0; } privs.set = set; result = rpccli_lsa_RemovePrivilegesFromAccount(cli, mem_ctx, &user_pol, false, &privs); if (!NT_STATUS_IS_OK(result)) { goto done; } rpccli_lsa_Close(cli, mem_ctx, &user_pol); rpccli_lsa_Close(cli, mem_ctx, &dom_pol); done: return result; }
int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv) { /* libsmb variables */ struct cli_state *cli; TALLOC_CTX *mem_ctx; uint32 acb_info = ACB_WSTRUST; uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; enum netr_SchannelType sec_channel_type; struct rpc_pipe_client *pipe_hnd = NULL; struct dcerpc_binding_handle *b = NULL; /* rpc variables */ struct policy_handle lsa_pol, sam_pol, domain_pol, user_pol; struct dom_sid *domain_sid; uint32 user_rid; /* Password stuff */ char *clear_trust_password = NULL; struct samr_CryptPassword crypt_pwd; uchar md4_trust_password[16]; union samr_UserInfo set_info; /* Misc */ NTSTATUS status, result; int retval = 1; const char *domain = NULL; char *acct_name; struct lsa_String lsa_acct_name; uint32 acct_flags=0; uint32_t access_granted = 0; union lsa_PolicyInformation *info = NULL; struct samr_Ids user_rids; struct samr_Ids name_types; /* check what type of join */ if (argc >= 0) { sec_channel_type = get_sec_channel_type(argv[0]); } else { sec_channel_type = get_sec_channel_type(NULL); } switch (sec_channel_type) { case SEC_CHAN_WKSTA: acb_info = ACB_WSTRUST; break; case SEC_CHAN_BDC: acb_info = ACB_SVRTRUST; break; #if 0 case SEC_CHAN_DOMAIN: acb_info = ACB_DOMTRUST; break; #endif default: DEBUG(0,("secure channel type %d not yet supported\n", sec_channel_type)); break; } /* Make authenticated connection to remote machine */ status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli); if (!NT_STATUS_IS_OK(status)) { return 1; } if (!(mem_ctx = talloc_init("net_rpc_join_newstyle"))) { DEBUG(0, ("Could not initialise talloc context\n")); goto done; } /* Fetch domain sid */ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id, &pipe_hnd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Error connecting to LSA pipe. Error was %s\n", nt_errstr(status) )); goto done; } b = pipe_hnd->binding_handle; CHECK_RPC_ERR(rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_FLAG_MAXIMUM_ALLOWED, &lsa_pol), "error opening lsa policy handle"); CHECK_DCERPC_ERR(dcerpc_lsa_QueryInfoPolicy(b, mem_ctx, &lsa_pol, LSA_POLICY_INFO_ACCOUNT_DOMAIN, &info, &result), "error querying info policy"); domain = info->account_domain.name.string; domain_sid = info->account_domain.sid; dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result); TALLOC_FREE(pipe_hnd); /* Done with this pipe */ /* Bail out if domain didn't get set. */ if (!domain) { DEBUG(0, ("Could not get domain name.\n")); goto done; } /* Create domain user */ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id, &pipe_hnd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n", nt_errstr(status) )); goto done; } b = pipe_hnd->binding_handle; CHECK_DCERPC_ERR(dcerpc_samr_Connect2(b, mem_ctx, pipe_hnd->desthost, SAMR_ACCESS_ENUM_DOMAINS | SAMR_ACCESS_LOOKUP_DOMAIN, &sam_pol, &result), "could not connect to SAM database"); CHECK_DCERPC_ERR(dcerpc_samr_OpenDomain(b, mem_ctx, &sam_pol, SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 | SAMR_DOMAIN_ACCESS_CREATE_USER | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, domain_sid, &domain_pol, &result), "could not open domain"); /* Create domain user */ if ((acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname())) == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } strlower_m(acct_name); init_lsa_String(&lsa_acct_name, acct_name); acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE | SEC_STD_WRITE_DAC | SEC_STD_DELETE | SAMR_USER_ACCESS_SET_PASSWORD | SAMR_USER_ACCESS_GET_ATTRIBUTES | SAMR_USER_ACCESS_SET_ATTRIBUTES; DEBUG(10, ("Creating account with flags: %d\n",acct_flags)); status = dcerpc_samr_CreateUser2(b, mem_ctx, &domain_pol, &lsa_acct_name, acb_info, acct_flags, &user_pol, &access_granted, &user_rid, &result); if (!NT_STATUS_IS_OK(status)) { goto done; } if (!NT_STATUS_IS_OK(result) && !NT_STATUS_EQUAL(result, NT_STATUS_USER_EXISTS)) { status = result; d_fprintf(stderr,_("Creation of workstation account failed\n")); /* If NT_STATUS_ACCESS_DENIED then we have a valid username/password combo but the user does not have administrator access. */ if (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) d_fprintf(stderr, _("User specified does not have " "administrator privileges\n")); goto done; } /* We *must* do this.... don't ask... */ if (NT_STATUS_IS_OK(result)) { dcerpc_samr_Close(b, mem_ctx, &user_pol, &result); } CHECK_DCERPC_ERR_DEBUG(dcerpc_samr_LookupNames(b, mem_ctx, &domain_pol, 1, &lsa_acct_name, &user_rids, &name_types, &result), ("error looking up rid for user %s: %s/%s\n", acct_name, nt_errstr(status), nt_errstr(result))); if (user_rids.count != 1) { status = NT_STATUS_INVALID_NETWORK_RESPONSE; goto done; } if (name_types.count != 1) { status = NT_STATUS_INVALID_NETWORK_RESPONSE; goto done; } if (name_types.ids[0] != SID_NAME_USER) { DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types.ids[0])); goto done; } user_rid = user_rids.ids[0]; /* Open handle on user */ CHECK_DCERPC_ERR_DEBUG( dcerpc_samr_OpenUser(b, mem_ctx, &domain_pol, SEC_FLAG_MAXIMUM_ALLOWED, user_rid, &user_pol, &result), ("could not re-open existing user %s: %s/%s\n", acct_name, nt_errstr(status), nt_errstr(result))); /* Create a random machine account password */ clear_trust_password = generate_random_str(talloc_tos(), DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); E_md4hash(clear_trust_password, md4_trust_password); /* Set password on machine account */ init_samr_CryptPassword(clear_trust_password, &cli->user_session_key, &crypt_pwd); set_info.info24.password = crypt_pwd; set_info.info24.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON; CHECK_DCERPC_ERR(dcerpc_samr_SetUserInfo2(b, mem_ctx, &user_pol, 24, &set_info, &result), "error setting trust account password"); /* Why do we have to try to (re-)set the ACB to be the same as what we passed in the samr_create_dom_user() call? When a NT workstation is joined to a domain by an administrator the acb_info is set to 0x80. For a normal user with "Add workstations to the domain" rights the acb_info is 0x84. I'm not sure whether it is supposed to make a difference or not. NT seems to cope with either value so don't bomb out if the set userinfo2 level 0x10 fails. -tpot */ set_info.info16.acct_flags = acb_info; /* Ignoring the return value is necessary for joining a domain as a normal user with "Add workstation to domain" privilege. */ status = dcerpc_samr_SetUserInfo(b, mem_ctx, &user_pol, 16, &set_info, &result); dcerpc_samr_Close(b, mem_ctx, &user_pol, &result); TALLOC_FREE(pipe_hnd); /* Done with this pipe */ /* Now check the whole process from top-to-bottom */ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id, &pipe_hnd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Error connecting to NETLOGON pipe. Error was %s\n", nt_errstr(status) )); goto done; } status = rpccli_netlogon_setup_creds(pipe_hnd, cli->desthost, /* server name */ domain, /* domain */ global_myname(), /* client name */ global_myname(), /* machine account name */ md4_trust_password, sec_channel_type, &neg_flags); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Error in domain join verification (credential setup failed): %s\n\n", nt_errstr(status))); if ( NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) && (sec_channel_type == SEC_CHAN_BDC) ) { d_fprintf(stderr, _("Please make sure that no computer " "account\nnamed like this machine " "(%s) exists in the domain\n"), global_myname()); } goto done; } /* We can only check the schannel connection if the client is allowed to do this and the server supports it. If not, just assume success (after all the rpccli_netlogon_setup_creds() succeeded, and we'll do the same again (setup creds) in net_rpc_join_ok(). JRA. */ if (lp_client_schannel() && (neg_flags & NETLOGON_NEG_SCHANNEL)) { struct rpc_pipe_client *netlogon_schannel_pipe; status = cli_rpc_pipe_open_schannel_with_key( cli, &ndr_table_netlogon.syntax_id, NCACN_NP, DCERPC_AUTH_LEVEL_PRIVACY, domain, &pipe_hnd->dc, &netlogon_schannel_pipe); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Error in domain join verification (schannel setup failed): %s\n\n", nt_errstr(status))); if ( NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) && (sec_channel_type == SEC_CHAN_BDC) ) { d_fprintf(stderr, _("Please make sure that no " "computer account\nnamed " "like this machine (%s) " "exists in the domain\n"), global_myname()); } goto done; } TALLOC_FREE(netlogon_schannel_pipe); } TALLOC_FREE(pipe_hnd); /* Now store the secret in the secrets database */ strupper_m(CONST_DISCARD(char *, domain)); if (!secrets_store_domain_sid(domain, domain_sid)) { DEBUG(0, ("error storing domain sid for %s\n", domain)); goto done; } if (!secrets_store_machine_password(clear_trust_password, domain, sec_channel_type)) { DEBUG(0, ("error storing plaintext domain secrets for %s\n", domain)); } /* double-check, connection from scratch */ status = net_rpc_join_ok(c, domain, cli->desthost, &cli->dest_ss); retval = NT_STATUS_IS_OK(status) ? 0 : -1; done: /* Display success or failure */ if (domain) { if (retval != 0) { fprintf(stderr,_("Unable to join domain %s.\n"),domain); } else { printf(_("Joined domain %s.\n"),domain); } } cli_shutdown(cli); TALLOC_FREE(clear_trust_password); return retval; }
static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status; struct policy_handle handle, sec_handle; struct lsa_String name; struct lsa_DATA_BUF_PTR new_val; NTTIME new_mtime = 0; struct lsa_DATA_BUF_PTR old_val; NTTIME old_mtime = 0; DATA_BLOB session_key; DATA_BLOB new_blob = data_blob_null; DATA_BLOB old_blob = data_blob_null; char *new_secret, *old_secret; if (argc < 2) { printf("Usage: %s name\n", argv[0]); return NT_STATUS_OK; } status = rpccli_lsa_open_policy2(cli, mem_ctx, true, SEC_FLAG_MAXIMUM_ALLOWED, &handle); if (!NT_STATUS_IS_OK(status)) { return status; } init_lsa_String(&name, argv[1]); status = rpccli_lsa_OpenSecret(cli, mem_ctx, &handle, name, SEC_FLAG_MAXIMUM_ALLOWED, &sec_handle); if (!NT_STATUS_IS_OK(status)) { goto done; } ZERO_STRUCT(new_val); ZERO_STRUCT(old_val); status = rpccli_lsa_QuerySecret(cli, mem_ctx, &sec_handle, &new_val, &new_mtime, &old_val, &old_mtime); if (!NT_STATUS_IS_OK(status)) { goto done; } status = cli_get_session_key(mem_ctx, cli, &session_key); if (!NT_STATUS_IS_OK(status)) { goto done; } if (new_val.buf) { new_blob = data_blob_const(new_val.buf->data, new_val.buf->length); } if (old_val.buf) { old_blob = data_blob_const(old_val.buf->data, old_val.buf->length); } new_secret = sess_decrypt_string(mem_ctx, &new_blob, &session_key); old_secret = sess_decrypt_string(mem_ctx, &old_blob, &session_key); if (new_secret) { d_printf("new secret: %s\n", new_secret); } if (old_secret) { d_printf("old secret: %s\n", old_secret); } done: if (is_valid_policy_hnd(&sec_handle)) { rpccli_lsa_Close(cli, mem_ctx, &sec_handle); } if (is_valid_policy_hnd(&handle)) { rpccli_lsa_Close(cli, mem_ctx, &handle); } return status; }