#include "auth/auth.h"
#include "auth/auth_sam_reply.h"
#include "dsdb/samdb/samdb.h"
+#include "dsdb/common/flags.h"
#include "rpc_server/samr/proto.h"
#include "util/util_ldb.h"
#include "libcli/auth/libcli_auth.h"
struct creds_CredentialState *creds;
void *sam_ctx;
struct samr_Password *mach_pwd;
- uint16_t acct_flags;
+ uint32_t user_account_control;
int num_records;
struct ldb_message **msgs;
NTSTATUS nt_status;
return NT_STATUS_ACCESS_DENIED;
}
- sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- acct_flags = samdb_result_acct_flags(msgs[0],
- "userAccountControl");
+
+ user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
- if (acct_flags & ACB_DISABLED) {
+ if (user_account_control & UF_ACCOUNTDISABLE) {
DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
return NT_STATUS_ACCESS_DENIED;
}
if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
- if (!(acct_flags & ACB_WSTRUST)) {
- DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
+ if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
+ DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
return NT_STATUS_ACCESS_DENIED;
}
} else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
- if (!(acct_flags & ACB_DOMTRUST)) {
- DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
+ if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
+ DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
+
return NT_STATUS_ACCESS_DENIED;
}
} else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
- if (!(acct_flags & ACB_SVRTRUST)) {
- DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
+ if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
+ DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
return NT_STATUS_ACCESS_DENIED;
}
} else {
/* remember this session key state */
- nt_status = schannel_store_session_key(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
+ nt_status = schannel_store_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
return nt_status;
}
the caller needs some of that information.
*/
-static NTSTATUS dcesrv_netr_creds_server_step_check(struct loadparm_context *lp_ctx,
+static NTSTATUS dcesrv_netr_creds_server_step_check(struct event_context *event_ctx,
+ struct loadparm_context *lp_ctx,
const char *computer_name,
TALLOC_CTX *mem_ctx,
struct netr_Authenticator *received_authenticator,
struct ldb_context *ldb;
int ret;
- ldb = schannel_db_connect(mem_ctx, lp_ctx);
+ ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx);
if (!ldb) {
return NT_STATUS_ACCESS_DENIED;
}
struct ldb_context *sam_ctx;
NTSTATUS nt_status;
- nt_status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
+ nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
r->in.computer_name, mem_ctx,
&r->in.credential, &r->out.return_authenticator,
&creds);
NT_STATUS_NOT_OK_RETURN(nt_status);
- sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
struct samr_CryptPassword password_buf;
- nt_status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
+ nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
r->in.computer_name, mem_ctx,
&r->in.credential, &r->out.return_authenticator,
&creds);
NT_STATUS_NOT_OK_RETURN(nt_status);
- sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
user_info->remote_host = NULL;
switch (r->in.logon_level) {
- case 1:
- case 3:
- case 5:
+ case NetlogonInteractiveInformation:
+ case NetlogonServiceInformation:
+ case NetlogonInteractiveTransitiveInformation:
+ case NetlogonServiceTransitiveInformation:
if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
creds_arcfour_crypt(creds,
r->in.logon.password->lmpassword.hash,
*user_info->password.hash.nt = r->in.logon.password->ntpassword;
break;
- case 2:
- case 6:
+ case NetlogonNetworkInformation:
+ case NetlogonNetworkTransitiveInformation:
/* TODO: we need to deny anonymous access here */
nt_status = auth_context_create(mem_ctx,
user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
break;
+
+
+ case NetlogonGenericInformation:
+ {
+ if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+ creds_arcfour_crypt(creds,
+ r->in.logon.generic->data, r->in.logon.generic->length);
+ } else {
+ /* Using DES to verify kerberos tickets makes no sense */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (strcmp(r->in.logon.generic->package_name.string, "Kerberos")) {
+ struct PAC_Validate pac_validate;
+ DATA_BLOB srv_sig;
+ struct PAC_SIGNATURE_DATA kdc_sig;
+ DATA_BLOB pac_validate_blob = data_blob_const(r->in.logon.generic->data,
+ r->in.logon.generic->length);
+ ndr_err = ndr_pull_struct_blob(&pac_validate_blob, mem_ctx,
+ lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx),
+ &pac_validate,
+ (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (pac_validate->MessageType != 3) {
+ /* We don't implement any other message types - such as certificate validation - yet */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (pac_validate->ChecksumAndSignature.length != (pac_validate->ChecksumLength + pac_validate->SignatureLength)
+ || pac_validate->ChecksumAndSignature.length < pac_validate->ChecksumLength
+ || pac_validate->ChecksumAndSignature.length < pac_validate->SignatureLength ) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ srv_sig = data_blob_const(pac_validate->ChecksumAndSignature.data,
+ pac_validate->ChecksumLength);
+
+ kdc_sig.type = pac_validate->SignatureType;
+ kdc_sig.signature = data_blob_const(&pac_validate->ChecksumAndSignature.data[pac_validate->ChecksumLength],
+ pac_validate->SignatureLength);
+ check_pac_checksum(mem_ctx, srv_sig, &kdc_sig,
+ context, keyblock);
+
+
+ }
+
+ /* Until we get an implemetnation of these other packages */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
default:
return NT_STATUS_INVALID_PARAMETER;
}
{
NTSTATUS nt_status;
struct creds_CredentialState *creds;
- nt_status = schannel_fetch_session_key(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, r->in.computer_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx), &creds);
+ nt_status = schannel_fetch_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, r->in.computer_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx), &creds);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
- nt_status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
+ nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
r->in.computer_name, mem_ctx,
r->in.credential, return_authenticator,
&creds);
}
-/*
- netr_NETRLOGONGETTRUSTRID
+/*
+ netr_LogonGetTrustRid
*/
-static WERROR dcesrv_netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct netr_NETRLOGONGETTRUSTRID *r)
+static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct netr_LogonGetTrustRid *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
const char *local_domain;
- status = dcesrv_netr_creds_server_step_check(dce_call->conn->dce_ctx->lp_ctx,
+ status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
r->in.computer_name, mem_ctx,
r->in.credential,
r->out.return_authenticator,
NULL);
NT_STATUS_NOT_OK_RETURN(status);
- sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
ZERO_STRUCT(r->out);
- sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
return WERR_DS_SERVICE_UNAVAILABLE;
}
ZERO_STRUCT(r->out);
- sam_ctx = samdb_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
+ sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
return WERR_GENERAL_FAILURE;
}
}
-/*
- netr_DSRDEREGISTERDNSHOSTRECORDS
+/*
+ netr_DsrDeregisterDNSHostRecords
*/
-static WERROR dcesrv_netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
+static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct netr_DsrDeregisterDNSHostRecords *r)
{
DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}