#if 0
/*
- * Currently this code is redundent as we already have a filter
+ * Currently this code is redundant as we already have a filter
* by hostname list. What this code really needs to do is to
* get a hosts allowed/hosts denied list from the SAM database
* on a per user basis, and make the access decision there.
goto out;
}
- become_root();
status = samr_find_machine_account(mem_ctx, h, mach_acct,
SEC_FLAG_MAXIMUM_ALLOWED,
&domain_sid, &user_rid,
&user_handle);
- unbecome_root();
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
struct auth_usersupplied_info *user_info = NULL;
struct auth_serversupplied_info *server_info = NULL;
struct auth_context *auth_context = NULL;
- uint8_t pipe_session_key[16];
- bool process_creds = true;
const char *fn;
+#ifdef DEBUG_PASSWORD
+ logon = netlogon_creds_shallow_copy_logon(p->mem_ctx,
+ r->in.logon_level,
+ r->in.logon);
+ if (logon == NULL) {
+ logon = r->in.logon;
+ }
+#endif
+
switch (p->opnum) {
case NDR_NETR_LOGONSAMLOGON:
- process_creds = true;
fn = "_netr_LogonSamLogon";
break;
case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
- process_creds = true;
fn = "_netr_LogonSamLogonWithFlags";
break;
case NDR_NETR_LOGONSAMLOGONEX:
- process_creds = false;
fn = "_netr_LogonSamLogonEx";
break;
default:
status = NT_STATUS_OK;
+ netlogon_creds_decrypt_samlogon_logon(creds,
+ r->in.logon_level,
+ logon);
+
switch (r->in.logon_level) {
case NetlogonNetworkInformation:
case NetlogonNetworkTransitiveInformation:
{
uint8_t chal[8];
+#ifdef DEBUG_PASSWORD
+ if (logon != r->in.logon) {
+ DEBUG(100,("lm owf password:"));
+ dump_data(100,
+ r->in.logon->password->lmpassword.hash, 16);
+
+ DEBUG(100,("nt owf password:"));
+ dump_data(100,
+ r->in.logon->password->ntpassword.hash, 16);
+ }
+
+ DEBUG(100,("decrypt of lm owf password:"));
+ dump_data(100, logon->password->lmpassword.hash, 16);
+
+ DEBUG(100,("decrypt of nt owf password:"));
+ dump_data(100, logon->password->ntpassword.hash, 16);
+#endif
status = make_auth_context_subsystem(talloc_tos(),
&auth_context);
if (!NT_STATUS_IS_OK(status)) {
logon->password->identity_info.parameter_control,
chal,
logon->password->lmpassword.hash,
- logon->password->ntpassword.hash,
- creds->session_key)) {
+ logon->password->ntpassword.hash)) {
status = NT_STATUS_NO_MEMORY;
}
break;
the SAM Local Security Authority should record that the user is
logged in to the domain. */
- if (process_creds) {
- /* Get the pipe session key from the creds. */
- memcpy(pipe_session_key, creds->session_key, 16);
- } else {
- struct schannel_state *schannel_auth;
- /* Get the pipe session key from the schannel. */
- if ((p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL)
- || (p->auth.auth_ctx == NULL)) {
- return NT_STATUS_INVALID_HANDLE;
- }
-
- schannel_auth = talloc_get_type_abort(p->auth.auth_ctx,
- struct schannel_state);
- memcpy(pipe_session_key, schannel_auth->creds->session_key, 16);
- }
-
switch (r->in.validation_level) {
case 2:
- status = serverinfo_to_SamInfo2(server_info, pipe_session_key, 16,
+ status = serverinfo_to_SamInfo2(server_info,
r->out.validation->sam2);
break;
case 3:
- status = serverinfo_to_SamInfo3(server_info, pipe_session_key, 16,
+ status = serverinfo_to_SamInfo3(server_info,
r->out.validation->sam3);
break;
case 6:
- status = serverinfo_to_SamInfo6(server_info, pipe_session_key, 16,
+ status = serverinfo_to_SamInfo6(server_info,
r->out.validation->sam6);
break;
}
TALLOC_FREE(server_info);
- return status;
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ netlogon_creds_encrypt_samlogon_validation(creds,
+ r->in.validation_level,
+ r->out.validation);
+ return NT_STATUS_OK;
}
/****************************************************************
/****************************************************************
****************************************************************/
-WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
- struct netr_DsRGetForestTrustInformation *r)
-{
- p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
-****************************************************************/
-
static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
struct lsa_ForestTrustInformation *info)
{
struct lsa_ForestTrustRecord *e;
struct pdb_domain_info *dom_info;
struct lsa_ForestTrustDomainInfo *domain_info;
+ char **upn_suffixes = NULL;
+ uint32_t num_suffixes = 0;
+ uint32_t i = 0;
+ NTSTATUS status;
dom_info = pdb_get_domain_info(mem_ctx);
if (dom_info == NULL) {
}
info->count = 2;
- info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, 2);
+
+ become_root();
+ status = pdb_enum_upn_suffixes(info, &num_suffixes, &upn_suffixes);
+ unbecome_root();
+ if (NT_STATUS_IS_OK(status) && (num_suffixes > 0)) {
+ info->count += num_suffixes;
+ }
+
+ info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, info->count);
if (info->entries == NULL) {
return NT_STATUS_NO_MEMORY;
}
info->entries[0] = e;
+ if (num_suffixes > 0) {
+ for (i = 0; i < num_suffixes ; i++) {
+ e = talloc(info, struct lsa_ForestTrustRecord);
+ if (e == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ e->flags = 0;
+ e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
+ e->time = 0; /* so far always 0 in traces. */
+ e->forest_trust_data.top_level_name.string = upn_suffixes[i];
+ info->entries[1 + i] = e;
+ }
+ }
+
e = talloc(info, struct lsa_ForestTrustRecord);
if (e == NULL) {
return NT_STATUS_NO_MEMORY;
domain_info->netbios_domain_name.string = talloc_steal(info,
dom_info->name);
- info->entries[1] = e;
+ info->entries[info->count - 1] = e;
return NT_STATUS_OK;
}
+/****************************************************************
+****************************************************************/
+
+WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
+ struct netr_DsRGetForestTrustInformation *r)
+{
+ NTSTATUS status;
+ struct lsa_ForestTrustInformation *info, **info_ptr;
+
+ if (!(p->pipe_bound && (p->auth.auth_type != DCERPC_AUTH_TYPE_NONE)
+ && (p->auth.auth_level != DCERPC_AUTH_LEVEL_NONE))) {
+ p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
+ return WERR_ACCESS_DENIED;
+ }
+
+ if (r->in.flags & (~DS_GFTI_UPDATE_TDO)) {
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_INVALID_FLAGS;
+ }
+
+ if ((r->in.flags & DS_GFTI_UPDATE_TDO) && (lp_server_role() != ROLE_DOMAIN_PDC)) {
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_NERR_NOTPRIMARY;
+ }
+
+ if ((r->in.trusted_domain_name == NULL) && (r->in.flags & DS_GFTI_UPDATE_TDO)) {
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_INVALID_PARAMETER;
+ }
+
+ /* retrieve forest trust information and stop further processing */
+ if (r->in.trusted_domain_name == NULL) {
+ info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
+ if (info_ptr == NULL) {
+ p->fault_state = DCERPC_FAULT_CANT_PERFORM;
+ return WERR_NOMEM;
+ }
+ info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
+ if (info == NULL) {
+ p->fault_state = DCERPC_FAULT_CANT_PERFORM;
+ return WERR_NOMEM;
+ }
+
+ /* Fill forest trust information and expand UPN suffixes list */
+ status = fill_forest_trust_array(p->mem_ctx, info);
+ if (!NT_STATUS_IS_OK(status)) {
+ p->fault_state = DCERPC_FAULT_CANT_PERFORM;
+ return WERR_NOMEM;
+ }
+
+ *info_ptr = info;
+ r->out.forest_trust_info = info_ptr;
+
+ return WERR_OK;
+
+ }
+
+ /* TODO: implement remaining parts of DsrGetForestTrustInformation (opnum 43)
+ * when trusted_domain_name is not NULL */
+
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return WERR_NOT_SUPPORTED;
+}
+
/****************************************************************
_netr_GetForestTrustInformation
****************************************************************/
return NT_STATUS_NO_MEMORY;
}
+ /* Fill forest trust information, do expand UPN suffixes list */
status = fill_forest_trust_array(p->mem_ctx, info);
if (!NT_STATUS_IS_OK(status)) {
return status;
static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
const DATA_BLOB *trustAuth_blob,
- const DATA_BLOB *session_key,
+ struct netlogon_creds_CredentialState *creds,
struct samr_Password *current_pw_enc,
struct samr_Password *previous_pw_enc)
{
return NT_STATUS_UNSUCCESSFUL;
}
-
if (trustAuth.count != 0 && trustAuth.current.count != 0 &&
trustAuth.current.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
- mdfour(previous_pw_enc->hash,
+ mdfour(current_pw_enc->hash,
trustAuth.current.array[0].AuthInfo.clear.password,
trustAuth.current.array[0].AuthInfo.clear.size);
+ netlogon_creds_des_encrypt(creds, current_pw_enc);
} else {
return NT_STATUS_UNSUCCESSFUL;
}
- arcfour_crypt_blob(current_pw_enc->hash, sizeof(current_pw_enc->hash),
- session_key);
if (trustAuth.previous.count != 0 &&
trustAuth.previous.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
mdfour(previous_pw_enc->hash,
trustAuth.previous.array[0].AuthInfo.clear.password,
trustAuth.previous.array[0].AuthInfo.clear.size);
+ netlogon_creds_des_encrypt(creds, previous_pw_enc);
} else {
- mdfour(previous_pw_enc->hash, NULL, 0);
+ ZERO_STRUCTP(previous_pw_enc);
}
- arcfour_crypt_blob(previous_pw_enc->hash, sizeof(previous_pw_enc->hash),
- session_key);
return NT_STATUS_OK;
}
bool trusted;
struct netr_TrustInfo *trust_info;
struct pdb_trusted_domain *td;
- DATA_BLOB trustAuth_blob;
- struct samr_Password *new_owf_enc;
- struct samr_Password *old_owf_enc;
- DATA_BLOB session_key;
struct loadparm_context *lp_ctx;
lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
*r->out.trust_info = trust_info;
}
- new_owf_enc = talloc_zero(p->mem_ctx, struct samr_Password);
- old_owf_enc = talloc_zero(p->mem_ctx, struct samr_Password);
- if (new_owf_enc == NULL || old_owf_enc == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
-/* TODO: which trustAuth shall we use if we have in/out trust or do they have to
- * be equal ? */
- if (td->trust_direction & NETR_TRUST_FLAG_INBOUND) {
- trustAuth_blob = td->trust_auth_incoming;
- } else if (td->trust_direction & NETR_TRUST_FLAG_OUTBOUND) {
- trustAuth_blob = td->trust_auth_outgoing;
+ if (td->trust_auth_incoming.data == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
}
- session_key.data = creds->session_key;
- session_key.length = sizeof(creds->session_key);
- status = get_password_from_trustAuth(p->mem_ctx, &trustAuth_blob,
- &session_key,
- new_owf_enc, old_owf_enc);
+ status = get_password_from_trustAuth(p->mem_ctx,
+ &td->trust_auth_incoming,
+ creds,
+ r->out.new_owf_password,
+ r->out.old_owf_password);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- r->out.new_owf_password = new_owf_enc;
- r->out.old_owf_password = old_owf_enc;
} else {
/* TODO: look for machine password */
- r->out.new_owf_password = NULL;
- r->out.old_owf_password = NULL;
+ ZERO_STRUCTP(r->out.new_owf_password);
+ ZERO_STRUCTP(r->out.old_owf_password);
return NT_STATUS_NOT_IMPLEMENTED;
}