From d9747b15c4a737a1422d0156d92efed762bb672d Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Thu, 20 Sep 2012 18:30:07 -0700 Subject: s4-torture: Complete test for winbindd PAC parsing Decode the PAC through the wbcAuthenticateUserEx call, also decode it locally and compare the result. Signed-off-by: Andrew Bartlett --- source4/torture/winbind/winbind.c | 92 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 6 deletions(-) (limited to 'source4') diff --git a/source4/torture/winbind/winbind.c b/source4/torture/winbind/winbind.c index cb895f53b3..5956834efa 100644 --- a/source4/torture/winbind/winbind.c +++ b/source4/torture/winbind/winbind.c @@ -3,6 +3,7 @@ SMB torture tester Copyright (C) Stefan Metzmacher 2007 Copyright (C) Andrew Bartlett 2012 + Copyright (C) Christof Schmit 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 @@ -29,6 +30,8 @@ #include "auth/credentials/credentials.h" #include "param/param.h" #include "lib/cmdline/popt_common.h" +#include "auth/kerberos/pac_utils.h" +#include "wbclient.h" struct pac_data { DATA_BLOB pac_blob; @@ -88,9 +91,89 @@ static NTSTATUS test_generate_session_info_pac(struct auth4_context *auth_ctx, return nt_status; } -/* Check to see if we can pass the PAC across to the NETLOGON server for validation */ +static bool torture_decode_compare_pac(struct torture_context *tctx, + DATA_BLOB pac) +{ + struct wbcAuthUserParams params; + struct wbcAuthUserInfo *info; + struct wbcAuthErrorInfo *error; + struct PAC_LOGON_INFO *logon_info; + struct netr_SamInfo3 *info3; + struct netr_SamBaseInfo *base; + wbcErr wbc_err; + NTSTATUS status; + int result, sid_idx, i; + char sid_str[50]; + + /* Let winbind decode the PAC */ + memset(¶ms, 0, sizeof(params)); + params.level = WBC_AUTH_USER_LEVEL_PAC; + params.password.pac.data = pac.data; + params.password.pac.length = pac.length; + + wbc_err = wbcAuthenticateUserEx(¶ms, &info, &error); + torture_assert(tctx, WBC_ERROR_IS_OK(wbc_err), wbcErrorString(wbc_err)); + + /* Decode the PAC internally */ + status = kerberos_pac_logon_info(tctx, pac, NULL, NULL, NULL, NULL, 0, + &logon_info); + torture_assert(tctx, NT_STATUS_IS_OK(status), "pac_logon_info"); + info3 = &logon_info->info3; + base = &info3->base; + + /* Compare the decoded data from winbind and from internal call */ + torture_assert(tctx, info->user_flags == base->user_flags, "user_flags"); + torture_assert_str_equal(tctx, info->account_name, base->account_name.string, "account_name"); + torture_assert_str_equal(tctx, info->full_name, base->full_name.string, "full_name"); + torture_assert_str_equal(tctx, info->domain_name, base->logon_domain.string, "domain_name"); + torture_assert(tctx, info->acct_flags == base->acct_flags, "acct_flags"); + torture_assert(tctx, info->logon_count == base->logon_count, "logon_count"); + torture_assert(tctx, info->bad_password_count == base->bad_password_count, "bad_password_count"); + torture_assert(tctx, info->logon_time == nt_time_to_unix(base->logon_time), "logon_time"); + torture_assert(tctx, info->logoff_time == nt_time_to_unix(base->logoff_time), "logoff_time"); + torture_assert(tctx, info->kickoff_time == nt_time_to_unix(base->kickoff_time), "kickoff_time"); + torture_assert(tctx, info->pass_last_set_time == nt_time_to_unix(base->last_password_change), "last_password_change"); + torture_assert(tctx, info->pass_can_change_time == nt_time_to_unix(base->allow_password_change), "allow_password_change"); + torture_assert(tctx, info->pass_must_change_time == nt_time_to_unix(base->force_password_change), "force_password_change"); + torture_assert(tctx, info->num_sids == 2 + base->groups.count + info3->sidcount, "num_sids"); + + sid_idx = 0; + wbcSidToStringBuf(&info->sids[sid_idx].sid, sid_str, sizeof(sid_str)); + torture_assert(tctx, + dom_sid_equal(dom_sid_parse_talloc(tctx, sid_str), + dom_sid_add_rid(tctx, base->domain_sid, base->rid)), + sid_str); + + sid_idx++; + wbcSidToStringBuf(&info->sids[sid_idx].sid, sid_str, sizeof(sid_str)); + torture_assert(tctx, + dom_sid_equal(dom_sid_parse_talloc(tctx, sid_str), + dom_sid_add_rid(tctx, base->domain_sid, base->primary_gid)), + sid_str); + + for(i = 0; i < base->groups.count; i++ ) { + sid_idx++; + wbcSidToStringBuf(&info->sids[sid_idx].sid, + sid_str, sizeof(sid_str)); + torture_assert(tctx, + dom_sid_equal(dom_sid_parse_talloc(tctx, sid_str), + dom_sid_add_rid(tctx, base->domain_sid, + base->groups.rids[i].rid)), + sid_str); + } + + for(i = 0; i < info3->sidcount; i++) { + sid_idx++; + wbcSidToStringBuf(&info->sids[sid_idx].sid, + sid_str, sizeof(sid_str)); + torture_assert(tctx, + dom_sid_equal(dom_sid_parse_talloc(tctx, sid_str), + info3->sids[i].sid), + sid_str); + } -/* Also happens to be a really good one-step verfication of our Kerberos stack */ + return true; +} static bool torture_winbind_pac(struct torture_context *tctx) { @@ -164,14 +247,11 @@ static bool torture_winbind_pac(struct torture_context *tctx) torture_assert(tctx, pac_data != NULL, "gensec_update failed to fill in pac_data in auth_context"); torture_assert(tctx, pac_data->pac_blob.data != NULL, "pac_blob not present"); - - /* TODO: Check the PAC blob with winbind */ + torture_decode_compare_pac(tctx, pac_data->pac_blob); return true; } - - NTSTATUS torture_winbind_init(void) { struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "winbind"); -- cgit