diff options
Diffstat (limited to 'source4')
52 files changed, 363 insertions, 3795 deletions
diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c index 5fb180d7b1..83901db6a5 100644 --- a/source4/auth/credentials/credentials.c +++ b/source4/auth/credentials/credentials.c @@ -668,7 +668,7 @@ _PUBLIC_ void cli_credentials_guess(struct cli_credentials *cred, */ _PUBLIC_ void cli_credentials_set_netlogon_creds(struct cli_credentials *cred, - struct creds_CredentialState *netlogon_creds) + struct netlogon_creds_CredentialState *netlogon_creds) { cred->netlogon_creds = talloc_reference(cred, netlogon_creds); } @@ -677,7 +677,7 @@ _PUBLIC_ void cli_credentials_set_netlogon_creds(struct cli_credentials *cred, * Return attached NETLOGON credentials */ -struct creds_CredentialState *cli_credentials_get_netlogon_creds(struct cli_credentials *cred) +struct netlogon_creds_CredentialState *cli_credentials_get_netlogon_creds(struct cli_credentials *cred) { return cred->netlogon_creds; } diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h index 3c2fb8f2e6..311cdc2450 100644 --- a/source4/auth/credentials/credentials.h +++ b/source4/auth/credentials/credentials.h @@ -102,7 +102,7 @@ struct cli_credentials { /* Private handle for the callback routines to use */ void *priv_data; - struct creds_CredentialState *netlogon_creds; + struct netlogon_creds_CredentialState *netlogon_creds; enum netr_SchannelType secure_channel_type; int kvno; @@ -167,7 +167,7 @@ int cli_credentials_get_keytab(struct cli_credentials *cred, struct loadparm_context *lp_ctx, struct keytab_container **_ktc); const char *cli_credentials_get_domain(struct cli_credentials *cred); -struct creds_CredentialState *cli_credentials_get_netlogon_creds(struct cli_credentials *cred); +struct netlogon_creds_CredentialState *cli_credentials_get_netlogon_creds(struct cli_credentials *cred); void cli_credentials_set_machine_account_pending(struct cli_credentials *cred, struct loadparm_context *lp_ctx); void cli_credentials_set_conf(struct cli_credentials *cred, @@ -210,7 +210,7 @@ bool cli_credentials_set_realm(struct cli_credentials *cred, void cli_credentials_set_secure_channel_type(struct cli_credentials *cred, enum netr_SchannelType secure_channel_type); void cli_credentials_set_netlogon_creds(struct cli_credentials *cred, - struct creds_CredentialState *netlogon_creds); + struct netlogon_creds_CredentialState *netlogon_creds); NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred, struct smb_krb5_context *smb_krb5_context); NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred, diff --git a/source4/auth/gensec/config.mk b/source4/auth/gensec/config.mk index 27cf442b68..a9ce228f12 100644 --- a/source4/auth/gensec/config.mk +++ b/source4/auth/gensec/config.mk @@ -78,7 +78,7 @@ $(eval $(call proto_header_template,$(gensecsrcdir)/schannel_proto.h,$(gensec_sc ################################################ # Start SUBSYSTEM SCHANNELDB [SUBSYSTEM::SCHANNELDB] -PRIVATE_DEPENDENCIES = LDB_WRAP +PRIVATE_DEPENDENCIES = LDB_WRAP COMMON_SCHANNELDB # End SUBSYSTEM SCHANNELDB ################################################ diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index c4e93ee97b..3b27e0f733 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -284,10 +284,10 @@ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, NTSTATUS gensec_session_info(struct gensec_security *gensec_security, struct auth_session_info **session_info); NTSTATUS auth_nt_status_squash(NTSTATUS nt_status); -struct creds_CredentialState; +struct netlogon_creds_CredentialState; NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, - struct creds_CredentialState **creds); + struct netlogon_creds_CredentialState **creds); NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr); NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr); diff --git a/source4/auth/gensec/schannel.c b/source4/auth/gensec/schannel.c index e6d38c14a3..08fce2f049 100644 --- a/source4/auth/gensec/schannel.c +++ b/source4/auth/gensec/schannel.c @@ -27,8 +27,6 @@ #include "auth/gensec/gensec.h" #include "auth/gensec/gensec_proto.h" #include "auth/gensec/schannel.h" -#include "auth/gensec/schannel_state.h" -#include "auth/gensec/schannel_proto.h" #include "librpc/rpc/dcerpc.h" #include "param/param.h" #include "auth/session_proto.h" @@ -52,8 +50,8 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ enum ndr_err_code ndr_err; struct schannel_bind bind_schannel; struct schannel_bind_ack bind_schannel_ack; - struct creds_CredentialState *creds; - + struct netlogon_creds_CredentialState *creds; + struct ldb_context *schannel_ldb; const char *workstation; const char *domain; *out = data_blob(NULL, 0); @@ -124,10 +122,22 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ domain = bind_schannel.u.info3.domain; } + if (strcasecmp_m(domain, lp_workgroup(gensec_security->settings->lp_ctx)) != 0) { + DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n", + domain, lp_workgroup(gensec_security->settings->lp_ctx))); + + return NT_STATUS_LOGON_FAILURE; + } + + schannel_ldb = schannel_db_connect(out_mem_ctx, gensec_security->event_ctx, + gensec_security->settings->lp_ctx); + if (!schannel_ldb) { + return NT_STATUS_ACCESS_DENIED; + } /* pull the session key for this client */ - status = schannel_fetch_session_key(out_mem_ctx, gensec_security->event_ctx, - gensec_security->settings->lp_ctx, workstation, - domain, &creds); + status = schannel_fetch_session_key(schannel_ldb, + out_mem_ctx, workstation, &creds); + talloc_free(schannel_ldb); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n", workstation, nt_errstr(status))); @@ -161,15 +171,16 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ } /** - * Return the struct creds_CredentialState. + * Return the struct netlogon_creds_CredentialState. * * Make sure not to call this unless gensec is using schannel... */ /* TODO: make this non-public */ + _PUBLIC_ NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, - TALLOC_CTX *mem_ctx, - struct creds_CredentialState **creds) + TALLOC_CTX *mem_ctx, + struct netlogon_creds_CredentialState **creds) { struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); diff --git a/source4/auth/gensec/schannel.h b/source4/auth/gensec/schannel.h index 2ddea29006..461f6ba2ff 100644 --- a/source4/auth/gensec/schannel.h +++ b/source4/auth/gensec/schannel.h @@ -20,7 +20,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "libcli/auth/credentials.h" +#include "libcli/auth/libcli_auth.h" +#include "auth/gensec/schannel_proto.h" +#include "auth/gensec/schannel_state.h" +#include "libcli/auth/schannel_state.h" enum schannel_position { SCHANNEL_STATE_START = 0, @@ -31,6 +34,6 @@ struct schannel_state { enum schannel_position state; uint32_t seq_num; bool initiator; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; }; diff --git a/source4/auth/gensec/schannel_sign.c b/source4/auth/gensec/schannel_sign.c index 9862a029a4..17a0c17d41 100644 --- a/source4/auth/gensec/schannel_sign.c +++ b/source4/auth/gensec/schannel_sign.c @@ -22,11 +22,9 @@ #include "includes.h" #include "../lib/crypto/crypto.h" -#include "auth/auth.h" -#include "auth/gensec/schannel.h" -#include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" -#include "auth/gensec/schannel_proto.h" +#include "auth/gensec/gensec_proto.h" +#include "auth/gensec/schannel.h" #define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } #define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } diff --git a/source4/auth/gensec/schannel_state.c b/source4/auth/gensec/schannel_state.c index ca8537cac9..1320db8933 100644 --- a/source4/auth/gensec/schannel_state.c +++ b/source4/auth/gensec/schannel_state.c @@ -21,7 +21,6 @@ #include "includes.h" #include "lib/ldb/include/ldb.h" -#include "librpc/gen_ndr/ndr_security.h" #include "ldb_wrap.h" #include "../lib/util/util_ldb.h" #include "libcli/auth/libcli_auth.h" @@ -29,45 +28,6 @@ #include "param/param.h" #include "auth/gensec/schannel_state.h" -static struct ldb_val *schannel_dom_sid_ldb_val(TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *smbiconv, - struct dom_sid *sid) -{ - enum ndr_err_code ndr_err; - struct ldb_val *v; - - v = talloc(mem_ctx, struct ldb_val); - if (!v) return NULL; - - ndr_err = ndr_push_struct_blob(v, mem_ctx, smbiconv, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(v); - return NULL; - } - - return v; -} - -static struct dom_sid *schannel_ldb_val_dom_sid(TALLOC_CTX *mem_ctx, - const struct ldb_val *v) -{ - enum ndr_err_code ndr_err; - struct dom_sid *sid; - - sid = talloc(mem_ctx, struct dom_sid); - if (!sid) return NULL; - - ndr_err = ndr_pull_struct_blob(v, sid, NULL, sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(sid); - return NULL; - } - return sid; -} - - /** connect to the schannel ldb */ @@ -104,246 +64,3 @@ struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx, struct tevent_conte return ldb; } -/* - remember an established session key for a netr server authentication - use a simple ldb structure -*/ -NTSTATUS schannel_store_session_key_ldb(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - struct creds_CredentialState *creds) -{ - struct ldb_message *msg; - struct ldb_val val, seed, client_state, server_state; - struct smb_iconv_convenience *smbiconv; - struct ldb_val *sid_val; - char *f; - char *sct; - int ret; - - f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags); - - if (f == NULL) { - return NT_STATUS_NO_MEMORY; - } - - sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type); - - if (sct == NULL) { - return NT_STATUS_NO_MEMORY; - } - - msg = ldb_msg_new(ldb); - if (msg == NULL) { - return NT_STATUS_NO_MEMORY; - } - - msg->dn = ldb_dn_new_fmt(msg, ldb, "computerName=%s", creds->computer_name); - if ( ! msg->dn) { - return NT_STATUS_NO_MEMORY; - } - - smbiconv = lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")); - sid_val = schannel_dom_sid_ldb_val(msg, smbiconv, creds->sid); - if (sid_val == NULL) { - return NT_STATUS_NO_MEMORY; - } - - val.data = creds->session_key; - val.length = sizeof(creds->session_key); - - seed.data = creds->seed.data; - seed.length = sizeof(creds->seed.data); - - client_state.data = creds->client.data; - client_state.length = sizeof(creds->client.data); - server_state.data = creds->server.data; - server_state.length = sizeof(creds->server.data); - - ldb_msg_add_string(msg, "objectClass", "schannelState"); - ldb_msg_add_value(msg, "sessionKey", &val, NULL); - ldb_msg_add_value(msg, "seed", &seed, NULL); - ldb_msg_add_value(msg, "clientState", &client_state, NULL); - ldb_msg_add_value(msg, "serverState", &server_state, NULL); - ldb_msg_add_string(msg, "negotiateFlags", f); - ldb_msg_add_string(msg, "secureChannelType", sct); - ldb_msg_add_string(msg, "accountName", creds->account_name); - ldb_msg_add_string(msg, "computerName", creds->computer_name); - ldb_msg_add_string(msg, "flatname", creds->domain); - ldb_msg_add_value(msg, "objectSid", sid_val, NULL); - - ldb_delete(ldb, msg->dn); - - ret = ldb_add(ldb, msg); - - if (ret != 0) { - DEBUG(0,("Unable to add %s to session key db - %s\n", - ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - return NT_STATUS_OK; -} - -NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct loadparm_context *lp_ctx, - struct creds_CredentialState *creds) -{ - struct ldb_context *ldb; - NTSTATUS nt_status; - int ret; - - ldb = schannel_db_connect(mem_ctx, ev_ctx, lp_ctx); - if (!ldb) { - return NT_STATUS_ACCESS_DENIED; - } - - ret = ldb_transaction_start(ldb); - if (ret != 0) { - talloc_free(ldb); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - nt_status = schannel_store_session_key_ldb(mem_ctx, ldb, creds); - - if (NT_STATUS_IS_OK(nt_status)) { - ret = ldb_transaction_commit(ldb); - } else { - ret = ldb_transaction_cancel(ldb); - } - - if (ret != 0) { - DEBUG(0,("Unable to commit adding credentials for %s to schannel key db - %s\n", - creds->computer_name, ldb_errstring(ldb))); - talloc_free(ldb); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - talloc_free(ldb); - return nt_status; -} - -/* - read back a credentials back for a computer -*/ -NTSTATUS schannel_fetch_session_key_ldb(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const char *computer_name, - const char *domain, - struct creds_CredentialState **creds) -{ - struct ldb_result *res; - int ret; - const struct ldb_val *val; - - *creds = talloc_zero(mem_ctx, struct creds_CredentialState); - if (!*creds) { - return NT_STATUS_NO_MEMORY; - } - - ret = ldb_search(ldb, mem_ctx, &res, - NULL, LDB_SCOPE_SUBTREE, NULL, - "(&(computerName=%s)(flatname=%s))", computer_name, domain); - if (ret != LDB_SUCCESS) { - DEBUG(3,("schannel: Failed to find a record for client %s: %s\n", computer_name, ldb_errstring(ldb))); - return NT_STATUS_INVALID_HANDLE; - } - if (res->count != 1) { - DEBUG(3,("schannel: Failed to find a record for client: %s (found %d records)\n", computer_name, res->count)); - talloc_free(res); - return NT_STATUS_INVALID_HANDLE; - } - - val = ldb_msg_find_ldb_val(res->msgs[0], "sessionKey"); - if (val == NULL || val->length != 16) { - DEBUG(1,("schannel: record in schannel DB must contain a sessionKey of length 16, when searching for client: %s\n", computer_name)); - talloc_free(res); - return NT_STATUS_INTERNAL_ERROR; - } - - memcpy((*creds)->session_key, val->data, 16); - - val = ldb_msg_find_ldb_val(res->msgs[0], "seed"); - if (val == NULL || val->length != 8) { - DEBUG(1,("schannel: record in schannel DB must contain a vaid seed of length 8, when searching for client: %s\n", computer_name)); - talloc_free(res); - return NT_STATUS_INTERNAL_ERROR; - } - - memcpy((*creds)->seed.data, val->data, 8); - - val = ldb_msg_find_ldb_val(res->msgs[0], "clientState"); - if (val == NULL || val->length != 8) { - DEBUG(1,("schannel: record in schannel DB must contain a vaid clientState of length 8, when searching for client: %s\n", computer_name)); - talloc_free(res); - return NT_STATUS_INTERNAL_ERROR; - } - memcpy((*creds)->client.data, val->data, 8); - - val = ldb_msg_find_ldb_val(res->msgs[0], "serverState"); - if (val == NULL || val->length != 8) { - DEBUG(1,("schannel: record in schannel DB must contain a vaid serverState of length 8, when searching for client: %s\n", computer_name)); - talloc_free(res); - return NT_STATUS_INTERNAL_ERROR; - } - memcpy((*creds)->server.data, val->data, 8); - - (*creds)->negotiate_flags = ldb_msg_find_attr_as_int(res->msgs[0], "negotiateFlags", 0); - - (*creds)->secure_channel_type = ldb_msg_find_attr_as_int(res->msgs[0], "secureChannelType", 0); - - (*creds)->account_name = talloc_strdup(*creds, ldb_msg_find_attr_as_string(res->msgs[0], "accountName", NULL)); - if ((*creds)->account_name == NULL) { - talloc_free(res); - return NT_STATUS_NO_MEMORY; - } - - (*creds)->computer_name = talloc_strdup(*creds, ldb_msg_find_attr_as_string(res->msgs[0], "computerName", NULL)); - if ((*creds)->computer_name == NULL) { - talloc_free(res); - return NT_STATUS_NO_MEMORY; - } - - (*creds)->domain = talloc_strdup(*creds, ldb_msg_find_attr_as_string(res->msgs[0], "flatname", NULL)); - if ((*creds)->domain == NULL) { - talloc_free(res); - return NT_STATUS_NO_MEMORY; - } - - val = ldb_msg_find_ldb_val(res->msgs[0], "objectSid"); - if (val == NULL) { - DEBUG(1,("schannel: missing ObjectSid for client: %s\n", computer_name)); - talloc_free(res); - return NT_STATUS_INTERNAL_ERROR; - } - (*creds)->sid = schannel_ldb_val_dom_sid(*creds, val); - if ((*creds)->sid == NULL) { - talloc_free(res); - return NT_STATUS_INTERNAL_ERROR; - } - - talloc_free(res); - return NT_STATUS_OK; -} - -NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct loadparm_context *lp_ctx, - const char *computer_name, - const char *domain, - struct creds_CredentialState **creds) -{ - NTSTATUS nt_status; - struct ldb_context *ldb; - - ldb = schannel_db_connect(mem_ctx, ev_ctx, lp_ctx); - if (!ldb) { - return NT_STATUS_ACCESS_DENIED; - } - - nt_status = schannel_fetch_session_key_ldb(mem_ctx, ldb, - computer_name, domain, - creds); - talloc_free(ldb); - return nt_status; -} diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index 96a13d5ed9..2b9b92812c 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -25,7 +25,7 @@ #include "lib/ldb/include/ldb.h" #include "../lib/util/util_ldb.h" #include "auth/auth.h" -#include "auth/ntlm/ntlm_check.h" +#include "../libcli/auth/ntlm_check.h" #include "auth/ntlm/auth_proto.h" #include "auth/auth_sam.h" #include "dsdb/samdb/samdb.h" diff --git a/source4/auth/ntlm/config.mk b/source4/auth/ntlm/config.mk index 668c528ea9..a9ae18e7c2 100644 --- a/source4/auth/ntlm/config.mk +++ b/source4/auth/ntlm/config.mk @@ -1,10 +1,5 @@ # NTLM auth server subsystem -[SUBSYSTEM::ntlm_check] -PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL - -ntlm_check_OBJ_FILES = $(addprefix $(authsrcdir)/ntlm/, ntlm_check.o) - ####################### # Start MODULE auth_sam [MODULE::auth_sam_module] diff --git a/source4/auth/ntlm/ntlm_check.c b/source4/auth/ntlm/ntlm_check.c deleted file mode 100644 index 0805b1b043..0000000000 --- a/source4/auth/ntlm/ntlm_check.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2004 - Copyright (C) Gerald Carter 2003 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "../lib/crypto/crypto.h" -#include "librpc/gen_ndr/netlogon.h" -#include "libcli/auth/libcli_auth.h" -#include "auth/ntlm/ntlm_check.h" - -/**************************************************************************** - Core of smb password checking routine. -****************************************************************************/ - -static bool smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx, - const DATA_BLOB *nt_response, - const uint8_t *part_passwd, - const DATA_BLOB *sec_blob, - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uint8_t p24[24]; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always false ! */ - return false; - } - - if (sec_blob->length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", - (unsigned long)sec_blob->length)); - return false; - } - - if (nt_response->length != 24) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", - (unsigned long)nt_response->length)); - return false; - } - - SMBOWFencrypt(part_passwd, sec_blob->data, p24); - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); - DEBUGADD(100,("Password from client was |\n")); - dump_data(100, nt_response->data, nt_response->length); - DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); - DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, p24, 24); -#endif - if (memcmp(p24, nt_response->data, 24) == 0) { - if (user_sess_key != NULL) { - *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); - SMBsesskeygen_ntv1(part_passwd, user_sess_key->data); - } - return true; - } - return false; -} - -/**************************************************************************** - Core of smb password checking routine. (NTLMv2, LMv2) - Note: The same code works with both NTLMv2 and LMv2. -****************************************************************************/ - -static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx, - const DATA_BLOB *ntv2_response, - const uint8_t *part_passwd, - const DATA_BLOB *sec_blob, - const char *user, const char *domain, - bool upper_case_domain, /* should the domain be transformed into upper case? */ - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uint8_t kr[16]; - uint8_t value_from_encryption[16]; - DATA_BLOB client_key_data; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always false */ - return false; - } - - if (sec_blob->length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", - (unsigned long)sec_blob->length)); - return false; - } - - if (ntv2_response->length < 24) { - /* We MUST have more than 16 bytes, or the stuff below will go - crazy. No known implementation sends less than the 24 bytes - for LMv2, let alone NTLMv2. */ - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", - (unsigned long)ntv2_response->length)); - return false; - } - - client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16); - /* - todo: should we be checking this for anything? We can't for LMv2, - but for NTLMv2 it is meant to contain the current time etc. - */ - - if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) { - return false; - } - - SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); - DEBUGADD(100,("Password from client was |\n")); - dump_data(100, ntv2_response->data, ntv2_response->length); - DEBUGADD(100,("Variable data from client was |\n")); - dump_data(100, client_key_data.data, client_key_data.length); - DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); - DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, value_from_encryption, 16); -#endif - data_blob_clear_free(&client_key_data); - if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) { - if (user_sess_key != NULL) { - *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); - SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); - } - return true; - } - return false; -} - -/**************************************************************************** - Core of smb password checking routine. (NTLMv2, LMv2) - Note: The same code works with both NTLMv2 and LMv2. -****************************************************************************/ - -static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx, - const DATA_BLOB *ntv2_response, - const uint8_t *part_passwd, - const DATA_BLOB *sec_blob, - const char *user, const char *domain, - bool upper_case_domain, /* should the domain be transformed into upper case? */ - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uint8_t kr[16]; - uint8_t value_from_encryption[16]; - DATA_BLOB client_key_data; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always false */ - return false; - } - - if (sec_blob->length != 8) { - DEBUG(0, ("smb_sess_key_ntlmv2: incorrect challenge size (%lu)\n", - (unsigned long)sec_blob->length)); - return false; - } - - if (ntv2_response->length < 24) { - /* We MUST have more than 16 bytes, or the stuff below will go - crazy. No known implementation sends less than the 24 bytes - for LMv2, let alone NTLMv2. */ - DEBUG(0, ("smb_sess_key_ntlmv2: incorrect password length (%lu)\n", - (unsigned long)ntv2_response->length)); - return false; - } - - client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16); - - if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) { - return false; - } - - SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); - *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16); - SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); - return true; -} - -/** - * Compare password hashes against those from the SAM - * - * @param mem_ctx talloc context - * @param client_lanman LANMAN password hash, as supplied by the client - * @param client_nt NT (MD4) password hash, as supplied by the client - * @param username internal Samba username, for log messages - * @param client_username username the client used - * @param client_domain domain name the client used (may be mapped) - * @param stored_lanman LANMAN password hash, as stored on the SAM - * @param stored_nt NT (MD4) password hash, as stored on the SAM - * @param user_sess_key User session key - * @param lm_sess_key LM session key (first 8 bytes of the LM hash) - */ - -NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx, - bool lanman_auth, - const struct samr_Password *client_lanman, - const struct samr_Password *client_nt, - const char *username, - const struct samr_Password *stored_lanman, - const struct samr_Password *stored_nt) -{ - if (stored_nt == NULL) { - DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", - username)); - } - - if (client_nt && stored_nt) { - if (memcmp(client_nt->hash, stored_nt->hash, sizeof(stored_nt->hash)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: Interactive logon: NT password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - } else if (client_lanman && stored_lanman) { - if (!lanman_auth) { - DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - if (strchr_m(username, '@')) { - return NT_STATUS_NOT_FOUND; - } - - if (memcmp(client_lanman->hash, stored_lanman->hash, sizeof(stored_lanman->hash)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } - if (strchr_m(username, '@')) { - return NT_STATUS_NOT_FOUND; - } - return NT_STATUS_WRONG_PASSWORD; -} - -/** - * Check a challenge-response password against the value of the NT or - * LM password hash. - * - * @param mem_ctx talloc context - * @param challenge 8-byte challenge. If all zero, forces plaintext comparison - * @param nt_response 'unicode' NT response to the challenge, or unicode password - * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page - * @param username internal Samba username, for log messages - * @param client_username username the client used - * @param client_domain domain name the client used (may be mapped) - * @param stored_lanman LANMAN ASCII password from our passdb or similar - * @param stored_nt MD4 unicode password from our passdb or similar - * @param user_sess_key User session key - * @param lm_sess_key LM session key (first 8 bytes of the LM hash) - */ - -NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - bool lanman_auth, - bool ntlm_auth, - uint32_t logon_parameters, - const DATA_BLOB *challenge, - const DATA_BLOB *lm_response, - const DATA_BLOB *nt_response, - const char *username, - const char *client_username, - const char *client_domain, - const struct samr_Password *stored_lanman, - const struct samr_Password *stored_nt, - DATA_BLOB *user_sess_key, - DATA_BLOB *lm_sess_key) -{ - const static uint8_t zeros[8]; - DATA_BLOB tmp_sess_key; - - if (stored_nt == NULL) { - DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", - username)); - } - - *lm_sess_key = data_blob(NULL, 0); - *user_sess_key = data_blob(NULL, 0); - - /* Check for cleartext netlogon. Used by Exchange 5.5. */ - if ((logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_ALLOWED) - && challenge->length == sizeof(zeros) - && (memcmp(challenge->data, zeros, challenge->length) == 0 )) { - struct samr_Password client_nt; - struct samr_Password client_lm; - char *unix_pw = NULL; - bool lm_ok; - - DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n", - username)); - mdfour(client_nt.hash, nt_response->data, nt_response->length); - - if (lm_response->length && - (convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, - lm_response->data, lm_response->length, - (void **)&unix_pw, NULL, false))) { - if (E_deshash(unix_pw, client_lm.hash)) { - lm_ok = true; - } else { - lm_ok = false; - } - } else { - lm_ok = false; - } - return hash_password_check(mem_ctx, - lanman_auth, - lm_ok ? &client_lm : NULL, - nt_response->length ? &client_nt : NULL, - username, - stored_lanman, stored_nt); - } - - if (nt_response->length != 0 && nt_response->length < 24) { - DEBUG(2,("ntlm_password_check: invalid NT password length (%lu) for user %s\n", - (unsigned long)nt_response->length, username)); - } - - if (nt_response->length > 24 && stored_nt) { - /* We have the NT MD4 hash challenge available - see if we can - use it - */ - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2(mem_ctx, - nt_response, - stored_nt->hash, challenge, - client_username, - client_domain, - false, - user_sess_key)) { - *lm_sess_key = *user_sess_key; - if (user_sess_key->length) { - lm_sess_key->length = 8; - } - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2(mem_ctx, - nt_response, - stored_nt->hash, challenge, - client_username, - client_domain, - true, - user_sess_key)) { - *lm_sess_key = *user_sess_key; - if (user_sess_key->length) { - lm_sess_key->length = 8; - } - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2(mem_ctx, - nt_response, - stored_nt->hash, challenge, - client_username, - "", - false, - user_sess_key)) { - *lm_sess_key = *user_sess_key; - if (user_sess_key->length) { - lm_sess_key->length = 8; - } - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n")); - } - } else if (nt_response->length == 24 && stored_nt) { - if (ntlm_auth) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(mem_ctx, - nt_response, - stored_nt->hash, challenge, - user_sess_key)) { - /* The LM session key for this response is not very secure, - so use it only if we otherwise allow LM authentication */ - - if (lanman_auth && stored_lanman) { - *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8); - } - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } else { - DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n", - username)); - /* no return, becouse we might pick up LMv2 in the LM field */ - } - } - - if (lm_response->length == 0) { - DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (lm_response->length < 24) { - DEBUG(2,("ntlm_password_check: invalid LanMan password length (%lu) for user %s\n", - (unsigned long)nt_response->length, username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (!lanman_auth) { - DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n", - username)); - } else if (!stored_lanman) { - DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n", - username)); - } else if (strchr_m(username, '@')) { - DEBUG(3,("ntlm_password_check: NO LanMan password allowed for username@realm logins (user: %s)\n", - username)); - } else { - DEBUG(4,("ntlm_password_check: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(mem_ctx, - lm_response, - stored_lanman->hash, challenge, - NULL)) { - /* The session key for this response is still very odd. - It not very secure, so use it only if we otherwise - allow LM authentication */ - - if (lanman_auth && stored_lanman) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, stored_lanman->hash, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob_talloc(mem_ctx, first_8_lm_hash, 16); - *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8); - } - return NT_STATUS_OK; - } - } - - if (!stored_nt) { - DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username)); - return NT_STATUS_WRONG_PASSWORD; - } - - /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. - - related to Win9X, legacy NAS pass-though authentication - */ - DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2(mem_ctx, - lm_response, - stored_nt->hash, challenge, - client_username, - client_domain, - false, - &tmp_sess_key)) { - if (nt_response->length > 24) { - /* If NTLMv2 authentication has preceeded us - * (even if it failed), then use the session - * key from that. See the RPC-SAMLOGON - * torture test */ - smb_sess_key_ntlmv2(mem_ctx, - nt_response, - stored_nt->hash, challenge, - client_username, - client_domain, - false, - user_sess_key); - } else { - /* Otherwise, use the LMv2 session key */ - *user_sess_key = tmp_sess_key; - } - *lm_sess_key = *user_sess_key; - if (user_sess_key->length) { - lm_sess_key->length = 8; - } - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2(mem_ctx, - lm_response, - stored_nt->hash, challenge, - client_username, - client_domain, - true, - &tmp_sess_key)) { - if (nt_response->length > 24) { - /* If NTLMv2 authentication has preceeded us - * (even if it failed), then use the session - * key from that. See the RPC-SAMLOGON - * torture test */ - smb_sess_key_ntlmv2(mem_ctx, - nt_response, - stored_nt->hash, challenge, - client_username, - client_domain, - true, - user_sess_key); - } else { - /* Otherwise, use the LMv2 session key */ - *user_sess_key = tmp_sess_key; - } - *lm_sess_key = *user_sess_key; - if (user_sess_key->length) { - lm_sess_key->length = 8; - } - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2(mem_ctx, - lm_response, - stored_nt->hash, challenge, - client_username, - "", - false, - &tmp_sess_key)) { - if (nt_response->length > 24) { - /* If NTLMv2 authentication has preceeded us - * (even if it failed), then use the session - * key from that. See the RPC-SAMLOGON - * torture test */ - smb_sess_key_ntlmv2(mem_ctx, - nt_response, - stored_nt->hash, challenge, - client_username, - "", - false, - user_sess_key); - } else { - /* Otherwise, use the LMv2 session key */ - *user_sess_key = tmp_sess_key; - } - *lm_sess_key = *user_sess_key; - if (user_sess_key->length) { - lm_sess_key->length = 8; - } - return NT_STATUS_OK; - } - - /* Apparently NT accepts NT responses in the LM field - - I think this is related to Win9X pass-though authentication - */ - DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n")); - if (ntlm_auth) { - if (smb_pwd_check_ntlmv1(mem_ctx, - lm_response, - stored_nt->hash, challenge, - NULL)) { - /* The session key for this response is still very odd. - It not very secure, so use it only if we otherwise - allow LM authentication */ - - if (lanman_auth && stored_lanman) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, stored_lanman->hash, 8); - memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob_talloc(mem_ctx, first_8_lm_hash, 16); - *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8); - } - return NT_STATUS_OK; - } - DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username)); - } else { - DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username)); - } - - /* Try and match error codes */ - if (strchr_m(username, '@')) { - return NT_STATUS_NOT_FOUND; - } - return NT_STATUS_WRONG_PASSWORD; -} - diff --git a/source4/auth/ntlm/ntlm_check.h b/source4/auth/ntlm/ntlm_check.h deleted file mode 100644 index df11f7d7a2..0000000000 --- a/source4/auth/ntlm/ntlm_check.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2004 - Copyright (C) Gerald Carter 2003 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - -/** - * Compare password hashes against those from the SAM - * - * @param mem_ctx talloc context - * @param client_lanman LANMAN password hash, as supplied by the client - * @param client_nt NT (MD4) password hash, as supplied by the client - * @param username internal Samba username, for log messages - * @param client_username username the client used - * @param client_domain domain name the client used (may be mapped) - * @param stored_lanman LANMAN password hash, as stored on the SAM - * @param stored_nt NT (MD4) password hash, as stored on the SAM - * @param user_sess_key User session key - * @param lm_sess_key LM session key (first 8 bytes of the LM hash) - */ - -NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx, - bool lanman_auth, - const struct samr_Password *client_lanman, - const struct samr_Password *client_nt, - const char *username, - const struct samr_Password *stored_lanman, - const struct samr_Password *stored_nt); - -/** - * Check a challenge-response password against the value of the NT or - * LM password hash. - * - * @param mem_ctx talloc context - * @param challenge 8-byte challenge. If all zero, forces plaintext comparison - * @param nt_response 'unicode' NT response to the challenge, or unicode password - * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page - * @param username internal Samba username, for log messages - * @param client_username username the client used - * @param client_domain domain name the client used (may be mapped) - * @param stored_lanman LANMAN ASCII password from our passdb or similar - * @param stored_nt MD4 unicode password from our passdb or similar - * @param user_sess_key User session key - * @param lm_sess_key LM session key (first 8 bytes of the LM hash) - */ - -NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - bool lanman_auth, - bool ntlm_auth, - uint32_t logon_parameters, - const DATA_BLOB *challenge, - const DATA_BLOB *lm_response, - const DATA_BLOB *nt_response, - const char *username, - const char *client_username, - const char *client_domain, - const struct samr_Password *stored_lanman, - const struct samr_Password *stored_nt, - DATA_BLOB *user_sess_key, - DATA_BLOB *lm_sess_key); diff --git a/source4/auth/ntlmssp/config.mk b/source4/auth/ntlmssp/config.mk index c0446bcac1..1be5fa98e7 100644 --- a/source4/auth/ntlmssp/config.mk +++ b/source4/auth/ntlmssp/config.mk @@ -1,9 +1,3 @@ -[SUBSYSTEM::MSRPC_PARSE] - -MSRPC_PARSE_OBJ_FILES = $(addprefix $(authsrcdir)/ntlmssp/, ntlmssp_parse.o) - -$(eval $(call proto_header_template,$(authsrcdir)/ntlmssp/msrpc_parse.h,$(MSRPC_PARSE_OBJ_FILES:.o=.c))) - ################################################ # Start MODULE gensec_ntlmssp [MODULE::gensec_ntlmssp] diff --git a/source4/auth/ntlmssp/ntlmssp.c b/source4/auth/ntlmssp/ntlmssp.c index c4b3a31365..e649bba4db 100644 --- a/source4/auth/ntlmssp/ntlmssp.c +++ b/source4/auth/ntlmssp/ntlmssp.c @@ -23,13 +23,11 @@ #include "includes.h" #include "auth/ntlmssp/ntlmssp.h" -#include "auth/ntlmssp/msrpc_parse.h" +#include "../libcli/auth/libcli_auth.h" #include "librpc/gen_ndr/ndr_dcerpc.h" #include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" #include "auth/gensec/gensec_proto.h" -#include "auth/auth.h" -#include "auth/ntlm/auth_proto.h" #include "param/param.h" /** diff --git a/source4/auth/ntlmssp/ntlmssp.h b/source4/auth/ntlmssp/ntlmssp.h index df950e4756..ff7225bb3c 100644 --- a/source4/auth/ntlmssp/ntlmssp.h +++ b/source4/auth/ntlmssp/ntlmssp.h @@ -66,11 +66,6 @@ enum ntlmssp_message_type #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 #define NTLMSSP_NEGOTIATE_56 0x80000000 -#define NTLMSSP_NAME_TYPE_SERVER 0x01 -#define NTLMSSP_NAME_TYPE_DOMAIN 0x02 -#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03 -#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04 - #define NTLMSSP_SIGN_VERSION 1 #define NTLMSSP_SIG_SIZE 16 diff --git a/source4/auth/ntlmssp/ntlmssp_client.c b/source4/auth/ntlmssp/ntlmssp_client.c index e28d8462d4..d3c1165994 100644 --- a/source4/auth/ntlmssp/ntlmssp_client.c +++ b/source4/auth/ntlmssp/ntlmssp_client.c @@ -23,9 +23,8 @@ #include "includes.h" #include "auth/ntlmssp/ntlmssp.h" -#include "auth/ntlmssp/msrpc_parse.h" #include "../lib/crypto/crypto.h" -#include "libcli/auth/libcli_auth.h" +#include "../libcli/auth/libcli_auth.h" #include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" #include "param/param.h" diff --git a/source4/auth/ntlmssp/ntlmssp_parse.c b/source4/auth/ntlmssp/ntlmssp_parse.c deleted file mode 100644 index 969845d6c5..0000000000 --- a/source4/auth/ntlmssp/ntlmssp_parse.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5/SPNEGO routines - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 - Copyright (C) Andrew Bartlett 2002-2003 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "auth/ntlmssp/msrpc_parse.h" - -/* - this is a tiny msrpc packet generator. I am only using this to - avoid tying this code to a particular varient of our rpc code. This - generator is not general enough for all our rpc needs, its just - enough for the spnego/ntlmssp code - - format specifiers are: - - U = unicode string (input is unix string) - a = address (input is char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) - B = data blob (pointer + length) - b = data blob in header (pointer + length) - D - d = word (4 bytes) - C = constant ascii string - */ -bool msrpc_gen(TALLOC_CTX *mem_ctx, - DATA_BLOB *blob, - const char *format, ...) -{ - int i, j; - bool ret; - va_list ap; - char *s; - uint8_t *b; - int head_size=0, data_size=0; - int head_ofs, data_ofs; - int *intargs; - size_t n; - - DATA_BLOB *pointers; - - pointers = talloc_array(mem_ctx, DATA_BLOB, strlen(format)); - intargs = talloc_array(pointers, int, strlen(format)); - - /* first scan the format to work out the header and body size */ - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - head_size += 8; - ret = push_ucs2_talloc(pointers, (smb_ucs2_t **)&pointers[i].data, - s, &n); - if (!ret) { - return false; - } - pointers[i].length = n; - pointers[i].length -= 2; - data_size += pointers[i].length; - break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - ret = push_ascii_talloc(pointers, (char **)&pointers[i].data, s, - &n); - if (!ret) { - return false; - } - pointers[i].length = n; - pointers[i].length -= 1; - data_size += pointers[i].length; - break; - case 'a': - j = va_arg(ap, int); - intargs[i] = j; - s = va_arg(ap, char *); - ret = push_ucs2_talloc(pointers, (smb_ucs2_t **)&pointers[i].data, - s, &n); - if (!ret) { - return false; - } - pointers[i].length = n; - pointers[i].length -= 2; - data_size += pointers[i].length + 4; - break; - case 'B': - b = va_arg(ap, uint8_t *); - head_size += 8; - pointers[i].data = b; - pointers[i].length = va_arg(ap, int); - data_size += pointers[i].length; - break; - case 'b': - b = va_arg(ap, uint8_t *); - pointers[i].data = b; - pointers[i].length = va_arg(ap, int); - head_size += pointers[i].length; - break; - case 'd': - j = va_arg(ap, int); - intargs[i] = j; - head_size += 4; - break; - case 'C': - s = va_arg(ap, char *); - pointers[i].data = (uint8_t *)s; - pointers[i].length = strlen(s)+1; - head_size += pointers[i].length; - break; - } - } - va_end(ap); - - /* allocate the space, then scan the format again to fill in the values */ - *blob = data_blob_talloc(mem_ctx, NULL, head_size + data_size); - - head_ofs = 0; - data_ofs = head_size; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - case 'A': - case 'B': - n = pointers[i].length; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - if (pointers[i].data && n) /* don't follow null pointers... */ - memcpy(blob->data+data_ofs, pointers[i].data, n); - data_ofs += n; - break; - case 'a': - j = intargs[i]; - SSVAL(blob->data, data_ofs, j); data_ofs += 2; - - n = pointers[i].length; - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (n >= 0) { - memcpy(blob->data+data_ofs, pointers[i].data, n); - } - data_ofs += n; - break; - case 'd': - j = intargs[i]; - SIVAL(blob->data, head_ofs, j); - head_ofs += 4; - break; - case 'b': - n = pointers[i].length; - memcpy(blob->data + head_ofs, pointers[i].data, n); - head_ofs += n; - break; - case 'C': - n = pointers[i].length; - memcpy(blob->data + head_ofs, pointers[i].data, n); - head_ofs += n; - break; - } - } - va_end(ap); - - talloc_free(pointers); - - return true; -} - - -/* a helpful macro to avoid running over the end of our blob */ -#define NEED_DATA(amount) \ -if ((head_ofs + amount) > blob->length) { \ - return false; \ -} - -/** - this is a tiny msrpc packet parser. This the the partner of msrpc_gen - - format specifiers are: - - U = unicode string (output is unix string) - A = ascii string - B = data blob - b = data blob in header - d = word (4 bytes) - C = constant ascii string - */ - -bool msrpc_parse(TALLOC_CTX *mem_ctx, - const DATA_BLOB *blob, - const char *format, ...) -{ - int i; - va_list ap; - const char **ps, *s; - DATA_BLOB *b; - size_t head_ofs = 0; - uint16_t len1, len2; - uint32_t ptr; - uint32_t *v; - size_t p_len = 1024; - char *p = talloc_array(mem_ctx, char, p_len); - bool ret = true; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - ps = (const char **)va_arg(ap, char **); - if (len1 == 0 && len2 == 0) { - *ps = ""; - } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - ret = false; - goto cleanup; - } - if (len1 & 1) { - /* if odd length and unicode */ - ret = false; - goto cleanup; - } - if (blob->data + ptr < (uint8_t *)(uintptr_t)ptr || - blob->data + ptr < blob->data) { - ret = false; - goto cleanup; - } - - if (0 < len1) { - pull_string(p, blob->data + ptr, p_len, - len1, STR_UNICODE|STR_NOALIGN); - (*ps) = talloc_strdup(mem_ctx, p); - if (!(*ps)) { - ret = false; - goto cleanup; - } - } else { - (*ps) = ""; - } - } - break; - case 'A': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - ps = (const char **)va_arg(ap, char **); - /* make sure its in the right format - be strict */ - if (len1 == 0 && len2 == 0) { - *ps = ""; - } else { - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - ret = false; - goto cleanup; - } - - if (blob->data + ptr < (uint8_t *)(uintptr_t)ptr || - blob->data + ptr < blob->data) { - ret = false; - goto cleanup; - } - - if (0 < len1) { - pull_string(p, blob->data + ptr, p_len, - len1, STR_ASCII|STR_NOALIGN); - (*ps) = talloc_strdup(mem_ctx, p); - if (!(*ps)) { - ret = false; - goto cleanup; - } - } else { - (*ps) = ""; - } - } - break; - case 'B': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - b = (DATA_BLOB *)va_arg(ap, void *); - if (len1 == 0 && len2 == 0) { - *b = data_blob_talloc(mem_ctx, NULL, 0); - } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - ret = false; - goto cleanup; - } - - if (blob->data + ptr < (uint8_t *)(uintptr_t)ptr || - blob->data + ptr < blob->data) { - ret = false; - goto cleanup; - } - - *b = data_blob_talloc(mem_ctx, blob->data + ptr, len1); - } - break; - case 'b': - b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, uint_t); - /* make sure its in the right format - be strict */ - NEED_DATA(len1); - if (blob->data + head_ofs < (uint8_t *)head_ofs || - blob->data + head_ofs < blob->data) { - ret = false; - goto cleanup; - } - - *b = data_blob_talloc(mem_ctx, blob->data + head_ofs, len1); - head_ofs += len1; - break; - case 'd': - v = va_arg(ap, uint32_t *); - NEED_DATA(4); - *v = IVAL(blob->data, head_ofs); head_ofs += 4; - break; - case 'C': - s = va_arg(ap, char *); - - if (blob->data + head_ofs < (uint8_t *)head_ofs || - blob->data + head_ofs < blob->data) { - ret = false; - goto cleanup; - } - - head_ofs += pull_string(p, - blob->data+head_ofs, p_len, - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - ret = false; - goto cleanup; - } - break; - } - } - -cleanup: - va_end(ap); - talloc_free(p); - return ret; -} diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index 9215ccac8c..00d3e56171 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -24,10 +24,8 @@ #include "includes.h" #include "system/network.h" #include "auth/ntlmssp/ntlmssp.h" -#include "auth/ntlmssp/msrpc_parse.h" +#include "../libcli/auth/libcli_auth.h" #include "../lib/crypto/crypto.h" -#include "libcli/auth/libcli_auth.h" -#include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" #include "auth/auth.h" #include "auth/ntlm/auth_proto.h" diff --git a/source4/auth/ntlmssp/ntlmssp_sign.c b/source4/auth/ntlmssp/ntlmssp_sign.c index 3a07d7e7bd..cf9eab67cd 100644 --- a/source4/auth/ntlmssp/ntlmssp_sign.c +++ b/source4/auth/ntlmssp/ntlmssp_sign.c @@ -20,11 +20,9 @@ */ #include "includes.h" -#include "auth/auth.h" #include "auth/ntlmssp/ntlmssp.h" -#include "auth/ntlmssp/msrpc_parse.h" +#include "../libcli/auth/libcli_auth.h" #include "../lib/crypto/crypto.h" -#include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" #define CLI_SIGN "session key to client-to-server signing key magic constant" diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk index 8d1647953f..0895a1dd86 100644 --- a/source4/dsdb/config.mk +++ b/source4/dsdb/config.mk @@ -8,7 +8,8 @@ mkinclude samdb/ldb_modules/config.mk PUBLIC_DEPENDENCIES = HEIMDAL_KRB5 PRIVATE_DEPENDENCIES = LIBNDR NDR_DRSUAPI NDR_DRSBLOBS NSS_WRAPPER \ auth_system_session LDAP_ENCODE LIBCLI_AUTH LIBNDR \ - SAMDB_SCHEMA LDB_WRAP SAMDB_COMMON + SAMDB_SCHEMA LDB_WRAP SAMDB_COMMON \ + LIBCLI_DRSUAPI SAMDB_OBJ_FILES = $(addprefix $(dsdbsrcdir)/, \ diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index 560f75da7a..78af3c8f6d 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -27,166 +27,10 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_drsblobs.h" #include "../lib/crypto/crypto.h" +#include "../libcli/drsuapi/drsuapi.h" #include "libcli/auth/libcli_auth.h" #include "param/param.h" -static WERROR dsdb_decrypt_attribute_value(TALLOC_CTX *mem_ctx, - const DATA_BLOB *gensec_skey, - bool rid_crypt, - uint32_t rid, - DATA_BLOB *in, - DATA_BLOB *out) -{ - DATA_BLOB confounder; - DATA_BLOB enc_buffer; - - struct MD5Context md5; - uint8_t _enc_key[16]; - DATA_BLOB enc_key; - - DATA_BLOB dec_buffer; - - uint32_t crc32_given; - uint32_t crc32_calc; - DATA_BLOB checked_buffer; - - DATA_BLOB plain_buffer; - - /* - * users with rid == 0 should not exist - */ - if (rid_crypt && rid == 0) { - return WERR_DS_DRA_INVALID_PARAMETER; - } - - /* - * the first 16 bytes at the beginning are the confounder - * followed by the 4 byte crc32 checksum - */ - if (in->length < 20) { - return WERR_DS_DRA_INVALID_PARAMETER; - } - confounder = data_blob_const(in->data, 16); - enc_buffer = data_blob_const(in->data + 16, in->length - 16); - - /* - * build the encryption key md5 over the session key followed - * by the confounder - * - * here the gensec session key is used and - * not the dcerpc ncacn_ip_tcp "SystemLibraryDTC" key! - */ - enc_key = data_blob_const(_enc_key, sizeof(_enc_key)); - MD5Init(&md5); - MD5Update(&md5, gensec_skey->data, gensec_skey->length); - MD5Update(&md5, confounder.data, confounder.length); - MD5Final(enc_key.data, &md5); - - /* - * copy the encrypted buffer part and - * decrypt it using the created encryption key using arcfour - */ - dec_buffer = data_blob_const(enc_buffer.data, enc_buffer.length); - arcfour_crypt_blob(dec_buffer.data, dec_buffer.length, &enc_key); - - /* - * the first 4 byte are the crc32 checksum - * of the remaining bytes - */ - crc32_given = IVAL(dec_buffer.data, 0); - crc32_calc = crc32_calc_buffer(dec_buffer.data + 4 , dec_buffer.length - 4); - if (crc32_given != crc32_calc) { - return WERR_SEC_E_DECRYPT_FAILURE; - } - checked_buffer = data_blob_const(dec_buffer.data + 4, dec_buffer.length - 4); - - plain_buffer = data_blob_talloc(mem_ctx, checked_buffer.data, checked_buffer.length); - W_ERROR_HAVE_NO_MEMORY(plain_buffer.data); - - /* - * The following rid_crypt obfuscation isn't session specific - * and not really needed here, because we allways know the rid of the - * user account. - * - * But for the rest of samba it's easier when we remove this static - * obfuscation here - */ - if (rid_crypt) { - uint32_t i, num_hashes; - - if ((checked_buffer.length % 16) != 0) { - return WERR_DS_DRA_INVALID_PARAMETER; - } - - num_hashes = plain_buffer.length / 16; - for (i = 0; i < num_hashes; i++) { - uint32_t offset = i * 16; - sam_rid_crypt(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0); - } - } - - *out = plain_buffer; - return WERR_OK; -} - -static WERROR dsdb_decrypt_attribute(const DATA_BLOB *gensec_skey, - uint32_t rid, - struct drsuapi_DsReplicaAttribute *attr) -{ - WERROR status; - TALLOC_CTX *mem_ctx; - DATA_BLOB *enc_data; - DATA_BLOB plain_data; - bool rid_crypt = false; - - if (attr->value_ctr.num_values == 0) { - return WERR_OK; - } - - switch (attr->attid) { - case DRSUAPI_ATTRIBUTE_dBCSPwd: - case DRSUAPI_ATTRIBUTE_unicodePwd: - case DRSUAPI_ATTRIBUTE_ntPwdHistory: - case DRSUAPI_ATTRIBUTE_lmPwdHistory: - rid_crypt = true; - break; - case DRSUAPI_ATTRIBUTE_supplementalCredentials: - case DRSUAPI_ATTRIBUTE_priorValue: - case DRSUAPI_ATTRIBUTE_currentValue: - case DRSUAPI_ATTRIBUTE_trustAuthOutgoing: - case DRSUAPI_ATTRIBUTE_trustAuthIncoming: - case DRSUAPI_ATTRIBUTE_initialAuthOutgoing: - case DRSUAPI_ATTRIBUTE_initialAuthIncoming: - break; - default: - return WERR_OK; - } - - if (attr->value_ctr.num_values > 1) { - return WERR_DS_DRA_INVALID_PARAMETER; - } - - if (!attr->value_ctr.values[0].blob) { - return WERR_DS_DRA_INVALID_PARAMETER; - } - - mem_ctx = attr->value_ctr.values[0].blob; - enc_data = attr->value_ctr.values[0].blob; - - status = dsdb_decrypt_attribute_value(mem_ctx, - gensec_skey, - rid_crypt, - rid, - enc_data, - &plain_data); - W_ERROR_NOT_OK_RETURN(status); - - talloc_free(attr->value_ctr.values[0].blob->data); - *attr->value_ctr.values[0].blob = plain_data; - - return WERR_OK; -} - static WERROR dsdb_convert_object(struct ldb_context *ldb, const struct dsdb_schema *schema, struct dsdb_extended_replicated_objects *ctr, @@ -279,7 +123,7 @@ static WERROR dsdb_convert_object(struct ldb_context *ldb, m = &md->ctr.ctr1.array[i]; e = &msg->elements[i]; - status = dsdb_decrypt_attribute(gensec_skey, rid, a); + status = drsuapi_decrypt_attribute(a->value_ctr.values[0].blob, gensec_skey, rid, a); W_ERROR_NOT_OK_RETURN(status); status = dsdb_attribute_drsuapi_to_ldb(ldb, schema, a, msg->elements, e); diff --git a/source4/libcli/auth/config.mk b/source4/libcli/auth/config.mk deleted file mode 100644 index 498c2af258..0000000000 --- a/source4/libcli/auth/config.mk +++ /dev/null @@ -1,17 +0,0 @@ -################################# -# Start SUBSYSTEM LIBCLI_AUTH -[SUBSYSTEM::LIBCLI_AUTH] -PUBLIC_DEPENDENCIES = \ - MSRPC_PARSE \ - LIBSAMBA-HOSTCONFIG -# End SUBSYSTEM LIBCLI_AUTH -################################# - -LIBCLI_AUTH_OBJ_FILES = $(addprefix $(libclisrcdir)/auth/, \ - credentials.o \ - session.o \ - smbencrypt.o \ - smbdes.o) - -PUBLIC_HEADERS += $(libclisrcdir)/auth/credentials.h -$(eval $(call proto_header_template,$(libclisrcdir)/auth/proto.h,$(LIBCLI_AUTH_OBJ_FILES:.o=.c))) diff --git a/source4/libcli/auth/credentials.c b/source4/libcli/auth/credentials.c deleted file mode 100644 index 3c77b0836d..0000000000 --- a/source4/libcli/auth/credentials.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - code to manipulate domain credentials - - Copyright (C) Andrew Tridgell 1997-2003 - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "system/time.h" -#include "auth/auth.h" -#include "../lib/crypto/crypto.h" -#include "libcli/auth/libcli_auth.h" - -/* - initialise the credentials state for old-style 64 bit session keys - - this call is made after the netr_ServerReqChallenge call -*/ -static void creds_init_64bit(struct creds_CredentialState *creds, - const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const struct samr_Password *machine_password) -{ - uint32_t sum[2]; - uint8_t sum2[8]; - - sum[0] = IVAL(client_challenge->data, 0) + IVAL(server_challenge->data, 0); - sum[1] = IVAL(client_challenge->data, 4) + IVAL(server_challenge->data, 4); - - SIVAL(sum2,0,sum[0]); - SIVAL(sum2,4,sum[1]); - - ZERO_STRUCT(creds->session_key); - - des_crypt128(creds->session_key, sum2, machine_password->hash); - - des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); - des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); - - creds->seed = creds->client; -} - -/* - initialise the credentials state for ADS-style 128 bit session keys - - this call is made after the netr_ServerReqChallenge call -*/ -static void creds_init_128bit(struct creds_CredentialState *creds, - const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const struct samr_Password *machine_password) -{ - unsigned char zero[4], tmp[16]; - HMACMD5Context ctx; - struct MD5Context md5; - - ZERO_STRUCT(creds->session_key); - - memset(zero, 0, sizeof(zero)); - - hmac_md5_init_rfc2104(machine_password->hash, sizeof(machine_password->hash), &ctx); - MD5Init(&md5); - MD5Update(&md5, zero, sizeof(zero)); - MD5Update(&md5, client_challenge->data, 8); - MD5Update(&md5, server_challenge->data, 8); - MD5Final(tmp, &md5); - hmac_md5_update(tmp, sizeof(tmp), &ctx); - hmac_md5_final(creds->session_key, &ctx); - - creds->client = *client_challenge; - creds->server = *server_challenge; - - des_crypt112(creds->client.data, client_challenge->data, creds->session_key, 1); - des_crypt112(creds->server.data, server_challenge->data, creds->session_key, 1); - - creds->seed = creds->client; -} - - -/* - step the credentials to the next element in the chain, updating the - current client and server credentials and the seed -*/ -static void creds_step(struct creds_CredentialState *creds) -{ - struct netr_Credential time_cred; - - DEBUG(5,("\tseed %08x:%08x\n", - IVAL(creds->seed.data, 0), IVAL(creds->seed.data, 4))); - - SIVAL(time_cred.data, 0, IVAL(creds->seed.data, 0) + creds->sequence); - SIVAL(time_cred.data, 4, IVAL(creds->seed.data, 4)); - - DEBUG(5,("\tseed+time %08x:%08x\n", IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - - des_crypt112(creds->client.data, time_cred.data, creds->session_key, 1); - - DEBUG(5,("\tCLIENT %08x:%08x\n", - IVAL(creds->client.data, 0), IVAL(creds->client.data, 4))); - - SIVAL(time_cred.data, 0, IVAL(creds->seed.data, 0) + creds->sequence + 1); - SIVAL(time_cred.data, 4, IVAL(creds->seed.data, 4)); - - DEBUG(5,("\tseed+time+1 %08x:%08x\n", - IVAL(time_cred.data, 0), IVAL(time_cred.data, 4))); - - des_crypt112(creds->server.data, time_cred.data, creds->session_key, 1); - - DEBUG(5,("\tSERVER %08x:%08x\n", - IVAL(creds->server.data, 0), IVAL(creds->server.data, 4))); - - creds->seed = time_cred; -} - - -/* - DES encrypt a 8 byte LMSessionKey buffer using the Netlogon session key -*/ -void creds_des_encrypt_LMKey(struct creds_CredentialState *creds, struct netr_LMSessionKey *key) -{ - struct netr_LMSessionKey tmp; - des_crypt56(tmp.key, key->key, creds->session_key, 1); - *key = tmp; -} - -/* - DES decrypt a 8 byte LMSessionKey buffer using the Netlogon session key -*/ -void creds_des_decrypt_LMKey(struct creds_CredentialState *creds, struct netr_LMSessionKey *key) -{ - struct netr_LMSessionKey tmp; - des_crypt56(tmp.key, key->key, creds->session_key, 0); - *key = tmp; -} - -/* - DES encrypt a 16 byte password buffer using the session key -*/ -void creds_des_encrypt(struct creds_CredentialState *creds, struct samr_Password *pass) -{ - struct samr_Password tmp; - des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 1); - *pass = tmp; -} - -/* - DES decrypt a 16 byte password buffer using the session key -*/ -void creds_des_decrypt(struct creds_CredentialState *creds, struct samr_Password *pass) -{ - struct samr_Password tmp; - des_crypt112_16(tmp.hash, pass->hash, creds->session_key, 0); - *pass = tmp; -} - -/* - ARCFOUR encrypt/decrypt a password buffer using the session key -*/ -void creds_arcfour_crypt(struct creds_CredentialState *creds, uint8_t *data, size_t len) -{ - DATA_BLOB session_key = data_blob(creds->session_key, 16); - - arcfour_crypt_blob(data, len, &session_key); - - data_blob_free(&session_key); -} - -/***************************************************************** -The above functions are common to the client and server interface -next comes the client specific functions -******************************************************************/ - -/* - initialise the credentials chain and return the first client - credentials -*/ -void creds_client_init(struct creds_CredentialState *creds, - const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const struct samr_Password *machine_password, - struct netr_Credential *initial_credential, - uint32_t negotiate_flags) -{ - creds->sequence = time(NULL); - creds->negotiate_flags = negotiate_flags; - - dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data)); - dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data)); - dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash)); - - if (negotiate_flags & NETLOGON_NEG_128BIT) { - creds_init_128bit(creds, client_challenge, server_challenge, machine_password); - } else { - creds_init_64bit(creds, client_challenge, server_challenge, machine_password); - } - - dump_data_pw("Session key", creds->session_key, 16); - dump_data_pw("Credential ", creds->client.data, 8); - - *initial_credential = creds->client; -} - -/* - step the credentials to the next element in the chain, updating the - current client and server credentials and the seed - - produce the next authenticator in the sequence ready to send to - the server -*/ -void creds_client_authenticator(struct creds_CredentialState *creds, - struct netr_Authenticator *next) -{ - creds->sequence += 2; - creds_step(creds); - - next->cred = creds->client; - next->timestamp = creds->sequence; -} - -/* - check that a credentials reply from a server is correct -*/ -bool creds_client_check(struct creds_CredentialState *creds, - const struct netr_Credential *received_credentials) -{ - if (!received_credentials || - memcmp(received_credentials->data, creds->server.data, 8) != 0) { - DEBUG(2,("credentials check failed\n")); - return false; - } - return true; -} - - -/***************************************************************** -The above functions are common to the client and server interface -next comes the server specific functions -******************************************************************/ - -/* - initialise the credentials chain and return the first server - credentials -*/ -void creds_server_init(struct creds_CredentialState *creds, - const struct netr_Credential *client_challenge, - const struct netr_Credential *server_challenge, - const struct samr_Password *machine_password, - struct netr_Credential *initial_credential, - uint32_t negotiate_flags) -{ - if (negotiate_flags & NETLOGON_NEG_128BIT) { - creds_init_128bit(creds, client_challenge, server_challenge, - machine_password); - } else { - creds_init_64bit(creds, client_challenge, server_challenge, - machine_password); - } - - *initial_credential = creds->server; - creds->negotiate_flags = negotiate_flags; -} - -/* - check that a credentials reply from a server is correct -*/ -bool creds_server_check(const struct creds_CredentialState *creds, - const struct netr_Credential *received_credentials) -{ - if (memcmp(received_credentials->data, creds->client.data, 8) != 0) { - DEBUG(2,("credentials check failed\n")); - dump_data_pw("client creds", creds->client.data, 8); - dump_data_pw("calc creds", received_credentials->data, 8); - return false; - } - return true; -} - -NTSTATUS creds_server_step_check(struct creds_CredentialState *creds, - struct netr_Authenticator *received_authenticator, - struct netr_Authenticator *return_authenticator) -{ - if (!received_authenticator || !return_authenticator) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (!creds) { - return NT_STATUS_ACCESS_DENIED; - } - - /* TODO: this may allow the a replay attack on a non-signed - connection. Should we check that this is increasing? */ - creds->sequence = received_authenticator->timestamp; - creds_step(creds); - if (creds_server_check(creds, &received_authenticator->cred)) { - return_authenticator->cred = creds->server; - return_authenticator->timestamp = creds->sequence; - return NT_STATUS_OK; - } else { - ZERO_STRUCTP(return_authenticator); - return NT_STATUS_ACCESS_DENIED; - } -} - -void creds_decrypt_samlogon(struct creds_CredentialState *creds, - uint16_t validation_level, - union netr_Validation *validation) -{ - static const char zeros[16]; - - struct netr_SamBaseInfo *base = NULL; - switch (validation_level) { - case 2: - if (validation->sam2) { - base = &validation->sam2->base; - } - break; - case 3: - if (validation->sam3) { - base = &validation->sam3->base; - } - break; - case 6: - if (validation->sam6) { - base = &validation->sam6->base; - } - break; - default: - /* If we can't find it, we can't very well decrypt it */ - return; - } - - if (!base) { - return; - } - - /* find and decyrpt the session keys, return in parameters above */ - if (validation_level == 6) { - /* they aren't encrypted! */ - } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - if (memcmp(base->key.key, zeros, - sizeof(base->key.key)) != 0) { - creds_arcfour_crypt(creds, - base->key.key, - sizeof(base->key.key)); - } - - if (memcmp(base->LMSessKey.key, zeros, - sizeof(base->LMSessKey.key)) != 0) { - creds_arcfour_crypt(creds, - base->LMSessKey.key, - sizeof(base->LMSessKey.key)); - } - } else { - if (memcmp(base->LMSessKey.key, zeros, - sizeof(base->LMSessKey.key)) != 0) { - creds_des_decrypt_LMKey(creds, - &base->LMSessKey); - } - } -} diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h deleted file mode 100644 index 4e11cb090f..0000000000 --- a/source4/libcli/auth/credentials.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - code to manipulate domain credentials - - Copyright (C) Andrew Tridgell 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "librpc/gen_ndr/netlogon.h" - -struct creds_CredentialState { - uint32_t negotiate_flags; - uint8_t session_key[16]; - uint32_t sequence; - struct netr_Credential seed; - struct netr_Credential client; - struct netr_Credential server; - uint16_t secure_channel_type; - const char *domain; - const char *computer_name; - const char *account_name; - struct dom_sid *sid; -}; - -/* for the timebeing, use the same neg flags as Samba3. */ -/* The 7 here seems to be required to get Win2k not to downgrade us - to NT4. Actually, anything other than 1ff would seem to do... */ -#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff - -/* these are the flags that ADS clients use */ -#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL) - - diff --git a/source4/libcli/auth/libcli_auth.h b/source4/libcli/auth/libcli_auth.h deleted file mode 100644 index ec1c1e7d98..0000000000 --- a/source4/libcli/auth/libcli_auth.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - samba -- Unix SMB/CIFS implementation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#ifndef __LIBCLI_AUTH_H__ -#define __LIBCLI_AUTH_H__ - -#include "librpc/gen_ndr/netlogon.h" -#include "libcli/auth/credentials.h" -#include "libcli/auth/proto.h" - -#endif /* __LIBCLI_AUTH_H__ */ diff --git a/source4/libcli/auth/session.c b/source4/libcli/auth/session.c deleted file mode 100644 index 10c728662d..0000000000 --- a/source4/libcli/auth/session.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - code to encrypt/decrypt data using the user session key - - Copyright (C) Andrew Tridgell 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "libcli/auth/libcli_auth.h" - -/* - encrypt or decrypt a blob of data using the user session key - as used in lsa_SetSecret - - before calling, the out blob must be initialised to be the same size - as the in blob -*/ -void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, - bool forward) -{ - int i, k; - - for (i=0,k=0; - i<in->length; - i += 8, k += 7) { - uint8_t bin[8], bout[8], key[7]; - - memset(bin, 0, 8); - memcpy(bin, &in->data[i], MIN(8, in->length-i)); - - if (k + 7 > session_key->length) { - k = (session_key->length - k); - } - memcpy(key, &session_key->data[k], 7); - - des_crypt56(bout, bin, key, forward?1:0); - - memcpy(&out->data[i], bout, MIN(8, in->length-i)); - } -} - - -/* - a convenient wrapper around sess_crypt_blob() for strings, using the LSA convention - - note that we round the length to a multiple of 8. This seems to be needed for - compatibility with windows - - caller should free using data_blob_free() -*/ -DATA_BLOB sess_encrypt_string(const char *str, const DATA_BLOB *session_key) -{ - DATA_BLOB ret, src; - int slen = strlen(str); - int dlen = (slen+7) & ~7; - - src = data_blob(NULL, 8+dlen); - if (!src.data) { - return data_blob(NULL, 0); - } - - ret = data_blob(NULL, 8+dlen); - if (!ret.data) { - data_blob_free(&src); - return data_blob(NULL, 0); - } - - SIVAL(src.data, 0, slen); - SIVAL(src.data, 4, 1); - memset(src.data+8, 0, dlen); - memcpy(src.data+8, str, slen); - - sess_crypt_blob(&ret, &src, session_key, true); - - data_blob_free(&src); - - return ret; -} - -/* - a convenient wrapper around sess_crypt_blob() for strings, using the LSA convention - - caller should free the returned string -*/ -char *sess_decrypt_string(TALLOC_CTX *mem_ctx, - DATA_BLOB *blob, const DATA_BLOB *session_key) -{ - DATA_BLOB out; - int slen; - char *ret; - - if (blob->length < 8) { - return NULL; - } - - out = data_blob_talloc(mem_ctx, NULL, blob->length); - if (!out.data) { - return NULL; - } - - sess_crypt_blob(&out, blob, session_key, false); - - if (IVAL(out.data, 4) != 1) { - DEBUG(0,("Unexpected revision number %d in session crypted string\n", - IVAL(out.data, 4))); - data_blob_free(&out); - return NULL; - } - - slen = IVAL(out.data, 0); - if (slen > blob->length - 8) { - DEBUG(0,("Invalid crypt length %d\n", slen)); - data_blob_free(&out); - return NULL; - } - - ret = talloc_strndup(mem_ctx, (const char *)(out.data+8), slen); - - data_blob_free(&out); - - DEBUG(0,("decrypted string '%s' of length %d\n", ret, slen)); - - return ret; -} - -/* - a convenient wrapper around sess_crypt_blob() for DATA_BLOBs, using the LSA convention - - note that we round the length to a multiple of 8. This seems to be needed for - compatibility with windows - - caller should free using data_blob_free() -*/ -DATA_BLOB sess_encrypt_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob_in, const DATA_BLOB *session_key) -{ - DATA_BLOB ret, src; - int dlen = (blob_in->length+7) & ~7; - - src = data_blob_talloc(mem_ctx, NULL, 8+dlen); - if (!src.data) { - return data_blob(NULL, 0); - } - - ret = data_blob_talloc(mem_ctx, NULL, 8+dlen); - if (!ret.data) { - data_blob_free(&src); - return data_blob(NULL, 0); - } - - SIVAL(src.data, 0, blob_in->length); - SIVAL(src.data, 4, 1); - memset(src.data+8, 0, dlen); - memcpy(src.data+8, blob_in->data, blob_in->length); - - sess_crypt_blob(&ret, &src, session_key, true); - - data_blob_free(&src); - - return ret; -} - -/* - Decrypt a DATA_BLOB using the LSA convention -*/ -NTSTATUS sess_decrypt_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const DATA_BLOB *session_key, - DATA_BLOB *ret) -{ - DATA_BLOB out; - int slen; - - if (blob->length < 8) { - DEBUG(0, ("Unexpected length %d in session crypted secret (BLOB)\n", - (int)blob->length)); - return NT_STATUS_INVALID_PARAMETER; - } - - out = data_blob_talloc(mem_ctx, NULL, blob->length); - if (!out.data) { - return NT_STATUS_NO_MEMORY; - } - - sess_crypt_blob(&out, blob, session_key, false); - - if (IVAL(out.data, 4) != 1) { - DEBUG(2,("Unexpected revision number %d in session crypted secret (BLOB)\n", - IVAL(out.data, 4))); - return NT_STATUS_UNKNOWN_REVISION; - } - - slen = IVAL(out.data, 0); - if (slen > blob->length - 8) { - DEBUG(0,("Invalid crypt length %d in session crypted secret (BLOB)\n", slen)); - return NT_STATUS_WRONG_PASSWORD; - } - - *ret = data_blob_talloc(mem_ctx, out.data+8, slen); - if (slen && !ret->data) { - return NT_STATUS_NO_MEMORY; - } - - data_blob_free(&out); - - return NT_STATUS_OK; -} diff --git a/source4/libcli/auth/smbdes.c b/source4/libcli/auth/smbdes.c deleted file mode 100644 index 32e65e779d..0000000000 --- a/source4/libcli/auth/smbdes.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a partial implementation of DES designed for use in the - SMB authentication protocol - - Copyright (C) Andrew Tridgell 1998 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "libcli/auth/libcli_auth.h" - -/* NOTES: - - This code makes no attempt to be fast! In fact, it is a very - slow implementation - - This code is NOT a complete DES implementation. It implements only - the minimum necessary for SMB authentication, as used by all SMB - products (including every copy of Microsoft Windows95 ever sold) - - In particular, it can only do a unchained forward DES pass. This - means it is not possible to use this code for encryption/decryption - of data, instead it is only useful as a "hash" algorithm. - - There is no entry point into this code that allows normal DES operation. - - I believe this means that this code does not come under ITAR - regulations but this is NOT a legal opinion. If you are concerned - about the applicability of ITAR regulations to this code then you - should confirm it for yourself (and maybe let me know if you come - up with a different answer to the one above) -*/ - - -static const uint8_t perm1[56] = {57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4}; - -static const uint8_t perm2[48] = {14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32}; - -static const uint8_t perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7}; - -static const uint8_t perm4[48] = { 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1}; - -static const uint8_t perm5[32] = { 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25}; - - -static const uint8_t perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25}; - - -static const uint8_t sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; - -static const uint8_t sbox[8][4][16] = { - {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, - {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, - {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, - {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, - - {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, - {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, - {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, - {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, - - {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, - {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, - {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, - {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, - - {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, - {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, - {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, - {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, - - {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, - {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, - {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, - {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, - - {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, - {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, - {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, - {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, - - {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, - {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, - {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, - {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, - - {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, - {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, - {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, - {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; - -static void permute(char *out, const char *in, const uint8_t *p, int n) -{ - int i; - for (i=0;i<n;i++) - out[i] = in[p[i]-1]; -} - -static void lshift(char *d, int count, int n) -{ - char out[64]; - int i; - for (i=0;i<n;i++) - out[i] = d[(i+count)%n]; - for (i=0;i<n;i++) - d[i] = out[i]; -} - -static void concat(char *out, char *in1, char *in2, int l1, int l2) -{ - while (l1--) - *out++ = *in1++; - while (l2--) - *out++ = *in2++; -} - -static void xor(char *out, char *in1, char *in2, int n) -{ - int i; - for (i=0;i<n;i++) - out[i] = in1[i] ^ in2[i]; -} - -static void dohash(char *out, char *in, char *key, int forw) -{ - int i, j, k; - char pk1[56]; - char c[28]; - char d[28]; - char cd[56]; - char ki[16][48]; - char pd1[64]; - char l[32], r[32]; - char rl[64]; - - permute(pk1, key, perm1, 56); - - for (i=0;i<28;i++) - c[i] = pk1[i]; - for (i=0;i<28;i++) - d[i] = pk1[i+28]; - - for (i=0;i<16;i++) { - lshift(c, sc[i], 28); - lshift(d, sc[i], 28); - - concat(cd, c, d, 28, 28); - permute(ki[i], cd, perm2, 48); - } - - permute(pd1, in, perm3, 64); - - for (j=0;j<32;j++) { - l[j] = pd1[j]; - r[j] = pd1[j+32]; - } - - for (i=0;i<16;i++) { - char er[48]; - char erk[48]; - char b[8][6]; - char cb[32]; - char pcb[32]; - char r2[32]; - - permute(er, r, perm4, 48); - - xor(erk, er, ki[forw ? i : 15 - i], 48); - - for (j=0;j<8;j++) - for (k=0;k<6;k++) - b[j][k] = erk[j*6 + k]; - - for (j=0;j<8;j++) { - int m, n; - m = (b[j][0]<<1) | b[j][5]; - - n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4]; - - for (k=0;k<4;k++) - b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0; - } - - for (j=0;j<8;j++) - for (k=0;k<4;k++) - cb[j*4+k] = b[j][k]; - permute(pcb, cb, perm5, 32); - - xor(r2, l, pcb, 32); - - for (j=0;j<32;j++) - l[j] = r[j]; - - for (j=0;j<32;j++) - r[j] = r2[j]; - } - - concat(rl, r, l, 32, 32); - - permute(out, rl, perm6, 64); -} - -static void str_to_key(const uint8_t *str,uint8_t *key) -{ - int i; - - key[0] = str[0]>>1; - key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); - key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); - key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); - key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); - key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); - key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); - key[7] = str[6]&0x7F; - for (i=0;i<8;i++) { - key[i] = (key[i]<<1); - } -} - -/* - basic des crypt using a 56 bit (7 byte) key -*/ -void des_crypt56(uint8_t out[8], const uint8_t in[8], const uint8_t key[7], int forw) -{ - int i; - char outb[64]; - char inb[64]; - char keyb[64]; - uint8_t key2[8]; - - str_to_key(key, key2); - - for (i=0;i<64;i++) { - inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - outb[i] = 0; - } - - dohash(outb, inb, keyb, forw); - - for (i=0;i<8;i++) { - out[i] = 0; - } - - for (i=0;i<64;i++) { - if (outb[i]) - out[i/8] |= (1<<(7-(i%8))); - } -} - -void E_P16(const uint8_t *p14,uint8_t *p16) -{ - const uint8_t sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - des_crypt56(p16, sp8, p14, 1); - des_crypt56(p16+8, sp8, p14+7, 1); -} - -void E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) -{ - des_crypt56(p24, c8, p21, 1); - des_crypt56(p24+8, c8, p21+7, 1); - des_crypt56(p24+16, c8, p21+14, 1); -} - -void D_P16(const uint8_t *p14, const uint8_t *in, uint8_t *out) -{ - des_crypt56(out, in, p14, 0); - des_crypt56(out+8, in+8, p14+7, 0); -} - -void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) -{ - des_crypt56(out, in, p14, 1); - des_crypt56(out+8, in+8, p14+7, 1); -} - -/* des encryption with a 128 bit key */ -void des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]) -{ - uint8_t buf[8]; - des_crypt56(buf, in, key, 1); - des_crypt56(out, buf, key+9, 1); -} - -/* des encryption with a 64 bit key */ -void des_crypt64(uint8_t out[8], const uint8_t in[8], const uint8_t key[8], int forw) -{ - uint8_t buf[8]; - uint8_t key2[8]; - ZERO_STRUCT(key2); - des_crypt56(buf, in, key, forw); - key2[0] = key[7]; - des_crypt56(out, buf, key2, forw); -} - -/* des encryption with a 112 bit (14 byte) key */ -void des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], int forw) -{ - uint8_t buf[8]; - des_crypt56(buf, in, key, forw); - des_crypt56(out, buf, key+7, forw); -} - -/* des encryption of a 16 byte lump of data with a 112 bit key */ -void des_crypt112_16(uint8_t out[16], uint8_t in[16], const uint8_t key[14], int forw) -{ - des_crypt56(out, in, key, forw); - des_crypt56(out + 8, in + 8, key+7, forw); -} - -/* Decode a sam password hash into a password. The password hash is the - same method used to store passwords in the NT registry. The DES key - used is based on the RID of the user. */ -void sam_rid_crypt(uint_t rid, const uint8_t *in, uint8_t *out, int forw) -{ - uint8_t s[14]; - - s[0] = s[4] = s[8] = s[12] = (uint8_t)(rid & 0xFF); - s[1] = s[5] = s[9] = s[13] = (uint8_t)((rid >> 8) & 0xFF); - s[2] = s[6] = s[10] = (uint8_t)((rid >> 16) & 0xFF); - s[3] = s[7] = s[11] = (uint8_t)((rid >> 24) & 0xFF); - - des_crypt56(out, in, s, forw); - des_crypt56(out+8, in+8, s+7, forw); -} diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c deleted file mode 100644 index c6118c6568..0000000000 --- a/source4/libcli/auth/smbencrypt.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1998 - Modified by Jeremy Allison 1995. - Copyright (C) Jeremy Allison 1995-2000. - Copyright (C) Luke Kennethc Casson Leighton 1996-2000. - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "system/time.h" -#include "auth/ntlmssp/ntlmssp.h" -#include "auth/ntlmssp/msrpc_parse.h" -#include "../lib/crypto/crypto.h" -#include "libcli/auth/libcli_auth.h" - -/* - This implements the X/Open SMB password encryption - It takes a password ('unix' string), a 8 byte "crypt key" - and puts 24 bytes of encrypted password into p24 - - Returns false if password must have been truncated to create LM hash -*/ -bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) -{ - bool ret; - uint8_t p21[21]; - - memset(p21,'\0',21); - ret = E_deshash(passwd, p21); - - SMBOWFencrypt(p21, c8, p24); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); -#endif - - return ret; -} - -/** - * Creates the MD4 Hash of the users password in NT UNICODE. - * @param passwd password in 'unix' charset. - * @param p16 return password hashed with md4, caller allocated 16 byte buffer - */ - -bool E_md4hash(const char *passwd, uint8_t p16[16]) -{ - size_t len; - smb_ucs2_t *wpwd; - bool ret; - - ret = push_ucs2_talloc(NULL, &wpwd, passwd, &len); - if (!ret || len < 2) { - /* We don't want to return fixed data, as most callers - * don't check */ - mdfour(p16, (const uint8_t *)passwd, strlen(passwd)); - return false; - } - - len -= 2; - mdfour(p16, (const uint8_t *)wpwd, len); - - talloc_free(wpwd); - return true; -} - -/** - * Creates the DES forward-only Hash of the users password in DOS ASCII charset - * @param passwd password in 'unix' charset. - * @param p16 return password hashed with DES, caller allocated 16 byte buffer - * @return false if password was > 14 characters, and therefore may be incorrect, otherwise true - * @note p16 is filled in regardless - */ - -bool E_deshash(const char *passwd, uint8_t p16[16]) -{ - bool ret = true; - char dospwd[256]; - ZERO_STRUCT(dospwd); - - /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_string(dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE); - - /* Only the first 14 chars are considered, password need not be null terminated. */ - E_P16((const uint8_t *)dospwd, p16); - - if (strlen(dospwd) > 14) { - ret = false; - } - - ZERO_STRUCT(dospwd); - - return ret; -} - -/* Does both the NTLMv2 owfs of a user's password */ -bool ntv2_owf_gen(const uint8_t owf[16], - const char *user_in, const char *domain_in, - bool upper_case_domain, /* Transform the domain into UPPER case */ - uint8_t kr_buf[16]) -{ - smb_ucs2_t *user; - smb_ucs2_t *domain; - size_t user_byte_len; - size_t domain_byte_len; - bool ret; - - HMACMD5Context ctx; - TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); - - if (!mem_ctx) { - return false; - } - - if (!user_in) { - user_in = ""; - } - - if (!domain_in) { - domain_in = ""; - } - - user_in = strupper_talloc(mem_ctx, user_in); - if (user_in == NULL) { - talloc_free(mem_ctx); - return false; - } - - if (upper_case_domain) { - domain_in = strupper_talloc(mem_ctx, domain_in); - if (domain_in == NULL) { - talloc_free(mem_ctx); - return false; - } - } - - ret = push_ucs2_talloc(mem_ctx, &user, user_in, &user_byte_len ); - if (!ret) { - DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n")); - talloc_free(mem_ctx); - return false; - } - - ret = push_ucs2_talloc(mem_ctx, &domain, domain_in, &domain_byte_len); - if (!ret) { - DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n")); - talloc_free(mem_ctx); - return false; - } - - SMB_ASSERT(user_byte_len >= 2); - SMB_ASSERT(domain_byte_len >= 2); - - /* We don't want null termination */ - user_byte_len = user_byte_len - 2; - domain_byte_len = domain_byte_len - 2; - - hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update((const void *)user, user_byte_len, &ctx); - hmac_md5_update((const void *)domain, domain_byte_len, &ctx); - hmac_md5_final(kr_buf, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, (const void *)user, user_byte_len); - dump_data(100, (const void *)domain, domain_byte_len); - dump_data(100, owf, 16); - dump_data(100, kr_buf, 16); -#endif - - talloc_free(mem_ctx); - return true; -} - -/* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]) -{ - uint8_t p21[21]; - - ZERO_STRUCT(p21); - - memcpy(p21, passwd, 16); - E_P24(p21, c8, p24); -} - -/* Does the NT MD4 hash then des encryption. */ - -void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24) -{ - uint8_t p21[21]; - - memset(p21,'\0',21); - - E_md4hash(passwd, p21); - SMBOWFencrypt(p21, c8, p24); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); -#endif -} - -/* Does the md5 encryption from the Key Response for NTLMv2. */ -void SMBOWFencrypt_ntv2(const uint8_t kr[16], - const DATA_BLOB *srv_chal, - const DATA_BLOB *smbcli_chal, - uint8_t resp_buf[16]) -{ - HMACMD5Context ctx; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); - hmac_md5_update(smbcli_chal->data, smbcli_chal->length, &ctx); - hmac_md5_final(resp_buf, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, smbcli_chal, resp_buf\n")); - dump_data(100, srv_chal->data, srv_chal->length); - dump_data(100, smbcli_chal->data, smbcli_chal->length); - dump_data(100, resp_buf, 16); -#endif -} - -void SMBsesskeygen_ntv2(const uint8_t kr[16], - const uint8_t * nt_resp, uint8_t sess_key[16]) -{ - /* a very nice, 128 bit, variable session key */ - - HMACMD5Context ctx; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(nt_resp, 16, &ctx); - hmac_md5_final((uint8_t *)sess_key, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_ntv2:\n")); - dump_data(100, sess_key, 16); -#endif -} - -void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]) -{ - /* yes, this session key does not change - yes, this - is a problem - but it is 128 bits */ - - mdfour((uint8_t *)sess_key, kr, 16); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_ntv1:\n")); - dump_data(100, sess_key, 16); -#endif -} - -void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], - const uint8_t lm_resp[24], /* only uses 8 */ - uint8_t sess_key[16]) -{ - /* Calculate the LM session key (effective length 40 bits, - but changes with each session) */ - uint8_t p24[24]; - uint8_t partial_lm_hash[14]; - - memcpy(partial_lm_hash, lm_hash, 8); - memset(partial_lm_hash + 8, 0xbd, 6); - - des_crypt56(p24, lm_resp, partial_lm_hash, 1); - des_crypt56(p24+8, lm_resp, partial_lm_hash + 7, 1); - - memcpy(sess_key, p24, 16); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n")); - dump_data(100, sess_key, 16); -#endif -} - -DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, - const char *hostname, - const char *domain) -{ - DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); - - msrpc_gen(mem_ctx, &names_blob, - "aaa", - NTLMSSP_NAME_TYPE_DOMAIN, domain, - NTLMSSP_NAME_TYPE_SERVER, hostname, - 0, ""); - return names_blob; -} - -static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) -{ - uint8_t client_chal[8]; - DATA_BLOB response = data_blob(NULL, 0); - uint8_t long_date[8]; - NTTIME nttime; - - unix_to_nt_time(&nttime, time(NULL)); - - generate_random_buffer(client_chal, sizeof(client_chal)); - - push_nttime(long_date, 0, nttime); - - /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ - - msrpc_gen(mem_ctx, &response, "ddbbdb", - 0x00000101, /* Header */ - 0, /* 'Reserved' */ - long_date, 8, /* Timestamp */ - client_chal, 8, /* client challenge */ - 0, /* Unknown */ - names_blob->data, names_blob->length); /* End of name list */ - - return response; -} - -static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, - const uint8_t ntlm_v2_hash[16], - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob) -{ - uint8_t ntlmv2_response[16]; - DATA_BLOB ntlmv2_client_data; - DATA_BLOB final_response; - - TALLOC_CTX *mem_ctx = talloc_named(out_mem_ctx, 0, - "NTLMv2_generate_response internal context"); - - if (!mem_ctx) { - return data_blob(NULL, 0); - } - - /* NTLMv2 */ - /* generate some data to pass into the response function - including - the hostname and domain name of the server */ - ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob); - - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); - - final_response = data_blob_talloc(out_mem_ctx, NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); - - memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); - - memcpy(final_response.data+sizeof(ntlmv2_response), - ntlmv2_client_data.data, ntlmv2_client_data.length); - - talloc_free(mem_ctx); - - return final_response; -} - -static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, - const uint8_t ntlm_v2_hash[16], - const DATA_BLOB *server_chal) -{ - uint8_t lmv2_response[16]; - DATA_BLOB lmv2_client_data = data_blob_talloc(mem_ctx, NULL, 8); - DATA_BLOB final_response = data_blob_talloc(mem_ctx, NULL,24); - - /* LMv2 */ - /* client-supplied random data */ - generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); - - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); - memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); - - /* after the first 16 bytes is the random data we generated above, - so the server can verify us with it */ - memcpy(final_response.data+sizeof(lmv2_response), - lmv2_client_data.data, lmv2_client_data.length); - - data_blob_free(&lmv2_client_data); - - return final_response; -} - -bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, - const char *user, const char *domain, const uint8_t nt_hash[16], - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) -{ - uint8_t ntlm_v2_hash[16]; - - /* We don't use the NT# directly. Instead we use it mashed up with - the username and domain. - This prevents username swapping during the auth exchange - */ - if (!ntv2_owf_gen(nt_hash, user, domain, true, ntlm_v2_hash)) { - return false; - } - - if (nt_response) { - *nt_response = NTLMv2_generate_response(mem_ctx, - ntlm_v2_hash, server_chal, - names_blob); - if (user_session_key) { - *user_session_key = data_blob_talloc(mem_ctx, NULL, 16); - - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data); - } - } - - /* LMv2 */ - - if (lm_response) { - *lm_response = LMv2_generate_response(mem_ctx, - ntlm_v2_hash, server_chal); - if (lm_session_key) { - *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16); - - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of lm_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data); - } - } - - return true; -} - -bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, - const char *user, const char *domain, - const char *password, - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) -{ - uint8_t nt_hash[16]; - E_md4hash(password, nt_hash); - - return SMBNTLMv2encrypt_hash(mem_ctx, - user, domain, nt_hash, server_chal, names_blob, - lm_response, nt_response, lm_session_key, user_session_key); -} - -/*********************************************************** - encode a password buffer with a unicode password. The buffer - is filled with random data to make it harder to attack. -************************************************************/ -bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags) -{ - uint8_t new_pw[512]; - size_t new_pw_len; - - /* the incoming buffer can be any alignment. */ - string_flags |= STR_NOALIGN; - - new_pw_len = push_string(new_pw, - password, - sizeof(new_pw), string_flags); - - memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - - generate_random_buffer(buffer, 512 - new_pw_len); - - /* - * The length of the new password is in the last 4 bytes of - * the data buffer. - */ - SIVAL(buffer, 512, new_pw_len); - ZERO_STRUCT(new_pw); - return true; -} - - -/*********************************************************** - decode a password buffer - *new_pw_len is the length in bytes of the possibly mulitbyte - returned password including termination. -************************************************************/ -bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd, - int new_pwrd_size, int string_flags) -{ - int byte_len=0; - ssize_t converted_pw_len; - - /* the incoming buffer can be any alignment. */ - string_flags |= STR_NOALIGN; - - /* - Warning !!! : This function is called from some rpc call. - The password IN the buffer may be a UNICODE string. - The password IN new_pwrd is an ASCII string - If you reuse that code somewhere else check first. - */ - - /* The length of the new password is in the last 4 bytes of the data buffer. */ - - byte_len = IVAL(in_buffer, 512); - -#ifdef DEBUG_PASSWORD - dump_data(100, in_buffer, 516); -#endif - - /* Password cannot be longer than the size of the password buffer */ - if ( (byte_len < 0) || (byte_len > 512)) { - return false; - } - - /* decode into the return buffer. Buffer length supplied */ - converted_pw_len = pull_string(new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, - byte_len, string_flags); - - if (converted_pw_len == -1) { - return false; - } - -#ifdef DEBUG_PASSWORD - DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (const uint8_t *)new_pwrd, converted_pw_len); - DEBUG(100,("multibyte len:%d\n", (int)converted_pw_len)); - DEBUG(100,("original char len:%d\n", byte_len/2)); -#endif - - return true; -} - -/*********************************************************** - encode a password buffer with an already unicode password. The - rest of the buffer is filled with random data to make it harder to attack. -************************************************************/ -bool set_pw_in_buffer(uint8_t buffer[516], DATA_BLOB *password) -{ - if (password->length > 512) { - return false; - } - - memcpy(&buffer[512 - password->length], password->data, password->length); - - generate_random_buffer(buffer, 512 - password->length); - - /* - * The length of the new password is in the last 4 bytes of - * the data buffer. - */ - SIVAL(buffer, 512, password->length); - return true; -} - -/*********************************************************** - decode a password buffer - *new_pw_size is the length in bytes of the extracted unicode password -************************************************************/ -bool extract_pw_from_buffer(TALLOC_CTX *mem_ctx, - uint8_t in_buffer[516], DATA_BLOB *new_pass) -{ - int byte_len=0; - - /* The length of the new password is in the last 4 bytes of the data buffer. */ - - byte_len = IVAL(in_buffer, 512); - -#ifdef DEBUG_PASSWORD - dump_data(100, in_buffer, 516); -#endif - - /* Password cannot be longer than the size of the password buffer */ - if ( (byte_len < 0) || (byte_len > 512)) { - return false; - } - - *new_pass = data_blob_talloc(mem_ctx, &in_buffer[512 - byte_len], byte_len); - - if (!new_pass->data) { - return false; - } - - return true; -} diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk index 5b50bdfcbe..ad7bc311c2 100644 --- a/source4/libcli/config.mk +++ b/source4/libcli/config.mk @@ -1,4 +1,3 @@ -mkinclude auth/config.mk mkinclude ldap/config.mk mkinclude security/config.mk mkinclude wbclient/config.mk diff --git a/source4/libnet/config.mk b/source4/libnet/config.mk index fac8af18b7..07d5434ebf 100644 --- a/source4/libnet/config.mk +++ b/source4/libnet/config.mk @@ -1,5 +1,5 @@ [SUBSYSTEM::LIBSAMBA-NET] -PUBLIC_DEPENDENCIES = CREDENTIALS dcerpc dcerpc_samr RPC_NDR_LSA RPC_NDR_SRVSVC RPC_NDR_DRSUAPI LIBCLI_COMPOSITE LIBCLI_RESOLVE LIBCLI_FINDDCS LIBCLI_CLDAP LIBCLI_FINDDCS gensec_schannel LIBCLI_AUTH LIBNDR SMBPASSWD PROVISION +PUBLIC_DEPENDENCIES = CREDENTIALS dcerpc dcerpc_samr RPC_NDR_LSA RPC_NDR_SRVSVC RPC_NDR_DRSUAPI LIBCLI_COMPOSITE LIBCLI_RESOLVE LIBCLI_FINDDCS LIBCLI_CLDAP LIBCLI_FINDDCS gensec_schannel LIBCLI_AUTH LIBNDR SMBPASSWD PROVISION LIBCLI_SAMSYNC LIBSAMBA-NET_OBJ_FILES = $(addprefix $(libnetsrcdir)/, \ libnet.o libnet_passwd.o libnet_time.o libnet_rpc.o \ diff --git a/source4/libnet/libnet_samdump.c b/source4/libnet/libnet_samdump.c index 10a14655f3..08a2295169 100644 --- a/source4/libnet/libnet_samdump.c +++ b/source4/libnet/libnet_samdump.c @@ -163,7 +163,6 @@ NTSTATUS libnet_SamDump(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, r2.out.error_string = NULL; r2.in.binding_string = r->in.binding_string; - r2.in.rid_crypt = lp_parm_bool(ctx->lp_ctx, NULL, "vampire", "rid decrypt", true); r2.in.init_fn = NULL; r2.in.delta_fn = libnet_samdump_fn; r2.in.fn_ctx = samdump_state; diff --git a/source4/libnet/libnet_samdump_keytab.c b/source4/libnet/libnet_samdump_keytab.c index a1846b81da..7749aa996c 100644 --- a/source4/libnet/libnet_samdump_keytab.c +++ b/source4/libnet/libnet_samdump_keytab.c @@ -115,7 +115,6 @@ NTSTATUS libnet_SamDump_keytab(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, r2.out.error_string = NULL; r2.in.binding_string = r->in.binding_string; - r2.in.rid_crypt = true; r2.in.init_fn = NULL; r2.in.delta_fn = libnet_samdump_keytab_fn; r2.in.fn_ctx = &data; diff --git a/source4/libnet/libnet_samsync.c b/source4/libnet/libnet_samsync.c index 51e49e94a0..4d512d6034 100644 --- a/source4/libnet/libnet_samsync.c +++ b/source4/libnet/libnet_samsync.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libnet/libnet.h" #include "libcli/auth/libcli_auth.h" +#include "../libcli/samsync/samsync.h" #include "auth/gensec/gensec.h" #include "auth/credentials/credentials.h" #include "auth/gensec/schannel_proto.h" @@ -30,144 +31,11 @@ #include "librpc/gen_ndr/ndr_netlogon_c.h" #include "param/param.h" - -/** - * Decrypt and extract the user's passwords. - * - * The writes decrypted (no longer 'RID encrypted' or arcfour encrypted) passwords back into the structure - */ -static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds, - bool rid_crypt, - enum netr_SamDatabaseID database, - struct netr_DELTA_ENUM *delta, - char **error_string) -{ - - uint32_t rid = delta->delta_id_union.rid; - struct netr_DELTA_USER *user = delta->delta_union.user; - struct samr_Password lm_hash; - struct samr_Password nt_hash; - const char *username = user->account_name.string; - - if (rid_crypt) { - if (user->lm_password_present) { - sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); - user->lmpassword = lm_hash; - } - - if (user->nt_password_present) { - sam_rid_crypt(rid, user->ntpassword.hash, nt_hash.hash, 0); - user->ntpassword = nt_hash; - } - } - - if (user->user_private_info.SensitiveData) { - DATA_BLOB data; - struct netr_USER_KEYS keys; - enum ndr_err_code ndr_err; - data.data = user->user_private_info.SensitiveData; - data.length = user->user_private_info.DataLength; - creds_arcfour_crypt(creds, data.data, data.length); - user->user_private_info.SensitiveData = data.data; - user->user_private_info.DataLength = data.length; - - ndr_err = ndr_pull_struct_blob(&data, mem_ctx, NULL, &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - *error_string = talloc_asprintf(mem_ctx, "Failed to parse Sensitive Data for %s:", username); - dump_data(10, data.data, data.length); - return ndr_map_error2ntstatus(ndr_err); - } - - if (keys.keys.keys2.lmpassword.length == 16) { - if (rid_crypt) { - sam_rid_crypt(rid, keys.keys.keys2.lmpassword.pwd.hash, lm_hash.hash, 0); - user->lmpassword = lm_hash; - } else { - user->lmpassword = keys.keys.keys2.lmpassword.pwd; - } - user->lm_password_present = true; - } - if (keys.keys.keys2.ntpassword.length == 16) { - if (rid_crypt) { - sam_rid_crypt(rid, keys.keys.keys2.ntpassword.pwd.hash, nt_hash.hash, 0); - user->ntpassword = nt_hash; - } else { - user->ntpassword = keys.keys.keys2.ntpassword.pwd; - } - user->nt_password_present = true; - } - /* TODO: rid decrypt history fields */ - } - return NT_STATUS_OK; -} - -/** - * Decrypt and extract the secrets - * - * The writes decrypted secrets back into the structure - */ -static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds, - enum netr_SamDatabaseID database, - struct netr_DELTA_ENUM *delta, - char **error_string) -{ - struct netr_DELTA_SECRET *secret = delta->delta_union.secret; - creds_arcfour_crypt(creds, secret->current_cipher.cipher_data, - secret->current_cipher.maxlen); - - creds_arcfour_crypt(creds, secret->old_cipher.cipher_data, - secret->old_cipher.maxlen); - - return NT_STATUS_OK; -} - -/** - * Fix up the delta, dealing with encryption issues so that the final - * callback need only do the printing or application logic - */ - -static NTSTATUS fix_delta(TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds, - bool rid_crypt, - enum netr_SamDatabaseID database, - struct netr_DELTA_ENUM *delta, - char **error_string) -{ - NTSTATUS nt_status = NT_STATUS_OK; - *error_string = NULL; - switch (delta->delta_type) { - case NETR_DELTA_USER: - { - nt_status = fix_user(mem_ctx, - creds, - rid_crypt, - database, - delta, - error_string); - break; - } - case NETR_DELTA_SECRET: - { - nt_status = fix_secret(mem_ctx, - creds, - database, - delta, - error_string); - break; - } - default: - break; - } - return nt_status; -} - NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_SamSync *r) { NTSTATUS nt_status, dbsync_nt_status; TALLOC_CTX *samsync_ctx, *loop_ctx, *delta_ctx; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_DatabaseSync dbsync; struct netr_Authenticator credential, return_authenticator; struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; @@ -343,7 +211,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx do { int d; loop_ctx = talloc_named(samsync_ctx, 0, "DatabaseSync loop context"); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); dbsync.in.credential = &credential; @@ -355,7 +223,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx return nt_status; } - if (!creds_client_check(creds, &dbsync.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &dbsync.out.return_authenticator->cred)) { r->out.error_string = talloc_strdup(mem_ctx, "Credential chaining on incoming DatabaseSync failed"); talloc_free(samsync_ctx); return NT_STATUS_ACCESS_DENIED; @@ -369,12 +237,10 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx delta_ctx = talloc_named(loop_ctx, 0, "DatabaseSync delta context"); /* 'Fix' elements, by decrypting and * de-obfuscating the data */ - nt_status = fix_delta(delta_ctx, - creds, - r->in.rid_crypt, - dbsync.in.database_id, - &delta_enum_array->delta_enum[d], - &error_string); + nt_status = samsync_fix_delta(delta_ctx, + creds, + dbsync.in.database_id, + &delta_enum_array->delta_enum[d]); if (!NT_STATUS_IS_OK(nt_status)) { r->out.error_string = talloc_steal(mem_ctx, error_string); talloc_free(samsync_ctx); diff --git a/source4/libnet/libnet_samsync.h b/source4/libnet/libnet_samsync.h index c2295f3957..439c3ba162 100644 --- a/source4/libnet/libnet_samsync.h +++ b/source4/libnet/libnet_samsync.h @@ -32,7 +32,6 @@ struct libnet_SamSync_state { struct libnet_SamSync { struct { const char *binding_string; - bool rid_crypt; NTSTATUS (*init_fn)(TALLOC_CTX *mem_ctx, void *private_data, struct libnet_SamSync_state *samsync_state, diff --git a/source4/libnet/libnet_samsync_ldb.c b/source4/libnet/libnet_samsync_ldb.c index e24c54a8c2..5bb75ca30d 100644 --- a/source4/libnet/libnet_samsync_ldb.c +++ b/source4/libnet/libnet_samsync_ldb.c @@ -1233,7 +1233,6 @@ NTSTATUS libnet_samsync_ldb(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, str r2.out.error_string = NULL; r2.in.binding_string = r->in.binding_string; - r2.in.rid_crypt = true; r2.in.init_fn = libnet_samsync_ldb_init; r2.in.delta_fn = libnet_samsync_ldb_fn; r2.in.fn_ctx = state; diff --git a/source4/librpc/idl-deps.pl b/source4/librpc/idl-deps.pl index 4d97139fc5..b3f0451eeb 100644 --- a/source4/librpc/idl-deps.pl +++ b/source4/librpc/idl-deps.pl @@ -1,6 +1,7 @@ #!/usr/bin/perl use strict; use File::Basename; +use Cwd 'abs_path'; sub add($$) { @@ -19,6 +20,7 @@ foreach(@ARGV) { my $gen_ndr = dirname($f); $gen_ndr =~ s/\/idl$/\/gen_ndr/; + $gen_ndr = abs_path($gen_ndr); print "# $f\n"; add("IDL_FILES", $f); diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c index e3add82bf2..c678a674c1 100644 --- a/source4/librpc/rpc/dcerpc_schannel.c +++ b/source4/librpc/rpc/dcerpc_schannel.c @@ -36,7 +36,7 @@ struct schannel_key_state { struct dcerpc_pipe *pipe2; struct dcerpc_binding *binding; struct cli_credentials *credentials; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; uint32_t negotiate_flags; struct netr_Credential credentials1; struct netr_Credential credentials2; @@ -167,9 +167,6 @@ static void continue_srv_challenge(struct rpc_request *req) /* prepare credentials for auth2 request */ s->mach_pwd = cli_credentials_get_nt_hash(s->credentials, c); - creds_client_init(s->creds, &s->credentials1, &s->credentials2, - s->mach_pwd, &s->credentials3, s->negotiate_flags); - /* auth2 request arguments */ s->a.in.server_name = s->r.in.server_name; s->a.in.account_name = cli_credentials_get_username(s->credentials); @@ -181,6 +178,14 @@ static void continue_srv_challenge(struct rpc_request *req) s->a.out.negotiate_flags = &s->negotiate_flags; s->a.out.return_credentials = &s->credentials3; + s->creds = netlogon_creds_client_init(s, + s->a.in.account_name, + s->a.in.computer_name, + &s->credentials1, &s->credentials2, + s->mach_pwd, &s->credentials3, s->negotiate_flags); + if (composite_nomem(s->creds, c)) { + return; + } /* authenticate on the netlogon pipe - a rpc request over secondary pipe */ @@ -208,7 +213,7 @@ static void continue_srv_auth2(struct rpc_request *req) if (!composite_is_ok(c)) return; /* verify credentials */ - if (!creds_client_check(s->creds, s->a.out.return_credentials)) { + if (!netlogon_creds_client_check(s->creds, s->a.out.return_credentials)) { composite_error(c, NT_STATUS_UNSUCCESSFUL); return; } @@ -246,9 +251,6 @@ struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx, s->credentials = credentials; /* allocate credentials */ - s->creds = talloc(c, struct creds_CredentialState); - if (composite_nomem(s->creds, c)) return c; - /* type of authentication depends on schannel type */ if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) { s->negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; diff --git a/source4/main.mk b/source4/main.mk index d7db0580e9..aaae329ed8 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -53,4 +53,7 @@ mkinclude ../lib/smbconf/config.mk mkinclude ../lib/async_req/config.mk mkinclude ../libcli/security/config.mk mkinclude ../libcli/ldap/config.mk +mkinclude ../libcli/auth/config.mk +mkinclude ../libcli/drsuapi/config.mk +mkinclude ../libcli/samsync/config.mk diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 2efddc74fc..b17ab86e26 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -31,14 +31,14 @@ #include "rpc_server/samr/proto.h" #include "../lib/util/util_ldb.h" #include "libcli/auth/libcli_auth.h" -#include "auth/gensec/schannel_state.h" +#include "auth/gensec/schannel.h" #include "libcli/security/security.h" #include "param/param.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_irpc.h" #include "librpc/gen_ndr/ndr_netlogon.h" -struct server_pipe_state { +struct netlogon_server_pipe_state { struct netr_Credential client_challenge; struct netr_Credential server_challenge; }; @@ -47,8 +47,8 @@ struct server_pipe_state { static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerReqChallenge *r) { - struct server_pipe_state *pipe_state = - (struct server_pipe_state *)dce_call->context->private_data; + struct netlogon_server_pipe_state *pipe_state = + talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state); ZERO_STRUCTP(r->out.return_credentials); @@ -59,7 +59,7 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal dce_call->context->private_data = NULL; } - pipe_state = talloc(dce_call->context, struct server_pipe_state); + pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state); NT_STATUS_HAVE_NO_MEMORY(pipe_state); pipe_state->client_challenge = *r->in.credentials; @@ -77,10 +77,11 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerAuthenticate3 *r) { - struct server_pipe_state *pipe_state = - (struct server_pipe_state *)dce_call->context->private_data; - struct creds_CredentialState *creds; - void *sam_ctx; + struct netlogon_server_pipe_state *pipe_state = + talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state); + struct netlogon_creds_CredentialState *creds; + struct ldb_context *schannel_ldb; + struct ldb_context *sam_ctx; struct samr_Password *mach_pwd; uint32_t user_account_control; int num_records; @@ -238,31 +239,30 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca return NT_STATUS_ACCESS_DENIED; } - creds = talloc(mem_ctx, struct creds_CredentialState); - NT_STATUS_HAVE_NO_MEMORY(creds); - - creds_server_init(creds, &pipe_state->client_challenge, - &pipe_state->server_challenge, mach_pwd, - r->out.return_credentials, - *r->in.negotiate_flags); + creds = netlogon_creds_server_init(mem_ctx, + r->in.account_name, + r->in.computer_name, + r->in.secure_channel_type, + &pipe_state->client_challenge, + &pipe_state->server_challenge, + mach_pwd, + r->in.credentials, + r->out.return_credentials, + *r->in.negotiate_flags); - if (!creds_server_check(creds, r->in.credentials)) { - talloc_free(creds); + if (!creds) { return NT_STATUS_ACCESS_DENIED; } - creds->account_name = talloc_steal(creds, r->in.account_name); - - creds->computer_name = talloc_steal(creds, r->in.computer_name); - creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)); - - creds->secure_channel_type = r->in.secure_channel_type; - creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid"); + schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); + if (!schannel_ldb) { + return NT_STATUS_ACCESS_DENIED; + } - /* remember this session key state */ - nt_status = schannel_store_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, creds); + nt_status = schannel_store_session_key(schannel_ldb, mem_ctx, creds); + talloc_free(schannel_ldb); return nt_status; } @@ -270,8 +270,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerAuthenticate *r) { - struct netr_ServerAuthenticate3 r3; - uint32_t rid = 0; + struct netr_ServerAuthenticate3 a; + uint32_t rid; /* TODO: * negotiate_flags is used as an [in] parameter * so it need to be initialised. @@ -281,17 +281,18 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_cal uint32_t negotiate_flags_in = 0; uint32_t negotiate_flags_out = 0; - r3.in.server_name = r->in.server_name; - r3.in.account_name = r->in.account_name; - r3.in.secure_channel_type = r->in.secure_channel_type; - r3.in.computer_name = r->in.computer_name; - r3.in.credentials = r->in.credentials; - r3.out.return_credentials = r->out.return_credentials; - r3.in.negotiate_flags = &negotiate_flags_in; - r3.out.negotiate_flags = &negotiate_flags_out; - r3.out.rid = &rid; - - return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3); + a.in.server_name = r->in.server_name; + a.in.account_name = r->in.account_name; + a.in.secure_channel_type = r->in.secure_channel_type; + a.in.computer_name = r->in.computer_name; + a.in.credentials = r->in.credentials; + a.in.negotiate_flags = &negotiate_flags_in; + + a.out.return_credentials = r->out.return_credentials; + a.out.rid = &rid; + a.out.negotiate_flags = &negotiate_flags_out; + + return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a); } static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, @@ -323,55 +324,31 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca the caller needs some of that information. */ -static NTSTATUS dcesrv_netr_creds_server_step_check(struct tevent_context *event_ctx, - struct loadparm_context *lp_ctx, +static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, const char *computer_name, - TALLOC_CTX *mem_ctx, - struct netr_Authenticator *received_authenticator, - struct netr_Authenticator *return_authenticator, - struct creds_CredentialState **creds_out) + struct netr_Authenticator *received_authenticator, + struct netr_Authenticator *return_authenticator, + struct netlogon_creds_CredentialState **creds_out) { - struct creds_CredentialState *creds; NTSTATUS nt_status; struct ldb_context *ldb; - int ret; + bool schannel_global_required = false; /* Should be lp_schannel_server() == true */ + bool schannel_in_use = dce_call->conn->auth_state.auth_info + && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL + && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY + || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY); - ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx); + ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); if (!ldb) { return NT_STATUS_ACCESS_DENIED; } - - ret = ldb_transaction_start(ldb); - if (ret != 0) { - talloc_free(ldb); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - /* Because this is a shared structure (even across - * disconnects) we must update the database every time we - * update the structure */ - - nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, - lp_workgroup(lp_ctx), - &creds); - if (NT_STATUS_IS_OK(nt_status)) { - nt_status = creds_server_step_check(creds, - received_authenticator, - return_authenticator); - } - if (NT_STATUS_IS_OK(nt_status)) { - nt_status = schannel_store_session_key_ldb(ldb, ldb, creds); - } - - if (NT_STATUS_IS_OK(nt_status)) { - ldb_transaction_commit(ldb); - if (creds_out) { - *creds_out = creds; - talloc_steal(mem_ctx, creds); - } - } else { - ldb_transaction_cancel(ldb); - } + nt_status = schannel_creds_server_step_check(ldb, mem_ctx, + computer_name, + schannel_global_required, + schannel_in_use, + received_authenticator, + return_authenticator, creds_out); talloc_free(ldb); return nt_status; } @@ -384,14 +361,15 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct tevent_context *event static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerPasswordSet *r) { - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct ldb_context *sam_ctx; NTSTATUS nt_status; - 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 = dcesrv_netr_creds_server_step_check(dce_call, + mem_ctx, + r->in.computer_name, + r->in.credential, r->out.return_authenticator, + &creds); NT_STATUS_NOT_OK_RETURN(nt_status); 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)); @@ -399,7 +377,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call return NT_STATUS_INVALID_SYSTEM_SERVICE; } - creds_des_decrypt(creds, r->in.new_password); + netlogon_creds_des_decrypt(creds, r->in.new_password); /* Using the sid for the account as the key, set the password */ nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, @@ -418,15 +396,16 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerPasswordSet2 *r) { - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct ldb_context *sam_ctx; NTSTATUS nt_status; DATA_BLOB new_password; struct samr_CryptPassword password_buf; - 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, + nt_status = dcesrv_netr_creds_server_step_check(dce_call, + mem_ctx, + r->in.computer_name, r->in.credential, r->out.return_authenticator, &creds); NT_STATUS_NOT_OK_RETURN(nt_status); @@ -438,7 +417,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal memcpy(password_buf.data, r->in.new_password->data, 512); SIVAL(password_buf.data, 512, r->in.new_password->length); - creds_arcfour_crypt(creds, password_buf.data, 516); + 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")); @@ -484,7 +463,7 @@ static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TAL We can't do the traditional 'wrapping' format completly, as this function must only run under schannel */ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds) + struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds) { struct auth_context *auth_context; struct auth_usersupplied_info *user_info; @@ -509,15 +488,15 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal case NetlogonInteractiveTransitiveInformation: case NetlogonServiceTransitiveInformation: if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - creds_arcfour_crypt(creds, + netlogon_creds_arcfour_crypt(creds, r->in.logon->password->lmpassword.hash, sizeof(r->in.logon->password->lmpassword.hash)); - creds_arcfour_crypt(creds, + netlogon_creds_arcfour_crypt(creds, r->in.logon->password->ntpassword.hash, sizeof(r->in.logon->password->ntpassword.hash)); } else { - creds_des_decrypt(creds, &r->in.logon->password->lmpassword); - creds_des_decrypt(creds, &r->in.logon->password->ntpassword); + netlogon_creds_des_decrypt(creds, &r->in.logon->password->lmpassword); + netlogon_creds_des_decrypt(creds, &r->in.logon->password->ntpassword); } /* TODO: we need to deny anonymous access here */ @@ -572,7 +551,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal case NetlogonGenericInformation: { if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - creds_arcfour_crypt(creds, + netlogon_creds_arcfour_crypt(creds, r->in.logon->generic->data, r->in.logon->generic->length); } else { /* Using DES to verify kerberos tickets makes no sense */ @@ -631,7 +610,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal 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) { - creds_arcfour_crypt(creds, + netlogon_creds_arcfour_crypt(creds, sam->key.key, sizeof(sam->key.key)); } @@ -642,11 +621,11 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal if ((r->in.validation_level != 6) && memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) { if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - creds_arcfour_crypt(creds, + netlogon_creds_arcfour_crypt(creds, sam->LMSessKey.key, sizeof(sam->LMSessKey.key)); } else { - creds_des_encrypt_LMKey(creds, + netlogon_creds_des_encrypt_LMKey(creds, &sam->LMSessKey); } } @@ -693,15 +672,20 @@ static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, struct netr_LogonSamLogonEx *r) { NTSTATUS nt_status; - struct creds_CredentialState *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); + struct netlogon_creds_CredentialState *creds; + struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); + if (!ldb) { + return NT_STATUS_ACCESS_DENIED; + } + + nt_status = schannel_fetch_session_key(ldb, mem_ctx, r->in.computer_name, &creds); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } if (!dce_call->conn->auth_state.auth_info || dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { - return NT_STATUS_INTERNAL_ERROR; + return NT_STATUS_ACCESS_DENIED; } return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds); } @@ -714,7 +698,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce struct netr_LogonSamLogonWithFlags *r) { NTSTATUS nt_status; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_LogonSamLogonEx r2; struct netr_Authenticator *return_authenticator; @@ -722,10 +706,11 @@ static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce 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->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - r->in.computer_name, mem_ctx, - r->in.credential, return_authenticator, - &creds); + nt_status = dcesrv_netr_creds_server_step_check(dce_call, + mem_ctx, + r->in.computer_name, + r->in.credential, return_authenticator, + &creds); NT_STATUS_NOT_OK_RETURN(nt_status); ZERO_STRUCT(r2); @@ -1089,11 +1074,12 @@ static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_cal const char *local_domain; - 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); + status = dcesrv_netr_creds_server_step_check(dce_call, + mem_ctx, + r->in.computer_name, + r->in.credential, + r->out.return_authenticator, + NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,(__location__ " Bad credentials - error\n")); } diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 895fef6174..bec2a064dc 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -111,7 +111,7 @@ PRIVATE_DEPENDENCIES = \ RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP \ RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER RPC_NDR_NTSVCS WB_HELPER LIBSAMBA-NET \ LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_LDB TORTURE_UTIL TORTURE_RAP \ - dcerpc_server service process_model ntvfs SERVICE_SMB RPC_NDR_BROWSER + dcerpc_server service process_model ntvfs SERVICE_SMB RPC_NDR_BROWSER LIBCLI_DRSUAPI torture_rpc_OBJ_FILES = $(addprefix $(torturesrcdir)/rpc/, \ join.o lsa.o lsa_lookup.o session_key.o echo.o dfs.o drsuapi.o \ diff --git a/source4/torture/rpc/dssync.c b/source4/torture/rpc/dssync.c index 1aaf914ceb..b47564cc91 100644 --- a/source4/torture/rpc/dssync.c +++ b/source4/torture/rpc/dssync.c @@ -30,6 +30,7 @@ #include "torture/ldap/proto.h" #include "libcli/auth/libcli_auth.h" #include "../lib/crypto/crypto.h" +#include "../libcli/drsuapi/drsuapi.h" #include "auth/credentials/credentials.h" #include "libcli/auth/libcli_auth.h" #include "auth/gensec/gensec.h" @@ -338,119 +339,6 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx) return ret; } -static DATA_BLOB decrypt_blob(TALLOC_CTX *mem_ctx, - const DATA_BLOB *gensec_skey, - bool rcrypt, - struct drsuapi_DsReplicaObjectIdentifier *id, - uint32_t rid, - const DATA_BLOB *buffer) -{ - DATA_BLOB confounder; - DATA_BLOB enc_buffer; - - struct MD5Context md5; - uint8_t _enc_key[16]; - DATA_BLOB enc_key; - - DATA_BLOB dec_buffer; - - uint32_t crc32_given; - uint32_t crc32_calc; - DATA_BLOB checked_buffer; - - DATA_BLOB plain_buffer; - - /* - * the combination "c[3] s[1] e[1] d[0]..." - * was successful!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - - /* - * the first 16 bytes at the beginning are the confounder - * followed by the 4 byte crc32 checksum - */ - if (buffer->length < 20) { - return data_blob_const(NULL, 0); - } - confounder = data_blob_const(buffer->data, 16); - enc_buffer = data_blob_const(buffer->data + 16, buffer->length - 16); - - /* - * build the encryption key md5 over the session key followed - * by the confounder - * - * here the gensec session key is used and - * not the dcerpc ncacn_ip_tcp "SystemLibraryDTC" key! - */ - enc_key = data_blob_const(_enc_key, sizeof(_enc_key)); - MD5Init(&md5); - MD5Update(&md5, gensec_skey->data, gensec_skey->length); - MD5Update(&md5, confounder.data, confounder.length); - MD5Final(enc_key.data, &md5); - - /* - * copy the encrypted buffer part and - * decrypt it using the created encryption key using arcfour - */ - dec_buffer = data_blob_talloc(mem_ctx, enc_buffer.data, enc_buffer.length); - if (!dec_buffer.data) { - return data_blob_const(NULL, 0); - } - arcfour_crypt_blob(dec_buffer.data, dec_buffer.length, &enc_key); - - /* - * the first 4 byte are the crc32 checksum - * of the remaining bytes - */ - crc32_given = IVAL(dec_buffer.data, 0); - crc32_calc = crc32_calc_buffer(dec_buffer.data + 4 , dec_buffer.length - 4); - if (crc32_given != crc32_calc) { - DEBUG(0,("CRC32: given[0x%08X] calc[0x%08X]\n", - crc32_given, crc32_calc)); - return data_blob_const(NULL, 0); - } - checked_buffer = data_blob_talloc(mem_ctx, dec_buffer.data + 4, dec_buffer.length - 4); - if (!checked_buffer.data) { - return data_blob_const(NULL, 0); - } - - /* - * some attributes seem to be in a usable form after this decryption - * (supplementalCredentials, priorValue, currentValue, trustAuthOutgoing, - * trustAuthIncoming, initialAuthOutgoing, initialAuthIncoming) - * At least supplementalCredentials contains plaintext - * like "Primary:Kerberos" (in unicode form) - * - * some attributes seem to have some additional encryption - * dBCSPwd, unicodePwd, ntPwdHistory, lmPwdHistory - * - * it's the sam_rid_crypt() function, as the value is constant, - * so it doesn't depend on sessionkeys. - */ - if (rcrypt) { - uint32_t i, num_hashes; - - if ((checked_buffer.length % 16) != 0) { - return data_blob_const(NULL, 0); - } - - plain_buffer = data_blob_talloc(mem_ctx, checked_buffer.data, checked_buffer.length); - if (!plain_buffer.data) { - return data_blob_const(NULL, 0); - } - - num_hashes = plain_buffer.length / 16; - for (i = 0; i < num_hashes; i++) { - uint32_t offset = i * 16; - sam_rid_crypt(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0); - } - } else { - plain_buffer = checked_buffer; - } - - return plain_buffer; -} - static void test_analyse_objects(struct torture_context *tctx, struct DsSyncTest *ctx, const DATA_BLOB *gensec_skey, @@ -481,6 +369,7 @@ static void test_analyse_objects(struct torture_context *tctx, } for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) { + WERROR werr; const char *name = NULL; bool rcrypt = false; DATA_BLOB *enc_data = NULL; @@ -549,9 +438,13 @@ static void test_analyse_objects(struct torture_context *tctx, enc_data = attr->value_ctr.values[0].blob; ZERO_STRUCT(plain_data); - plain_data = decrypt_blob(ctx, gensec_skey, rcrypt, - cur->object.identifier, rid, - enc_data); + werr = drsuapi_decrypt_attribute_value(ctx, gensec_skey, rcrypt, + rid, + enc_data, &plain_data); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("Failed to decrypt %s\n", name)); + continue; + } if (!dn_printed) { object_id++; DEBUG(0,("DN[%u] %s\n", object_id, dn)); diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index ad94add071..23443cc9d1 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -77,13 +77,13 @@ static bool test_LogonUasLogoff(struct torture_context *tctx, bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx, struct cli_credentials *credentials, - struct creds_CredentialState **creds_out) + struct netlogon_creds_CredentialState **creds_out) { NTSTATUS status; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate a; struct netr_Credential credentials1, credentials2, credentials3; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; const struct samr_Password *mach_password; const char *machine_name; @@ -92,9 +92,6 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx, torture_comment(tctx, "Testing ServerReqChallenge\n"); - creds = talloc(tctx, struct creds_CredentialState); - torture_assert(tctx, creds != NULL, "memory allocation"); - r.in.server_name = NULL; r.in.computer_name = machine_name; r.in.credentials = &credentials1; @@ -112,9 +109,13 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx, a.in.credentials = &credentials3; a.out.return_credentials = &credentials3; - creds_client_init(creds, &credentials1, &credentials2, - mach_password, &credentials3, - 0); + creds = netlogon_creds_client_init(tctx, a.in.account_name, + a.in.computer_name, + &credentials1, &credentials2, + mach_password, &credentials3, + 0); + torture_assert(tctx, creds != NULL, "memory allocation"); + torture_comment(tctx, "Testing ServerAuthenticate\n"); @@ -128,7 +129,7 @@ bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate"); - torture_assert(tctx, creds_client_check(creds, &credentials3), + torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed"); *creds_out = creds; @@ -139,13 +140,13 @@ bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx, uint32_t negotiate_flags, struct cli_credentials *machine_credentials, int sec_chan_type, - struct creds_CredentialState **creds_out) + struct netlogon_creds_CredentialState **creds_out) { NTSTATUS status; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate2 a; struct netr_Credential credentials1, credentials2, credentials3; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; const struct samr_Password *mach_password; const char *machine_name; @@ -154,8 +155,6 @@ bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx, torture_comment(tctx, "Testing ServerReqChallenge\n"); - creds = talloc(tctx, struct creds_CredentialState); - torture_assert(tctx, creds != NULL, "memory allocation"); r.in.server_name = NULL; r.in.computer_name = machine_name; @@ -176,16 +175,20 @@ bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx, a.in.credentials = &credentials3; a.out.return_credentials = &credentials3; - creds_client_init(creds, &credentials1, &credentials2, - mach_password, &credentials3, - negotiate_flags); + creds = netlogon_creds_client_init(tctx, a.in.account_name, + a.in.computer_name, + &credentials1, &credentials2, + mach_password, &credentials3, + negotiate_flags); + + torture_assert(tctx, creds != NULL, "memory allocation"); torture_comment(tctx, "Testing ServerAuthenticate2\n"); status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a); torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2"); - torture_assert(tctx, creds_client_check(creds, &credentials3), + torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed"); torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags); @@ -198,13 +201,13 @@ bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx, static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx, uint32_t negotiate_flags, struct cli_credentials *machine_credentials, - struct creds_CredentialState **creds_out) + struct netlogon_creds_CredentialState **creds_out) { NTSTATUS status; struct netr_ServerReqChallenge r; struct netr_ServerAuthenticate3 a; struct netr_Credential credentials1, credentials2, credentials3; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct samr_Password mach_password; uint32_t rid; const char *machine_name; @@ -215,9 +218,6 @@ static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context torture_comment(tctx, "Testing ServerReqChallenge\n"); - creds = talloc(tctx, struct creds_CredentialState); - torture_assert(tctx, creds != NULL, "memory allocation"); - r.in.server_name = NULL; r.in.computer_name = machine_name; r.in.credentials = &credentials1; @@ -240,15 +240,19 @@ static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context a.out.negotiate_flags = &negotiate_flags; a.out.rid = &rid; - creds_client_init(creds, &credentials1, &credentials2, - &mach_password, &credentials3, - negotiate_flags); + creds = netlogon_creds_client_init(tctx, a.in.account_name, + a.in.computer_name, + &credentials1, &credentials2, + &mach_password, &credentials3, + negotiate_flags); + + torture_assert(tctx, creds != NULL, "memory allocation"); torture_comment(tctx, "Testing ServerAuthenticate3\n"); status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a); torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3"); - torture_assert(tctx, creds_client_check(creds, &credentials3), "Credential chaining failed"); + torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed"); torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags); @@ -270,7 +274,7 @@ static bool test_SetPassword(struct torture_context *tctx, NTSTATUS status; struct netr_ServerPasswordSet r; const char *password; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_Authenticator credential, return_authenticator; struct samr_Password new_password; @@ -289,18 +293,18 @@ static bool test_SetPassword(struct torture_context *tctx, password = generate_random_str(tctx, 8); E_md4hash(password, new_password.hash); - creds_des_encrypt(creds, &new_password); + netlogon_creds_des_encrypt(creds, &new_password); torture_comment(tctx, "Testing ServerPasswordSet on machine account\n"); torture_comment(tctx, "Changing machine account password to '%s'\n", password); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); status = dcerpc_netr_ServerPasswordSet(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -313,12 +317,12 @@ static bool test_SetPassword(struct torture_context *tctx, torture_comment(tctx, "Changing machine account password to '%s' (same as previous run)\n", password); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); status = dcerpc_netr_ServerPasswordSet(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -360,7 +364,7 @@ static bool test_SetPassword2(struct torture_context *tctx, struct netr_ServerPasswordSet2 r; const char *password; DATA_BLOB new_random_pass; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct samr_CryptPassword password_buf; struct samr_Password nt_hash; struct netr_Authenticator credential, return_authenticator; @@ -380,7 +384,7 @@ static bool test_SetPassword2(struct torture_context *tctx, password = generate_random_str(tctx, 8); encode_pw_buffer(password_buf.data, password, STR_UNICODE); - creds_arcfour_crypt(creds, password_buf.data, 516); + netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); memcpy(new_password.data, password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512); @@ -388,12 +392,12 @@ static bool test_SetPassword2(struct torture_context *tctx, torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n"); torture_comment(tctx, "Changing machine account password to '%s'\n", password); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -410,7 +414,7 @@ static bool test_SetPassword2(struct torture_context *tctx, */ password = ""; encode_pw_buffer(password_buf.data, password, STR_UNICODE); - creds_arcfour_crypt(creds, password_buf.data, 516); + netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); memcpy(new_password.data, password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512); @@ -420,12 +424,12 @@ static bool test_SetPassword2(struct torture_context *tctx, torture_comment(tctx, "Changing machine account password to '%s'\n", password); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -438,7 +442,7 @@ static bool test_SetPassword2(struct torture_context *tctx, /* now try a random password */ password = generate_random_str(tctx, 8); encode_pw_buffer(password_buf.data, password, STR_UNICODE); - creds_arcfour_crypt(creds, password_buf.data, 516); + netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); memcpy(new_password.data, password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512); @@ -446,12 +450,12 @@ static bool test_SetPassword2(struct torture_context *tctx, torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n"); torture_comment(tctx, "Changing machine account password to '%s'\n", password); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -464,12 +468,12 @@ static bool test_SetPassword2(struct torture_context *tctx, torture_comment(tctx, "Changing machine account password to '%s' (same as previous run)\n", password); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -484,7 +488,7 @@ static bool test_SetPassword2(struct torture_context *tctx, /* now try a random stream of bytes for a password */ set_pw_in_buffer(password_buf.data, &new_random_pass); - creds_arcfour_crypt(creds, password_buf.data, 516); + netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); memcpy(new_password.data, password_buf.data, 512); new_password.length = IVAL(password_buf.data, 512); @@ -492,12 +496,12 @@ static bool test_SetPassword2(struct torture_context *tctx, torture_comment(tctx, "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n"); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -518,7 +522,7 @@ static bool test_GetPassword(struct torture_context *tctx, struct cli_credentials *machine_credentials) { struct netr_ServerPasswordGet r; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_Authenticator credential; NTSTATUS status; struct netr_Authenticator return_authenticator; @@ -528,7 +532,7 @@ static bool test_GetPassword(struct torture_context *tctx, return false; } - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME); @@ -549,7 +553,7 @@ static bool test_GetTrustPasswords(struct torture_context *tctx, struct cli_credentials *machine_credentials) { struct netr_ServerTrustPasswordsGet r; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_Authenticator credential; NTSTATUS status; struct netr_Authenticator return_authenticator; @@ -559,7 +563,7 @@ static bool test_GetTrustPasswords(struct torture_context *tctx, return false; } - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME); @@ -581,7 +585,7 @@ static bool test_GetTrustPasswords(struct torture_context *tctx, */ bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx, struct cli_credentials *credentials, - struct creds_CredentialState *creds) + struct netlogon_creds_CredentialState *creds) { NTSTATUS status; struct netr_LogonSamLogon r; @@ -647,14 +651,15 @@ bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx, for (i=2;i<3;i++) { ZERO_STRUCT(auth2); - creds_client_authenticator(creds, &auth); + netlogon_creds_client_authenticator(creds, &auth); r.in.validation_level = i; status = dcerpc_netr_LogonSamLogon(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed"); - torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred), + torture_assert(tctx, netlogon_creds_client_check(creds, + &r.out.return_authenticator->cred), "Credential chaining failed"); } @@ -682,7 +687,7 @@ static bool test_SamLogon(struct torture_context *tctx, struct dcerpc_pipe *p, struct cli_credentials *credentials) { - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; if (!test_SetupCredentials(p, tctx, credentials, &creds)) { return false; @@ -703,7 +708,7 @@ static bool test_DatabaseSync(struct torture_context *tctx, { NTSTATUS status; struct netr_DatabaseSync r; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; int i; struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; @@ -733,7 +738,7 @@ static bool test_DatabaseSync(struct torture_context *tctx, torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id); do { - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); r.in.credential = &credential; @@ -747,7 +752,7 @@ static bool test_DatabaseSync(struct torture_context *tctx, } torture_assert_ntstatus_ok(tctx, status, "DatabaseSync"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -777,7 +782,7 @@ static bool test_DatabaseDeltas(struct torture_context *tctx, { NTSTATUS status; struct netr_DatabaseDeltas r; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_Authenticator credential; struct netr_Authenticator return_authenticator; struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; @@ -807,7 +812,7 @@ static bool test_DatabaseDeltas(struct torture_context *tctx, r.in.database_id, (unsigned long long)*r.in.sequence_num); do { - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); status = dcerpc_netr_DatabaseDeltas(p, tctx, &r); if (NT_STATUS_EQUAL(status, @@ -821,7 +826,7 @@ static bool test_DatabaseDeltas(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas"); - if (!creds_client_check(creds, &return_authenticator.cred)) { + if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -838,7 +843,7 @@ static bool test_DatabaseRedo(struct torture_context *tctx, { NTSTATUS status; struct netr_DatabaseRedo r; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_Authenticator credential; struct netr_Authenticator return_authenticator; struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; @@ -1300,7 +1305,7 @@ static bool test_DatabaseRedo(struct torture_context *tctx, continue; } - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); r.in.credential = &credential; @@ -1352,7 +1357,7 @@ static bool test_DatabaseRedo(struct torture_context *tctx, } } - if (!creds_client_check(creds, &return_authenticator.cred)) { + if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) { torture_comment(tctx, "Credential chaining failed\n"); if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) { return false; @@ -1374,7 +1379,7 @@ static bool test_AccountDeltas(struct torture_context *tctx, { NTSTATUS status; struct netr_AccountDeltas r; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_AccountBuffer buffer; uint32_t count_returned = 0; @@ -1391,7 +1396,7 @@ static bool test_AccountDeltas(struct torture_context *tctx, r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.computername = TEST_MACHINE_NAME; r.in.return_authenticator = &return_authenticator; - creds_client_authenticator(creds, &r.in.credential); + netlogon_creds_client_authenticator(creds, &r.in.credential); ZERO_STRUCT(r.in.uas); r.in.count=10; r.in.level=0; @@ -1417,7 +1422,7 @@ static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p { NTSTATUS status; struct netr_AccountSync r; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct netr_AccountBuffer buffer; uint32_t count_returned = 0; @@ -1436,7 +1441,7 @@ static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.computername = TEST_MACHINE_NAME; r.in.return_authenticator = &return_authenticator; - creds_client_authenticator(creds, &r.in.credential); + netlogon_creds_client_authenticator(creds, &r.in.credential); r.in.recordid = &recordid; r.in.reference=0; r.in.level=0; @@ -1622,7 +1627,7 @@ static bool test_DatabaseSync2(struct torture_context *tctx, struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; struct netr_Authenticator return_authenticator, credential; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; const uint32_t database_ids[] = {0, 1, 2}; int i; @@ -1653,7 +1658,7 @@ static bool test_DatabaseSync2(struct torture_context *tctx, torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id); do { - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); r.in.credential = &credential; @@ -1668,7 +1673,7 @@ static bool test_DatabaseSync2(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2"); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { torture_comment(tctx, "Credential chaining failed\n"); } @@ -2072,14 +2077,14 @@ static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx, struct samr_Password old_owf_password; struct netr_TrustInfo *trust_info; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, machine_credentials, &creds)) { return false; } - creds_client_authenticator(creds, &a); + netlogon_creds_client_authenticator(creds, &a); r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME); @@ -2094,7 +2099,7 @@ static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx, status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "failed"); - torture_assert(tctx, creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed"); + torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed"); return true; } @@ -2108,7 +2113,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, struct netr_LogonGetDomainInfo r; struct netr_DomainQuery1 q1; struct netr_Authenticator a; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; union netr_DomainInfo info; if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, @@ -2118,7 +2123,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, ZERO_STRUCT(r); - creds_client_authenticator(creds, &a); + netlogon_creds_client_authenticator(creds, &a); r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); r.in.computer_name = TEST_MACHINE_NAME; @@ -2143,14 +2148,14 @@ static bool test_GetDomainInfo(struct torture_context *tctx, status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo"); - torture_assert(tctx, creds_client_check(creds, &a.cred), "Credential chaining failed"); + torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed"); torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call\n"); - creds_client_authenticator(creds, &a); + netlogon_creds_client_authenticator(creds, &a); status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo"); - torture_assert(tctx, creds_client_check(creds, &a.cred), "Credential chaining failed"); + torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed"); return true; } @@ -2173,8 +2178,8 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx, struct netr_DomainQuery1 q1; struct netr_Authenticator a; #define ASYNC_COUNT 100 - struct creds_CredentialState *creds; - struct creds_CredentialState *creds_async[ASYNC_COUNT]; + struct netlogon_creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT]; struct rpc_request *req[ASYNC_COUNT]; int i; int *async_counter = talloc(tctx, int); @@ -2210,9 +2215,9 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx, *async_counter = 0; for (i=0;i<ASYNC_COUNT;i++) { - creds_client_authenticator(creds, &a); + netlogon_creds_client_authenticator(creds, &a); - creds_async[i] = (struct creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds)); + creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds)); req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r); req[i]->async.callback = async_callback; @@ -2230,7 +2235,7 @@ static bool test_GetDomainInfo_async(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async"); torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); - torture_assert(tctx, creds_client_check(creds_async[i], &a.cred), + torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred), "Credential chaining failed at async"); } diff --git a/source4/torture/rpc/netlogon.h b/source4/torture/rpc/netlogon.h index 92d366b46a..9038286ded 100644 --- a/source4/torture/rpc/netlogon.h +++ b/source4/torture/rpc/netlogon.h @@ -3,4 +3,4 @@ bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx, uint32_t negotiate_flags, struct cli_credentials *machine_credentials, int sec_chan_type, - struct creds_CredentialState **creds_out); + struct netlogon_creds_CredentialState **creds_out); diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 53754e02af..6d638d1868 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -57,7 +57,7 @@ static bool test_PACVerify(struct torture_context *tctx, struct netr_Authenticator auth, auth2; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct gensec_security *gensec_client_context; struct gensec_security *gensec_server_context; @@ -149,7 +149,7 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption"); - creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length); + netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length); generic.length = pac_wrapped.length; generic.data = pac_wrapped.data; @@ -168,7 +168,7 @@ static bool test_PACVerify(struct torture_context *tctx, logon.generic = &generic; ZERO_STRUCT(auth2); - creds_client_authenticator(creds, &auth); + netlogon_creds_client_authenticator(creds, &auth); r.in.credential = &auth; r.in.return_authenticator = &auth2; r.in.logon = &logon; @@ -190,7 +190,7 @@ static bool test_PACVerify(struct torture_context *tctx, logon.generic = &generic; ZERO_STRUCT(auth2); - creds_client_authenticator(creds, &auth); + netlogon_creds_client_authenticator(creds, &auth); r.in.credential = &auth; r.in.return_authenticator = &auth2; r.in.logon_level = NetlogonGenericInformation; @@ -203,7 +203,7 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert_ntstatus_equal(tctx, status, NT_STATUS_LOGON_FAILURE, "LogonSamLogon failed"); - torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred), + torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred), "Credential chaining failed"); /* This will break the parsing nicely (even in the crypto wrapping), check we get INVALID_PARAMETER */ @@ -212,7 +212,7 @@ static bool test_PACVerify(struct torture_context *tctx, logon.generic = &generic; ZERO_STRUCT(auth2); - creds_client_authenticator(creds, &auth); + netlogon_creds_client_authenticator(creds, &auth); r.in.credential = &auth; r.in.return_authenticator = &auth2; r.in.logon_level = NetlogonGenericInformation; @@ -225,7 +225,8 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER, "LogonSamLogon failed"); - torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred), + torture_assert(tctx, netlogon_creds_client_check(creds, + &r.out.return_authenticator->cred), "Credential chaining failed"); pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length; @@ -251,7 +252,7 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption"); - creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length); + netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length); generic.length = pac_wrapped.length; generic.data = pac_wrapped.data; @@ -259,7 +260,7 @@ static bool test_PACVerify(struct torture_context *tctx, logon.generic = &generic; ZERO_STRUCT(auth2); - creds_client_authenticator(creds, &auth); + netlogon_creds_client_authenticator(creds, &auth); r.in.credential = &auth; r.in.return_authenticator = &auth2; r.in.logon_level = NetlogonGenericInformation; @@ -272,7 +273,7 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert_ntstatus_equal(tctx, status, NT_STATUS_LOGON_FAILURE, "LogonSamLogon failed"); - torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred), + torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred), "Credential chaining failed"); pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length; @@ -298,7 +299,7 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed"); torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption"); - creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length); + netlogon_creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length); generic.length = pac_wrapped.length; generic.data = pac_wrapped.data; @@ -306,7 +307,7 @@ static bool test_PACVerify(struct torture_context *tctx, logon.generic = &generic; ZERO_STRUCT(auth2); - creds_client_authenticator(creds, &auth); + netlogon_creds_client_authenticator(creds, &auth); r.in.credential = &auth; r.in.return_authenticator = &auth2; r.in.logon_level = NetlogonGenericInformation; @@ -319,7 +320,7 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER, "LogonSamLogon failed"); - torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred), + torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred), "Credential chaining failed"); return true; } diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index fe128fea52..e31135c0de 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -904,7 +904,7 @@ static bool auth2(struct smbcli_state *cli, struct netr_Credential netr_srv_creds; uint32_t negotiate_flags; struct netr_ServerAuthenticate2 a; - struct creds_CredentialState *creds_state; + struct netlogon_creds_CredentialState *creds_state; struct netr_Credential netr_cred; struct samr_Password mach_pw; @@ -958,11 +958,6 @@ static bool auth2(struct smbcli_state *cli, negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; E_md4hash(cli_credentials_get_password(wks_cred), mach_pw.hash); - creds_state = talloc(mem_ctx, struct creds_CredentialState); - creds_client_init(creds_state, r.in.credentials, - r.out.return_credentials, &mach_pw, - &netr_cred, negotiate_flags); - a.in.server_name = talloc_asprintf( mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); a.in.account_name = talloc_asprintf( @@ -974,6 +969,13 @@ static bool auth2(struct smbcli_state *cli, a.in.credentials = &netr_cred; a.out.return_credentials = &netr_cred; + creds_state = netlogon_creds_client_init(mem_ctx, + a.in.account_name, + a.in.computer_name, + r.in.credentials, + r.out.return_credentials, &mach_pw, + &netr_cred, negotiate_flags); + status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a); if (!NT_STATUS_IS_OK(status)) { d_printf("netr_ServerServerAuthenticate2 failed: %s\n", @@ -981,7 +983,7 @@ static bool auth2(struct smbcli_state *cli, goto done; } - if (!creds_client_check(creds_state, a.out.return_credentials)) { + if (!netlogon_creds_client_check(creds_state, a.out.return_credentials)) { d_printf("creds_client_check failed\n"); goto done; } @@ -1054,7 +1056,7 @@ static bool schan(struct smbcli_state *cli, for (i=2; i<4; i++) { int flags; DATA_BLOB chal, nt_resp, lm_resp, names_blob, session_key; - struct creds_CredentialState *creds_state; + struct netlogon_creds_CredentialState *creds_state; struct netr_Authenticator netr_auth, netr_auth2; struct netr_NetworkInfo ninfo; struct netr_PasswordInfo pinfo; @@ -1088,7 +1090,7 @@ static bool schan(struct smbcli_state *cli, } creds_state = cli_credentials_get_netlogon_creds(wks_creds); - creds_client_authenticator(creds_state, &netr_auth); + netlogon_creds_client_authenticator(creds_state, &netr_auth); ninfo.identity_info.account_name.string = cli_credentials_get_username(user_creds); @@ -1129,13 +1131,13 @@ static bool schan(struct smbcli_state *cli, } if ((r.out.return_authenticator == NULL) || - (!creds_client_check(creds_state, + (!netlogon_creds_client_check(creds_state, &r.out.return_authenticator->cred))) { d_printf("Credentials check failed!\n"); goto done; } - creds_client_authenticator(creds_state, &netr_auth); + netlogon_creds_client_authenticator(creds_state, &netr_auth); pinfo.identity_info = ninfo.identity_info; ZERO_STRUCT(pinfo.lmpassword.hash); @@ -1161,7 +1163,7 @@ static bool schan(struct smbcli_state *cli, } if ((r.out.return_authenticator == NULL) || - (!creds_client_check(creds_state, + (!netlogon_creds_client_check(creds_state, &r.out.return_authenticator->cred))) { d_printf("Credentials check failed!\n"); goto done; @@ -1171,7 +1173,7 @@ static bool schan(struct smbcli_state *cli, { struct netr_ServerPasswordSet s; char *password = generate_random_str(wks_creds, 8); - struct creds_CredentialState *creds_state; + struct netlogon_creds_CredentialState *creds_state; struct netr_Authenticator credential, return_authenticator; struct samr_Password new_password; @@ -1188,8 +1190,8 @@ static bool schan(struct smbcli_state *cli, E_md4hash(password, new_password.hash); creds_state = cli_credentials_get_netlogon_creds(wks_creds); - creds_des_encrypt(creds_state, &new_password); - creds_client_authenticator(creds_state, &credential); + netlogon_creds_des_encrypt(creds_state, &new_password); + netlogon_creds_client_authenticator(creds_state, &credential); status = dcerpc_netr_ServerPasswordSet(net_pipe, mem_ctx, &s); if (!NT_STATUS_IS_OK(status)) { @@ -1197,8 +1199,8 @@ static bool schan(struct smbcli_state *cli, goto done; } - if (!creds_client_check(creds_state, - &s.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds_state, + &s.out.return_authenticator->cred)) { printf("Credential chaining failed\n"); } @@ -2088,7 +2090,7 @@ bool torture_samba3_rpc_randomauth2(struct torture_context *torture) struct netr_Credential netr_srv_creds; uint32_t negotiate_flags; struct netr_ServerAuthenticate2 a; - struct creds_CredentialState *creds_state; + struct netlogon_creds_CredentialState *creds_state; struct netr_Credential netr_cred; struct samr_Password mach_pw; struct smbcli_state *cli; @@ -2155,11 +2157,6 @@ bool torture_samba3_rpc_randomauth2(struct torture_context *torture) negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; E_md4hash("foobar", mach_pw.hash); - creds_state = talloc(mem_ctx, struct creds_CredentialState); - creds_client_init(creds_state, r.in.credentials, - r.out.return_credentials, &mach_pw, - &netr_cred, negotiate_flags); - a.in.server_name = talloc_asprintf( mem_ctx, "\\\\%s", dcerpc_server_name(net_pipe)); a.in.account_name = talloc_asprintf( @@ -2171,6 +2168,14 @@ bool torture_samba3_rpc_randomauth2(struct torture_context *torture) a.in.credentials = &netr_cred; a.out.return_credentials = &netr_cred; + creds_state = netlogon_creds_client_init(mem_ctx, + a.in.account_name, + a.in.computer_name, + r.in.credentials, + r.out.return_credentials, &mach_pw, + &netr_cred, negotiate_flags); + + status = dcerpc_netr_ServerAuthenticate2(net_pipe, mem_ctx, &a); if (!NT_STATUS_EQUAL(status, NT_STATUS_NO_TRUST_SAM_ACCOUNT)) { diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c index ce9bf5ea6e..8318930989 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/torture/rpc/samlogon.c @@ -63,7 +63,7 @@ struct samlogon_state { struct netr_LogonSamLogonEx r_ex; struct netr_LogonSamLogonWithFlags r_flags; struct netr_Authenticator auth, auth2; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; NTSTATUS expected_error; bool old_password; /* Allow an old password to be accepted or rejected without error, as well as session key bugs */ DATA_BLOB chall; @@ -153,12 +153,12 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, switch (samlogon_state->function_level) { case NDR_NETR_LOGONSAMLOGON: ZERO_STRUCT(samlogon_state->auth2); - creds_client_authenticator(samlogon_state->creds, &samlogon_state->auth); + netlogon_creds_client_authenticator(samlogon_state->creds, &samlogon_state->auth); r->out.return_authenticator = NULL; status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r); if (!r->out.return_authenticator || - !creds_client_check(samlogon_state->creds, &r->out.return_authenticator->cred)) { + !netlogon_creds_client_check(samlogon_state->creds, &r->out.return_authenticator->cred)) { d_printf("Credential chaining failed\n"); } if (!NT_STATUS_IS_OK(status)) { @@ -170,7 +170,7 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, validation_level = r->in.validation_level; - creds_decrypt_samlogon(samlogon_state->creds, validation_level, r->out.validation); + netlogon_creds_decrypt_samlogon(samlogon_state->creds, validation_level, r->out.validation); switch (validation_level) { case 2: @@ -195,7 +195,7 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, validation_level = r_ex->in.validation_level; - creds_decrypt_samlogon(samlogon_state->creds, validation_level, r_ex->out.validation); + netlogon_creds_decrypt_samlogon(samlogon_state->creds, validation_level, r_ex->out.validation); switch (validation_level) { case 2: @@ -211,12 +211,12 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, break; case NDR_NETR_LOGONSAMLOGONWITHFLAGS: ZERO_STRUCT(samlogon_state->auth2); - creds_client_authenticator(samlogon_state->creds, &samlogon_state->auth); + netlogon_creds_client_authenticator(samlogon_state->creds, &samlogon_state->auth); r_flags->out.return_authenticator = NULL; status = dcerpc_netr_LogonSamLogonWithFlags(samlogon_state->p, samlogon_state->mem_ctx, r_flags); if (!r_flags->out.return_authenticator || - !creds_client_check(samlogon_state->creds, &r_flags->out.return_authenticator->cred)) { + !netlogon_creds_client_check(samlogon_state->creds, &r_flags->out.return_authenticator->cred)) { d_printf("Credential chaining failed\n"); } if (!NT_STATUS_IS_OK(status)) { @@ -228,7 +228,7 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, validation_level = r_flags->in.validation_level; - creds_decrypt_samlogon(samlogon_state->creds, validation_level, r_flags->out.validation); + netlogon_creds_decrypt_samlogon(samlogon_state->creds, validation_level, r_flags->out.validation); switch (validation_level) { case 2: @@ -1314,7 +1314,7 @@ static const struct ntlm_tests { */ static bool test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct torture_context *tctx, - struct creds_CredentialState *creds, + struct netlogon_creds_CredentialState *creds, const char *comment, const char *account_domain, const char *account_name, const char *plain_pass, uint32_t parameter_control, @@ -1429,7 +1429,7 @@ static bool test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, test an ADS style interactive domain logon */ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds, + struct netlogon_creds_CredentialState *creds, const char *comment, const char *workstation_name, const char *account_domain, const char *account_name, @@ -1454,7 +1454,7 @@ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, ZERO_STRUCT(logon); ZERO_STRUCT(validation); - creds_client_authenticator(creds, &a); + netlogon_creds_client_authenticator(creds, &a); logon.password = &pinfo; @@ -1483,18 +1483,18 @@ bool test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, E_md4hash(plain_pass, pinfo.ntpassword.hash); if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16); - creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16); + netlogon_creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16); + netlogon_creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16); } else { - creds_des_encrypt(creds, &pinfo.lmpassword); - creds_des_encrypt(creds, &pinfo.ntpassword); + netlogon_creds_des_encrypt(creds, &pinfo.lmpassword); + netlogon_creds_des_encrypt(creds, &pinfo.ntpassword); } d_printf("Testing netr_LogonSamLogonWithFlags '%s' (Interactive Logon)\n", comment); status = dcerpc_netr_LogonSamLogonWithFlags(p, fn_ctx, &r); if (!r.out.return_authenticator - || !creds_client_check(creds, &r.out.return_authenticator->cred)) { + || !netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { d_printf("Credential chaining failed\n"); talloc_free(fn_ctx); return false; @@ -1540,7 +1540,7 @@ bool torture_rpc_samlogon(struct torture_context *torture) 0 /* yes, this is a valid flag, causes the use of DES */ }; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME); /* We only need to join as a workstation here, and in future, diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 9c867fd5e4..9483ae2a9a 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -2632,7 +2632,7 @@ static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p, static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx, struct cli_credentials *machine_credentials, struct cli_credentials *test_credentials, - struct creds_CredentialState *creds, + struct netlogon_creds_CredentialState *creds, NTSTATUS expected_result) { NTSTATUS status; @@ -2700,7 +2700,7 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string); ZERO_STRUCT(auth2); - creds_client_authenticator(creds, &auth); + netlogon_creds_client_authenticator(creds, &auth); r.in.validation_level = 2; @@ -2712,7 +2712,7 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed"); } - torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred), + torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred), "Credential chaining failed"); return true; @@ -2724,7 +2724,7 @@ static bool test_SamLogon(struct torture_context *tctx, struct cli_credentials *test_credentials, NTSTATUS expected_result) { - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) { return false; diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index 00798214f3..ee11ede83f 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -47,7 +47,7 @@ try a netlogon SamLogon */ static NTSTATUS test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds, + struct netlogon_creds_CredentialState *creds, const char *domain, const char *account_name, const char *workstation, struct samr_Password *lm_hash, @@ -100,13 +100,13 @@ static NTSTATUS test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.out.authoritative = &authoritative; ZERO_STRUCT(auth2); - creds_client_authenticator(creds, &auth); + netlogon_creds_client_authenticator(creds, &auth); r.in.validation_level = 3; status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r); - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { printf("Credential chaining failed\n"); } @@ -123,8 +123,8 @@ struct samsync_state { const char *domain_name[2]; struct samsync_secret *secrets; struct samsync_trusted_domain *trusted_domains; - struct creds_CredentialState *creds; - struct creds_CredentialState *creds_netlogon_wksta; + struct netlogon_creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds_netlogon_wksta; struct policy_handle *connect_handle; struct policy_handle *domain_handle[2]; struct dom_sid *sid[2]; @@ -578,7 +578,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct enum ndr_err_code ndr_err; data.data = user->user_private_info.SensitiveData; data.length = user->user_private_info.DataLength; - creds_arcfour_crypt(samsync_state->creds, data.data, data.length); + netlogon_creds_arcfour_crypt(samsync_state->creds, data.data, data.length); ndr_err = ndr_pull_struct_blob(&data, mem_ctx, lp_iconv_convenience(tctx->lp_ctx), &keys, (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS); if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { if (keys.keys.keys2.lmpassword.length == 16) { @@ -843,10 +843,10 @@ static bool samsync_handle_secret(TALLOC_CTX *mem_ctx, struct samsync_state *sam DATA_BLOB lsa_blob1, lsa_blob_out, session_key; NTSTATUS status; - creds_arcfour_crypt(samsync_state->creds, secret->current_cipher.cipher_data, + netlogon_creds_arcfour_crypt(samsync_state->creds, secret->current_cipher.cipher_data, secret->current_cipher.maxlen); - creds_arcfour_crypt(samsync_state->creds, secret->old_cipher.cipher_data, + netlogon_creds_arcfour_crypt(samsync_state->creds, secret->old_cipher.cipher_data, secret->old_cipher.maxlen); nsec->name = talloc_reference(nsec, name); @@ -1182,7 +1182,7 @@ static bool test_DatabaseSync(struct torture_context *tctx, do { loop_ctx = talloc_named(mem_ctx, 0, "DatabaseSync loop context"); - creds_client_authenticator(samsync_state->creds, &credential); + netlogon_creds_client_authenticator(samsync_state->creds, &credential); r.in.credential = &credential; @@ -1194,7 +1194,7 @@ static bool test_DatabaseSync(struct torture_context *tctx, break; } - if (!creds_client_check(samsync_state->creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(samsync_state->creds, &r.out.return_authenticator->cred)) { printf("Credential chaining failed\n"); } @@ -1395,7 +1395,7 @@ static bool test_DatabaseDeltas(struct samsync_state *samsync_state, TALLOC_CTX do { loop_ctx = talloc_named(mem_ctx, 0, "test_DatabaseDeltas loop context"); - creds_client_authenticator(samsync_state->creds, &credential); + netlogon_creds_client_authenticator(samsync_state->creds, &credential); status = dcerpc_netr_DatabaseDeltas(samsync_state->p, loop_ctx, &r); if (!NT_STATUS_IS_OK(status) && @@ -1405,7 +1405,7 @@ static bool test_DatabaseDeltas(struct samsync_state *samsync_state, TALLOC_CTX ret = false; } - if (!creds_client_check(samsync_state->creds, &return_authenticator.cred)) { + if (!netlogon_creds_client_check(samsync_state->creds, &return_authenticator.cred)) { printf("Credential chaining failed\n"); } @@ -1422,7 +1422,7 @@ static bool test_DatabaseDeltas(struct samsync_state *samsync_state, TALLOC_CTX try a netlogon DatabaseSync2 */ static bool test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds) + struct netlogon_creds_CredentialState *creds) { NTSTATUS status; TALLOC_CTX *loop_ctx; @@ -1455,7 +1455,7 @@ static bool test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, do { loop_ctx = talloc_named(mem_ctx, 0, "test_DatabaseSync2 loop context"); - creds_client_authenticator(creds, &credential); + netlogon_creds_client_authenticator(creds, &credential); r.in.credential = &credential; @@ -1466,7 +1466,7 @@ static bool test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, ret = false; } - if (!creds_client_check(creds, &r.out.return_authenticator->cred)) { + if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) { printf("Credential chaining failed\n"); } diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index bc3cbeac3b..fc0087e4d3 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -43,7 +43,7 @@ */ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, struct cli_credentials *credentials, - struct creds_CredentialState *creds) + struct netlogon_creds_CredentialState *creds) { NTSTATUS status; struct netr_LogonSamLogonEx r; @@ -259,7 +259,7 @@ static bool test_schannel(struct torture_context *tctx, struct dcerpc_pipe *p_netlogon3 = NULL; struct dcerpc_pipe *p_samr2 = NULL; struct dcerpc_pipe *p_lsa = NULL; - struct creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds; struct cli_credentials *credentials; join_ctx = torture_join_domain(tctx, @@ -765,7 +765,7 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture) { struct netr_ServerPasswordSet pwset; char *password = generate_random_str(s->join_ctx1, 8); - struct creds_CredentialState *creds_state; + struct netlogon_creds_CredentialState *creds_state; struct dcerpc_pipe *net_pipe; struct netr_Authenticator credential, return_authenticator; struct samr_Password new_password; @@ -793,14 +793,14 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture) creds_state = cli_credentials_get_netlogon_creds( s->wks_creds1); - creds_des_encrypt(creds_state, &new_password); - creds_client_authenticator(creds_state, &credential); + netlogon_creds_des_encrypt(creds_state, &new_password); + netlogon_creds_client_authenticator(creds_state, &credential); status = dcerpc_netr_ServerPasswordSet(net_pipe, torture, &pwset); torture_assert_ntstatus_ok(torture, status, "ServerPasswordSet failed"); - if (!creds_client_check(creds_state, + if (!netlogon_creds_client_check(creds_state, &pwset.out.return_authenticator->cred)) { printf("Credential chaining failed\n"); } diff --git a/source4/torture/rpc/wkssvc.c b/source4/torture/rpc/wkssvc.c index 3c34229dff..06b1d05ee4 100644 --- a/source4/torture/rpc/wkssvc.c +++ b/source4/torture/rpc/wkssvc.c @@ -1148,43 +1148,6 @@ static bool test_NetrJoinDomain(struct torture_context *tctx, return true; } -/* encode a wkssvc_PasswordBuffer for remote joining/unjoining: - * - * similar to samr_CryptPasswordEx. Different: 8byte confounder (instead of - * 16byte), confounder in front of the 516 byte buffer (instead of after that - * buffer), calling MD5Update() first with session_key and then with confounder - * (vice versa in samr) - Guenther */ - -static void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, - const char *pwd, - DATA_BLOB *session_key, - struct wkssvc_PasswordBuffer *pwd_buf) -{ - uint8_t buffer[516]; - struct MD5Context ctx; - - DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); - - int confounder_len = 8; - uint8_t confounder[8]; - - encode_pw_buffer(buffer, pwd, STR_UNICODE); - - generate_random_buffer((uint8_t *)confounder, confounder_len); - - MD5Init(&ctx); - MD5Update(&ctx, session_key->data, session_key->length); - MD5Update(&ctx, confounder, confounder_len); - MD5Final(confounded_session_key.data, &ctx); - - arcfour_crypt_blob(buffer, 516, &confounded_session_key); - - memcpy(&pwd_buf->data[0], confounder, confounder_len); - memcpy(&pwd_buf->data[8], buffer, 516); - - data_blob_free(&confounded_session_key); -} - /* * prerequisites for remotely joining an unjoined XP SP2 workstation: * - firewall needs to be disabled (or open for ncacn_np access) @@ -1202,7 +1165,7 @@ static bool test_NetrJoinDomain2(struct torture_context *tctx, const char *domain_admin_account = NULL; const char *domain_admin_password = NULL; const char *domain_name = NULL; - struct wkssvc_PasswordBuffer pwd_buf; + struct wkssvc_PasswordBuffer *pwd_buf; enum wkssvc_NetJoinStatus join_status; const char *join_name = NULL; WERROR expected_err; @@ -1253,7 +1216,7 @@ static bool test_NetrJoinDomain2(struct torture_context *tctx, r.in.domain_name = domain_name; r.in.account_ou = NULL; r.in.admin_account = domain_admin_account; - r.in.encrypted_password = &pwd_buf; + r.in.encrypted_password = pwd_buf; r.in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE; @@ -1286,7 +1249,7 @@ static bool test_NetrUnjoinDomain2(struct torture_context *tctx, struct wkssvc_NetrUnjoinDomain2 r; const char *domain_admin_account = NULL; const char *domain_admin_password = NULL; - struct wkssvc_PasswordBuffer pwd_buf; + struct wkssvc_PasswordBuffer *pwd_buf; enum wkssvc_NetJoinStatus join_status; const char *join_name = NULL; WERROR expected_err; @@ -1332,7 +1295,7 @@ static bool test_NetrUnjoinDomain2(struct torture_context *tctx, r.in.server_name = dcerpc_server_name(p); r.in.account = domain_admin_account; - r.in.encrypted_password = &pwd_buf; + r.in.encrypted_password = pwd_buf; r.in.unjoin_flags = 0; torture_comment(tctx, "testing NetrUnjoinDomain2 (assuming non-DC)\n"); diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c index 2c6f353252..1c9eabe09a 100644 --- a/source4/utils/ntlm_auth.c +++ b/source4/utils/ntlm_auth.c @@ -30,7 +30,6 @@ #include "auth/auth.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "auth/auth_sam.h" -#include "auth/ntlm/ntlm_check.h" #include "libcli/auth/libcli_auth.h" #include "libcli/security/security.h" #include "lib/events/events.h" diff --git a/source4/winbind/wb_sam_logon.c b/source4/winbind/wb_sam_logon.c index 5ceb6e4af0..fa3d6032c8 100644 --- a/source4/winbind/wb_sam_logon.c +++ b/source4/winbind/wb_sam_logon.c @@ -36,7 +36,7 @@ struct wb_sam_logon_state { struct winbind_SamLogon *req; - struct creds_CredentialState *creds_state; + struct netlogon_creds_CredentialState *creds_state; struct netr_Authenticator auth1, auth2; TALLOC_CTX *r_mem_ctx; @@ -86,7 +86,7 @@ static void wb_sam_logon_recv_domain(struct composite_context *creq) if (!composite_is_ok(s->ctx)) return; s->creds_state = cli_credentials_get_netlogon_creds(domain->libnet_ctx->cred); - creds_client_authenticator(s->creds_state, &s->auth1); + netlogon_creds_client_authenticator(s->creds_state, &s->auth1); s->r.in.server_name = talloc_asprintf(s, "\\\\%s", dcerpc_server_name(domain->netlogon_pipe)); @@ -135,8 +135,8 @@ static void wb_sam_logon_recv_samlogon(struct rpc_request *req) if (!composite_is_ok(s->ctx)) return; if ((s->r.out.return_authenticator == NULL) || - (!creds_client_check(s->creds_state, - &s->r.out.return_authenticator->cred))) { + (!netlogon_creds_client_check(s->creds_state, + &s->r.out.return_authenticator->cred))) { DEBUG(0, ("Credentials check failed!\n")); composite_error(s->ctx, NT_STATUS_ACCESS_DENIED); return; @@ -145,9 +145,9 @@ static void wb_sam_logon_recv_samlogon(struct rpc_request *req) /* Decrypt the session keys before we reform the info3, so the * person on the other end of winbindd pipe doesn't have to. * They won't have the encryption key anyway */ - creds_decrypt_samlogon(s->creds_state, - s->r.in.validation_level, - s->r.out.validation); + netlogon_creds_decrypt_samlogon(s->creds_state, + s->r.in.validation_level, + s->r.out.validation); composite_done(s->ctx); } |