const char *trust_dom_attrs[] = {"flatname", NULL};
const char *account_name;
+ uint32_t negotiate_flags = 0;
ZERO_STRUCTP(r->out.return_credentials);
*r->out.rid = 0;
+ negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
+ NETLOGON_NEG_PERSISTENT_SAMREPL |
+ NETLOGON_NEG_ARCFOUR |
+ NETLOGON_NEG_PROMOTION_COUNT |
+ NETLOGON_NEG_CHANGELOG_BDC |
+ NETLOGON_NEG_FULL_SYNC_REPL |
+ NETLOGON_NEG_MULTIPLE_SIDS |
+ NETLOGON_NEG_REDO |
+ NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
+ NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
+ NETLOGON_NEG_GENERIC_PASSTHROUGH |
+ NETLOGON_NEG_CONCURRENT_RPC |
+ NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
+ NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
+ NETLOGON_NEG_TRANSITIVE_TRUSTS |
+ NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
+ NETLOGON_NEG_PASSWORD_SET2 |
+ NETLOGON_NEG_GETDOMAININFO |
+ NETLOGON_NEG_CROSS_FOREST_TRUSTS |
+ NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
+ NETLOGON_NEG_RODC_PASSTHROUGH |
+ NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
+ NETLOGON_NEG_AUTHENTICATED_RPC;
+
+ if (*r->in.negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
+ negotiate_flags |= NETLOGON_NEG_STRONG_KEYS;
+ }
+
+ if (*r->in.negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+ negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
+ }
+
/*
* According to Microsoft (see bugid #6099)
* Windows 7 looks at the negotiate_flags
* returned in this structure *even if the
* call fails with access denied!
*/
- *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
- NETLOGON_NEG_PERSISTENT_SAMREPL |
- NETLOGON_NEG_ARCFOUR |
- NETLOGON_NEG_PROMOTION_COUNT |
- NETLOGON_NEG_CHANGELOG_BDC |
- NETLOGON_NEG_FULL_SYNC_REPL |
- NETLOGON_NEG_MULTIPLE_SIDS |
- NETLOGON_NEG_REDO |
- NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
- NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
- NETLOGON_NEG_GENERIC_PASSTHROUGH |
- NETLOGON_NEG_CONCURRENT_RPC |
- NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
- NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
- NETLOGON_NEG_STRONG_KEYS |
- NETLOGON_NEG_TRANSITIVE_TRUSTS |
- NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
- NETLOGON_NEG_PASSWORD_SET2 |
- NETLOGON_NEG_GETDOMAININFO |
- NETLOGON_NEG_CROSS_FOREST_TRUSTS |
- NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
- NETLOGON_NEG_RODC_PASSTHROUGH |
- NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
- NETLOGON_NEG_AUTHENTICATED_RPC;
+ *r->out.negotiate_flags = negotiate_flags;
switch (r->in.secure_channel_type) {
case SEC_CHAN_WKSTA:
mach_pwd,
r->in.credentials,
r->out.return_credentials,
- *r->in.negotiate_flags);
-
+ negotiate_flags);
if (!creds) {
return NT_STATUS_ACCESS_DENIED;
}
memcpy(password_buf.data, r->in.new_password->data, 512);
SIVAL(password_buf.data, 512, r->in.new_password->length);
- netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
+
+ if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+ netlogon_creds_aes_decrypt(creds, password_buf.data, 516);
+ } else {
+ netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
+ }
if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
DEBUG(3,("samr: failed to decode password buffer\n"));
struct auth_usersupplied_info *user_info;
struct auth_user_info_dc *user_info_dc;
NTSTATUS nt_status;
- static const char zeros[16];
struct netr_SamBaseInfo *sam;
struct netr_SamInfo2 *sam2;
struct netr_SamInfo3 *sam3;
case NetlogonServiceInformation:
case NetlogonInteractiveTransitiveInformation:
case NetlogonServiceTransitiveInformation:
- if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+ if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+ netlogon_creds_aes_decrypt(creds,
+ r->in.logon->password->lmpassword.hash,
+ sizeof(r->in.logon->password->lmpassword.hash));
+ netlogon_creds_aes_decrypt(creds,
+ r->in.logon->password->ntpassword.hash,
+ sizeof(r->in.logon->password->ntpassword.hash));
+ } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
netlogon_creds_arcfour_crypt(creds,
r->in.logon->password->lmpassword.hash,
sizeof(r->in.logon->password->lmpassword.hash));
case NetlogonGenericInformation:
{
- if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+ if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+ netlogon_creds_aes_decrypt(creds,
+ r->in.logon->generic->data, r->in.logon->generic->length);
+ } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
netlogon_creds_arcfour_crypt(creds,
r->in.logon->generic->data, r->in.logon->generic->length);
} else {
return NT_STATUS_INVALID_INFO_CLASS;
}
- /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
- /* It appears that level 6 is not individually encrypted */
- if ((r->in.validation_level != 6) &&
- memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
- /* This key is sent unencrypted without the ARCFOUR flag set */
- if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
- netlogon_creds_arcfour_crypt(creds,
- sam->key.key,
- sizeof(sam->key.key));
- }
- }
-
- /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
- /* It appears that level 6 is not individually encrypted */
- if ((r->in.validation_level != 6) &&
- memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
- if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
- netlogon_creds_arcfour_crypt(creds,
- sam->LMSessKey.key,
- sizeof(sam->LMSessKey.key));
- } else {
- netlogon_creds_des_encrypt_LMKey(creds,
- &sam->LMSessKey);
- }
- }
+ netlogon_creds_encrypt_samlogon_validation(creds,
+ r->in.validation_level,
+ r->out.validation);
/* TODO: Describe and deal with these flags */
*r->out.flags = 0;
static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct netr_LogonGetCapabilities *r)
{
+ struct netlogon_creds_CredentialState *creds;
+ NTSTATUS status;
- /* we don't support AES yet */
- return NT_STATUS_NOT_IMPLEMENTED;
+ status = dcesrv_netr_creds_server_step_check(dce_call,
+ mem_ctx,
+ r->in.computer_name,
+ r->in.credential,
+ r->out.return_authenticator,
+ &creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,(__location__ " Bad credentials - error\n"));
+ }
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ if (r->in.query_level != 1) {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ r->out.capabilities->server_capabilities = creds->negotiate_flags;
+
+ return NT_STATUS_OK;
}
return WERR_DS_UNAVAILABLE;
}
+ /*
+ * We assume to be a DC when we get called over NETLOGON. Hence we
+ * get our site name always by using "samdb_server_site_name()"
+ * and not "samdb_client_site_name()".
+ */
*r->out.site = samdb_server_site_name(sam_ctx, mem_ctx);
W_ERROR_HAVE_NO_MEMORY(*r->out.site);
}
domain_info->workstation_flags =
- r->in.query->workstation_info->workstation_flags;
+ r->in.query->workstation_info->workstation_flags & (
+ NETR_WS_FLAG_HANDLES_SPN_UPDATE | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS);
r->out.info->domain_info = domain_info;
break;
}
-#define GET_CHECK_STR(dest, mem, msg, attr) \
-do {\
- const char *s; \
- s = ldb_msg_find_attr_as_string(msg, attr, NULL); \
- if (!s) { \
- DEBUG(0, ("DB Error, TustedDomain entry (%s) " \
- "without flatname\n", \
- ldb_dn_get_linearized(msg->dn))); \
- continue; \
- } \
- dest = talloc_strdup(mem, s); \
- W_ERROR_HAVE_NO_MEMORY(dest); \
-} while(0)
-
-
static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
struct ldb_context *sam_ctx,
struct netr_DomainTrustList *trusts,
n + 1);
W_ERROR_HAVE_NO_MEMORY(trusts->array);
- GET_CHECK_STR(trusts->array[n].netbios_name, trusts,
- dom_res[i], "flatname");
- GET_CHECK_STR(trusts->array[n].dns_name, trusts,
- dom_res[i], "trustPartner");
+ trusts->array[n].netbios_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "flatname", NULL));
+ if (!trusts->array[n].netbios_name) {
+ DEBUG(0, ("DB Error, TrustedDomain entry (%s) "
+ "without flatname\n",
+ ldb_dn_get_linearized(dom_res[i]->dn)));
+ }
+
+ trusts->array[n].dns_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "trustPartner", NULL));
trusts->array[n].trust_flags = flags;
if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) &&