/* set password via encrypted NT and LM hash buffers */ NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call, struct ldb_context *sam_ctx, struct ldb_dn *account_dn, struct ldb_dn *domain_dn, TALLOC_CTX *mem_ctx, const uint8_t *lm_pwd_hash, const uint8_t *nt_pwd_hash) { struct samr_Password *d_lm_pwd_hash = NULL, *d_nt_pwd_hash = NULL; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB in, out; NTSTATUS nt_status = NT_STATUS_OK; nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } if (lm_pwd_hash != NULL) { in = data_blob_const(lm_pwd_hash, 16); out = data_blob_talloc_zero(mem_ctx, 16); sess_crypt_blob(&out, &in, &session_key, false); d_lm_pwd_hash = (struct samr_Password *) out.data; } if (nt_pwd_hash != NULL) { in = data_blob_const(nt_pwd_hash, 16); out = data_blob_talloc_zero(mem_ctx, 16); sess_crypt_blob(&out, &in, &session_key, false); d_nt_pwd_hash = (struct samr_Password *) out.data; } if ((d_lm_pwd_hash != NULL) || (d_nt_pwd_hash != NULL)) { nt_status = samdb_set_password(sam_ctx, mem_ctx, account_dn, domain_dn, NULL, d_lm_pwd_hash, d_nt_pwd_hash, NULL, NULL, /* this is a password set */ NULL, NULL); } return nt_status; }
char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in) { DATA_BLOB data_out, sess_key; uchar nt_hash[16]; uint32_t length; uint32_t version; fstring cleartextpwd; if (!data_in || !pass) return NULL; /* generate md4 password-hash derived from the NT UNICODE password */ E_md4hash(pass, nt_hash); /* hashed twice with md4 */ mdfour(nt_hash, nt_hash, 16); /* 16-Byte session-key */ sess_key = data_blob(nt_hash, 16); if (sess_key.data == NULL) return NULL; data_out = data_blob(NULL, data_in->length); if (data_out.data == NULL) return NULL; /* decrypt with des3 */ sess_crypt_blob(&data_out, data_in, &sess_key, 0); /* 4 Byte length, 4 Byte version */ length = IVAL(data_out.data, 0); version = IVAL(data_out.data, 4); if (length > data_in->length - 8) { DEBUG(0,("decrypt_trustdom_secret: invalid length (%d)\n", length)); return NULL; } if (version != 1) { DEBUG(0,("decrypt_trustdom_secret: unknown version number (%d)\n", version)); return NULL; } rpcstr_pull(cleartextpwd, data_out.data + 8, sizeof(fstring), length, 0 ); #ifdef DEBUG_PASSWORD DEBUG(100,("decrypt_trustdom_secret: length is: %d, version is: %d, password is: %s\n", length, version, cleartextpwd)); #endif data_blob_free(&data_out); data_blob_free(&sess_key); return SMB_STRDUP(cleartextpwd); }