From b7b48793501915ecf5cb52b3044fd2f902987802 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 8 Aug 2012 15:22:03 +1000 Subject: [PATCH] s3-torture: Extend pdbtest to also run an authentication unit-test This tests both the builtin auth_sam against passdb directly and the configured auth module. Andrew Bartlett --- source3/torture/pdbtest.c | 117 +++++++++++++++++++++++++++++++++++++++++++++- source3/wscript_build | 4 +- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c index 821f39bee73..d0d529e9223 100644 --- a/source3/torture/pdbtest.c +++ b/source3/torture/pdbtest.c @@ -4,6 +4,7 @@ Copyright (C) Wilco Baan Hofman 2006 Copyright (C) Jelmer Vernooij 2006 + Copyright (C) Andrew Bartlett 2012 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 @@ -27,6 +28,10 @@ #include "../librpc/gen_ndr/drsblobs.h" #include "../librpc/gen_ndr/ndr_drsblobs.h" #include "../libcli/security/dom_sid.h" +#include "../libcli/auth/libcli_auth.h" +#include "../auth/common_auth.h" +#include "lib/tsocket/tsocket.h" +#include "include/auth.h" #define TRUST_DOM "trustdom" #define TRUST_PWD "trustpwd1232" @@ -38,6 +43,7 @@ static bool samu_correct(struct samu *s1, struct samu *s2) uint32 s1_len, s2_len; const char *s1_buf, *s2_buf; const uint8 *d1_buf, *d2_buf; + const struct dom_sid *s1_sid, *s2_sid; /* Check Unix username */ s1_buf = pdb_get_username(s1); @@ -233,11 +239,111 @@ static bool samu_correct(struct samu *s1, struct samu *s2) ret = False; } - /* TODO Check user and group sids */ + /* Check user and group sids */ + s1_sid = pdb_get_user_sid(s1); + s2_sid = pdb_get_user_sid(s2); + if (s2_sid == NULL && s1_sid != NULL) { + DEBUG(0, ("USER SID not set\n")); + ret = False; + } else if (s1_sid == NULL) { + /* Do nothing */ + } else if (!dom_sid_equal(s1_sid, s2_sid)) { + DEBUG(0, ("USER SID is not written correctly\n")); + ret = False; + } return ret; } +static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry) +{ + struct auth_usersupplied_info *user_info; + struct auth_context *auth_context; + static const uint8_t challenge_8[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + DATA_BLOB challenge = data_blob_const(challenge_8, sizeof(challenge_8)); + struct tsocket_address *tsocket_address; + unsigned char local_nt_response[24]; + DATA_BLOB nt_resp = data_blob_const(local_nt_response, sizeof(local_nt_response)); + unsigned char local_nt_session_key[16]; + struct netr_SamInfo3 *info3_sam, *info3_auth; + struct auth_serversupplied_info *server_info; + NTSTATUS status; + + SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry), challenge_8, + local_nt_response); + SMBsesskeygen_ntv1(pdb_get_nt_passwd(pdb_entry), local_nt_session_key); + + if (tsocket_address_inet_from_strings(NULL, "ip", NULL, 0, &tsocket_address) != 0) { + return False; + } + + status = make_user_info(&user_info, pdb_get_username(pdb_entry), pdb_get_username(pdb_entry), + pdb_get_domain(pdb_entry), pdb_get_domain(pdb_entry), lp_netbios_name(), + tsocket_address, NULL, &nt_resp, NULL, NULL, NULL, + AUTH_PASSWORD_RESPONSE); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status))); + return False; + } + + status = check_sam_security_info3(&challenge, NULL, user_info, &info3_sam); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status))); + return False; + } + + if (memcmp(info3_sam->base.key.key, local_nt_session_key, 16) != 0) { + DEBUG(0, ("Returned NT session key is incorrect\n")); + return False; + } + + status = make_auth_context_fixed(NULL, &auth_context, challenge.data); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status))); + return False; + } + + status = auth_check_ntlm_password(auth_context, user_info, &server_info); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Failed to test authentication with auth module: %s\n", nt_errstr(status))); + return False; + } + + info3_auth = talloc_zero(mem_ctx, struct netr_SamInfo3); + if (info3_auth == NULL) { + return False; + } + + status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3_auth); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n", + nt_errstr(status))); + return False; + } + + if (memcmp(info3_auth->base.key.key, local_nt_session_key, 16) != 0) { + DEBUG(0, ("Returned NT session key is incorrect\n")); + return False; + } + + if (!dom_sid_equal(info3_sam->base.domain_sid, info3_auth->base.domain_sid)) { + DEBUG(0, ("domain_sid in SAM info3 %s does not match domain_sid in AUTH info3 %s\n", + dom_sid_string(NULL, info3_sam->base.domain_sid), + dom_sid_string(NULL, info3_auth->base.domain_sid))); + return False; + } + + /* TODO: + * Compre more details from the two info3 structures, + * then test that an expired/disabled/pwdmustchange account + * returns the correct errors + */ + + return True; +} + static bool test_trusted_domains(TALLOC_CTX *ctx, struct pdb_methods *pdb, bool *error) @@ -363,6 +469,7 @@ int main(int argc, char **argv) /* Load configuration */ lp_load_global(get_dyn_CONFIGFILE()); setup_logging("pdbtest", DEBUG_STDOUT); + init_names(); if (backend == NULL) { backend = lp_passdb_backend(); @@ -464,6 +571,14 @@ int main(int argc, char **argv) error = True; } + if (test_auth(ctx, out)) { + printf("Authentication module test passed\n"); + } else { + printf("Authentication module test failed!\n"); + error = True; + } + + /* Delete account */ if (!NT_STATUS_IS_OK(rv = pdb->delete_sam_account(pdb, out))) { fprintf(stderr, "Error in delete_sam_account %s\n", diff --git a/source3/wscript_build b/source3/wscript_build index 91256670295..2b00a167f85 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -1480,7 +1480,9 @@ bld.SAMBA3_BINARY('pdbtest', deps=''' talloc pdb - popt_samba3''', + popt_samba3 + AUTH_COMMON + auth''', vars=locals()) bld.SAMBA3_BINARY('vfstest', -- 2.11.4.GIT