[PATCHSET] Samba AD with MIT Kerberos
Jeremy Allison
jra at samba.org
Mon Mar 13 17:44:24 UTC 2017
On Mon, Mar 13, 2017 at 08:29:37AM +0100, Andreas Schneider via samba-technical wrote:
> Hello,
>
> after more than 3 years of work I finally got this:
>
>
> ALL OK (14658 tests in 2030 testsuites)
>
>
> The testsuite completed for the first time!
>
>
> The journey started with the cwrap [1] project to make it possible to test
> Samba with the MIT KDC. We already pushed some code upstream especially code
> which not only handles MIT Kerberos but also fixed bugs with Heimdal. We
> discovered a lot of issues while working on this code.
>
> Attached is the patchset to implement the missing parts and get everything
> working.
>
>
> 46 files changed, 3113 insertions(+), 507 deletions(-)
>
>
> What isn't working yet
> ----------------------
>
> * KDC canon tests are not implemented yet
> * PKINIT
> * S4U2SELF/S4U2PROXY
> * RODC
>
>
> The patches are also available at [2].
>
>
> It requires MIT Kerberos 1.15.1! Packages for Fedora 25 can be found at [3].
>
>
> Review is much appreciated!
w00t!!!!! This is *AMAZING*. Thanks Andreas and everyone
who worked on this.
I will start working on reviewing this as time permits.
Cheers,
Jeremy.
> [1] https://cwrap.org
> [2] https://git.samba.org/?p=asn/samba.git;a=shortlog;h=refs/heads/master-mit-kdc-ok
> [3] https://copr.fedorainfracloud.org/coprs/asn/samba_ad_dc/
>
> --
> Andreas Schneider GPG-ID: CC014E3D
> Samba Team asn at samba.org
> www.samba.org
> From 1351b58987c672bfc576b0d36baaeed3a5531534 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 21 Dec 2016 19:08:58 +0100
> Subject: [PATCH 01/49] s4:torture: Fix the remote_pac test
>
> All the Kerberos implementation do not expect an order of the pac
> buffer. The buffers are not processed in the oder they are sent but when
> required just located.
>
> I confirmed this with MS at the IO Lab.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/torture/rpc/remote_pac.c | 72 +++++++++++++++++++++++++---------------
> 1 file changed, 46 insertions(+), 26 deletions(-)
>
> diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c
> index 25a581bb46b..091309874fe 100644
> --- a/source4/torture/rpc/remote_pac.c
> +++ b/source4/torture/rpc/remote_pac.c
> @@ -122,6 +122,23 @@ static NTSTATUS test_generate_session_info_pac(struct auth4_context *auth_ctx,
>
> /* Check to see if we can pass the PAC across to the NETLOGON server for validation */
>
> +static const struct PAC_BUFFER *get_pac_buffer(const struct PAC_DATA *pac_data,
> + enum PAC_TYPE type)
> +{
> + const struct PAC_BUFFER *pac_buf = NULL;
> + uint32_t i;
> +
> + for (i = 0; i < pac_data->num_buffers; ++i) {
> + pac_buf = &pac_data->buffers[i];
> +
> + if (pac_buf->type == type) {
> + break;
> + }
> + }
> +
> + return pac_buf;
> +}
> +
> /* Also happens to be a really good one-step verfication of our Kerberos stack */
>
> static bool test_PACVerify(struct torture_context *tctx,
> @@ -274,42 +291,45 @@ static bool test_PACVerify(struct torture_context *tctx,
> torture_assert_int_equal(tctx, pac_data_struct.version, 0, "version");
> torture_assert_int_equal(tctx, pac_data_struct.num_buffers, num_pac_buffers, "num_buffers");
>
> - pac_buf = pac_data_struct.buffers;
> - torture_assert_int_equal(tctx, pac_buf->type,
> - PAC_TYPE_LOGON_INFO, "PAC_TYPE_LOGON_INFO");
> - torture_assert(tctx, pac_buf->info != NULL,
> + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_LOGON_INFO);
> + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_LOGON_INFO");
> + torture_assert(tctx,
> + pac_buf->info != NULL,
> "PAC_TYPE_LOGON_INFO info");
> - pac_buf++;
> +
> if (pkinit_in_use) {
> - torture_assert_int_equal(tctx, pac_buf->type,
> - PAC_TYPE_CREDENTIAL_INFO,
> - "PAC_TYPE_CREDENTIAL_INFO");
> - torture_assert(tctx, pac_buf->info != NULL,
> + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_CREDENTIAL_INFO);
> + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_CREDENTIAL_INFO");
> + torture_assert(tctx,
> + pac_buf->info != NULL,
> "PAC_TYPE_CREDENTIAL_INFO info");
> - pac_buf++;
> }
> - torture_assert_int_equal(tctx, pac_buf->type,
> - PAC_TYPE_LOGON_NAME, "PAC_TYPE_LOGON_NAME");
> - torture_assert(tctx, pac_buf->info != NULL,
> +
> + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_LOGON_NAME);
> + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_LOGON_NAME");
> + torture_assert(tctx,
> + pac_buf->info != NULL,
> "PAC_TYPE_LOGON_NAME info");
> - pac_buf++;
> +
> if (expect_pac_upn_dns_info) {
> - torture_assert_int_equal(tctx, pac_buf->type,
> - PAC_TYPE_UPN_DNS_INFO, "PAC_TYPE_UPN_DNS_INFO");
> - torture_assert(tctx, pac_buf->info != NULL,
> + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_UPN_DNS_INFO);
> + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_UPN_DNS_INFO");
> + torture_assert(tctx,
> + pac_buf->info != NULL,
> "PAC_TYPE_UPN_DNS_INFO info");
> - pac_buf++;
> }
> - torture_assert_int_equal(tctx, pac_buf->type,
> - PAC_TYPE_SRV_CHECKSUM, "PAC_TYPE_SRV_CHECKSUM");
> - torture_assert(tctx, pac_buf->info != NULL,
> +
> + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_SRV_CHECKSUM);
> + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_SRV_CHECKSUM");
> + torture_assert(tctx,
> + pac_buf->info != NULL,
> "PAC_TYPE_SRV_CHECKSUM info");
> - pac_buf++;
> - torture_assert_int_equal(tctx, pac_buf->type,
> - PAC_TYPE_KDC_CHECKSUM, "PAC_TYPE_KDC_CHECKSUM");
> - torture_assert(tctx, pac_buf->info != NULL,
> +
> + pac_buf = get_pac_buffer(&pac_data_struct, PAC_TYPE_KDC_CHECKSUM);
> + torture_assert_not_null(tctx, pac_buf, "PAC_TYPE_KDC_CHECKSUM");
> + torture_assert(tctx,
> + pac_buf->info != NULL,
> "PAC_TYPE_KDC_CHECKSUM info");
> - pac_buf++;
>
> pac_wrapped_struct.ChecksumLength = pac_data->pac_srv_sig->signature.length;
> pac_wrapped_struct.SignatureType = pac_data->pac_kdc_sig->type;
> --
> 2.12.0
>
>
> From dbe9c881b9059b5d17534cc13f06cce48ef89263 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Tue, 13 Sep 2016 08:24:06 +0200
> Subject: [PATCH 02/49] testprogs: Add common kinit function
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> testprogs/blackbox/common_test_fns.inc | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/testprogs/blackbox/common_test_fns.inc b/testprogs/blackbox/common_test_fns.inc
> index aff1aa9dc79..db1daf351d7 100755
> --- a/testprogs/blackbox/common_test_fns.inc
> +++ b/testprogs/blackbox/common_test_fns.inc
> @@ -36,3 +36,19 @@ test_smbclient_expect_failure() {
> fi
> return $status
> }
> +
> +kerberos_kinit() {
> + kinit_tool="${1}"
> + principal="${2}"
> + password="${3}"
> + shift 3
> + kbase=$(basename ${kinit_tool})
> + if [ ${kase} = "samba4kinit" ]; then
> + kpassfile=$(mktemp)
> + echo $password > ${kpassfile}
> + $kinit_tool --password-file=$PREFIX/tmpuserpassfile $principal $@
> + rm -f ${kpassfile}
> + else
> + echo $password | $kinit_tool $principal $@
> + fi
> +}
> --
> 2.12.0
>
>
> From cc424914cfe06f60d2671c0f0d8c7a81c330b816 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Tue, 13 Sep 2016 08:24:41 +0200
> Subject: [PATCH 03/49] s3-tests: Use common functions in
> test_smbclient_netbios_aliases.sh
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> .../script/tests/test_smbclient_netbios_aliases.sh | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/source3/script/tests/test_smbclient_netbios_aliases.sh b/source3/script/tests/test_smbclient_netbios_aliases.sh
> index 610eeda5ab6..853d6be789e 100755
> --- a/source3/script/tests/test_smbclient_netbios_aliases.sh
> +++ b/source3/script/tests/test_smbclient_netbios_aliases.sh
> @@ -7,7 +7,7 @@ EOF
> exit 1;
> fi
>
> -SMBCLIENT3=$1
> +smbclient=$1
> SERVER=$2
> USERNAME=$3
> PASSWORD=$4
> @@ -15,11 +15,11 @@ PREFIX=$5
> shift 5
> ADDARGS="$*"
>
> -samba4bindir="$BINDIR"
> -samba4srcdir="$SRCDIR/source4"
> -samba4kinit=kinit
> -if test -x $BINDIR/samba4kinit; then
> - samba4kinit=$BINDIR/samba4kinit
> +samba_bindir="$BINDIR"
> +samba_srcdir="$SRCDIR/source4"
> +samba_kinit=kinit
> +if test -x ${samba_bindir}/samba4kinit; then
> + samba4kinit=${samba_bindir}/samba4kinit
> fi
>
> KRB5CCNAME_PATH="$PREFIX/test_smbclient_netbios_aliases_krb5ccache"
> @@ -30,11 +30,11 @@ export KRB5CCNAME
>
> incdir=`dirname $0`/../../../testprogs/blackbox
> . $incdir/subunit.sh
> +. $incdir/common_test_fns.inc
>
> -echo $PASSWORD > $PREFIX/tmppassfile
> -testit "kinit" $samba4kinit --password-file=$PREFIX/tmppassfile $USERNAME || failed=`expr $failed + 1`
> -rm -f $PREFIX/tmppassfile
> -testit "smbclient" $VALGRIND $SMBCLIENT3 -k //$SERVER/tmp -c 'ls' $ADDARGS || failed=`expr $failed + 1`
> +testit "kinit" kerberos_kinit ${samba_kinit} ${USERNAME} ${PASSWORD}
> +
> +test_smbclient "smbclient (krb5)" "ls" "//$SERVER/tmp" -k || failed=`expr $failed + 1`
>
> rm -rf $KRB5CCNAME_PATH
>
> --
> 2.12.0
>
>
> From 4e60c2b5607d84e74ef95f5c082fb59482600a72 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 30 Jul 2015 17:38:34 +0200
> Subject: [PATCH 04/49] samba_dnsupdate: Do not rewrite krb5.conf in selftest
>
> The samba_dnsupdate script is responsible to provision the DNS entries.
> The private krb5.conf uses dns lookups to find the KDC to acquire a
> Kerberos ticket. Obviously this will fail because currently we are are
> in the process of adding the DNS entries for the KDC.
>
> If we are inside of selftest we need to use the krb5.conf created by
> selftest itself.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/scripting/bin/samba_dnsupdate | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate
> index 1633561e173..5e06789887a 100755
> --- a/source4/scripting/bin/samba_dnsupdate
> +++ b/source4/scripting/bin/samba_dnsupdate
> @@ -662,10 +662,13 @@ if opts.update_cache:
> else:
> dns_update_cache = lp.private_path('dns_update_cache')
>
> -# use our private krb5.conf to avoid problems with the wrong domain
> -# bind9 nsupdate wants the default domain set
> -krb5conf = lp.private_path('krb5.conf')
> -os.environ['KRB5_CONFIG'] = krb5conf
> +krb5conf = None
> +# only change the krb5.conf if we are not in selftest
> +if 'SOCKET_WRAPPER_DIR' not in os.environ:
> + # use our private krb5.conf to avoid problems with the wrong domain
> + # bind9 nsupdate wants the default domain set
> + krb5conf = lp.private_path('krb5.conf')
> + os.environ['KRB5_CONFIG'] = krb5conf
>
> file = open(dns_update_list, "r")
>
> --
> 2.12.0
>
>
> From e1f0e896236406fb185fa42b17c3aa062bb8340e Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 26 Jan 2017 16:54:30 +0100
> Subject: [PATCH 05/49] mit-kdb: Zero the db principal when we allocate it
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit_samba.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
> index f5015840055..8a2bfe9b715 100644
> --- a/source4/kdc/mit_samba.c
> +++ b/source4/kdc/mit_samba.c
> @@ -188,7 +188,7 @@ int mit_samba_get_principal(struct mit_samba_context *ctx,
> int ret;
> int sflags = 0;
>
> - kentry = malloc(sizeof(krb5_db_entry));
> + kentry = calloc(1, sizeof(krb5_db_entry));
> if (kentry == NULL) {
> return ENOMEM;
> }
> --
> 2.12.0
>
>
> From fa42b2a7e102df23a1814a6fe2ef1d02a858e11a Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 20 Jan 2017 09:14:03 +0100
> Subject: [PATCH 06/49] waf: Require MIT Kerberos 1.15.1 for Samba AD
>
> Are build without AD DC still only requried MIT Kerberos 1.9.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> wscript_configure_system_mitkrb5 | 27 ++++++++++++++++++---------
> 1 file changed, 18 insertions(+), 9 deletions(-)
>
> diff --git a/wscript_configure_system_mitkrb5 b/wscript_configure_system_mitkrb5
> index d3e8ebf0dcd..1fb28092e54 100644
> --- a/wscript_configure_system_mitkrb5
> +++ b/wscript_configure_system_mitkrb5
> @@ -3,6 +3,14 @@ import Logs, Options, sys
> # Check for kerberos
> have_gssapi=False
>
> +# Requried versions
> +krb5_required_version = "1.9"
> +if conf.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
> + krb5_required_version = "1.15.1"
> +
> +def parse_version(v):
> + return tuple(map(str, (v.split("."))))
> +
> def krb5_define_syslib(conf, lib, deps):
> found = 'FOUND_SYSTEMLIB_' + lib
> if found in conf.env:
> @@ -44,19 +52,20 @@ if conf.env.KRB5_CONFIG:
> if conf.env.KRB5_VENDOR != 'heimdal':
> conf.define('USING_SYSTEM_KRB5', 1)
> del conf.env.HEIMDAL_KRB5_CONFIG
> - kversion = conf.cmd_and_log("%(path)s --version" % dict(path=conf.env.KRB5_CONFIG), dict()).strip()
> - kversion_split = kversion.split(' ')[-1].split('.')
> + krb5_conf_version = conf.cmd_and_log("%(path)s --version" % dict(path=conf.env.KRB5_CONFIG), dict()).strip()
> +
> + krb5_version = krb5_conf_version.split()[-1]
> +
> # drop '-prerelease' suffix
> - if kversion_split[-1].find('-') > 0:
> - last_digit = kversion_split[-1].split('-')[0]
> - kversion_split[-1] = last_digit
> - kversion_check = map(int, kversion_split)
> - if kversion_check < [1, 9]:
> - Logs.error('ERROR: MIT krb5 build requires at least 1.9.0. %s is found and cannot be used' % (kversion))
> + if krb5_version.find('-') > 0:
> + krb5_version = krb5_version.split("-")[0]
> +
> + if parse_version(krb5_version) < parse_version(krb5_required_version):
> + Logs.error('ERROR: MIT krb5 build requires at least %s. %s is found and cannot be used' % (krb5_version, krb5_required_version))
> Logs.error('ERROR: You may try to build with embedded Heimdal Kerebros by not specifying --with-system-mitkrb5')
> sys.exit(1)
> else:
> - Logs.info('%s is detected, MIT krb5 build can proceed' % (kversion))
> + Logs.info('MIT Kerberos %s detected, MIT krb5 build can proceed' % (krb5_version))
>
> conf.CHECK_CFG(args="--cflags --libs", package="com_err", uselib_store="com_err")
> conf.CHECK_FUNCS_IN('_et_list', 'com_err')
> --
> 2.12.0
>
>
> From 8d93bb024a1307b602ec6ce0a645cd339e57d340 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 26 Jan 2017 16:52:15 +0100
> Subject: [PATCH 07/49] mit-kdb: Update KDB vtable for DAL version 6
>
> This changed between 1.14 and 1.15. Also the 1.15 change removed the
> ability that the KDB module can free memory. This caused issues of
> serveral projects. It got fixed with 1.15.1.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit-kdb/kdb_samba.c | 92 +++++++++++++-----------------
> source4/kdc/mit-kdb/kdb_samba.h | 6 --
> source4/kdc/mit-kdb/kdb_samba_common.c | 48 ----------------
> source4/kdc/mit-kdb/kdb_samba_principals.c | 33 ++++-------
> source4/kdc/sdb_to_kdb.c | 16 ++++--
> 5 files changed, 63 insertions(+), 132 deletions(-)
>
> diff --git a/source4/kdc/mit-kdb/kdb_samba.c b/source4/kdc/mit-kdb/kdb_samba.c
> index b7f802c8c66..c5157d6ed1b 100644
> --- a/source4/kdc/mit-kdb/kdb_samba.c
> +++ b/source4/kdc/mit-kdb/kdb_samba.c
> @@ -126,60 +126,50 @@ static krb5_error_code kdb_samba_db_unlock(krb5_context context)
> return 0;
> }
>
> -static void *kdb_samba_db_alloc(krb5_context context, void *ptr, size_t size)
> +static void kdb_samba_db_free_principal_e_data(krb5_context context,
> + krb5_octet *e_data)
> {
> - return realloc(ptr, size);
> -}
> + struct samba_kdc_entry *skdc_entry;
>
> -static void kdb_samba_db_free(krb5_context context, void *ptr)
> -{
> - free(ptr);
> + skdc_entry = talloc_get_type_abort(e_data,
> + struct samba_kdc_entry);
> + talloc_set_destructor(skdc_entry, NULL);
> + TALLOC_FREE(skdc_entry);
> }
>
> kdb_vftabl kdb_function_table = {
> - KRB5_KDB_DAL_MAJOR_VERSION, /* major version number */
> - 0, /* minor version number */
> - kdb_samba_init_library, /* init_library */
> - kdb_samba_fini_library, /* fini_library */
> - kdb_samba_init_module, /* init_module */
> - kdb_samba_fini_module, /* fini_module */
> -
> - kdb_samba_db_create, /* db_create */
> - kdb_samba_db_destroy, /* db_destroy */
> - kdb_samba_db_get_age, /* db_get_age */
> - kdb_samba_db_lock, /* db_lock */
> - kdb_samba_db_unlock, /* db_unlock */
> -
> - kdb_samba_db_get_principal, /* db_get_principal */
> - kdb_samba_db_free_principal, /* db_free_principal */
> - kdb_samba_db_put_principal, /* db_put_principal */
> - kdb_samba_db_delete_principal, /* db_delete_principal */
> - kdb_samba_db_iterate, /* db_iterate */
> -
> - NULL, /* create_policy */
> - NULL, /* get_policy */
> - NULL, /* put_policy */
> - NULL, /* iter_policy */
> - NULL, /* delete_policy */
> - NULL, /* free_policy */
> -
> - kdb_samba_db_alloc, /* db_alloc */
> - kdb_samba_db_free, /* db_free */
> -
> - kdb_samba_fetch_master_key, /* fetch_master_key */
> - kdb_samba_fetch_master_key_list, /* fetch_master_key_list */
> - NULL, /* store_master_key_list */
> - NULL, /* dbe_search_enctype */
> - kdb_samba_change_pwd, /* change_pwd */
> - NULL, /* promote_db */
> - kdb_samba_dbekd_decrypt_key_data, /* decrypt_key_data */
> - kdb_samba_dbekd_encrypt_key_data, /* encrypt_key_data */
> -
> - kdb_samba_db_sign_auth_data, /* sign_authdata */
> - NULL, /* check_transited_realms */
> - kdb_samba_db_check_policy_as, /* check_policy_as */
> - NULL, /* check_policy_tgs */
> - kdb_samba_db_audit_as_req, /* audit_as_req */
> - NULL, /* refresh_config */
> - kdb_samba_db_check_allowed_to_delegate
> + .maj_ver = KRB5_KDB_DAL_MAJOR_VERSION,
> + .min_ver = 1,
> +
> + .init_library = kdb_samba_init_library,
> + .fini_library = kdb_samba_fini_library,
> + .init_module = kdb_samba_init_module,
> + .fini_module = kdb_samba_fini_module,
> +
> + .create = kdb_samba_db_create,
> + .destroy = kdb_samba_db_destroy,
> + .get_age = kdb_samba_db_get_age,
> + .lock = kdb_samba_db_lock,
> + .unlock = kdb_samba_db_unlock,
> +
> + .get_principal = kdb_samba_db_get_principal,
> + .put_principal = kdb_samba_db_put_principal,
> + .delete_principal = kdb_samba_db_delete_principal,
> +
> + .iterate = kdb_samba_db_iterate,
> +
> + .fetch_master_key = kdb_samba_fetch_master_key,
> + .fetch_master_key_list = kdb_samba_fetch_master_key_list,
> +
> + .change_pwd = kdb_samba_change_pwd,
> +
> + .decrypt_key_data = kdb_samba_dbekd_decrypt_key_data,
> + .encrypt_key_data = kdb_samba_dbekd_encrypt_key_data,
> +
> + .sign_authdata = kdb_samba_db_sign_auth_data,
> + .check_policy_as = kdb_samba_db_check_policy_as,
> + .audit_as_req = kdb_samba_db_audit_as_req,
> + .check_allowed_to_delegate = kdb_samba_db_check_allowed_to_delegate,
> +
> + .free_principal_e_data = kdb_samba_db_free_principal_e_data,
> };
> diff --git a/source4/kdc/mit-kdb/kdb_samba.h b/source4/kdc/mit-kdb/kdb_samba.h
> index 0258b2d313f..abca2c166ae 100644
> --- a/source4/kdc/mit-kdb/kdb_samba.h
> +++ b/source4/kdc/mit-kdb/kdb_samba.h
> @@ -48,9 +48,6 @@
>
> struct mit_samba_context *ks_get_context(krb5_context kcontext);
>
> -void ks_free_krb5_db_entry(krb5_context context,
> - krb5_db_entry *entry);
> -
> bool ks_data_eq_string(krb5_data d, const char *s);
>
> krb5_data ks_make_data(void *data, unsigned int len);
> @@ -74,9 +71,6 @@ krb5_error_code kdb_samba_db_get_principal(krb5_context context,
> unsigned int kflags,
> krb5_db_entry **kentry);
>
> -void kdb_samba_db_free_principal(krb5_context context,
> - krb5_db_entry *entry);
> -
> krb5_error_code kdb_samba_db_put_principal(krb5_context context,
> krb5_db_entry *entry,
> char **db_args);
> diff --git a/source4/kdc/mit-kdb/kdb_samba_common.c b/source4/kdc/mit-kdb/kdb_samba_common.c
> index 1cd546977b7..e89aed6aeba 100644
> --- a/source4/kdc/mit-kdb/kdb_samba_common.c
> +++ b/source4/kdc/mit-kdb/kdb_samba_common.c
> @@ -43,54 +43,6 @@ struct mit_samba_context *ks_get_context(krb5_context kcontext)
> return (struct mit_samba_context *)db_ctx;
> }
>
> -void ks_free_krb5_db_entry(krb5_context context,
> - krb5_db_entry *entry)
> -{
> - krb5_tl_data *tl_data_next = NULL;
> - krb5_tl_data *tl_data = NULL;
> - int i, j;
> -
> - if (entry == NULL) {
> - return;
> - }
> -
> -#if 0 /* TODO FIXME do we have something to free? */
> - if (entry->e_data != NULL) {
> - /* FREE ME! */
> - }
> -#endif
> -
> - krb5_free_principal(context, entry->princ);
> -
> - for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) {
> - tl_data_next = tl_data->tl_data_next;
> - if (tl_data->tl_data_contents != NULL)
> - free(tl_data->tl_data_contents);
> - free(tl_data);
> - }
> -
> - if (entry->key_data != NULL) {
> - for (i = 0; i < entry->n_key_data; i++) {
> - for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
> - if (entry->key_data[i].key_data_length[j] != 0) {
> - if (entry->key_data[i].key_data_contents[j] != NULL) {
> - memset(entry->key_data[i].key_data_contents[j],
> - 0,
> - entry->key_data[i].key_data_length[j]);
> - free(entry->key_data[i].key_data_contents[j]);
> - }
> - }
> - entry->key_data[i].key_data_contents[j] = NULL;
> - entry->key_data[i].key_data_length[j] = 0;
> - entry->key_data[i].key_data_type[j] = 0;
> - }
> - }
> - free(entry->key_data);
> - }
> -
> - free(entry);
> -}
> -
> bool ks_data_eq_string(krb5_data d, const char *s)
> {
> int rc;
> diff --git a/source4/kdc/mit-kdb/kdb_samba_principals.c b/source4/kdc/mit-kdb/kdb_samba_principals.c
> index 7b6fd6a81e9..1dbb69b561d 100644
> --- a/source4/kdc/mit-kdb/kdb_samba_principals.c
> +++ b/source4/kdc/mit-kdb/kdb_samba_principals.c
> @@ -93,7 +93,7 @@ static krb5_error_code ks_get_master_key_principal(krb5_context context,
> code = krb5_copy_principal(context, princ, &kentry->princ);
> }
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> @@ -101,7 +101,7 @@ static krb5_error_code ks_get_master_key_principal(krb5_context context,
>
> code = krb5_dbe_update_mod_princ_data(context, kentry, now, kentry->princ);
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> @@ -109,7 +109,7 @@ static krb5_error_code ks_get_master_key_principal(krb5_context context,
> kentry->n_key_data = 1;
> kentry->key_data = calloc(1, sizeof(krb5_key_data));
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> @@ -119,7 +119,7 @@ static krb5_error_code ks_get_master_key_principal(krb5_context context,
> key_data->key_data_kvno = 1;
> key_data->key_data_type[0] = ENCTYPE_UNKNOWN;
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> @@ -169,7 +169,7 @@ static krb5_error_code ks_create_principal(krb5_context context,
>
> code = krb5_copy_principal(context, princ, &kentry->princ);
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> @@ -177,13 +177,13 @@ static krb5_error_code ks_create_principal(krb5_context context,
>
> code = krb5_dbe_update_mod_princ_data(context, kentry, now, kentry->princ);
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> code = mit_samba_generate_salt(&salt);
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> @@ -194,7 +194,7 @@ static krb5_error_code ks_create_principal(krb5_context context,
> /* create a random password */
> code = mit_samba_generate_random_password(&pwd);
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
> }
> @@ -202,14 +202,14 @@ static krb5_error_code ks_create_principal(krb5_context context,
> code = krb5_c_string_to_key(context, enctype, &pwd, &salt, &key);
> SAFE_FREE(pwd.data);
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> kentry->n_key_data = 1;
> kentry->key_data = calloc(1, sizeof(krb5_key_data));
> if (code != 0) {
> - ks_free_krb5_db_entry(context, kentry);
> + krb5_db_free_principal(context, kentry);
> return code;
> }
>
> @@ -288,19 +288,6 @@ krb5_error_code kdb_samba_db_get_principal(krb5_context context,
> return code;
> }
>
> -void kdb_samba_db_free_principal(krb5_context context,
> - krb5_db_entry *entry)
> -{
> - struct mit_samba_context *mit_ctx;
> -
> - mit_ctx = ks_get_context(context);
> - if (mit_ctx == NULL) {
> - return;
> - }
> -
> - ks_free_krb5_db_entry(context, entry);
> -}
> -
> krb5_error_code kdb_samba_db_put_principal(krb5_context context,
> krb5_db_entry *entry,
> char **db_args)
> diff --git a/source4/kdc/sdb_to_kdb.c b/source4/kdc/sdb_to_kdb.c
> index ff50c0cab87..74d882738f8 100644
> --- a/source4/kdc/sdb_to_kdb.c
> +++ b/source4/kdc/sdb_to_kdb.c
> @@ -318,27 +318,35 @@ static int samba_kdc_kdb_entry_destructor(struct samba_kdc_entry *p)
> krb5_error_code ret;
> krb5_context context;
>
> + if (entry_ex->e_data != NULL) {
> + struct samba_kdc_entry *skdc_entry;
> +
> + skdc_entry = talloc_get_type(entry_ex->e_data,
> + struct samba_kdc_entry);
> + talloc_set_destructor(skdc_entry, NULL);
> + entry_ex->e_data = NULL;
> + }
> +
> ret = krb5_init_context(&context);
> if (ret) {
> return ret;
> }
>
> - free_krb5_db_entry(context, entry_ex);
> + krb5_db_free_principal(context, entry_ex);
> krb5_free_context(context);
>
> return 0;
> }
>
> -
> int sdb_entry_ex_to_kdb_entry_ex(krb5_context context,
> const struct sdb_entry_ex *s,
> krb5_db_entry *k)
> {
> - struct samba_kdc_entry *skdc_entry;
> -
> ZERO_STRUCTP(k);
>
> if (s->ctx != NULL) {
> + struct samba_kdc_entry *skdc_entry;
> +
> skdc_entry = talloc_get_type(s->ctx, struct samba_kdc_entry);
>
> k->e_data = (void *)skdc_entry;
> --
> 2.12.0
>
>
> From ad65ccb65fed7644a272e0961ed4af9bdb139f03 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 23 Jul 2015 13:49:09 +0200
> Subject: [PATCH 08/49] waf: Check for MIT KDC binary
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> wscript | 5 +++++
> wscript_configure_system_mitkrb5 | 13 +++++++++++++
> 2 files changed, 18 insertions(+)
>
> diff --git a/wscript b/wscript
> index 4fd56ed0026..c017c359d32 100644
> --- a/wscript
> +++ b/wscript
> @@ -51,6 +51,11 @@ def set_options(opt):
> help='enable system MIT krb5 build (includes Samba 4 client and Samba 3 code base).'+
> 'You may specify list of paths where Kerberos is installed (e.g. /usr/local /usr/kerberos) to search krb5-config',
> action='callback', callback=system_mitkrb5_callback, dest='with_system_mitkrb5', default=False)
> + opt.add_option('--with-system-mitkdc',
> + help=('Specify the path to the krb5kdc binary from MIT Kerberos'),
> + type="string",
> + dest='with_system_mitkdc',
> + default=None)
>
> opt.add_option('--without-ad-dc',
> help='disable AD DC functionality (enables Samba 4 client and Samba 3 code base).',
> diff --git a/wscript_configure_system_mitkrb5 b/wscript_configure_system_mitkrb5
> index 1fb28092e54..a520238a46b 100644
> --- a/wscript_configure_system_mitkrb5
> +++ b/wscript_configure_system_mitkrb5
> @@ -290,3 +290,16 @@ conf.CHECK_CODE('''
> 'HAVE_FLAGS_IN_KRB5_CREDS',
> headers='krb5.h', lib='krb5', execute=False,
> msg="Checking whether krb5_creds have flags property")
> +
> +# Check for MIT KDC
> +if conf.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'):
> + Logs.info("Looking for MIT KDC")
> + conf.DEFINE('SAMBA_USES_MITKDC', 1);
> +
> + kdc_path_list = [ '/usr/sbin', '/usr/lib/mit/sbin']
> +
> + if getattr(Options.options, 'with_system_mitkdc', None):
> + conf.DEFINE('MIT_KDC_PATH', '"' + Options.options.with_system_mitkdc + '"')
> + else:
> + conf.find_program('krb5kdc', path_list=kdc_path_list, var='MIT_KDC_BINARY', mandatory=True)
> + conf.DEFINE('MIT_KDC_PATH', '"' + conf.env.MIT_KDC_BINARY + '"')
> --
> 2.12.0
>
>
> From ee4d9787fa002b69b879327bc80732d3168c269b Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 28 Apr 2014 15:22:34 +0200
> Subject: [PATCH 09/49] param: Add 'mit kdc command' to change the default.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> docs-xml/smbdotconf/security/mitkdccommand.xml | 15 +++++++++++++++
> lib/param/loadparm.c | 5 +++++
> source3/param/loadparm.c | 4 ++++
> 3 files changed, 24 insertions(+)
> create mode 100644 docs-xml/smbdotconf/security/mitkdccommand.xml
>
> diff --git a/docs-xml/smbdotconf/security/mitkdccommand.xml b/docs-xml/smbdotconf/security/mitkdccommand.xml
> new file mode 100644
> index 00000000000..2c7601fb5f5
> --- /dev/null
> +++ b/docs-xml/smbdotconf/security/mitkdccommand.xml
> @@ -0,0 +1,15 @@
> +<samba:parameter name="mit kdc command"
> + context="G"
> + type="list"
> + advanced="1"
> + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> +<description>
> + <para>This option specifies the path to the MIT kdc binary.</para>
> +
> + <para>If the KDC is not installed in the default location and wasn't
> + correctly detected during build then you should moify this variable and
> + point it to the correct binary.</para>
> +</description>
> +
> +<value type="example">/opt/mit/sbin/krb5kdc</value>
> +</samba:parameter>
> diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
> index 335c54a3abe..70fd58e35ad 100644
> --- a/lib/param/loadparm.c
> +++ b/lib/param/loadparm.c
> @@ -2696,6 +2696,11 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
> lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
> lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
> "%s/samba_kcc", dyn_SCRIPTSBINDIR);
> +#ifdef MIT_KDC_PATH
> + lpcfg_do_global_parameter_var(lp_ctx,
> + "mit kdc command",
> + MIT_KDC_PATH);
> +#endif
> lpcfg_do_global_parameter(lp_ctx, "template shell", "/bin/false");
> lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%D/%U");
>
> diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
> index c65e613feea..05c825cf2f2 100644
> --- a/source3/param/loadparm.c
> +++ b/source3/param/loadparm.c
> @@ -897,6 +897,10 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
> Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
> TALLOC_FREE(s);
>
> +#ifdef MIT_KDC_PATH
> + Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
> +#endif
> +
> s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
> if (s == NULL) {
> smb_panic("init_globals: ENOMEM");
> --
> 2.12.0
>
>
> From 9c946e1cee2f894946f00c9f6a22663d2b34c9eb Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 8 Sep 2016 09:46:52 +0200
> Subject: [PATCH 10/49] s4-kdc: Add a MIT Kerberos KDC service
>
> This starts the krb5kdc binary shipped with MIT Kerberos.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/kdc-service-mit.c | 120 ++++++++++++++++++++++++++++++++++++++++++
> source4/kdc/kdc-service-mit.h | 27 ++++++++++
> source4/kdc/wscript_build | 50 +++++++++++-------
> 3 files changed, 179 insertions(+), 18 deletions(-)
> create mode 100644 source4/kdc/kdc-service-mit.c
> create mode 100644 source4/kdc/kdc-service-mit.h
>
> diff --git a/source4/kdc/kdc-service-mit.c b/source4/kdc/kdc-service-mit.c
> new file mode 100644
> index 00000000000..5ac191d3ba0
> --- /dev/null
> +++ b/source4/kdc/kdc-service-mit.c
> @@ -0,0 +1,120 @@
> +/*
> + Unix SMB/CIFS implementation.
> +
> + run s3 file server within Samba4
> +
> + Copyright (c) 2014 Andreas Schneider <asn at samba.org>
> +
> + 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 "talloc.h"
> +#include "tevent.h"
> +#include "system/filesys.h"
> +#include "lib/param/param.h"
> +#include "lib/util/samba_util.h"
> +#include "source4/smbd/service.h"
> +#include "source4/smbd/process_model.h"
> +#include "kdc/kdc-service-mit.h"
> +#include "dynconfig.h"
> +#include "libds/common/roles.h"
> +
> +static void mitkdc_server_done(struct tevent_req *subreq);
> +
> +/*
> + * Startup a copy of the krb5kdc as a child daemon
> + */
> +void mitkdc_task_init(struct task_server *task)
> +{
> + struct tevent_req *subreq;
> + const char * const *kdc_cmd;
> +
> + task_server_set_title(task, "task[mitkdc_parent]");
> +
> + switch (lpcfg_server_role(task->lp_ctx)) {
> + case ROLE_STANDALONE:
> + task_server_terminate(task,
> + "The KDC is not required in standalone "
> + "server configuration, terminate!",
> + false);
> + return;
> + case ROLE_DOMAIN_MEMBER:
> + task_server_terminate(task,
> + "The KDC is not required in member "
> + "server configuration",
> + false);
> + return;
> + case ROLE_ACTIVE_DIRECTORY_DC:
> + /* Yes, we want to start the KDC */
> + break;
> + }
> +
> + /* start it as a child process */
> + kdc_cmd = lpcfg_mit_kdc_command(task->lp_ctx);
> +
> + subreq = samba_runcmd_send(task,
> + task->event_ctx,
> + timeval_zero(),
> + 1, /* stdout log level */
> + 0, /* stderr log level */
> + kdc_cmd,
> + "-n", /* Don't go into background */
> +#if 0
> + "-w 2", /* Start two workers */
> +#endif
> + NULL);
> + if (subreq == NULL) {
> + DEBUG(0, ("Failed to start MIT KDC as child daemon\n"));
> +
> + task_server_terminate(task,
> + "Failed to startup mitkdc task",
> + true);
> + return;
> + }
> +
> + tevent_req_set_callback(subreq, mitkdc_server_done, task);
> +
> + DEBUG(5,("Started krb5kdc process\n"));
> +}
> +
> +/*
> + * This gets called the kdc exits.
> + */
> +static void mitkdc_server_done(struct tevent_req *subreq)
> +{
> + struct task_server *task =
> + tevent_req_callback_data(subreq,
> + struct task_server);
> + int sys_errno;
> + int ret;
> +
> + ret = samba_runcmd_recv(subreq, &sys_errno);
> + if (ret != 0) {
> + DEBUG(0, ("The MIT KDC daemon died with exit status %d\n",
> + sys_errno));
> + } else {
> + DEBUG(0,("The MIT KDC daemon exited normally\n"));
> + }
> +
> + task_server_terminate(task, "mitkdc child process exited", true);
> +}
> +
> +/* Called at MIT KRB5 startup - register ourselves as a server service */
> +NTSTATUS server_service_mitkdc_init(void);
> +
> +NTSTATUS server_service_mitkdc_init(void)
> +{
> + return register_server_service("kdc", mitkdc_task_init);
> +}
> diff --git a/source4/kdc/kdc-service-mit.h b/source4/kdc/kdc-service-mit.h
> new file mode 100644
> index 00000000000..2c06484705e
> --- /dev/null
> +++ b/source4/kdc/kdc-service-mit.h
> @@ -0,0 +1,27 @@
> +/*
> + Unix SMB/CIFS implementation.
> +
> + run s3 file server within Samba4
> +
> + Copyright (C) Andrew Tridgell 2011
> +
> + 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 _KDC_SERVICE_MIT_H
> +#define _KDC_SERVICE_MIT_H
> +
> +void mitkdc_task_init(struct task_server *task);
> +
> +#endif /* _KDC_SERVICE_MIT_H */
> diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build
> index 24d89f4c89b..e720aab01f8 100644
> --- a/source4/kdc/wscript_build
> +++ b/source4/kdc/wscript_build
> @@ -6,24 +6,38 @@ if not bld.CONFIG_SET("USING_SYSTEM_KDC"):
> else:
> kdc_include = getattr(bld.env, "CPPPATH_KDC")
>
> -bld.SAMBA_MODULE('service_kdc',
> - source='kdc-heimdal.c',
> - subsystem='service',
> - init_function='server_service_kdc_init',
> - deps='''
> - kdc
> - HDB_SAMBA4
> - WDC_SAMBA4
> - samba-hostconfig
> - com_err
> - samba_server_gensec
> - PAC_GLUE
> - KDC-GLUE
> - KDC-SERVER
> - KPASSWD-SERVICE
> - KPASSWD_GLUE
> - ''',
> - internal_module=False)
> +if bld.CONFIG_SET('SAMBA4_USES_HEIMDAL'):
> + bld.SAMBA_MODULE('service_kdc',
> + source='kdc-heimdal.c',
> + subsystem='service',
> + init_function='server_service_kdc_init',
> + deps='''
> + kdc
> + HDB_SAMBA4
> + WDC_SAMBA4
> + samba-hostconfig
> + com_err
> + samba_server_gensec
> + PAC_GLUE
> + KDC-GLUE
> + KDC-SERVER
> + KPASSWD-SERVICE
> + KPASSWD_GLUE
> + ''',
> + internal_module=False)
> +
> +if bld.CONFIG_GET('SAMBA_USES_MITKDC'):
> + bld.SAMBA_MODULE('service_kdc',
> + source='kdc-service-mit.c',
> + subsystem='service',
> + init_function='server_service_mitkdc_init',
> + deps='''
> + samba-hostconfig
> + service
> + talloc
> + UTIL_RUNCMD
> + ''',
> + internal_module=False)
>
> bld.SAMBA_LIBRARY('HDB_SAMBA4',
> source='hdb-samba4.c hdb-samba4-plugin.c',
> --
> 2.12.0
>
>
> From 90716ec367d411496b954c207dfc80b1795f02fc Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 8 Sep 2016 09:55:41 +0200
> Subject: [PATCH 11/49] s4-kdc: Add MIT KRB5 based irpc service for PAC
> validation
>
> Pair-Programmed-With: Guenther Deschner <gd at samba.org>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> Signed-off-by: Guenther Deschner <gd at samba.org>
> ---
> source4/kdc/mit_kdc_irpc.c | 190 +++++++++++++++++++++++++++++++++++++++++++++
> source4/kdc/mit_kdc_irpc.h | 20 +++++
> source4/kdc/wscript_build | 15 ++++
> 3 files changed, 225 insertions(+)
> create mode 100644 source4/kdc/mit_kdc_irpc.c
> create mode 100644 source4/kdc/mit_kdc_irpc.h
>
> diff --git a/source4/kdc/mit_kdc_irpc.c b/source4/kdc/mit_kdc_irpc.c
> new file mode 100644
> index 00000000000..63ae75e578e
> --- /dev/null
> +++ b/source4/kdc/mit_kdc_irpc.c
> @@ -0,0 +1,190 @@
> +/*
> + * Unix SMB/CIFS implementation.
> + *
> + * Copyright (c) 2015 Andreas Schneider <asn at samba.org>
> + *
> + * 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/kerberos.h"
> +#include "source4/auth/kerberos/kerberos.h"
> +#include "auth/kerberos/pac_utils.h"
> +
> +#include "librpc/gen_ndr/irpc.h"
> +#include "lib/messaging/irpc.h"
> +#include "source4/librpc/gen_ndr/ndr_irpc.h"
> +#include "source4/librpc/gen_ndr/irpc.h"
> +
> +#include "librpc/gen_ndr/ndr_krb5pac.h"
> +
> +#include "source4/smbd/process_model.h"
> +#include "lib/param/param.h"
> +
> +#include "samba_kdc.h"
> +#include "db-glue.h"
> +#include "sdb.h"
> +#include "mit_kdc_irpc.h"
> +
> +struct mit_kdc_irpc_context {
> + struct task_server *task;
> + krb5_context krb5_context;
> + struct samba_kdc_db_context *db_ctx;
> +};
> +
> +static NTSTATUS netr_samlogon_generic_logon(struct irpc_message *msg,
> + struct kdc_check_generic_kerberos *r)
> +{
> + struct PAC_Validate pac_validate;
> + DATA_BLOB pac_chksum;
> + struct PAC_SIGNATURE_DATA pac_kdc_sig;
> + struct mit_kdc_irpc_context *mki_ctx =
> + talloc_get_type(msg->private_data,
> + struct mit_kdc_irpc_context);
> + enum ndr_err_code ndr_err;
> + int code;
> + krb5_principal principal;
> + struct sdb_entry_ex sentry = {};
> + struct sdb_keys skeys;
> + unsigned int i;
> +
> + /* There is no reply to this request */
> + r->out.generic_reply = data_blob(NULL, 0);
> +
> + ndr_err = ndr_pull_struct_blob(&r->in.generic_request,
> + msg,
> + &pac_validate,
> + (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
> + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
> + return NT_STATUS_INVALID_PARAMETER;
> + }
> +
> + if (pac_validate.MessageType != NETLOGON_GENERIC_KRB5_PAC_VALIDATE) {
> + /*
> + * We don't implement any other message types - such as
> + * certificate validation - yet
> + */
> + return NT_STATUS_INVALID_PARAMETER;
> + }
> +
> + if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength)
> + || pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength
> + || pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) {
> + return NT_STATUS_INVALID_PARAMETER;
> + }
> +
> + /* PAC Checksum */
> + pac_chksum = data_blob_const(pac_validate.ChecksumAndSignature.data,
> + pac_validate.ChecksumLength);
> +
> + /* Create the krbtgt principal */
> + code = smb_krb5_make_principal(mki_ctx->krb5_context,
> + &principal,
> + lpcfg_realm(mki_ctx->task->lp_ctx),
> + "krbtgt",
> + lpcfg_realm(mki_ctx->task->lp_ctx),
> + NULL);
> + if (code != 0) {
> + DEBUG(0, ("Failed to create krbtgt@%s principal!\n",
> + lpcfg_realm(mki_ctx->task->lp_ctx)));
> + return NT_STATUS_NO_MEMORY;
> + }
> +
> + /* Get the krbtgt from the DB */
> + code = samba_kdc_fetch(mki_ctx->krb5_context,
> + mki_ctx->db_ctx,
> + principal,
> + SDB_F_GET_KRBTGT | SDB_F_DECRYPT,
> + 0,
> + &sentry);
> + krb5_free_principal(mki_ctx->krb5_context, principal);
> + if (code != 0) {
> + DEBUG(0, ("Failed to fetch krbtgt@%s principal entry!\n",
> + lpcfg_realm(mki_ctx->task->lp_ctx)));
> + return NT_STATUS_LOGON_FAILURE;
> + }
> +
> + /* PAC Signature */
> + pac_kdc_sig.type = pac_validate.SignatureType;
> + pac_kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength],
> + pac_validate.SignatureLength);
> +
> + /*
> + * Brute force variant because MIT KRB5 doesn't provide a function like
> + * krb5_checksum_to_enctype().
> + */
> + skeys = sentry.entry.keys;
> +
> + for (i = 0; i < skeys.len; i++) {
> + krb5_keyblock krbtgt_keyblock = skeys.val[i].key;
> +
> + code = check_pac_checksum(pac_chksum,
> + &pac_kdc_sig,
> + mki_ctx->krb5_context,
> + &krbtgt_keyblock);
> + if (code == 0) {
> + break;
> + }
> + }
> +
> + sdb_free_entry(&sentry);
> +
> + if (code != 0) {
> + return NT_STATUS_LOGON_FAILURE;
> + }
> +
> + return NT_STATUS_OK;
> +}
> +
> +NTSTATUS samba_setup_mit_kdc_irpc(struct task_server *task)
> +{
> + struct samba_kdc_base_context base_ctx;
> + struct mit_kdc_irpc_context *mki_ctx;
> + NTSTATUS status;
> + int code;
> +
> + mki_ctx = talloc_zero(task, struct mit_kdc_irpc_context);
> + mki_ctx->task = task;
> +
> + base_ctx.ev_ctx = task->event_ctx;
> + base_ctx.lp_ctx = task->lp_ctx;
> +
> + /* db-glue.h */
> + status = samba_kdc_setup_db_ctx(mki_ctx,
> + &base_ctx,
> + &mki_ctx->db_ctx);
> + if (!NT_STATUS_IS_OK(status)) {
> + return status;
> + }
> +
> + code = smb_krb5_init_context_basic(mki_ctx,
> + task->lp_ctx,
> + &mki_ctx->krb5_context);
> + if (code != 0) {
> + return NT_STATUS_INTERNAL_ERROR;
> + }
> +
> + status = IRPC_REGISTER(task->msg_ctx,
> + irpc,
> + KDC_CHECK_GENERIC_KERBEROS,
> + netr_samlogon_generic_logon,
> + mki_ctx);
> + if (!NT_STATUS_IS_OK(status)) {
> + return status;
> + }
> +
> + irpc_add_name(task->msg_ctx, "kdc_server");
> +
> + return status;
> +}
> diff --git a/source4/kdc/mit_kdc_irpc.h b/source4/kdc/mit_kdc_irpc.h
> new file mode 100644
> index 00000000000..943c76cfb38
> --- /dev/null
> +++ b/source4/kdc/mit_kdc_irpc.h
> @@ -0,0 +1,20 @@
> +/*
> + * Unix SMB/CIFS implementation.
> + *
> + * Copyright (c) 2015 Andreas Schneider <asn at samba.org>
> + *
> + * 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/>.
> + */
> +
> +NTSTATUS samba_setup_mit_kdc_irpc(struct task_server *task);
> diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build
> index e720aab01f8..c6782ea51b1 100644
> --- a/source4/kdc/wscript_build
> +++ b/source4/kdc/wscript_build
> @@ -143,6 +143,21 @@ bld.SAMBA_SUBSYSTEM('KPASSWD_GLUE',
> includes=kdc_include,
> deps='ldb com_err')
>
> +bld.SAMBA_SUBSYSTEM('MIT_KDC_IRPC',
> + source='mit_kdc_irpc.c',
> + deps='''
> + ldb
> + auth4_sam
> + auth_sam_reply
> + samba-credentials
> + db-glue
> + samba-hostconfig
> + com_err
> + kdb5
> + ''',
> + enabled=(bld.CONFIG_SET('SAMBA_USES_MITKDC') and bld.CONFIG_SET('HAVE_KDB_H'))
> + )
> +
> bld.SAMBA_SUBSYSTEM('MIT_SAMBA',
> source='mit_samba.c',
> deps='''
> --
> 2.12.0
>
>
> From 6a727d512cd1e2b7a71eef0b338408c59c4e83fb Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 8 Sep 2016 09:56:37 +0200
> Subject: [PATCH 12/49] s4-kdc: Register the MIT irpc PAC validation service
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/kdc-service-mit.c | 12 ++++++++++++
> source4/kdc/wscript_build | 1 +
> 2 files changed, 13 insertions(+)
>
> diff --git a/source4/kdc/kdc-service-mit.c b/source4/kdc/kdc-service-mit.c
> index 5ac191d3ba0..10b9e5f0e82 100644
> --- a/source4/kdc/kdc-service-mit.c
> +++ b/source4/kdc/kdc-service-mit.c
> @@ -31,6 +31,8 @@
> #include "dynconfig.h"
> #include "libds/common/roles.h"
>
> +#include "source4/kdc/mit_kdc_irpc.h"
> +
> static void mitkdc_server_done(struct tevent_req *subreq);
>
> /*
> @@ -40,6 +42,7 @@ void mitkdc_task_init(struct task_server *task)
> {
> struct tevent_req *subreq;
> const char * const *kdc_cmd;
> + NTSTATUS status;
>
> task_server_set_title(task, "task[mitkdc_parent]");
>
> @@ -87,6 +90,15 @@ void mitkdc_task_init(struct task_server *task)
> tevent_req_set_callback(subreq, mitkdc_server_done, task);
>
> DEBUG(5,("Started krb5kdc process\n"));
> +
> + status = samba_setup_mit_kdc_irpc(task);
> + if (!NT_STATUS_IS_OK(status)) {
> + task_server_terminate(task,
> + "Failed to setup kdc irpc service",
> + true);
> + }
> +
> + DEBUG(5,("Started irpc service for kdc_server\n"));
> }
>
> /*
> diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build
> index c6782ea51b1..84c5d88b830 100644
> --- a/source4/kdc/wscript_build
> +++ b/source4/kdc/wscript_build
> @@ -36,6 +36,7 @@ if bld.CONFIG_GET('SAMBA_USES_MITKDC'):
> service
> talloc
> UTIL_RUNCMD
> + MIT_KDC_IRPC
> ''',
> internal_module=False)
>
> --
> 2.12.0
>
>
> From 30866a3f093b6271488ae538d1221e559d5c4958 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 7 Oct 2015 14:36:57 +0200
> Subject: [PATCH 13/49] param: Add 'mit kdc config' option to smb.conf
>
> This points to the kdc config file created by Samba by default.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> docs-xml/smbdotconf/security/mitkdccommand.xml | 12 ++++++++++++
> source4/kdc/kdc-service-mit.c | 7 +++++++
> 2 files changed, 19 insertions(+)
>
> diff --git a/docs-xml/smbdotconf/security/mitkdccommand.xml b/docs-xml/smbdotconf/security/mitkdccommand.xml
> index 2c7601fb5f5..a1876f5fa54 100644
> --- a/docs-xml/smbdotconf/security/mitkdccommand.xml
> +++ b/docs-xml/smbdotconf/security/mitkdccommand.xml
> @@ -13,3 +13,15 @@
>
> <value type="example">/opt/mit/sbin/krb5kdc</value>
> </samba:parameter>
> +
> +<samba:parameter name="mit kdc config"
> + context="G"
> + type="string"
> + advanced="1"
> + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> +<description>
> + <para>This option specifies the path to the MIT KDC config file.</para>
> +</description>
> +
> +<value type="example">/etc/samba/kdc.conf</value>
> +</samba:parameter>
> diff --git a/source4/kdc/kdc-service-mit.c b/source4/kdc/kdc-service-mit.c
> index 10b9e5f0e82..a1cdd3a4471 100644
> --- a/source4/kdc/kdc-service-mit.c
> +++ b/source4/kdc/kdc-service-mit.c
> @@ -42,6 +42,7 @@ void mitkdc_task_init(struct task_server *task)
> {
> struct tevent_req *subreq;
> const char * const *kdc_cmd;
> + const char *kdc_config;
> NTSTATUS status;
>
> task_server_set_title(task, "task[mitkdc_parent]");
> @@ -64,6 +65,12 @@ void mitkdc_task_init(struct task_server *task)
> break;
> }
>
> + kdc_config = lpcfg_mit_kdc_config(task->lp_ctx, task);
> + if (kdc_config != NULL && kdc_config[0] != '\0') {
> + /* Do not overwrite the variable if already set! */
> + setenv("KRB5_KDC_PROFILE", kdc_config, 0);
> + }
> +
> /* start it as a child process */
> kdc_cmd = lpcfg_mit_kdc_command(task->lp_ctx);
>
> --
> 2.12.0
>
>
> From 61884959c78a804667472851c2bea00bd5750646 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 4 Dec 2015 08:12:03 +0100
> Subject: [PATCH 14/49] waf: Do not disable the ntvfs fileserver when we have
> MIT DC build
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> wscript | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/wscript b/wscript
> index c017c359d32..487260be3ad 100644
> --- a/wscript
> +++ b/wscript
> @@ -182,17 +182,15 @@ def configure(conf):
> conf.RECURSE('lib/socket_wrapper')
> conf.RECURSE('lib/uid_wrapper')
> if Options.options.with_ntvfs_fileserver != False:
> - if not (Options.options.without_ad_dc or Options.options.with_system_mitkrb5):
> + if not (Options.options.without_ad_dc):
> conf.DEFINE('WITH_NTVFS_FILESERVER', 1)
> if Options.options.with_ntvfs_fileserver == False:
> - if not (Options.options.without_ad_dc or Options.options.with_system_mitkrb5):
> + if not (Options.options.without_ad_dc):
> raise Utils.WafError('--without-ntvfs-fileserver conflicts with --enable-selftest while building the AD DC')
>
> if Options.options.with_ntvfs_fileserver == True:
> if Options.options.without_ad_dc:
> raise Utils.WafError('--with-ntvfs-fileserver conflicts with --without-ad-dc')
> - if Options.options.with_system_mitkrb5:
> - raise Utils.WafError('--with-ntvfs-fileserver conflicts with --with-system-mitkrb5')
> conf.DEFINE('WITH_NTVFS_FILESERVER', 1)
>
> if Options.options.with_pthreadpool:
> --
> 2.12.0
>
>
> From e64530829e5d4ab887cf1046790a404358a9f44f Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 5 May 2014 13:27:58 +0200
> Subject: [PATCH 15/49] selftest: Start MIT KDC if Kerberos is from MIT
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> selftest/selftest.pl | 6 ++++++
> selftest/wscript | 3 +++
> 2 files changed, 9 insertions(+)
>
> diff --git a/selftest/selftest.pl b/selftest/selftest.pl
> index 45e0ae0451f..64dacbece8a 100755
> --- a/selftest/selftest.pl
> +++ b/selftest/selftest.pl
> @@ -49,6 +49,7 @@ my @opt_exclude = ();
> my @opt_include = ();
> my $opt_testenv = 0;
> my $opt_list = 0;
> +my $opt_mitkrb5 = 0;
> my $ldap = undef;
> my $opt_resetup_env = undef;
> my $opt_load_list = undef;
> @@ -246,6 +247,7 @@ my $result = GetOptions (
> 'bindir=s' => \$bindir,
> 'testenv' => \$opt_testenv,
> 'list' => \$opt_list,
> + 'mitkrb5' => \$opt_mitkrb5,
> 'ldap:s' => \$ldap,
> 'resetup-environment' => \$opt_resetup_env,
> 'testlist=s' => \@testlists,
> @@ -415,6 +417,10 @@ if ($opt_use_dns_faking) {
> my $target;
> my $testenv_default = "none";
>
> +if ($opt_mitkrb5 == 1) {
> + $ENV{MITKRB5} = $opt_mitkrb5;
> +}
> +
> # After this many seconds, the server will self-terminate. All tests
> # must terminate in this time, and testenv will only stay alive this
> # long
> diff --git a/selftest/wscript b/selftest/wscript
> index f35efa8e7a3..34dd7a0d1f9 100644
> --- a/selftest/wscript
> +++ b/selftest/wscript
> @@ -230,6 +230,9 @@ def cmd_testonly(opt):
> # FIXME REMOVE ME!
> env.OPTIONS += " --use-dns-faking"
>
> + if CONFIG_GET(opt, 'USING_SYSTEM_KRB5') and CONFIG_GET(opt, 'MIT_KDC_PATH'):
> + env.OPTIONS += " --mitkrb5"
> +
> if not CONFIG_GET(opt, 'HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X'):
> # older MIT krb5 libraries (< 1.14) don't have
> # GSS_KRB5_CRED_NO_CI_FLAGS_X
> --
> 2.12.0
>
>
> From 76209e8359447145ff4f4e9fba885a12bde2b622 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Tue, 20 Sep 2016 12:43:38 +0200
> Subject: [PATCH 16/49] selftest: Disable RODC tests with MIT KDC
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> selftest/skip_mit_kdc | 3 +++
> selftest/wscript | 2 +-
> 2 files changed, 4 insertions(+), 1 deletion(-)
> create mode 100644 selftest/skip_mit_kdc
>
> diff --git a/selftest/skip_mit_kdc b/selftest/skip_mit_kdc
> new file mode 100644
> index 00000000000..b0c901514d5
> --- /dev/null
> +++ b/selftest/skip_mit_kdc
> @@ -0,0 +1,3 @@
> +# We do not support RODC yet
> +.*rodc
> +.*RODC
> diff --git a/selftest/wscript b/selftest/wscript
> index 34dd7a0d1f9..2299195428f 100644
> --- a/selftest/wscript
> +++ b/selftest/wscript
> @@ -231,7 +231,7 @@ def cmd_testonly(opt):
> env.OPTIONS += " --use-dns-faking"
>
> if CONFIG_GET(opt, 'USING_SYSTEM_KRB5') and CONFIG_GET(opt, 'MIT_KDC_PATH'):
> - env.OPTIONS += " --mitkrb5"
> + env.OPTIONS += " --mitkrb5 --exclude=${srcdir}/selftest/skip_mit_kdc"
>
> if not CONFIG_GET(opt, 'HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X'):
> # older MIT krb5 libraries (< 1.14) don't have
> --
> 2.12.0
>
>
> From 646cd4dec554bda234ca00d4753414e06e212feb Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 30 Apr 2014 09:32:49 +0200
> Subject: [PATCH 17/49] selftest: Setup configs for MIT KDC
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> selftest/target/Samba.pm | 49 +++++++++++++++++++++++++++++++++++++++++++++++
> selftest/target/Samba4.pm | 8 ++++++++
> 2 files changed, 57 insertions(+)
>
> diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
> index e5c7f93fe03..fa1fc7633b3 100644
> --- a/selftest/target/Samba.pm
> +++ b/selftest/target/Samba.pm
> @@ -274,6 +274,55 @@ sub mk_realms_stanza($$$$)
> return $realms_stanza;
> }
>
> +sub mk_mitkdc_conf($$)
> +{
> + # samba_kdb_dir is the path to mit_samba.so
> + my ($ctx, $samba_kdb_dir) = @_;
> +
> + unless (open(KDCCONF, ">$ctx->{mitkdc_conf}")) {
> + warn("can't open $ctx->{mitkdc_conf}$?");
> + return undef;
> + }
> +
> + print KDCCONF "
> +# Generated kdc.conf for $ctx->{realm}
> +
> +[kdcdefaults]
> + kdc_ports = 88
> + kdc_tcp_ports = 88
> +
> +[realms]
> + $ctx->{realm} = {
> + }
> +
> + $ctx->{dnsname} = {
> + }
> +
> + $ctx->{domain} = {
> + }
> +
> +[dbmodules]
> + db_module_dir = $samba_kdb_dir
> +
> + $ctx->{realm} = {
> + db_library = samba
> + }
> +
> + $ctx->{dnsname} = {
> + db_library = samba
> + }
> +
> + $ctx->{domain} = {
> + db_library = samba
> + }
> +
> +[logging]
> + kdc = FILE:$ctx->{logdir}/mit_kdc.log
> +";
> +
> + close(KDCCONF);
> +}
> +
> sub get_interface($)
> {
> my ($netbiosname) = @_;
> diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
> index 8b5e699389b..0808eac5835 100755
> --- a/selftest/target/Samba4.pm
> +++ b/selftest/target/Samba4.pm
> @@ -123,6 +123,9 @@ sub check_or_start($$$)
>
> $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
> $ENV{KRB5CCNAME} = "$env_vars->{KRB5_CCACHE}.samba";
> + if (defined($ENV{MITKRB5})) {
> + $ENV{KRB5_KDC_PROFILE} = $env_vars->{MITKDC_CONFIG};
> + }
> $ENV{SELFTEST_WINBINDD_SOCKET_DIR} = $env_vars->{SELFTEST_WINBINDD_SOCKET_DIR};
> $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
>
> @@ -435,6 +438,7 @@ sub provision_raw_prepare($$$$$$$$$$$)
> $ctx->{smb_conf} = "$ctx->{etcdir}/smb.conf";
> $ctx->{krb5_conf} = "$ctx->{etcdir}/krb5.conf";
> $ctx->{krb5_ccache} = "$prefix_abs/krb5_ccache";
> + $ctx->{mitkdc_conf} = "$ctx->{etcdir}/mitkdc.conf";
> $ctx->{privatedir} = "$prefix_abs/private";
> $ctx->{ncalrpcdir} = "$prefix_abs/ncalrpc";
> $ctx->{lockdir} = "$prefix_abs/lockdir";
> @@ -612,6 +616,7 @@ sub provision_raw_step1($$)
> }
>
> Samba::mk_krb5_conf($ctx);
> + Samba::mk_mitkdc_conf($ctx, abs_path(Samba::bindir_path($self, "shared")));
>
> open(PWD, ">$ctx->{nsswrap_passwd}");
> if ($ctx->{unix_uid} != 0) {
> @@ -675,6 +680,7 @@ nogroup:x:65534:nobody
> my $ret = {
> KRB5_CONFIG => $ctx->{krb5_conf},
> KRB5_CCACHE => $ctx->{krb5_ccache},
> + MITKDC_CONFIG => $ctx->{mitkdc_conf},
> PIDDIR => $ctx->{piddir},
> SERVER => $ctx->{hostname},
> SERVER_IP => $ctx->{ipv4},
> @@ -1362,6 +1368,7 @@ sub provision_subdom_dc($$$)
> }
>
> Samba::mk_krb5_conf($ctx);
> + Samba::mk_mitkdc_conf($ctx, abs_path(Samba::bindir_path($self, "shared")));
>
> my $samba_tool = Samba::bindir_path($self, "samba-tool");
> my $cmd = "";
> @@ -1669,6 +1676,7 @@ sub provision_rodc($$$)
> $ctx->{kdc_ipv4} = $ret->{SERVER_IP};
> $ctx->{kdc_ipv6} = $ret->{SERVER_IPV6};
> Samba::mk_krb5_conf($ctx);
> + Samba::mk_mitkdc_conf($ctx, abs_path(Samba::bindir_path($self, "shared")));
>
> $ret->{RODC_DC_SERVER} = $ret->{SERVER};
> $ret->{RODC_DC_SERVER_IP} = $ret->{SERVER_IP};
> --
> 2.12.0
>
>
> From e3bfbbbbb36ce8e0529d9ae9709000977d5eb8b9 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 26 Sep 2016 18:51:33 +0200
> Subject: [PATCH 18/49] selftest: Set clowskew grace time to 1 second
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> selftest/target/Samba.pm | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
> index fa1fc7633b3..ebffa027bc8 100644
> --- a/selftest/target/Samba.pm
> +++ b/selftest/target/Samba.pm
> @@ -201,6 +201,9 @@ sub mk_krb5_conf($$)
> ticket_lifetime = 24h
> forwardable = yes
> allow_weak_crypto = yes
> + # Set the grace clocskew to 1 second
> + # This is especially required by samba3.raw.session krb5
> + clockskew = 1
>
> ";
>
> --
> 2.12.0
>
>
> From aa9c489c34006f9a6877799e74a1b3616b91f5af Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
> Date: Sat, 7 Feb 2015 12:48:54 +0100
> Subject: [PATCH 19/49] s4-torture: disable s4u2self/proxy remote pac tests for
> MIT build for now.
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> Guenther
>
> Signed-off-by: Günther Deschner <gd at samba.org>
> ---
> source4/torture/rpc/remote_pac.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c
> index 091309874fe..9fca10f1b08 100644
> --- a/source4/torture/rpc/remote_pac.c
> +++ b/source4/torture/rpc/remote_pac.c
> @@ -616,6 +616,7 @@ static bool test_PACVerify_workstation_des(struct torture_context *tctx,
>
>
> /* Check various ways to get the PAC, in particular check the group membership and other details between the PAC from a normal kinit, S2U4Self and a SamLogon */
> +#ifdef SAMBA4_USES_HEIMDAL
> static bool test_S2U4Self(struct torture_context *tctx,
> struct dcerpc_pipe *p1,
> struct cli_credentials *credentials,
> @@ -929,6 +930,7 @@ static bool test_S2U4Self_workstation_aes(struct torture_context *tctx,
> TEST_MACHINE_NAME_S2U4SELF_WKSTA,
> NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES);
> }
> +#endif
>
> struct torture_suite *torture_rpc_remote_pac(TALLOC_CTX *mem_ctx)
> {
> @@ -954,7 +956,7 @@ struct torture_suite *torture_rpc_remote_pac(TALLOC_CTX *mem_ctx)
> tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon-member-des",
> &ndr_table_netlogon, TEST_MACHINE_NAME_WKSTA_DES);
> torture_rpc_tcase_add_test_join(tcase, "verify-sig", test_PACVerify_workstation_des);
> -
> +#ifdef SAMBA4_USES_HEIMDAL
> tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netr-bdc-arcfour",
> &ndr_table_netlogon, TEST_MACHINE_NAME_S2U4SELF_BDC);
> torture_rpc_tcase_add_test_creds(tcase, "s2u4self-arcfour", test_S2U4Self_bdc_arcfour);
> @@ -970,6 +972,6 @@ struct torture_suite *torture_rpc_remote_pac(TALLOC_CTX *mem_ctx)
> tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netr-mem-aes",
> &ndr_table_netlogon, TEST_MACHINE_NAME_S2U4SELF_WKSTA);
> torture_rpc_tcase_add_test_creds(tcase, "s2u4self-aes", test_S2U4Self_workstation_aes);
> -
> +#endif
> return suite;
> }
> --
> 2.12.0
>
>
> From c5553971a2b3501684a3321ffee8610981140cbb Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 22 Apr 2015 15:19:10 +0200
> Subject: [PATCH 20/49] testprogs: Fix test_chgdcpass blackbox test with MIT
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> testprogs/blackbox/test_chgdcpass.sh | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/testprogs/blackbox/test_chgdcpass.sh b/testprogs/blackbox/test_chgdcpass.sh
> index 120f0024cff..3830cb4e31d 100755
> --- a/testprogs/blackbox/test_chgdcpass.sh
> +++ b/testprogs/blackbox/test_chgdcpass.sh
> @@ -25,7 +25,9 @@ samba4bindir="$BINDIR"
> samba4srcdir="$SRCDIR/source4"
>
> samba4kinit=kinit
> +heimdal=0
> if test -x $BINDIR/samba4kinit; then
> + heimdal=1
> samba4kinit=bin/samba4kinit
> fi
>
> @@ -59,7 +61,12 @@ enctype="-e $ENCTYPE"
> KRB5CCNAME="$PREFIX/tmpccache"
> export KRB5CCNAME
> rm -f $KRB5CCNAME
> -testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.keytab --use-keytab $USERNAME || failed=`expr $failed + 1`
> +
> +if [ $heimdal -eq 1 ]; then
> + testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.keytab --use-keytab $USERNAME || failed=`expr $failed + 1`
> +else
> + testit "kinit with keytab" $samba4kinit -k -t $PROVDIR/private/secrets.keytab $USERNAME || failed=`expr $failed + 1`
> +fi
>
> #This is important because it puts the ticket for the old KVNO and password into a local ccache
> test_smbclient "Test login with kerberos ccache before password change" 'ls' "$unc" -k yes || failed=`expr $failed + 1`
> @@ -94,8 +101,13 @@ test_drs bind "Test drs bind after 2nd password change" || failed=`expr $failed
> test_drs options "Test drs options after 2nd password change" || failed=`expr $failed + 1`
>
> #This confirms that the DC password is valid for a kinit too
> -testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.keytab --use-keytab $USERNAME || failed=`expr $failed + 1`
> +if [ $heimdal -eq 1 ]; then
> + testit "kinit with keytab" $samba4kinit $enctype -t $PROVDIR/private/secrets.keytab --use-keytab $USERNAME || failed=`expr $failed + 1`
> +else
> + testit "kinit with keytab" $samba4kinit -k -t $PROVDIR/private/secrets.keytab $USERNAME || failed=`expr $failed + 1`
> +fi
> test_smbclient "Test login with kerberos ccache with fresh kinit" 'ls' "$unc" -k yes || failed=`expr $failed + 1`
> +
> rm -f $KRB5CCNAME
>
> rm -f $PREFIX/tmpccache tmpccfile tmppassfile tmpuserpassfile tmpuserccache tmpkpasswdscript
> --
> 2.12.0
>
>
> From c6cc25353bf5f088d2e57ae6b0852118e6ff37b4 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 22 Apr 2015 15:39:45 +0200
> Subject: [PATCH 21/49] testprogs: Fix usage printout of bogus blackbox test
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> testprogs/blackbox/bogus.sh | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/testprogs/blackbox/bogus.sh b/testprogs/blackbox/bogus.sh
> index be67e1992e7..3056b538aee 100755
> --- a/testprogs/blackbox/bogus.sh
> +++ b/testprogs/blackbox/bogus.sh
> @@ -2,7 +2,7 @@
>
> if [ $# -lt 1 ]; then
> cat <<EOF
> -Usage: blackbox_newuser.sh PREFIX
> +Usage: bogus.sh SERVER SHARE USER PASSWORD DC_USER DC_PASSWORD SMBCLIENT
> EOF
> exit 1;
> fi
> --
> 2.12.0
>
>
> From 1a0d7d150c3f15f5af1dc3d13c7f017310505065 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 22 Apr 2015 12:00:21 +0200
> Subject: [PATCH 22/49] s4-torture: Fix kinit of samba4.blackbox.locktest
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/torture/tests/test_locktest.sh | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/source4/torture/tests/test_locktest.sh b/source4/torture/tests/test_locktest.sh
> index c4368363536..95fc7ffc275 100755
> --- a/source4/torture/tests/test_locktest.sh
> +++ b/source4/torture/tests/test_locktest.sh
> @@ -23,6 +23,6 @@ locktest="$samba4bindir/locktest"
>
> . `dirname $0`/../../../testprogs/blackbox/subunit.sh
>
> -testit "locktest" $VALGRIND $locktest //$SERVER/test1 //$SERVER/test2 --num-ops=100 -W "$DOMAIN" -U"$USERNAME%$PASSWORD" $@ || failed=`expr $failed + 1`
> +testit "locktest" $VALGRIND $locktest //$SERVER/test1 //$SERVER/test2 --num-ops=100 -W "$DOMAIN" -U"$DOMAIN\\$USERNAME%$PASSWORD" $@ || failed=`expr $failed + 1`
>
> exit $failed
> --
> 2.12.0
>
>
> From b3b20a4eb53040f916c30c545a5afc80d8f2e8b4 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 14 Jan 2016 16:41:36 +0100
> Subject: [PATCH 23/49] testprogs: Add test_kinit_mit.sh test
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/selftest/tests.py | 4 +
> testprogs/blackbox/test_kinit_mit.sh | 310 +++++++++++++++++++++++++++++++++++
> 2 files changed, 314 insertions(+)
> create mode 100755 testprogs/blackbox/test_kinit_mit.sh
>
> diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
> index c2c5486d43e..0adac3d6bb1 100755
> --- a/source4/selftest/tests.py
> +++ b/source4/selftest/tests.py
> @@ -396,6 +396,10 @@ if have_heimdal_support:
> plantestsuite("samba4.blackbox.kinit_trust(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_kinit_trusts_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external", "arcfour-hmac-md5"])
> plantestsuite("samba4.blackbox.export.keytab(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_export_keytab_heimdal.sh"), '$SERVER', '$USERNAME', '$REALM', '$DOMAIN', "$PREFIX", smbclient4])
> plantestsuite("samba4.blackbox.kpasswd(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_kpasswd_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', "$PREFIX/ad_dc_ntvfs"])
> +else:
> + plantestsuite("samba4.blackbox.kinit(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_kinit_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', smbclient4, configuration])
> + plantestsuite("samba4.blackbox.kinit(fl2000dc:local)", "fl2000dc:local", [os.path.join(bbdir, "test_kinit_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', smbclient4, configuration])
> + plantestsuite("samba4.blackbox.kinit(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_kinit_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', smbclient4, configuration])
>
> plantestsuite("samba4.blackbox.trust_utils(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_trust_utils.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "forest"])
> plantestsuite("samba4.blackbox.trust_utils(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_trust_utils.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external"])
> diff --git a/testprogs/blackbox/test_kinit_mit.sh b/testprogs/blackbox/test_kinit_mit.sh
> new file mode 100755
> index 00000000000..3e07281b8c7
> --- /dev/null
> +++ b/testprogs/blackbox/test_kinit_mit.sh
> @@ -0,0 +1,310 @@
> +#!/bin/sh
> +# Blackbox tests for kinit and kerberos integration with smbclient etc
> +# Copyright (c) 2015-2016 Andreas Schneider <asn at samba.org>
> +
> +if [ $# -lt 5 ]; then
> +cat <<EOF
> +Usage: test_kinit.sh SERVER USERNAME PASSWORD REALM DOMAIN PREFIX SMBCLIENT
> +EOF
> +exit 1;
> +fi
> +
> +SERVER=$1
> +USERNAME=$2
> +PASSWORD=$3
> +REALM=$4
> +DOMAIN=$5
> +PREFIX=$6
> +smbclient=$7
> +shift 7
> +failed=0
> +
> +samba_bindir="$BINDIR"
> +samba_srcdir="$SRCDIR/source4"
> +samba_kinit=kinit
> +samba_kdestroy=kdestroy
> +samba_kpasswd=kpasswd
> +
> +samba_tool="$samba_bindir/samba-tool"
> +samba_texpect="$samba_bindir/texpect"
> +
> +samba_enableaccount="$samba_tool user enable"
> +machineaccountccache="$samba_srcdir/scripting/bin/machineaccountccache"
> +
> +ldbmodify="ldbmodify"
> +if [ -x "$samba4bindir/ldbmodify" ]; then
> + ldbmodify="$samba4bindir/ldbmodify"
> +fi
> +
> +ldbsearch="ldbsearch"
> +if [ -x "$samba4bindir/ldbsearch" ]; then
> + ldbsearch="$samba4bindir/ldbsearch"
> +fi
> +
> +. `dirname $0`/subunit.sh
> +
> +test_smbclient() {
> + name="$1"
> + cmd="$2"
> + shift
> + shift
> + echo "test: $name"
> + $VALGRIND $smbclient $CONFIGURATION //$SERVER/tmp -c "$cmd" $@
> + status=$?
> + if [ x$status = x0 ]; then
> + echo "success: $name"
> + else
> + echo "failure: $name"
> + fi
> + return $status
> +}
> +
> +ADMIN_LDBMODIFY_CONFIG="-H ldap://$SERVER -U$USERNAME%$PASSWORD"
> +export ADMIN_LDBMODIFY_CONFIG
> +
> +KRB5CCNAME_PATH="$PREFIX/tmpccache"
> +KRB5CCNAME="FILE:$KRB5CCNAME_PATH"
> +ADMIN_KRB5CCNAME="FILE:$KRB5CCNAME_PATH"
> +export KRB5CCNAME
> +rm -rf $KRB5CCNAME_PATH
> +
> +testit "reset password policies beside of minimum password age of 0 days" $VALGRIND $samba_tool domain passwordsettings $ADMIN_LDBMODIFY_CONFIG set --complexity=default --history-length=default --min-pwd-length=default --min-pwd-age=0 --max-pwd-age=default || failed=`expr $failed + 1`
> +
> +cat > $PREFIX/tmpkinitscript <<EOF
> +expect Password for
> +send ${PASSWORD}\n
> +EOF
> +
> +###########################################################
> +### Test kinit defaults
> +###########################################################
> +
> +testit "kinit with password" $samba_texpect $PREFIX/tmpkinitscript $samba_kinit $USERNAME@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +testit "kinit renew ticket" $samba_kinit -R || failed=`expr $failed + 1`
> +test_smbclient "Test login with kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +###########################################################
> +### Test kinit with enterprice principal
> +###########################################################
> +
> +testit "kinit with password (enterprise style)" $samba_texpect $PREFIX/tmpkinitscript $samba_kinit -E $USERNAME@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +# This does not work with MIT Kerberos 1.14 or older
> +testit "kinit renew ticket (enterprise style)" $samba_kinit -R || failed=`expr $failed + 1`
> +test_smbclient "Test login with kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +###########################################################
> +### Tests with kinit default again
> +###########################################################
> +
> +testit "kinit with password" $samba_texpect $PREFIX/tmpkinitscript $samba_kinit $USERNAME@$REALM || failed=`expr $failed + 1`
> +testit "check time with kerberos ccache" $VALGRIND $samba_tool time $SERVER $CONFIGURATION -k yes $@ || failed=`expr $failed + 1`
> +
> +USERPASS="testPass at 12%"
> +
> +testit "add user with kerberos ccache" $VALGRIND $samba_tool user create nettestuser $USERPASS $CONFIGURATION -k yes $@ || failed=`expr $failed + 1`
> +
> +echo "Getting defaultNamingContext"
> +BASEDN=`$ldbsearch $options --basedn='' -H ldap://$SERVER -s base DUMMY=x defaultNamingContext | grep defaultNamingContext | awk '{print $2}'`
> +
> +cat > $PREFIX/tmpldbmodify <<EOF
> +dn: cn=nettestuser,cn=users,$BASEDN
> +changetype: modify
> +add: servicePrincipalName
> +servicePrincipalName: host/nettestuser
> +replace: userPrincipalName
> +userPrincipalName: nettest@$REALM
> +EOF
> +
> +testit "modify servicePrincipalName and userPrincpalName" $VALGRIND $ldbmodify -H ldap://$SERVER $PREFIX/tmpldbmodify -k yes $@ || failed=`expr $failed + 1`
> +
> +testit "set user password with kerberos ccache" $VALGRIND $samba_tool user setpassword nettestuser --newpassword=$USERPASS $CONFIGURATION -k yes $@ || failed=`expr $failed + 1`
> +
> +testit "enable user with kerberos cache" $VALGRIND $samba_enableaccount nettestuser -H ldap://$SERVER -k yes $@ || failed=`expr $failed + 1`
> +
> +###########################################################
> +### Test kinit with user credentials
> +###########################################################
> +
> +KRB5CCNAME_PATH="$PREFIX/tmpuserccache"
> +KRB5CCNAME="FILE:$KRB5CCNAME_PATH"
> +export KRB5CCNAME
> +
> +rm -f $KRB5CCNAME_PATH
> +
> +cat > $PREFIX/tmpkinituserpassscript <<EOF
> +expect Password for
> +send ${USERPASS}\n
> +EOF
> +
> +testit "kinit with user password" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit nettestuser@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +### Change password
> +
> +NEWUSERPASS="testPaSS at 34%"
> +testit "change user password with 'samba-tool user password' (rpc)" $VALGRIND $samba_tool user password -W$DOMAIN -Unettestuser%$USERPASS $CONFIGURATION -k no --newpassword=$NEWUSERPASS $@ || failed=`expr $failed + 1`
> +
> +cat > $PREFIX/tmpkinituserpassscript <<EOF
> +expect Password for
> +send ${NEWUSERPASS}\n
> +EOF
> +
> +testit "kinit with new user password" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit nettestuser@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +###########################################################
> +### Test kinit with user credentials in special formats
> +###########################################################
> +
> +testit "kinit with new (NT-Principal style) using UPN" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit nettest@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache from NT UPN" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +testit "kinit with new (enterprise style) using UPN" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit -E nettest@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache from enterprise UPN" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +###########################################################
> +### Test kinit with user credentials and changed realm
> +###########################################################
> +
> +cat > $PREFIX/tmpldbmodify <<EOF
> +dn: cn=nettestuser,cn=users,$BASEDN
> +changetype: modify
> +replace: userPrincipalName
> +userPrincipalName: nettest@$REALM.org
> +EOF
> +
> +testit "modify userPrincipalName to be a different domain" $VALGRIND $ldbmodify $ADMIN_LDBMODIFY_CONFIG $PREFIX/tmpldbmodify $PREFIX/tmpldbmodify -k yes $@ || failed=`expr $failed + 1`
> +
> +testit "kinit with new (enterprise style) using UPN" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit -E nettest@$REALM.org || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache from enterprise UPN" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +###########################################################
> +### Test password change with kpasswd
> +###########################################################
> +
> +testit "kinit with user password" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit nettestuser@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +USERPASS=$NEWUSERPASS
> +NEWUSERPASS=testPaSS at 56%
> +
> +cat > $PREFIX/tmpkpasswdscript <<EOF
> +expect Password for
> +password ${USERPASS}\n
> +expect Enter new password
> +send ${NEWUSERPASS}\n
> +expect Enter it again
> +send ${NEWUSERPASS}\n
> +expect Password changed
> +EOF
> +
> +testit "change user password with kpasswd" $samba_texpect $PREFIX/tmpkpasswdscript $samba_kpasswd nettestuser@$REALM || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +USERPASS=$NEWUSERPASS
> +cat > $PREFIX/tmpkinituserpassscript <<EOF
> +expect Password for
> +send ${USERPASS}\n
> +EOF
> +
> +testit "kinit with user password" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit nettestuser@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +###########################################################
> +### TODO Test set password with kpasswd
> +###########################################################
> +
> +# This is not implemented in kpasswd
> +
> +###########################################################
> +### Test password expiry
> +###########################################################
> +
> +cat > $PREFIX/tmpldbmodify <<EOF
> +dn: cn=nettestuser,cn=users,$BASEDN
> +changetype: modify
> +replace: pwdLastSet
> +pwdLastSet: 0
> +EOF
> +
> +USERPASS=$NEWUSERPASS
> +NEWUSERPASS=testPaSS at 911%
> +
> +testit "modify pwdLastSet" $VALGRIND $ldbmodify $ADMIN_LDBMODIFY_CONFIG $PREFIX/tmpldbmodify $PREFIX/tmpldbmodify -k yes $@ || failed=`expr $failed + 1`
> +
> +cat > $PREFIX/tmpkinituserpassscript <<EOF
> +expect Password for
> +send ${USERPASS}\n
> +expect Password expired. You must change it now.
> +expect Enter new password
> +send ${NEWUSERPASS}\n
> +expect Enter it again
> +send ${NEWUSERPASS}\n
> +EOF
> +
> +testit "kinit (MIT) with user password for expired password" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit nettestuser@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +USERPASS=$NEWUSERPASS
> +cat > $PREFIX/tmpkinituserpassscript <<EOF
> +expect Password for
> +send ${USERPASS}\n
> +EOF
> +
> +testit "kinit with user password" $samba_texpect $PREFIX/tmpkinituserpassscript $samba_kinit nettestuser@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +###########################################################
> +### Test login with lowercase realm
> +###########################################################
> +
> +KRB5CCNAME_PATH="$PREFIX/tmpccache"
> +KRB5CCNAME="FILE:$KRB5CCNAME_PATH"
> +export KRB5CCNAME
> +
> +rm -rf $KRB5CCNAME_PATH
> +
> +lowerrealm=$(echo $REALM | tr '[A-Z]' '[a-z]')
> +test_smbclient "Test login with user kerberos lowercase realm" 'ls' -k yes -Unettestuser@$lowerrealm%$NEWUSERPASS || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos lowercase realm 2" 'ls' -k yes -Unettestuser@$REALM%$NEWUSERPASS --realm=$lowerrealm || failed=`expr $failed + 1`
> +
> +testit "del user with kerberos ccache" $VALGRIND $samba_tool user delete nettestuser $CONFIGURATION -k yes $@ || failed=`expr $failed + 1`
> +
> +###########################################################
> +### Test login with machine account
> +###########################################################
> +
> +rm -f $KRB5CCNAME_PATH
> +testit "kinit with machineaccountccache script" $machineaccountccache $CONFIGURATION $KRB5CCNAME || failed=`expr $failed + 1`
> +test_smbclient "Test machine account login with kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +testit "reset password policies" $VALGRIND $samba_tool domain passwordsettings $ADMIN_LDBMODIFY_CONFIG set --complexity=default --history-length=default --min-pwd-length=default --min-pwd-age=default --max-pwd-age=default || failed=`expr $failed + 1`
> +
> +### Cleanup
> +
> +$samba_kdestroy
> +
> +rm -f $KRB5CCNAME_PATH
> +rm -f $PREFIX/tmpkinituserpassscript
> +rm -f $PREFIX/tmpkinitscript
> +
> +exit $failed
> --
> 2.12.0
>
>
> From a1826448187d3df69cd7d3eca1ec07f0152a1280 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 15 Feb 2016 08:22:58 +0100
> Subject: [PATCH 24/49] testprogs: Add a kinit trust test for MIT KDC
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/selftest/tests.py | 3 +
> testprogs/blackbox/test_kinit_trusts_mit.sh | 139 ++++++++++++++++++++++++++++
> 2 files changed, 142 insertions(+)
> create mode 100755 testprogs/blackbox/test_kinit_trusts_mit.sh
>
> diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
> index 0adac3d6bb1..6e52d6d2f7f 100755
> --- a/source4/selftest/tests.py
> +++ b/source4/selftest/tests.py
> @@ -401,6 +401,9 @@ else:
> plantestsuite("samba4.blackbox.kinit(fl2000dc:local)", "fl2000dc:local", [os.path.join(bbdir, "test_kinit_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', smbclient4, configuration])
> plantestsuite("samba4.blackbox.kinit(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_kinit_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', smbclient4, configuration])
>
> + plantestsuite("samba4.blackbox.kinit_trust(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_kinit_trusts_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "forest"])
> + plantestsuite("samba4.blackbox.kinit_trust(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_kinit_trusts_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external"])
> +
> plantestsuite("samba4.blackbox.trust_utils(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_trust_utils.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "forest"])
> plantestsuite("samba4.blackbox.trust_utils(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_trust_utils.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external"])
> plantestsuite("samba4.blackbox.ktpass(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(bbdir, "test_ktpass.sh"), '$PREFIX/ad_dc_ntvfs'])
> diff --git a/testprogs/blackbox/test_kinit_trusts_mit.sh b/testprogs/blackbox/test_kinit_trusts_mit.sh
> new file mode 100755
> index 00000000000..6696f441363
> --- /dev/null
> +++ b/testprogs/blackbox/test_kinit_trusts_mit.sh
> @@ -0,0 +1,139 @@
> +#!/bin/sh
> +# Blackbox tests for kinit and trust validation
> +# Copyright (c) 2015 Stefan Metzmacher <metze at samba.org>
> +# Copyright (c) 2016 Andreas Schneider <asn at samba.org>
> +
> +if [ $# -lt 5 ]; then
> +cat <<EOF
> +Usage: test_kinit_trusts.sh SERVER USERNAME PASSWORD REALM DOMAIN TRUST_USERNAME TRUST_PASSWORD TRUST_REALM TRUST_DOMAIN PREFIX TYPE
> +EOF
> +exit 1;
> +fi
> +
> +SERVER=$1
> +USERNAME=$2
> +PASSWORD=$3
> +REALM=$4
> +DOMAIN=$5
> +shift 5
> +TRUST_SERVER=$1
> +TRUST_USERNAME=$2
> +TRUST_PASSWORD=$3
> +TRUST_REALM=$4
> +TRUST_DOMAIN=$5
> +shift 5
> +PREFIX=$1
> +TYPE=$2
> +shift 2
> +
> +failed=0
> +
> +samba_bindir="$BINDIR"
> +samba_srcdir="$SRCDIR/source4"
> +samba_kinit=kinit
> +samba_kdestroy=kdestroy
> +samba_kpasswd=kpasswd
> +
> +samba_tool="$samba_bindir/samba-tool"
> +samba_texpect="$samba_bindir/texpect"
> +
> +smbclient="$samba_bindir/smbclient"
> +wbinfo="$samba_bindir/wbinfo"
> +rpcclient="$samba_bindir/rpcclient"
> +
> +SMBCLIENT_UNC="//$SERVER.$REALM/tmp"
> +
> +. `dirname $0`/subunit.sh
> +
> +test_smbclient() {
> + name="$1"
> + cmd="$2"
> + shift
> + shift
> + echo "test: $name"
> + $VALGRIND $smbclient $CONFIGURATION $SMBCLIENT_UNC -c "$cmd" $@
> + status=$?
> + if [ x$status = x0 ]; then
> + echo "success: $name"
> + else
> + echo "failure: $name"
> + fi
> + return $status
> +}
> +
> +KRB5CCNAME_PATH="$PREFIX/test_kinit_trusts_ccache"
> +KRB5CCNAME="FILE:$KRB5CCNAME_PATH"
> +export KRB5CCNAME
> +rm -rf $KRB5CCNAME_PATH
> +
> +cat > $PREFIX/tmpkinitscript <<EOF
> +expect Password for
> +send ${TRUST_PASSWORD}\n
> +EOF
> +
> +###########################################################
> +### Test incoming trust direction
> +###########################################################
> +
> +testit "kinit with password" $samba_texpect $PREFIX/tmpkinitscript $samba_kinit $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +$samba_kdestroy
> +
> +smbclient="$samba_bindir/smbclient4"
> +
> +testit "kinit with password" $samba_texpect $PREFIX/tmpkinitscript $samba_kinit $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with kerberos ccache (smbclient4)" 'ls' -k yes || failed=`expr $failed + 1`
> +$samba_kdestroy
> +
> +smbclient="$samba_bindir/smbclient"
> +
> +testit "kinit with password (enterprise)" $samba_texpect $PREFIX/tmpkinitscript $samba_kinit -E $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +if test x"${TYPE}" = x"forest" ;then
> + testit "kinit with password (enterprise UPN)" $samba_texpect $PREFIX/tmpkinitscript $samba_kinit -E testdenied_upn@${TRUST_REALM}.upn || failed=`expr $failed + 1`
> + test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +fi
> +
> +$samba_kdestroy
> +
> +testit "kinit with password (enterprise)" $samba_texpect $PREFIX/tmpkinitscript $samba_kinit -E $TRUST_USERNAME@$TRUST_REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +testit "kinit renew ticket" $samba_kinit -R
> +test_smbclient "Test login with kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +
> +testit "check time with kerberos ccache" $VALGRIND $samba_tool time $SERVER.$REALM $CONFIGURATION -k yes $@ || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +
> +lowerrealm=$(echo $TRUST_REALM | tr '[A-Z]' '[a-z]')
> +test_smbclient "Test login with user kerberos lowercase realm" 'ls' -k yes -d5 -U$TRUST_USERNAME@$lowerrealm%$TRUST_PASSWORD || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos lowercase realm 2" 'ls' -k yes -U$TRUST_USERNAME@$TRUST_REALM%$TRUST_PASSWORD --realm=$lowerrealm || failed=`expr $failed + 1`
> +
> +###########################################################
> +### Test outgoing trust direction
> +###########################################################
> +
> +SMBCLIENT_UNC="//$TRUST_SERVER.$TRUST_REALM/tmp"
> +test_smbclient "Test user login with the first outgoing secret" 'ls' -k yes -U$USERNAME@$REALM%$PASSWORD || failed=`expr $failed + 1`
> +
> +testit_expect_failure "setpassword should not work" $VALGRIND $samba_tool user setpassword "${TRUST_DOMAIN}\$" --random-password || failed=`expr $failed + 1`
> +
> +testit "wbinfo ping dc" $VALGRIND $wbinfo --ping-dc --domain=$TRUST_DOMAIN || failed=`expr $failed + 1`
> +testit "wbinfo change outgoing trust pw" $VALGRIND $wbinfo --change-secret --domain=$TRUST_DOMAIN || failed=`expr $failed + 1`
> +testit "wbinfo check outgoing trust pw" $VALGRIND $wbinfo --check-secret --domain=$TRUST_DOMAIN || failed=`expr $failed + 1`
> +
> +test_smbclient "Test user login with the changed outgoing secret" 'ls' -k yes -U$USERNAME@$REALM%$PASSWORD || failed=`expr $failed + 1`
> +
> +### Cleanup
> +
> +$samba_kdestroy
> +
> +rm -f $KRB5CCNAME_PATH
> +rm -f $PREFIX/tmpkinituserpassscript
> +rm -f $PREFIX/tmpkinitscript
> +
> +exit $failed
> --
> 2.12.0
>
>
> From 6c2ecb98c4a29b54fa14087015a78dd68c6d6655 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 10 Mar 2016 14:35:23 +0100
> Subject: [PATCH 25/49] testprogs: Add test with exported keytab from
> samba-tool
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/selftest/tests.py | 2 +
> testprogs/blackbox/test_export_keytab_mit.sh | 127 +++++++++++++++++++++++++++
> 2 files changed, 129 insertions(+)
> create mode 100755 testprogs/blackbox/test_export_keytab_mit.sh
>
> diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
> index 6e52d6d2f7f..ef9c9332f74 100755
> --- a/source4/selftest/tests.py
> +++ b/source4/selftest/tests.py
> @@ -404,6 +404,8 @@ else:
> plantestsuite("samba4.blackbox.kinit_trust(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_kinit_trusts_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "forest"])
> plantestsuite("samba4.blackbox.kinit_trust(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_kinit_trusts_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external"])
>
> + plantestsuite("samba4.blackbox.export.keytab(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_export_keytab_mit.sh"), '$SERVER', '$USERNAME', '$REALM', '$DOMAIN', "$PREFIX", smbclient4])
> +
> plantestsuite("samba4.blackbox.trust_utils(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_trust_utils.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "forest"])
> plantestsuite("samba4.blackbox.trust_utils(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_trust_utils.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external"])
> plantestsuite("samba4.blackbox.ktpass(ad_dc_ntvfs)", "ad_dc_ntvfs", [os.path.join(bbdir, "test_ktpass.sh"), '$PREFIX/ad_dc_ntvfs'])
> diff --git a/testprogs/blackbox/test_export_keytab_mit.sh b/testprogs/blackbox/test_export_keytab_mit.sh
> new file mode 100755
> index 00000000000..b972cd8f1c4
> --- /dev/null
> +++ b/testprogs/blackbox/test_export_keytab_mit.sh
> @@ -0,0 +1,127 @@
> +#!/bin/sh
> +#
> +# Blackbox tests for an exported keytab with kinit
> +#
> +# Copyright (C) 2006-2007 Jelmer Vernooij <jelmer at samba.org>
> +# Copyright (C) 2006-2008 Andrew Bartlett <abartlet at samba.org>
> +# Copyright (C) 2016 Andreas Schneider <asn at cryptomilk.org>
> +
> +if [ $# -lt 5 ]; then
> +cat <<EOF
> +Usage: test_extract_keytab.sh SERVER USERNAME REALM DOMAIN PREFIX SMBCLIENT
> +EOF
> +exit 1;
> +fi
> +
> +SERVER=$1
> +USERNAME=$2
> +REALM=$3
> +DOMAIN=$4
> +PREFIX=$5
> +smbclient=$6
> +shift 6
> +failed=0
> +
> +samba_bindir="$BINDIR"
> +samba_tool="$samba_bindir/samba-tool"
> +samba_newuser="$samba_tool user create"
> +samba_texpect="$samba_bindir/texpect"
> +samba_ktutil="$BINDIR/samba4ktutil"
> +
> +samba_kinit=kinit
> +samba_kdestroy=kdestroy
> +
> +SERVER_FQDN="$SERVER.$(echo $REALM | tr '[:upper:]' '[:lower:]')"
> +
> +source `dirname $0`/subunit.sh
> +
> +test_smbclient() {
> + name="$1"
> + cmd="$2"
> + shift
> + shift
> + echo "test: $name"
> + $VALGRIND $smbclient //$SERVER/tmp -c "$cmd" $@
> + status=$?
> + if [ x$status = x0 ]; then
> + echo "success: $name"
> + else
> + echo "failure: $name"
> + fi
> + return $status
> +}
> +
> +test_keytab() {
> + testname="$1"
> + keytab="$2"
> + principal="$3"
> + expected_nkeys="$4"
> +
> + echo "test: $testname"
> +
> + NKEYS=$($VALGRIND $samba_ktutil $keytab | grep -i "$principal" | egrep -c "DES|AES|ArcFour")
> + status=$?
> + if [ x$status != x0 ]; then
> + echo "failure: $testname"
> + return $status
> + fi
> +
> + if [ x$NKEYS != x$expected_nkeys ] ; then
> + echo "failure: $testname"
> + return 1
> + fi
> + echo "success: $testname"
> + return 0
> +}
> +
> +TEST_USER=nettestuser
> +TEST_PASSWORD=testPaSS at 01%
> +
> +testit "create local user $TEST_USER" $VALGRIND $samba_newuser $TEST_USER $TEST_PASSWORD $@ || failed=`expr $failed + 1`
> +
> +testit "dump keytab from domain" $VALGRIND $samba_tool domain exportkeytab $PREFIX/tmpkeytab-all $@ || failed=`expr $failed + 1`
> +test_keytab "read keytab from domain" "$PREFIX/tmpkeytab-all" "$SERVER\\\$" 5
> +
> +testit "dump keytab from domain (2nd time)" $VALGRIND $samba_tool domain exportkeytab $PREFIX/tmpkeytab-all $@ || failed=`expr $failed + 1`
> +test_keytab "read keytab from domain (2nd time)" "$PREFIX/tmpkeytab-all" "$SERVER\\\$" 5
> +
> +testit "dump keytab from domain for cifs service principal" $VALGRIND $samba_tool domain exportkeytab $PREFIX/tmpkeytab-server --principal=cifs/$SERVER_FQDN $@ || failed=`expr $failed + 1`
> +test_keytab "read keytab from domain for cifs service principal" "$PREFIX/tmpkeytab-server" "cifs/$SERVER_FQDN" 5
> +testit "dump keytab from domain for cifs service principal (2nd time)" $VALGRIND $samba_tool domain exportkeytab $PREFIX/tmpkeytab-server --principal=cifs/$SERVER_FQDN $@ || failed=`expr $failed + 1`
> +test_keytab "read keytab from domain for cifs service principal (2nd time)" "$PREFIX/tmpkeytab-server" "cifs/$SERVER_FQDN" 5
> +
> +testit "dump keytab from domain for user principal" $VALGRIND $samba_tool domain exportkeytab $PREFIX/tmpkeytab-user-princ --principal=$TEST_USER $@ || failed=`expr $failed + 1`
> +test_keytab "dump keytab from domain for user principal" "$PREFIX/tmpkeytab-user-princ" "$TEST_USER@$REALM" 5
> +testit "dump keytab from domain for user principal (2nd time)" $VALGRIND $samba_tool domain exportkeytab $PREFIX/tmpkeytab-user-princ --principal=$TEST_USER@$REALM $@ || failed=`expr $failed + 1`
> +test_keytab "dump keytab from domain for user principal (2nd time)" "$PREFIX/tmpkeytab-user-princ" "$TEST_USER@$REALM" 5
> +
> +KRB5CCNAME="$PREFIX/tmpuserccache"
> +export KRB5CCNAME
> +
> +testit "kinit with keytab as user" $VALGRIND $samba_kinit -k -t $PREFIX/tmpkeytab-all $TEST_USER@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
> +$samba_kdestroy
> +
> +testit "kinit with keytab as user (one princ)" $VALGRIND $samba_kinit -k -t $PREFIX/tmpkeytab-user-princ $TEST_USER@$REALM || failed=`expr $failed + 1`
> +test_smbclient "Test login with user kerberos ccache (one princ)" 'ls' -k yes || failed=`expr $failed + 1`
> +$samba_kdestroy
> +
> +KRB5CCNAME="$PREFIX/tmpadminccache"
> +export KRB5CCNAME
> +
> +testit "kinit with keytab as $USERNAME" $VALGRIND $samba_kinit -k -t $PREFIX/tmpkeytab-all $USERNAME@$REALM || failed=`expr $failed + 1`
> +
> +KRB5CCNAME="$PREFIX/tmpserverccache"
> +export KRB5CCNAME
> +echo "$samba_kinit -k -t $PREFIX/tmpkeytab-server cifs/$SERVER_FQDN"
> +testit "kinit with SPN from keytab" $VALGRIND $samba_kinit -k -t $PREFIX/tmpkeytab-server cifs/$SERVER_FQDN || failed=`expr $failed + 1`
> +
> +exit 0
> +
> +# cleanup
> +testit "delete user $TEST_USER" $VALGRIND $samba_tool user delete nettestuser -k yes $@ || failed=`expr $failed + 1`
> +
> +$samba_kdestroy
> +rm -f $PREFIX/tmpadminccache $PREFIX/tmpuserccache $PREFIX/tmpkeytab $PREFIX/tmpkeytab-2 $PREFIX/tmpkeytab-server
> +
> +exit $failed
> --
> 2.12.0
>
>
> From e1d112a2e04669ef984b61a2ec72b41fdb3d6715 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 13 May 2016 09:36:34 +0200
> Subject: [PATCH 26/49] s4-torture: Add KDC test harness and first test
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/torture/krb5/kdc-mit.c | 347 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 343 insertions(+), 4 deletions(-)
>
> diff --git a/source4/torture/krb5/kdc-mit.c b/source4/torture/krb5/kdc-mit.c
> index 88bff0b0ee4..0b2b8651c79 100644
> --- a/source4/torture/krb5/kdc-mit.c
> +++ b/source4/torture/krb5/kdc-mit.c
> @@ -1,4 +1,3 @@
> -
> /*
> Unix SMB/CIFS implementation.
>
> @@ -31,13 +30,339 @@
> #include "source4/auth/kerberos/kerberos_util.h"
> #include "lib/util/util_net.h"
>
> -static bool test_skip(struct torture_context *tctx)
> +#define krb5_is_app_tag(dat,tag) \
> + ((dat != NULL) && (dat)->length && \
> + ((((dat)->data[0] & ~0x20) == ((tag) | 0x40))))
> +
> +#define krb5_is_as_req(dat) krb5_is_app_tag(dat, 10)
> +#define krb5_is_as_rep(dat) krb5_is_app_tag(dat, 11)
> +#define krb5_is_krb_error(dat) krb5_is_app_tag(dat, 30)
> +
> +enum torture_krb5_test {
> + TORTURE_KRB5_TEST_PLAIN,
> + TORTURE_KRB5_TEST_PAC_REQUEST,
> + TORTURE_KRB5_TEST_BREAK_PW,
> + TORTURE_KRB5_TEST_CLOCK_SKEW,
> +};
> +
> +struct torture_krb5_context {
> + struct torture_context *tctx;
> + krb5_context krb5_context;
> + enum torture_krb5_test test;
> + int recv_packet_count;
> + krb5_kdc_req *as_req;
> + krb5_kdc_rep *as_rep;
> +};
> +
> +krb5_error_code decode_krb5_error(const krb5_data *output, krb5_error **rep);
> +
> +krb5_error_code decode_krb5_as_req(const krb5_data *output, krb5_kdc_req **req);
> +krb5_error_code decode_krb5_as_rep(const krb5_data *output, krb5_kdc_rep **rep);
> +
> +void krb5_free_kdc_req(krb5_context ctx, krb5_kdc_req *req);
> +void krb5_free_kdc_rep(krb5_context ctx, krb5_kdc_rep *rep);
> +
> +static bool torture_check_krb5_as_req(struct torture_krb5_context *test_context,
> + krb5_context context,
> + const krb5_data *message)
> +{
> + krb5_error_code code;
> + int nktypes;
> +
> + code = decode_krb5_as_req(message, &test_context->as_req);
> + torture_assert_int_equal(test_context->tctx,
> + code, 0,
> + "decode_as_req failed");
> + torture_assert_int_equal(test_context->tctx,
> + test_context->as_req->msg_type,
> + KRB5_AS_REQ,
> + "Not a AS REQ");
> +
> + nktypes = test_context->as_req->nktypes;
> + torture_assert_int_not_equal(test_context->tctx,
> + nktypes, 0,
> + "No keytypes");
> +
> + return true;
> +}
> +
> +static krb5_error_code torture_krb5_pre_send_test(krb5_context context,
> + void *data,
> + const krb5_data *realm,
> + const krb5_data *message,
> + krb5_data **new_message_out,
> + krb5_data **new_reply_out)
> +{
> + bool ok;
> + struct torture_krb5_context *test_context =
> + (struct torture_krb5_context *)data;
> +
> + switch (test_context->test)
> + {
> + case TORTURE_KRB5_TEST_PLAIN:
> + case TORTURE_KRB5_TEST_PAC_REQUEST:
> + case TORTURE_KRB5_TEST_BREAK_PW:
> + case TORTURE_KRB5_TEST_CLOCK_SKEW:
> + ok = torture_check_krb5_as_req(test_context,
> + context,
> + message);
> + if (!ok) {
> + return KRB5KDC_ERR_BADOPTION;
> + }
> + break;
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * We need these function to validate packets because our torture macros
> + * do a 'return false' on error.
> + */
> +static bool torture_check_krb5_error(struct torture_krb5_context *test_context,
> + krb5_context context,
> + const krb5_data *reply,
> + krb5_error_code error_code)
> +
> {
> - torture_skip(tctx, "Skip kdc tests with MIT Kerberos");
> + krb5_error *krb_error;
> + krb5_error_code code;
> +
> + code = decode_krb5_error(reply, &krb_error);
> + torture_assert_int_equal(test_context->tctx,
> + code,
> + 0,
> + "decode_krb5_error failed");
> +
> + torture_assert_int_equal(test_context->tctx,
> + krb_error->error,
> + error_code - KRB5KDC_ERR_NONE,
> + "Got wrong error code");
> +
> + krb5_free_error(context, krb_error);
>
> return true;
> }
>
> +static bool torture_check_krb5_as_rep(struct torture_krb5_context *test_context,
> + krb5_context context,
> + const krb5_data *reply)
> +{
> + krb5_error_code code;
> + bool ok;
> +
> + code = decode_krb5_as_rep(reply, &test_context->as_rep);
> + torture_assert_int_equal(test_context->tctx,
> + code,
> + 0,
> + "decode_krb5_as_rep failed");
> +
> + torture_assert(test_context->tctx,
> + test_context->as_rep->ticket->enc_part.kvno,
> + "No KVNO set");
> +
> + ok = torture_setting_bool(test_context->tctx,
> + "expect_cached_at_rodc",
> + false);
> + if (ok) {
> + torture_assert_int_not_equal(test_context->tctx,
> + test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
> + 0,
> + "Did not get a RODC number in the KVNO");
> + } else {
> + torture_assert_int_equal(test_context->tctx,
> + test_context->as_rep->ticket->enc_part.kvno & 0xFFFF0000,
> + 0,
> + "Unexpecedly got a RODC number in the KVNO");
> + }
> +
> + return true;
> +}
> +
> +static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> + void *data,
> + krb5_error_code kdc_code,
> + const krb5_data *realm,
> + const krb5_data *message,
> + const krb5_data *reply,
> + krb5_data **new_reply_out)
> +{
> + struct torture_krb5_context *test_context =
> + (struct torture_krb5_context *)data;
> + krb5_error_code code;
> + bool ok = true;
> +
> + torture_comment(test_context->tctx,
> + "PACKET COUNT = %d\n",
> + test_context->recv_packet_count);
> +
> + torture_comment(test_context->tctx,
> + "KRB5_AS_REP = %d\n",
> + krb5_is_as_req(reply));
> +
> + torture_comment(test_context->tctx,
> + "KRB5_ERROR = %d\n",
> + krb5_is_krb_error(reply));
> +
> + torture_comment(test_context->tctx,
> + "KDC ERROR CODE = %d\n",
> + kdc_code);
> +
> + switch (test_context->test)
> + {
> + case TORTURE_KRB5_TEST_PLAIN:
> + if (test_context->recv_packet_count == 0) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KDC_ERR_PREAUTH_REQUIRED);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_error failed");
> + } else {
> + ok = torture_check_krb5_as_rep(test_context,
> + context,
> + reply);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_as_rep failed");
> + }
> +
> + torture_assert_goto(test_context->tctx,
> + test_context->recv_packet_count < 2,
> + ok,
> + out,
> + "Too many packets");
> +
> + break;
> + case TORTURE_KRB5_TEST_PAC_REQUEST:
> + case TORTURE_KRB5_TEST_BREAK_PW:
> + case TORTURE_KRB5_TEST_CLOCK_SKEW:
> + break;
> + }
> +
> + code = kdc_code;
> +out:
> + if (!ok) {
> + code = EINVAL;
> + }
> +
> + /* Cleanup */
> + krb5_free_kdc_req(test_context->krb5_context, test_context->as_req);
> + krb5_free_kdc_rep(test_context->krb5_context, test_context->as_rep);
> +
> + test_context->recv_packet_count++;
> +
> + return code;
> +}
> +
> +static bool torture_krb5_init_context(struct torture_context *tctx,
> + enum torture_krb5_test test,
> + struct smb_krb5_context **smb_krb5_context)
> +{
> + krb5_error_code code;
> +
> + struct torture_krb5_context *test_context = talloc_zero(tctx,
> + struct torture_krb5_context);
> + torture_assert(tctx, test_context != NULL, "Failed to allocate");
> +
> + test_context->test = test;
> + test_context->tctx = tctx;
> +
> + code = smb_krb5_init_context(tctx, tctx->lp_ctx, smb_krb5_context);
> + torture_assert_int_equal(tctx, code, 0, "smb_krb5_init_context failed");
> +
> + test_context->krb5_context = (*smb_krb5_context)->krb5_context;
> +
> + krb5_set_kdc_send_hook((*smb_krb5_context)->krb5_context,
> + torture_krb5_pre_send_test,
> + test_context);
> +
> + krb5_set_kdc_recv_hook((*smb_krb5_context)->krb5_context,
> + torture_krb5_post_recv_test,
> + test_context);
> +
> + return true;
> +}
> +static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> + struct cli_credentials *credentials,
> + enum torture_krb5_test test)
> +{
> + krb5_get_init_creds_opt *krb_options = NULL;
> + struct smb_krb5_context *smb_krb5_context;
> + enum credentials_obtained obtained;
> + const char *error_string;
> + const char *password;
> + krb5_principal principal;
> + krb5_error_code code;
> + krb5_creds my_creds;
> + bool ok;
> +
> + ok = torture_krb5_init_context(tctx, test, &smb_krb5_context);
> + torture_assert(tctx, ok, "torture_krb5_init_context failed");
> +
> + code = principal_from_credentials(tctx,
> + credentials,
> + smb_krb5_context,
> + &principal,
> + &obtained,
> + &error_string);
> + torture_assert_int_equal(tctx, code, 0, error_string);
> +
> + switch (test)
> + {
> + case TORTURE_KRB5_TEST_PLAIN:
> + case TORTURE_KRB5_TEST_PAC_REQUEST:
> + case TORTURE_KRB5_TEST_BREAK_PW:
> + case TORTURE_KRB5_TEST_CLOCK_SKEW:
> + break;
> + }
> +
> + password = cli_credentials_get_password(credentials);
> +
> + code = krb5_get_init_creds_password(smb_krb5_context->krb5_context,
> + &my_creds,
> + principal,
> + password,
> + NULL,
> + NULL,
> + 0,
> + NULL,
> + krb_options);
> + krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context,
> + krb_options);
> +
> + switch (test)
> + {
> + case TORTURE_KRB5_TEST_PLAIN:
> + case TORTURE_KRB5_TEST_PAC_REQUEST:
> + torture_assert_int_equal(tctx,
> + code,
> + 0,
> + "krb5_get_init_creds_password failed");
> + break;
> + case TORTURE_KRB5_TEST_BREAK_PW:
> + case TORTURE_KRB5_TEST_CLOCK_SKEW:
> + break;
> + }
> +
> + krb5_free_cred_contents(smb_krb5_context->krb5_context,
> + &my_creds);
> +
> + return true;
> +}
> +
> +static bool torture_krb5_as_req_cmdline(struct torture_context *tctx)
> +{
> + return torture_krb5_as_req_creds(tctx,
> + cmdline_credentials,
> + TORTURE_KRB5_TEST_PLAIN);
> +}
> +
> NTSTATUS torture_krb5_init(void)
> {
> struct torture_suite *suite =
> @@ -46,8 +371,22 @@ NTSTATUS torture_krb5_init(void)
> suite->description = talloc_strdup(suite, "Kerberos tests");
> kdc_suite->description = talloc_strdup(kdc_suite, "Kerberos KDC tests");
>
> - torture_suite_add_simple_test(kdc_suite, "skip", test_skip);
> + torture_suite_add_simple_test(kdc_suite,
> + "as-req-cmdline",
> + torture_krb5_as_req_cmdline);
> +
> +#if 0
> + torture_suite_add_simple_test(kdc_suite, "as-req-pac-request",
> + torture_krb5_as_req_pac_request);
> +
> + torture_suite_add_simple_test(kdc_suite, "as-req-break-pw",
> + torture_krb5_as_req_break_pw);
> +
> + torture_suite_add_simple_test(kdc_suite, "as-req-clock-skew",
> + torture_krb5_as_req_clock_skew);
>
> + torture_suite_add_suite(kdc_suite, torture_krb5_canon(kdc_suite));
> +#endif
> torture_suite_add_suite(suite, kdc_suite);
>
> torture_register_suite(suite);
> --
> 2.12.0
>
>
> From d082f1e36d88f347d45caddae167ee57a5c1468b Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 4 Jul 2016 11:35:19 +0200
> Subject: [PATCH 27/49] s4-torture: Add TORTURE_KRB5_TEST_PAC_REQUEST test
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/torture/krb5/kdc-mit.c | 84 +++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 83 insertions(+), 1 deletion(-)
>
> diff --git a/source4/torture/krb5/kdc-mit.c b/source4/torture/krb5/kdc-mit.c
> index 0b2b8651c79..9b7b6eed4fc 100644
> --- a/source4/torture/krb5/kdc-mit.c
> +++ b/source4/torture/krb5/kdc-mit.c
> @@ -240,6 +240,53 @@ static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
>
> break;
> case TORTURE_KRB5_TEST_PAC_REQUEST:
> + if (test_context->recv_packet_count == 0) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KRB_ERR_RESPONSE_TOO_BIG);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_error failed");
> + } else if (test_context->recv_packet_count == 1) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KDC_ERR_PREAUTH_REQUIRED);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_error failed");
> + } else if (krb5_is_krb_error(reply)) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KRB_ERR_RESPONSE_TOO_BIG);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_error failed");
> + } else {
> + ok = torture_check_krb5_as_rep(test_context,
> + context,
> + reply);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_as_rep failed");
> + }
> +
> + torture_assert_goto(test_context->tctx,
> + test_context->recv_packet_count < 3,
> + ok,
> + out,
> + "Too many packets");
> + break;
> case TORTURE_KRB5_TEST_BREAK_PW:
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> break;
> @@ -316,7 +363,23 @@ static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> switch (test)
> {
> case TORTURE_KRB5_TEST_PLAIN:
> + break;
> case TORTURE_KRB5_TEST_PAC_REQUEST:
> +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
> + code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
> + &krb_options);
> + torture_assert_int_equal(tctx,
> + code, 0,
> + "krb5_get_init_creds_opt_alloc failed");
> +
> + code = krb5_get_init_creds_opt_set_pac_request(smb_krb5_context->krb5_context,
> + krb_options,
> + 1);
> + torture_assert_int_equal(tctx,
> + code, 0,
> + "krb5_get_init_creds_opt_set_pac_request failed");
> +#endif
> + break;
> case TORTURE_KRB5_TEST_BREAK_PW:
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> break;
> @@ -363,6 +426,22 @@ static bool torture_krb5_as_req_cmdline(struct torture_context *tctx)
> TORTURE_KRB5_TEST_PLAIN);
> }
>
> +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
> +static bool torture_krb5_as_req_pac_request(struct torture_context *tctx)
> +{
> + bool ok;
> +
> + ok = torture_setting_bool(tctx, "expect_rodc", false);
> + if (ok) {
> + torture_skip(tctx,
> + "This test needs further investigation in the "
> + "RODC case against a Windows DC, in particular "
> + "with non-cached users");
> + }
> + return torture_krb5_as_req_creds(tctx, cmdline_credentials, TORTURE_KRB5_TEST_PAC_REQUEST);
> +}
> +#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST */
> +
> NTSTATUS torture_krb5_init(void)
> {
> struct torture_suite *suite =
> @@ -375,10 +454,13 @@ NTSTATUS torture_krb5_init(void)
> "as-req-cmdline",
> torture_krb5_as_req_cmdline);
>
> -#if 0
> +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
> + /* Only available with MIT Kerveros 1.15 and newer */
> torture_suite_add_simple_test(kdc_suite, "as-req-pac-request",
> torture_krb5_as_req_pac_request);
> +#endif
>
> +#if 0
> torture_suite_add_simple_test(kdc_suite, "as-req-break-pw",
> torture_krb5_as_req_break_pw);
>
> --
> 2.12.0
>
>
> From af2c6b4437acf11697428cb1debe9de61c0984fa Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 4 Jul 2016 16:37:08 +0200
> Subject: [PATCH 28/49] s4-torture: Add TORTURE_KRB5_TEST_BREAK_PW test
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/torture/krb5/kdc-mit.c | 100 +++++++++++++++++++++++++++++++++++++----
> 1 file changed, 92 insertions(+), 8 deletions(-)
>
> diff --git a/source4/torture/krb5/kdc-mit.c b/source4/torture/krb5/kdc-mit.c
> index 9b7b6eed4fc..885b6e40f1b 100644
> --- a/source4/torture/krb5/kdc-mit.c
> +++ b/source4/torture/krb5/kdc-mit.c
> @@ -59,8 +59,11 @@ krb5_error_code decode_krb5_error(const krb5_data *output, krb5_error **rep);
> krb5_error_code decode_krb5_as_req(const krb5_data *output, krb5_kdc_req **req);
> krb5_error_code decode_krb5_as_rep(const krb5_data *output, krb5_kdc_rep **rep);
>
> +krb5_error_code decode_krb5_padata_sequence(const krb5_data *output, krb5_pa_data ***rep);
> +
> void krb5_free_kdc_req(krb5_context ctx, krb5_kdc_req *req);
> void krb5_free_kdc_rep(krb5_context ctx, krb5_kdc_rep *rep);
> +void krb5_free_pa_data(krb5_context ctx, krb5_pa_data **data);
>
> static bool torture_check_krb5_as_req(struct torture_krb5_context *test_context,
> krb5_context context,
> @@ -122,7 +125,8 @@ static krb5_error_code torture_krb5_pre_send_test(krb5_context context,
> static bool torture_check_krb5_error(struct torture_krb5_context *test_context,
> krb5_context context,
> const krb5_data *reply,
> - krb5_error_code error_code)
> + krb5_error_code error_code,
> + bool check_pa_data)
>
> {
> krb5_error *krb_error;
> @@ -139,6 +143,34 @@ static bool torture_check_krb5_error(struct torture_krb5_context *test_context,
> error_code - KRB5KDC_ERR_NONE,
> "Got wrong error code");
>
> + if (check_pa_data) {
> + krb5_pa_data **d, **pa_data = NULL;
> + bool timestamp_found = false;
> +
> + torture_assert_int_not_equal(test_context->tctx,
> + krb_error->e_data.length, 0,
> + "No e-data returned");
> +
> + code = decode_krb5_padata_sequence(&krb_error->e_data,
> + &pa_data);
> + torture_assert_int_equal(test_context->tctx,
> + code,
> + 0,
> + "decode_krb5_padata_sequence failed");
> +
> + for (d = pa_data; d != NULL; d++) {
> + if ((*d)->pa_type == KRB5_PADATA_ENC_TIMESTAMP) {
> + timestamp_found = true;
> + break;
> + }
> + }
> + torture_assert(test_context->tctx,
> + timestamp_found,
> + "Encrypted timestamp not found");
> +
> + krb5_free_pa_data(context, pa_data);
> + }
> +
> krb5_free_error(context, krb_error);
>
> return true;
> @@ -215,7 +247,8 @@ static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> ok = torture_check_krb5_error(test_context,
> context,
> reply,
> - KRB5KDC_ERR_PREAUTH_REQUIRED);
> + KRB5KDC_ERR_PREAUTH_REQUIRED,
> + false);
> torture_assert_goto(test_context->tctx,
> ok,
> ok,
> @@ -244,7 +277,8 @@ static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> ok = torture_check_krb5_error(test_context,
> context,
> reply,
> - KRB5KRB_ERR_RESPONSE_TOO_BIG);
> + KRB5KRB_ERR_RESPONSE_TOO_BIG,
> + false);
> torture_assert_goto(test_context->tctx,
> ok,
> ok,
> @@ -254,7 +288,8 @@ static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> ok = torture_check_krb5_error(test_context,
> context,
> reply,
> - KRB5KDC_ERR_PREAUTH_REQUIRED);
> + KRB5KDC_ERR_PREAUTH_REQUIRED,
> + false);
> torture_assert_goto(test_context->tctx,
> ok,
> ok,
> @@ -264,7 +299,8 @@ static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> ok = torture_check_krb5_error(test_context,
> context,
> reply,
> - KRB5KRB_ERR_RESPONSE_TOO_BIG);
> + KRB5KRB_ERR_RESPONSE_TOO_BIG,
> + false);
> torture_assert_goto(test_context->tctx,
> ok,
> ok,
> @@ -288,6 +324,39 @@ static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> "Too many packets");
> break;
> case TORTURE_KRB5_TEST_BREAK_PW:
> + if (test_context->recv_packet_count == 0) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KDC_ERR_PREAUTH_REQUIRED,
> + false);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_error failed");
> + if (!ok) {
> + goto out;
> + }
> + } else if (test_context->recv_packet_count == 1) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KDC_ERR_PREAUTH_FAILED,
> + true);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_error failed");
> + }
> +
> + torture_assert_goto(test_context->tctx,
> + test_context->recv_packet_count < 2,
> + ok,
> + out,
> + "Too many packets");
> + break;
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> break;
> }
> @@ -360,6 +429,8 @@ static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> &error_string);
> torture_assert_int_equal(tctx, code, 0, error_string);
>
> + password = cli_credentials_get_password(credentials);
> +
> switch (test)
> {
> case TORTURE_KRB5_TEST_PLAIN:
> @@ -381,12 +452,12 @@ static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> #endif
> break;
> case TORTURE_KRB5_TEST_BREAK_PW:
> + password = "NOT the password";
> + break;
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> break;
> }
>
> - password = cli_credentials_get_password(credentials);
> -
> code = krb5_get_init_creds_password(smb_krb5_context->krb5_context,
> &my_creds,
> principal,
> @@ -409,6 +480,12 @@ static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> "krb5_get_init_creds_password failed");
> break;
> case TORTURE_KRB5_TEST_BREAK_PW:
> + torture_assert_int_equal(tctx,
> + code,
> + KRB5KDC_ERR_PREAUTH_FAILED,
> + "krb5_get_init_creds_password should "
> + "have failed");
> + return true;
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> break;
> }
> @@ -442,6 +519,13 @@ static bool torture_krb5_as_req_pac_request(struct torture_context *tctx)
> }
> #endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST */
>
> +static bool torture_krb5_as_req_break_pw(struct torture_context *tctx)
> +{
> + return torture_krb5_as_req_creds(tctx,
> + cmdline_credentials,
> + TORTURE_KRB5_TEST_BREAK_PW);
> +}
> +
> NTSTATUS torture_krb5_init(void)
> {
> struct torture_suite *suite =
> @@ -460,10 +544,10 @@ NTSTATUS torture_krb5_init(void)
> torture_krb5_as_req_pac_request);
> #endif
>
> -#if 0
> torture_suite_add_simple_test(kdc_suite, "as-req-break-pw",
> torture_krb5_as_req_break_pw);
>
> +#if 0
> torture_suite_add_simple_test(kdc_suite, "as-req-clock-skew",
> torture_krb5_as_req_clock_skew);
>
> --
> 2.12.0
>
>
> From ea41ac36e6782a28c2afb35682f35e8bc9b148f2 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Tue, 5 Jul 2016 16:16:17 +0200
> Subject: [PATCH 29/49] s4-torture: Add TORTURE_KRB5_TEST_CLOCK_SKEW test
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> selftest/target/Samba.pm | 3 ++
> source4/torture/krb5/kdc-mit.c | 62 ++++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 63 insertions(+), 2 deletions(-)
>
> diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
> index ebffa027bc8..930cb44e744 100644
> --- a/selftest/target/Samba.pm
> +++ b/selftest/target/Samba.pm
> @@ -204,6 +204,9 @@ sub mk_krb5_conf($$)
> # Set the grace clocskew to 1 second
> # This is especially required by samba3.raw.session krb5
> clockskew = 1
> + # We are running on the same machine, do not correct
> + # system clock differences
> + kdc_timesync = 0
>
> ";
>
> diff --git a/source4/torture/krb5/kdc-mit.c b/source4/torture/krb5/kdc-mit.c
> index 885b6e40f1b..1edaa291689 100644
> --- a/source4/torture/krb5/kdc-mit.c
> +++ b/source4/torture/krb5/kdc-mit.c
> @@ -21,6 +21,7 @@
>
> #include "includes.h"
> #include "system/kerberos.h"
> +#include "system/time.h"
> #include "torture/smbtorture.h"
> #include "torture/winbind/proto.h"
> #include "torture/krb5/proto.h"
> @@ -358,6 +359,44 @@ static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> "Too many packets");
> break;
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> + if (test_context->recv_packet_count == 0) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KDC_ERR_PREAUTH_REQUIRED,
> + false);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_error failed");
> + if (!ok) {
> + goto out;
> + }
> + } else if (test_context->recv_packet_count == 1) {
> + /*
> + * This only works if kdc_timesync 0 is set in krb5.conf
> + *
> + * See commit 5f39a4438eafd693a3eb8366bbc3901efe62e538
> + * in the MIT Kerberos source tree.
> + */
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KRB_AP_ERR_SKEW,
> + false);
> + torture_assert_goto(test_context->tctx,
> + ok,
> + ok,
> + out,
> + "torture_check_krb5_error failed");
> + }
> +
> + torture_assert_goto(test_context->tctx,
> + test_context->recv_packet_count < 2,
> + ok,
> + out,
> + "Too many packets");
> break;
> }
>
> @@ -455,6 +494,12 @@ static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> password = "NOT the password";
> break;
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> + code = krb5_set_real_time(smb_krb5_context->krb5_context,
> + time(NULL) + 3600,
> + 0);
> + torture_assert_int_equal(tctx,
> + code, 0,
> + "krb5_set_real_time failed");
> break;
> }
>
> @@ -487,7 +532,12 @@ static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> "have failed");
> return true;
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> - break;
> + torture_assert_int_equal(tctx,
> + code,
> + KRB5KRB_AP_ERR_SKEW,
> + "krb5_get_init_creds_password should "
> + "have failed");
> + return true;
> }
>
> krb5_free_cred_contents(smb_krb5_context->krb5_context,
> @@ -526,6 +576,13 @@ static bool torture_krb5_as_req_break_pw(struct torture_context *tctx)
> TORTURE_KRB5_TEST_BREAK_PW);
> }
>
> +static bool torture_krb5_as_req_clock_skew(struct torture_context *tctx)
> +{
> + return torture_krb5_as_req_creds(tctx,
> + cmdline_credentials,
> + TORTURE_KRB5_TEST_CLOCK_SKEW);
> +}
> +
> NTSTATUS torture_krb5_init(void)
> {
> struct torture_suite *suite =
> @@ -547,10 +604,11 @@ NTSTATUS torture_krb5_init(void)
> torture_suite_add_simple_test(kdc_suite, "as-req-break-pw",
> torture_krb5_as_req_break_pw);
>
> -#if 0
> + /* This only works if kdc_timesync 0 is set in krb5.conf */
> torture_suite_add_simple_test(kdc_suite, "as-req-clock-skew",
> torture_krb5_as_req_clock_skew);
>
> +#if 0
> torture_suite_add_suite(kdc_suite, torture_krb5_canon(kdc_suite));
> #endif
> torture_suite_add_suite(suite, kdc_suite);
> --
> 2.12.0
>
>
> From b4dcd03549f6f61ad8051dc083eca628240dd292 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 1 Jul 2016 12:33:45 +0200
> Subject: [PATCH 30/49] s4-torture: Add AES and RC4 enctype checks
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/torture/krb5/kdc-mit.c | 175 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 175 insertions(+)
>
> diff --git a/source4/torture/krb5/kdc-mit.c b/source4/torture/krb5/kdc-mit.c
> index 1edaa291689..a4997357c7e 100644
> --- a/source4/torture/krb5/kdc-mit.c
> +++ b/source4/torture/krb5/kdc-mit.c
> @@ -44,6 +44,9 @@ enum torture_krb5_test {
> TORTURE_KRB5_TEST_PAC_REQUEST,
> TORTURE_KRB5_TEST_BREAK_PW,
> TORTURE_KRB5_TEST_CLOCK_SKEW,
> + TORTURE_KRB5_TEST_AES,
> + TORTURE_KRB5_TEST_RC4,
> + TORTURE_KRB5_TEST_AES_RC4,
> };
>
> struct torture_krb5_context {
> @@ -107,6 +110,9 @@ static krb5_error_code torture_krb5_pre_send_test(krb5_context context,
> case TORTURE_KRB5_TEST_PAC_REQUEST:
> case TORTURE_KRB5_TEST_BREAK_PW:
> case TORTURE_KRB5_TEST_CLOCK_SKEW:
> + case TORTURE_KRB5_TEST_AES:
> + case TORTURE_KRB5_TEST_RC4:
> + case TORTURE_KRB5_TEST_AES_RC4:
> ok = torture_check_krb5_as_req(test_context,
> context,
> message);
> @@ -212,6 +218,30 @@ static bool torture_check_krb5_as_rep(struct torture_krb5_context *test_context,
> return true;
> }
>
> +static bool torture_check_krb5_as_rep_enctype(struct torture_krb5_context *test_context,
> + krb5_context context,
> + const krb5_data *reply,
> + krb5_enctype expected_enctype)
> +{
> + krb5_enctype reply_enctype;
> + bool ok;
> +
> + ok = torture_check_krb5_as_rep(test_context,
> + context,
> + reply);
> + if (!ok) {
> + return false;
> + }
> +
> + reply_enctype = test_context->as_rep->enc_part.enctype;
> +
> + torture_assert_int_equal(test_context->tctx,
> + reply_enctype, expected_enctype,
> + "Ticket encrypted with invalid algorithm");
> +
> + return true;
> +}
> +
> static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> void *data,
> krb5_error_code kdc_code,
> @@ -398,6 +428,72 @@ static krb5_error_code torture_krb5_post_recv_test(krb5_context context,
> out,
> "Too many packets");
> break;
> + case TORTURE_KRB5_TEST_AES:
> + torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES\n");
> +
> + if (test_context->recv_packet_count == 0) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KDC_ERR_PREAUTH_REQUIRED,
> + false);
> + if (!ok) {
> + goto out;
> + }
> + } else {
> + ok = torture_check_krb5_as_rep_enctype(test_context,
> + context,
> + reply,
> + ENCTYPE_AES256_CTS_HMAC_SHA1_96);
> + if (!ok) {
> + goto out;
> + }
> + }
> + break;
> + case TORTURE_KRB5_TEST_RC4:
> + torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_RC4\n");
> +
> + if (test_context->recv_packet_count == 0) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KDC_ERR_PREAUTH_REQUIRED,
> + false);
> + if (!ok) {
> + goto out;
> + }
> + } else {
> + ok = torture_check_krb5_as_rep_enctype(test_context,
> + context,
> + reply,
> + ENCTYPE_ARCFOUR_HMAC);
> + if (!ok) {
> + goto out;
> + }
> + }
> + break;
> + case TORTURE_KRB5_TEST_AES_RC4:
> + torture_comment(test_context->tctx, "TORTURE_KRB5_TEST_AES_RC4\n");
> +
> + if (test_context->recv_packet_count == 0) {
> + ok = torture_check_krb5_error(test_context,
> + context,
> + reply,
> + KRB5KDC_ERR_PREAUTH_REQUIRED,
> + false);
> + if (!ok) {
> + goto out;
> + }
> + } else {
> + ok = torture_check_krb5_as_rep_enctype(test_context,
> + context,
> + reply,
> + ENCTYPE_AES256_CTS_HMAC_SHA1_96);
> + if (!ok) {
> + goto out;
> + }
> + }
> + break;
> }
>
> code = kdc_code;
> @@ -501,6 +597,49 @@ static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> code, 0,
> "krb5_set_real_time failed");
> break;
> + case TORTURE_KRB5_TEST_AES: {
> + krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96 };
> +
> + code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
> + &krb_options);
> + torture_assert_int_equal(tctx,
> + code, 0,
> + "krb5_get_init_creds_opt_alloc failed");
> +
> + krb5_get_init_creds_opt_set_etype_list(krb_options,
> + etype,
> + 1);
> + break;
> + }
> + case TORTURE_KRB5_TEST_RC4: {
> + krb5_enctype etype[] = { ENCTYPE_ARCFOUR_HMAC };
> +
> + code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
> + &krb_options);
> + torture_assert_int_equal(tctx,
> + code, 0,
> + "krb5_get_init_creds_opt_alloc failed");
> +
> + krb5_get_init_creds_opt_set_etype_list(krb_options,
> + etype,
> + 1);
> + break;
> + }
> + case TORTURE_KRB5_TEST_AES_RC4: {
> + krb5_enctype etype[] = { ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_ARCFOUR_HMAC };
> +
> + code = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context,
> + &krb_options);
> + torture_assert_int_equal(tctx,
> + code, 0,
> + "krb5_get_init_creds_opt_alloc failed");
> +
> +
> + krb5_get_init_creds_opt_set_etype_list(krb_options,
> + etype,
> + 2);
> + break;
> + }
> }
>
> code = krb5_get_init_creds_password(smb_krb5_context->krb5_context,
> @@ -519,6 +658,9 @@ static bool torture_krb5_as_req_creds(struct torture_context *tctx,
> {
> case TORTURE_KRB5_TEST_PLAIN:
> case TORTURE_KRB5_TEST_PAC_REQUEST:
> + case TORTURE_KRB5_TEST_AES:
> + case TORTURE_KRB5_TEST_RC4:
> + case TORTURE_KRB5_TEST_AES_RC4:
> torture_assert_int_equal(tctx,
> code,
> 0,
> @@ -583,6 +725,27 @@ static bool torture_krb5_as_req_clock_skew(struct torture_context *tctx)
> TORTURE_KRB5_TEST_CLOCK_SKEW);
> }
>
> +static bool torture_krb5_as_req_aes(struct torture_context *tctx)
> +{
> + return torture_krb5_as_req_creds(tctx,
> + cmdline_credentials,
> + TORTURE_KRB5_TEST_AES);
> +}
> +
> +static bool torture_krb5_as_req_rc4(struct torture_context *tctx)
> +{
> + return torture_krb5_as_req_creds(tctx,
> + cmdline_credentials,
> + TORTURE_KRB5_TEST_RC4);
> +}
> +
> +static bool torture_krb5_as_req_aes_rc4(struct torture_context *tctx)
> +{
> + return torture_krb5_as_req_creds(tctx,
> + cmdline_credentials,
> + TORTURE_KRB5_TEST_AES_RC4);
> +}
> +
> NTSTATUS torture_krb5_init(void)
> {
> struct torture_suite *suite =
> @@ -611,6 +774,18 @@ NTSTATUS torture_krb5_init(void)
> #if 0
> torture_suite_add_suite(kdc_suite, torture_krb5_canon(kdc_suite));
> #endif
> + torture_suite_add_simple_test(kdc_suite,
> + "as-req-aes",
> + torture_krb5_as_req_aes);
> +
> + torture_suite_add_simple_test(kdc_suite,
> + "as-req-rc4",
> + torture_krb5_as_req_rc4);
> +
> + torture_suite_add_simple_test(kdc_suite,
> + "as-req-aes-rc4",
> + torture_krb5_as_req_aes_rc4);
> +
> torture_suite_add_suite(suite, kdc_suite);
>
> torture_register_suite(suite);
> --
> 2.12.0
>
>
> From edc090d784cdef38b4203c2d53be09dba0690298 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 7 Sep 2016 12:32:50 +0200
> Subject: [PATCH 31/49] s4-kdc: Add MIT Kerberos specific kpasswd code
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/kpasswd-service-mit.c | 300 ++++++++++++++++++++++++++++++++++++++
> source4/kdc/wscript_build | 3 +-
> 2 files changed, 301 insertions(+), 2 deletions(-)
> create mode 100644 source4/kdc/kpasswd-service-mit.c
>
> diff --git a/source4/kdc/kpasswd-service-mit.c b/source4/kdc/kpasswd-service-mit.c
> new file mode 100644
> index 00000000000..eb3a098eb76
> --- /dev/null
> +++ b/source4/kdc/kpasswd-service-mit.c
> @@ -0,0 +1,300 @@
> +/*
> + Unix SMB/CIFS implementation.
> +
> + Samba kpasswd implementation
> +
> + Copyright (c) 2016 Andreas Schneider <asn at samba.org>
> +
> + 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 "smbd/service_task.h"
> +#include "param/param.h"
> +#include "auth/auth.h"
> +#include "auth/gensec/gensec.h"
> +#include "kdc/kdc-server.h"
> +#include "kdc/kpasswd_glue.h"
> +#include "kdc/kpasswd-service.h"
> +#include "kdc/kpasswd-helper.h"
> +
> +#define RFC3244_VERSION 0xff80
> +
> +krb5_error_code decode_krb5_setpw_req(const krb5_data *code,
> + krb5_data **password_out,
> + krb5_principal *target_out);
> +
> +static krb5_error_code kpasswd_change_password(struct kdc_server *kdc,
> + TALLOC_CTX *mem_ctx,
> + struct auth_session_info *session_info,
> + DATA_BLOB *password,
> + DATA_BLOB *kpasswd_reply,
> + const char **error_string)
> +{
> + NTSTATUS status;
> + NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
> + enum samPwdChangeReason reject_reason;
> + const char *reject_string = NULL;
> + struct samr_DomInfo1 *dominfo;
> + bool ok;
> +
> + status = samdb_kpasswd_change_password(mem_ctx,
> + kdc->task->lp_ctx,
> + kdc->task->event_ctx,
> + kdc->samdb,
> + session_info,
> + password,
> + &reject_reason,
> + &dominfo,
> + &reject_string,
> + &result);
> + if (!NT_STATUS_IS_OK(status)) {
> + ok = kpasswd_make_error_reply(mem_ctx,
> + KRB5_KPASSWD_ACCESSDENIED,
> + reject_string,
> + kpasswd_reply);
> + if (!ok) {
> + *error_string = "Failed to create reply";
> + return KRB5_KPASSWD_HARDERROR;
> + }
> + /* We want to send an an authenticated packet. */
> + return 0;
> + }
> +
> + ok = kpasswd_make_pwchange_reply(mem_ctx,
> + result,
> + reject_reason,
> + dominfo,
> + kpasswd_reply);
> + if (!ok) {
> + *error_string = "Failed to create reply";
> + return KRB5_KPASSWD_HARDERROR;
> + }
> +
> + return 0;
> +}
> +
> +static krb5_error_code kpasswd_set_password(struct kdc_server *kdc,
> + TALLOC_CTX *mem_ctx,
> + struct auth_session_info *session_info,
> + DATA_BLOB *decoded_data,
> + DATA_BLOB *kpasswd_reply,
> + const char **error_string)
> +{
> + krb5_context context = kdc->smb_krb5_context->krb5_context;
> + krb5_data k_dec_data;
> + krb5_data *k_clear_data;
> + krb5_principal target_principal;
> + krb5_error_code code;
> + DATA_BLOB password;
> + char *target_realm = NULL;
> + char *target_name = NULL;
> + char *target_principal_string = NULL;
> + bool is_service_principal = false;
> + bool ok;
> + size_t num_components;
> + enum samPwdChangeReason reject_reason = SAM_PWD_CHANGE_NO_ERROR;
> + struct samr_DomInfo1 *dominfo = NULL;
> + NTSTATUS status;
> +
> + k_dec_data.length = decoded_data->length;
> + k_dec_data.data = (char *)decoded_data->data;
> +
> + code = decode_krb5_setpw_req(&k_dec_data, &k_clear_data, &target_principal);
> + if (code != 0) {
> + DBG_WARNING("decode_krb5_setpw_req failed: %s\n",
> + error_message(code));
> + ok = kpasswd_make_error_reply(mem_ctx,
> + KRB5_KPASSWD_MALFORMED,
> + "Failed to decode packet",
> + kpasswd_reply);
> + if (!ok) {
> + *error_string = "Failed to create reply";
> + return KRB5_KPASSWD_HARDERROR;
> + }
> + return 0;
> + }
> +
> + ok = convert_string_talloc_handle(mem_ctx,
> + lpcfg_iconv_handle(kdc->task->lp_ctx),
> + CH_UTF8,
> + CH_UTF16,
> + (const char *)k_clear_data->data,
> + k_clear_data->length,
> + (void **)&password.data,
> + &password.length);
> + krb5_free_data(context, k_clear_data);
> + if (!ok) {
> + DBG_WARNING("String conversion failed\n");
> + *error_string = "String conversion failed";
> + return KRB5_KPASSWD_HARDERROR;
> + }
> +
> + target_realm = smb_krb5_principal_get_realm(context, target_principal);
> + code = krb5_unparse_name_flags(context,
> + target_principal,
> + KRB5_PRINCIPAL_UNPARSE_NO_REALM,
> + &target_name);
> + if (code != 0) {
> + DBG_WARNING("Failed to parse principal\n");
> + *error_string = "String conversion failed";
> + return KRB5_KPASSWD_HARDERROR;
> + }
> +
> + if ((target_name != NULL && target_realm == NULL) ||
> + (target_name == NULL && target_realm != NULL)) {
> + krb5_free_principal(context, target_principal);
> + SAFE_FREE(target_realm);
> + SAFE_FREE(target_name);
> +
> + ok = kpasswd_make_error_reply(mem_ctx,
> + KRB5_KPASSWD_MALFORMED,
> + "Realm and principal must be "
> + "both present, or neither present",
> + kpasswd_reply);
> + if (!ok) {
> + *error_string = "Failed to create reply";
> + return KRB5_KPASSWD_HARDERROR;
> + }
> + return 0;
> + }
> +
> + if (target_name != NULL && target_realm != NULL) {
> + SAFE_FREE(target_realm);
> + SAFE_FREE(target_name);
> + } else {
> + krb5_free_principal(context, target_principal);
> + SAFE_FREE(target_realm);
> + SAFE_FREE(target_name);
> +
> + return kpasswd_change_password(kdc,
> + mem_ctx,
> + session_info,
> + &password,
> + kpasswd_reply,
> + error_string);
> + }
> +
> + num_components = krb5_princ_size(context, target_principal);
> + if (num_components >= 2) {
> + is_service_principal = true;
> + code = krb5_unparse_name_flags(context,
> + target_principal,
> + KRB5_PRINCIPAL_UNPARSE_SHORT,
> + &target_principal_string);
> + } else {
> + code = krb5_unparse_name(context,
> + target_principal,
> + &target_principal_string);
> + }
> + krb5_free_principal(context, target_principal);
> + if (code != 0) {
> + ok = kpasswd_make_error_reply(mem_ctx,
> + KRB5_KPASSWD_MALFORMED,
> + "Failed to parse principal",
> + kpasswd_reply);
> + if (!ok) {
> + *error_string = "Failed to create reply";
> + return KRB5_KPASSWD_HARDERROR;
> + }
> + }
> +
> + status = kpasswd_samdb_set_password(mem_ctx,
> + kdc->task->event_ctx,
> + kdc->task->lp_ctx,
> + session_info,
> + is_service_principal,
> + target_principal_string,
> + &password,
> + &reject_reason,
> + &dominfo);
> + if (!NT_STATUS_IS_OK(status)) {
> + DBG_ERR("kpasswd_samdb_set_password failed - %s\n",
> + nt_errstr(status));
> + }
> +
> + ok = kpasswd_make_pwchange_reply(mem_ctx,
> + status,
> + reject_reason,
> + dominfo,
> + kpasswd_reply);
> + if (!ok) {
> + *error_string = "Failed to create reply";
> + return KRB5_KPASSWD_HARDERROR;
> + }
> +
> + return 0;
> +}
> +
> +krb5_error_code kpasswd_handle_request(struct kdc_server *kdc,
> + TALLOC_CTX *mem_ctx,
> + struct gensec_security *gensec_security,
> + uint16_t verno,
> + DATA_BLOB *decoded_data,
> + DATA_BLOB *kpasswd_reply,
> + const char **error_string)
> +{
> + struct auth_session_info *session_info;
> + NTSTATUS status;
> +
> + status = gensec_session_info(gensec_security,
> + mem_ctx,
> + &session_info);
> + if (!NT_STATUS_IS_OK(status)) {
> + *error_string = talloc_asprintf(mem_ctx,
> + "gensec_session_info failed - %s",
> + nt_errstr(status));
> + return KRB5_KPASSWD_HARDERROR;
> + }
> +
> + switch(verno) {
> + case 1: {
> + DATA_BLOB password;
> + bool ok;
> +
> + ok = convert_string_talloc_handle(mem_ctx,
> + lpcfg_iconv_handle(kdc->task->lp_ctx),
> + CH_UTF8,
> + CH_UTF16,
> + (const char *)decoded_data->data,
> + decoded_data->length,
> + (void **)&password.data,
> + &password.length);
> + if (!ok) {
> + *error_string = "String conversion failed!";
> + DBG_WARNING("%s\n", *error_string);
> + return KRB5_KPASSWD_HARDERROR;
> + }
> +
> + return kpasswd_change_password(kdc,
> + mem_ctx,
> + session_info,
> + &password,
> + kpasswd_reply,
> + error_string);
> + }
> + case RFC3244_VERSION: {
> + return kpasswd_set_password(kdc,
> + mem_ctx,
> + session_info,
> + decoded_data,
> + kpasswd_reply,
> + error_string);
> + }
> + default:
> + return KRB5_KPASSWD_BAD_VERSION;
> + }
> +
> + return 0;
> +}
> diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build
> index 84c5d88b830..26d4bc80f9b 100644
> --- a/source4/kdc/wscript_build
> +++ b/source4/kdc/wscript_build
> @@ -67,8 +67,7 @@ bld.SAMBA_SUBSYSTEM('KDC-SERVER',
> ldb
> LIBTSOCKET
> LIBSAMBA_TSOCKET
> - ''',
> - enabled=bld.CONFIG_SET('SAMBA4_USES_HEIMDAL'))
> + ''')
>
> kpasswd_flavor_src = 'kpasswd-service.c kpasswd-helper.c'
> if bld.CONFIG_SET('SAMBA4_USES_HEIMDAL'):
> --
> 2.12.0
>
>
> From e34a2a9b47d348093ab22300b9f4d93e68b735a5 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Wed, 7 Sep 2016 12:29:18 +0200
> Subject: [PATCH 32/49] waf: Search for MIT kadm-server library
>
> This is needed for plugin registration in the KDC.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> wscript_configure_system_mitkrb5 | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/wscript_configure_system_mitkrb5 b/wscript_configure_system_mitkrb5
> index a520238a46b..6f9330deb2a 100644
> --- a/wscript_configure_system_mitkrb5
> +++ b/wscript_configure_system_mitkrb5
> @@ -34,6 +34,10 @@ if conf.env.KRB5_CONFIG:
> krb5_define_syslib(conf, "krb5", conf.env['LIB_KRB5'])
>
> conf.CHECK_CFG(path=conf.env.KRB5_CONFIG, args="--cflags --libs",
> + package="kadm-server", uselib_store="KADM-SERVER")
> + conf.CHECK_FUNCS_IN('kadm5_init', 'kadm5srv_mit')
> +
> + conf.CHECK_CFG(path=conf.env.KRB5_CONFIG, args="--cflags --libs",
> package="kdb", uselib_store="KDB5")
> krb5_define_syslib(conf, "kdb5", conf.env['LIB_KDB5'])
>
> --
> 2.12.0
>
>
> From aec58ce9498c2f4b52a3ec4e1f6b36e71d573c3f Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 8 Sep 2016 09:58:44 +0200
> Subject: [PATCH 33/49] s4-kdc: Start the kpasswd service with MIT KDC
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/kdc-service-mit.c | 217 ++++++++++++++++++++++++++++++++++++++++++
> source4/kdc/wscript_build | 7 ++
> 2 files changed, 224 insertions(+)
>
> diff --git a/source4/kdc/kdc-service-mit.c b/source4/kdc/kdc-service-mit.c
> index a1cdd3a4471..780822b7fb0 100644
> --- a/source4/kdc/kdc-service-mit.c
> +++ b/source4/kdc/kdc-service-mit.c
> @@ -30,11 +30,114 @@
> #include "kdc/kdc-service-mit.h"
> #include "dynconfig.h"
> #include "libds/common/roles.h"
> +#include "lib/socket/netif.h"
> +#include "samba/session.h"
> +#include "dsdb/samdb/samdb.h"
> +#include "kdc/samba_kdc.h"
> +#include "kdc/kdc-server.h"
> +#include "kdc/kpasswd-service.h"
> +#include <kadm5/admin.h>
> +#include <kdb.h>
>
> #include "source4/kdc/mit_kdc_irpc.h"
>
> +/* PROTOTYPES */
> static void mitkdc_server_done(struct tevent_req *subreq);
>
> +static int kdc_server_destroy(struct kdc_server *kdc)
> +{
> + if (kdc->private_data != NULL) {
> + kadm5_destroy(kdc->private_data);
> + }
> +
> + return 0;
> +}
> +
> +static NTSTATUS startup_kpasswd_server(TALLOC_CTX *mem_ctx,
> + struct kdc_server *kdc,
> + struct loadparm_context *lp_ctx,
> + struct interface *ifaces)
> +{
> + const struct model_ops *model_ops;
> + int num_interfaces;
> + int i;
> + TALLOC_CTX *tmp_ctx;
> + NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
> + uint16_t kpasswd_port;
> + bool done_wildcard = false;
> + bool ok;
> +
> + kpasswd_port = lpcfg_kpasswd_port(lp_ctx);
> + if (kpasswd_port == 0) {
> + return NT_STATUS_OK;
> + }
> +
> + model_ops = process_model_startup("single");
> + if (model_ops == NULL) {
> + DBG_ERR("Can't find 'single' process model_ops\n");
> + return NT_STATUS_INTERNAL_ERROR;
> + }
> +
> + tmp_ctx = talloc_new(mem_ctx);
> + if (tmp_ctx == NULL) {
> + return NT_STATUS_NO_MEMORY;
> + }
> +
> + num_interfaces = iface_list_count(ifaces);
> +
> + ok = lpcfg_bind_interfaces_only(lp_ctx);
> + if (!ok) {
> + int num_binds = 0;
> + char **wcard;
> +
> + wcard = iface_list_wildcard(tmp_ctx);
> + if (wcard == NULL) {
> + status = NT_STATUS_NO_MEMORY;
> + goto out;
> + }
> +
> + for (i = 0; wcard[i] != NULL; i++) {
> + status = kdc_add_socket(kdc,
> + model_ops,
> + "kpasswd",
> + wcard[i],
> + kpasswd_port,
> + kpasswd_process,
> + false);
> + if (NT_STATUS_IS_OK(status)) {
> + num_binds++;
> + }
> + }
> + talloc_free(wcard);
> +
> + if (num_binds == 0) {
> + status = NT_STATUS_INVALID_PARAMETER_MIX;
> + goto out;
> + }
> +
> + done_wildcard = true;
> + }
> +
> + for (i = 0; i < num_interfaces; i++) {
> + const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i));
> +
> + status = kdc_add_socket(kdc,
> + model_ops,
> + "kpasswd",
> + address,
> + kpasswd_port,
> + kpasswd_process,
> + done_wildcard);
> + if (NT_STATUS_IS_OK(status)) {
> + goto out;
> + }
> + }
> +
> +out:
> + talloc_free(tmp_ctx);
> + return status;
> +}
> +
> /*
> * Startup a copy of the krb5kdc as a child daemon
> */
> @@ -42,8 +145,14 @@ void mitkdc_task_init(struct task_server *task)
> {
> struct tevent_req *subreq;
> const char * const *kdc_cmd;
> + struct interface *ifaces;
> const char *kdc_config;
> + struct kdc_server *kdc;
> + krb5_error_code code;
> NTSTATUS status;
> + kadm5_ret_t ret;
> + kadm5_config_params config;
> + void *server_handle;
>
> task_server_set_title(task, "task[mitkdc_parent]");
>
> @@ -65,6 +174,15 @@ void mitkdc_task_init(struct task_server *task)
> break;
> }
>
> + /* Load interfaces for kpasswd */
> + load_interface_list(task, task->lp_ctx, &ifaces);
> + if (iface_list_count(ifaces) == 0) {
> + task_server_terminate(task,
> + "KDC: no network interfaces configured",
> + false);
> + return;
> + }
> +
> kdc_config = lpcfg_mit_kdc_config(task->lp_ctx, task);
> if (kdc_config != NULL && kdc_config[0] != '\0') {
> /* Do not overwrite the variable if already set! */
> @@ -106,6 +224,105 @@ void mitkdc_task_init(struct task_server *task)
> }
>
> DEBUG(5,("Started irpc service for kdc_server\n"));
> +
> + kdc = talloc_zero(task, struct kdc_server);
> + if (kdc == NULL) {
> + task_server_terminate(task, "KDC: Out of memory", true);
> + return;
> + }
> + talloc_set_destructor(kdc, kdc_server_destroy);
> +
> + kdc->task = task;
> +
> + kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
> + if (kdc->base_ctx == NULL) {
> + task_server_terminate(task, "KDC: Out of memory", true);
> + return;
> + }
> +
> + kdc->base_ctx->ev_ctx = task->event_ctx;
> + kdc->base_ctx->lp_ctx = task->lp_ctx;
> +
> + initialize_krb5_error_table();
> +
> + code = smb_krb5_init_context(kdc,
> + kdc->task->lp_ctx,
> + &kdc->smb_krb5_context);
> + if (code != 0) {
> + task_server_terminate(task,
> + "KDC: Unable to initialized krb5 context",
> + true);
> + return;
> + }
> +
> + code = kadm5_init_krb5_context(&kdc->smb_krb5_context->krb5_context);
> + if (code != 0) {
> + task_server_terminate(task,
> + "KDC: Unable to init kadm5 krb5_context",
> + true);
> + return;
> + }
> +
> + ZERO_STRUCT(config);
> + config.mask = KADM5_CONFIG_REALM;
> + config.realm = discard_const_p(char, lpcfg_realm(kdc->task->lp_ctx));
> +
> + ret = kadm5_init(kdc->smb_krb5_context->krb5_context,
> + discard_const_p(char, "kpasswd"),
> + NULL, /* pass */
> + discard_const_p(char, "kpasswd"),
> + &config,
> + KADM5_STRUCT_VERSION,
> + KADM5_API_VERSION_4,
> + NULL,
> + &server_handle);
> + if (ret != 0) {
> + task_server_terminate(task,
> + "KDC: Initialize kadm5",
> + true);
> + return;
> + }
> + kdc->private_data = server_handle;
> +
> + code = krb5_db_register_keytab(kdc->smb_krb5_context->krb5_context);
> + if (code != 0) {
> + task_server_terminate(task,
> + "KDC: Unable to KDB",
> + true);
> + return;
> + }
> +
> + kdc->keytab_name = talloc_asprintf(kdc, "KDB:");
> + if (kdc->keytab_name == NULL) {
> + task_server_terminate(task,
> + "KDC: Out of memory",
> + true);
> + return;
> + }
> +
> + kdc->samdb = samdb_connect(kdc,
> + kdc->task->event_ctx,
> + kdc->task->lp_ctx,
> + system_session(kdc->task->lp_ctx),
> + 0);
> + if (kdc->samdb == NULL) {
> + task_server_terminate(task,
> + "KDC: Unable to connect to sambdb",
> + true);
> + return;
> + }
> +
> + status = startup_kpasswd_server(kdc,
> + kdc,
> + task->lp_ctx,
> + ifaces);
> + if (!NT_STATUS_IS_OK(status)) {
> + task_server_terminate(task,
> + "KDC: Unable to start kpasswd server",
> + true);
> + }
> +
> + DEBUG(5,("Started kpasswd service for kdc_server\n"));
> }
>
> /*
> diff --git a/source4/kdc/wscript_build b/source4/kdc/wscript_build
> index 26d4bc80f9b..d2e0a70c698 100644
> --- a/source4/kdc/wscript_build
> +++ b/source4/kdc/wscript_build
> @@ -37,6 +37,11 @@ if bld.CONFIG_GET('SAMBA_USES_MITKDC'):
> talloc
> UTIL_RUNCMD
> MIT_KDC_IRPC
> + KDC-SERVER
> + KPASSWD-SERVICE
> + com_err
> + kadm5srv_mit
> + kdb5
> ''',
> internal_module=False)
>
> @@ -72,6 +77,8 @@ bld.SAMBA_SUBSYSTEM('KDC-SERVER',
> kpasswd_flavor_src = 'kpasswd-service.c kpasswd-helper.c'
> if bld.CONFIG_SET('SAMBA4_USES_HEIMDAL'):
> kpasswd_flavor_src = kpasswd_flavor_src + ' kpasswd-service-heimdal.c'
> +elif bld.CONFIG_GET('SAMBA_USES_MITKDC'):
> + kpasswd_flavor_src = kpasswd_flavor_src + ' kpasswd-service-mit.c'
>
> bld.SAMBA_SUBSYSTEM('KPASSWD-SERVICE',
> source=kpasswd_flavor_src,
> --
> 2.12.0
>
>
> From 7d634fb50313f7ad8589d8778d273f2ee612efbd Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 5 Sep 2016 18:01:57 +0200
> Subject: [PATCH 34/49] testprogs: Add MIT Kerberos specific kpasswd blackbox
> test
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/selftest/tests.py | 2 +
> testprogs/blackbox/test_kpasswd_mit.sh | 231 +++++++++++++++++++++++++++++++++
> 2 files changed, 233 insertions(+)
> create mode 100755 testprogs/blackbox/test_kpasswd_mit.sh
>
> diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
> index ef9c9332f74..bb1691494e1 100755
> --- a/source4/selftest/tests.py
> +++ b/source4/selftest/tests.py
> @@ -404,6 +404,8 @@ else:
> plantestsuite("samba4.blackbox.kinit_trust(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_kinit_trusts_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "forest"])
> plantestsuite("samba4.blackbox.kinit_trust(fl2003dc:local)", "fl2003dc:local", [os.path.join(bbdir, "test_kinit_trusts_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external"])
>
> + plantestsuite("samba4.blackbox.kpasswd(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_kpasswd_mit.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', "$PREFIX/ad_dc_ntvfs"])
> +
> plantestsuite("samba4.blackbox.export.keytab(ad_dc_ntvfs:local)", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_export_keytab_mit.sh"), '$SERVER', '$USERNAME', '$REALM', '$DOMAIN', "$PREFIX", smbclient4])
>
> plantestsuite("samba4.blackbox.trust_utils(fl2008r2dc:local)", "fl2008r2dc:local", [os.path.join(bbdir, "test_trust_utils.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "forest"])
> diff --git a/testprogs/blackbox/test_kpasswd_mit.sh b/testprogs/blackbox/test_kpasswd_mit.sh
> new file mode 100755
> index 00000000000..8a0bce449f3
> --- /dev/null
> +++ b/testprogs/blackbox/test_kpasswd_mit.sh
> @@ -0,0 +1,231 @@
> +#!/bin/sh
> +# Blackbox tests for chainging passwords with kinit and kpasswd
> +#
> +# Copyright (c) 2006-2007 Jelmer Vernooij <jelmer at samba.org>
> +# Copyright (c) 2006-2008 Andrew Bartlett <abartlet at samba.org>
> +# Copyright (c) 2016 Andreas Schneider <asn at samba.org>
> +
> +if [ $# -lt 6 ]; then
> +cat <<EOF
> +Usage: test_kpasswd_mit.sh SERVER USERNAME PASSWORD REALM DOMAIN PREFIX
> +EOF
> +exit 1;
> +fi
> +
> +SERVER=$1
> +USERNAME=$2
> +PASSWORD=$3
> +REALM=$4
> +DOMAIN=$5
> +PREFIX=$6
> +shift 6
> +failed=0
> +
> +samba_bindir="$BINDIR"
> +
> +samba_kinit=kinit
> +samba_kpasswd=kpasswd
> +
> +smbclient="$samba_bindir/smbclient"
> +samba_tool="$samba_bindir/samba-tool"
> +net_tool="$samba_bindir/net"
> +texpect="$samba_bindir/texpect"
> +
> +newuser="$samba_tool user create"
> +SMB_UNC="//$SERVER/tmp"
> +
> +. `dirname $0`/subunit.sh
> +. `dirname $0`/common_test_fns.inc
> +
> +do_kinit() {
> + principal="$1"
> + password="$2"
> + shift
> + shift
> + echo $password | $samba_kinit $principal
> +}
> +
> +UID_WRAPPER_ROOT=1
> +export UID_WRAPPER_ROOT
> +
> +CONFIG="--configfile=$PREFIX/etc/smb.conf"
> +export CONFIG
> +
> +testit "reset password policies beside of minimum password age of 0 days" \
> + $VALGRIND $samba_tool domain passwordsettings $CONFIG set --complexity=default --history-length=default --min-pwd-length=default --min-pwd-age=0 --max-pwd-age=default || failed=`expr $failed + 1`
> +
> +TEST_USERNAME="samson"
> +TEST_PASSWORD="testPaSS at 00%"
> +TEST_PASSWORD_NEW="testPaSS at 01%"
> +TEST_PASSWORD_SHORT="secret"
> +TEST_PASSWORD_WEAK="Supersecret"
> +TEST_PRINCIPAL="$TEST_USERNAME@$REALM"
> +
> +testit "create user locally" \
> + $VALGRIND $newuser $CONFIG $TEST_USERNAME $TEST_PASSWORD || failed=`expr $failed + 1`
> +
> +KRB5CCNAME="$PREFIX/tmpuserccache"
> +export KRB5CCNAME
> +
> +testit "kinit with user password" \
> + do_kinit $TEST_PRINCIPAL $TEST_PASSWORD || failed=`expr $failed + 1`
> +
> +test_smbclient "Test login with user kerberos ccache" \
> + "ls" "$SMB_UNC" -k yes || failed=`expr $failed + 1`
> +
> +testit "change user password with 'samba-tool user password' (unforced)" \
> + $VALGRIND $samba_tool user password -W$DOMAIN -U$TEST_USERNAME%$TEST_PASSWORD -k no --newpassword=$TEST_PASSWORD_NEW || failed=`expr $failed + 1`
> +
> +TEST_PASSWORD_OLD=$TEST_PASSWORD
> +TEST_PASSWORD=$TEST_PASSWORD_NEW
> +TEST_PASSWORD_NEW="testPaSS at 02%"
> +
> +testit "kinit with user password" \
> + do_kinit $TEST_PRINCIPAL $TEST_PASSWORD || failed=`expr $failed + 1`
> +
> +test_smbclient "Test login with user kerberos ccache" \
> + "ls" "$SMB_UNC" -k yes || failed=`expr $failed + 1`
> +
> +###########################################################
> +### check that a password mismatch is detected
> +###########################################################
> +
> +cat > $PREFIX/tmpkpasswdscript <<EOF
> +expect Password for $TEST_PRINCIPAL
> +password ${TEST_PASSWORD}\n
> +expect Enter new password
> +send ${TEST_PASSWORD_WEAK}\n
> +expect Enter it again
> +send ${TEST_PASSWORD_NEW}\n
> +expect kpasswd: Password mismatch while reading password
> +EOF
> +
> +testit_expect_failure "kpasswd check password mismatch" \
> + $texpect $PREFIX/tmpkpasswdscript $samba_kpasswd $TEST_PRINCIPAL && failed=`expr $failed + 1`
> +
> +###########################################################
> +### check that a short password is rejected
> +###########################################################
> +
> +cat > $PREFIX/tmpkpasswdscript <<EOF
> +expect Password for $TEST_PRINCIPAL
> +password ${TEST_PASSWORD}\n
> +expect Enter new password
> +send ${TEST_PASSWORD_SHORT}\n
> +expect Enter it again
> +send ${TEST_PASSWORD_SHORT}\n
> +expect Password change rejected: Password too short, password must be at least 7 characters long
> +EOF
> +
> +testit_expect_failure "kpasswd check short user password" \
> + $texpect $PREFIX/tmpkpasswdscript $samba_kpasswd $TEST_PRINCIPAL && failed=`expr $failed + 1`
> +
> +###########################################################
> +### check that a weak password is rejected
> +###########################################################
> +
> +cat > $PREFIX/tmpkpasswdscript <<EOF
> +expect Password for $TEST_PRINCIPAL
> +password ${TEST_PASSWORD}\n
> +expect Enter new password
> +send ${TEST_PASSWORD_WEAK}\n
> +expect Enter it again
> +send ${TEST_PASSWORD_WEAK}\n
> +expect Password change rejected: Password does not meet complexity requirement
> +EOF
> +
> +testit_expect_failure "kpasswd check weak user password" \
> + $texpect $PREFIX/tmpkpasswdscript $samba_kpasswd $TEST_PRINCIPAL && failed=`expr $failed + 1`
> +
> +###########################################################
> +### check that a strong password is accepted
> +###########################################################
> +
> +cat > $PREFIX/tmpkpasswdscript <<EOF
> +expect Password for $TEST_PRINCIPAL
> +password ${TEST_PASSWORD}\n
> +expect Enter new password
> +send ${TEST_PASSWORD_NEW}\n
> +expect Enter it again
> +send ${TEST_PASSWORD_NEW}\n
> +expect Password changed.
> +EOF
> +
> +testit "kpasswd change user password" \
> + $texpect $PREFIX/tmpkpasswdscript $samba_kpasswd $TEST_PRINCIPAL|| failed=`expr $failed + 1`
> +
> +TEST_PASSWORD=$TEST_PASSWORD_NEW
> +TEST_PASSWORD_NEW="testPaSS at 03%"
> +
> +test_smbclient "Test login with user kerberos" 'ls' "$SMB_UNC" -k yes -U$TEST_PRINCIPAL%$TEST_PASSWORD || failed=`expr $failed + 1`
> +
> +###########################################################
> +### Force password change at login
> +###########################################################
> +
> +testit "set password on user locally" \
> + $VALGRIND $samba_tool user setpassword $TEST_USERNAME $CONFIG --newpassword=$TEST_PASSWORD_NEW --must-change-at-next-login || failed=`expr $failed + 1`
> +
> +TEST_PASSWORD=$TEST_PASSWORD_NEW
> +TEST_PASSWORD_NEW="testPaSS at 04%"
> +
> +cat > $PREFIX/tmpkinitscript <<EOF
> +expect Password for $TEST_PRINCIPAL
> +password ${TEST_PASSWORD}\n
> +expect Password expired
> +expect Enter new password
> +send ${TEST_PASSWORD_NEW}\n
> +expect Enter it again
> +send ${TEST_PASSWORD_NEW}\n
> +EOF
> +
> +testit "kinit and change user password" \
> + $texpect $PREFIX/tmpkinitscript $samba_kinit $TEST_PRINCIPAL|| failed=`expr $failed + 1`
> +
> +TEST_PASSWORD=$TEST_PASSWORD_NEW
> +TEST_PASSWORD_NEW="testPaSS at 05%"
> +
> +test_smbclient "Test login with user kerberos" \
> + "ls" "$SMB_UNC" -k yes -U$TEST_PRINCIPAL%$TEST_PASSWORD || failed=`expr $failed + 1`
> +
> +###########################################################
> +### Test kpasswd service via 'net ads password'
> +###########################################################
> +
> +# NOTE: This call works if it is compiled with Heimdal, because the Heimdal
> +# krb5_set_password() implementation falls back to change_password. The MIT
> +# function doesn't!
> +testit_expect_failure "change user password with 'net ads password', admin: $DOMAIN/$TEST_USERNAME, target: $TEST_PRINCIPAL (will fail)" \
> + $VALGRIND $net_tool ads password -W$DOMAIN -U$TEST_PRINCIPAL%$TEST_PASSWORD $TEST_PRINCIPAL "$TEST_PASSWORD_NEW" && failed=`expr $failed + 1`
> +
> +#TEST_PASSWORD=$TEST_PASSWORD_NEW
> +#TEST_PASSWORD_NEW="testPaSS at 06%"
> +
> +#test_smbclient "Test login with smbclient (ntlm)" \
> +# "ls" "$SMB_UNC" -k no -U$TEST_PRINCIPAL%$TEST_PASSWORD || failed=`expr $failed + 1`
> +
> +###########################################################
> +### Test kpasswd service via 'net ads password' as admin
> +###########################################################
> +
> +testit "set user password with 'net ads password', admin: $DOMAIN/$USERNAME, target: $TEST_PRINCIPAL" \
> + $VALGRIND $net_tool ads password -W$DOMAIN -U$USERNAME@$REALM%$PASSWORD $TEST_PRINCIPAL "$TEST_PASSWORD_NEW" || failed=`expr $failed + 1`
> +
> +TEST_PASSWORD=$TEST_PASSWORD_NEW
> +TEST_PASSWORD_NEW="testPaSS at 07%"
> +
> +test_smbclient "Test login with smbclient (ntlm)" \
> + "ls" "$SMB_UNC" -k no -U$TEST_PRINCIPAL%$TEST_PASSWORD || failed=`expr $failed + 1`
> +
> +###########################################################
> +### Cleanup
> +###########################################################
> +
> +testit "reset password policies" \
> + $VALGRIND $samba_tool domain passwordsettings $CONFIG set --complexity=default --history-length=default --min-pwd-length=default --min-pwd-age=default --max-pwd-age=default || failed=`expr $failed + 1`
> +
> +testit "delete user" \
> + $VALGRIND $samba_tool user delete $TEST_USERNAME -U"$USERNAME%$PASSWORD" $CONFIG -k no || failed=`expr $failed + 1`
> +
> +rm -f $PREFIX/tmpuserccache $PREFIX/tmpkpasswdscript $PREFIX/tmpkinitscript
> +exit $failed
> --
> 2.12.0
>
>
> From e96c4030c516a03f3174c64bdd0468d34935de43 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 13 Apr 2015 15:58:14 +0200
> Subject: [PATCH 35/49] selftest: Skip s4u2proxy tests, no support yet
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> selftest/skip_mit_kdc | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/selftest/skip_mit_kdc b/selftest/skip_mit_kdc
> index b0c901514d5..4a51c98ea0b 100644
> --- a/selftest/skip_mit_kdc
> +++ b/selftest/skip_mit_kdc
> @@ -1,3 +1,5 @@
> # We do not support RODC yet
> .*rodc
> .*RODC
> +^samba4.ntvfs.cifs.ntlm.base.unlink
> +^samba4.ntvfs.cifs.krb5.base.unlink
> --
> 2.12.0
>
>
> From 8bff750d5dd8e6e94f878977f96971bd7d8057fb Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 23 Nov 2015 11:44:26 +0100
> Subject: [PATCH 36/49] waf: Create kerberos_implementation.py for provisioning
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> .gitignore | 3 +++
> python/wscript | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> wscript | 1 +
> 3 files changed, 50 insertions(+)
> create mode 100644 python/wscript
>
> diff --git a/.gitignore b/.gitignore
> index 1a43d43b3b3..f8d4eab2a7c 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -65,3 +65,6 @@ semantic.cache
> /.emacs.desktop*
> /.gdb_history
> .clang-format
> +
> +# generated by configure
> +python/samba/provision/kerberos_implementation.py
> diff --git a/python/wscript b/python/wscript
> new file mode 100644
> index 00000000000..f85bb6c784a
> --- /dev/null
> +++ b/python/wscript
> @@ -0,0 +1,46 @@
> +#!/usr/bin/env python
> +
> +import os
> +
> +def configure(conf):
> + kerberos_py = conf.srcdir + "/python/samba/provision/kerberos_implementation.py"
> +
> + f = open(kerberos_py, 'w')
> + try:
> + header = """#
> +# Copyright (c) 2016 Andreas Schneider <asn at samba.org>
> +#
> +# 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/>.
> +#
> +"""
> + f.write(header)
> +
> + data = """krb5_implementation = "{0}"
> +kdb_modules_dir = "{1}"
> +kdc_default_config_dir = "{2}"
> +"""
> +
> + if conf.env.HEIMDAL_KRB5_CONFIG:
> + f.write(data.format("HEIMDAL", "", ""))
> + else:
> + modulesdir = "%s/krb5/plugins/kdb" % conf.env.LIBDIR
> + paths = [ "/var/kerberos/krb5kdc", "/var/lib/kerberos/krb5kdc" ]
> + kdc_path = None
> + for p in paths:
> + if os.path.exists(p):
> + kdc_path = p
> +
> + f.write(data.format("MIT", modulesdir, kdc_path))
> + finally:
> + f.close()
> diff --git a/wscript b/wscript
> index 487260be3ad..abc8cf84f15 100644
> --- a/wscript
> +++ b/wscript
> @@ -202,6 +202,7 @@ def configure(conf):
>
> conf.RECURSE('source3')
> conf.RECURSE('lib/texpect')
> + conf.RECURSE('python')
> if conf.env.with_ctdb:
> conf.RECURSE('ctdb')
> conf.RECURSE('lib/socket')
> --
> 2.12.0
>
>
> From d398671e121307ebd70a76c62c549638a5e37117 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 12 Sep 2016 21:52:23 +0200
> Subject: [PATCH 37/49] selftest: Add a variable to indicate that selftest is
> running
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> selftest/selftest.pl | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/selftest/selftest.pl b/selftest/selftest.pl
> index 64dacbece8a..c1553e79a0b 100755
> --- a/selftest/selftest.pl
> +++ b/selftest/selftest.pl
> @@ -321,6 +321,8 @@ my $srcdir_abs = abs_path($srcdir);
> die("using an empty absolute prefix isn't allowed") unless $prefix_abs ne "";
> die("using '/' as absolute prefix isn't allowed") unless $prefix_abs ne "/";
>
> +$ENV{SAMBA_SELFTEST} = "1";
> +
> $ENV{PREFIX} = $prefix;
> $ENV{PREFIX_ABS} = $prefix_abs;
> $ENV{SRCDIR} = $srcdir;
> --
> 2.12.0
>
>
> From 941124ceb96249efdc39a48e3ba093e16033d636 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 9 Oct 2015 15:06:52 +0200
> Subject: [PATCH 38/49] python: Add provisioning support for MIT KDC in
> samba-tool
>
> Signed-off-by: Andreas Schneider <asn at cryptomilk.org>
> ---
> python/samba/netcmd/domain.py | 16 +++++-
> python/samba/provision/__init__.py | 18 ++++---
> python/samba/provision/kerberos.py | 101 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 128 insertions(+), 7 deletions(-)
> create mode 100644 python/samba/provision/kerberos.py
>
> diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py
> index e0397244725..78404fa2edc 100644
> --- a/python/samba/netcmd/domain.py
> +++ b/python/samba/netcmd/domain.py
> @@ -87,6 +87,10 @@ from samba.provision import (
> ProvisioningError
> )
>
> +from samba.provision.kerberos_implementation import (
> + krb5_implementation,
> + kdc_default_config_dir)
> +
> from samba.provision.common import (
> FILL_FULL,
> FILL_NT4SYNC,
> @@ -263,12 +267,20 @@ class cmd_domain_provision(Command):
> default="auto")
> ]
>
> + kdc_options = [
> + Option("--kdc-config-dir", type="string", metavar="KDC-CONFIG-DIR",
> + help="Set the MIT KDC config directory (default='%s')" % kdc_default_config_dir),
> + ]
> +
> if os.getenv('TEST_LDAP', "no") == "yes":
> takes_options.extend(openldap_options)
>
> if samba.is_ntvfs_fileserver_built():
> takes_options.extend(ntvfs_options)
>
> + if krb5_implementation is "MIT":
> + takes_options.extend(kdc_options)
> +
> takes_args = []
>
> def run(self, sambaopts=None, versionopts=None,
> @@ -304,6 +316,7 @@ class cmd_domain_provision(Command):
> use_xattrs="auto",
> slapd_path=None,
> use_ntvfs=False,
> + kdc_config_dir=None,
> use_rfc2307=None,
> ldap_backend_nosync=None,
> ldap_backend_extra_port=None,
> @@ -471,7 +484,8 @@ class cmd_domain_provision(Command):
> use_rfc2307=use_rfc2307, skip_sysvolacl=False,
> ldap_backend_extra_port=ldap_backend_extra_port,
> ldap_backend_forced_uri=ldap_backend_forced_uri,
> - nosync=ldap_backend_nosync, ldap_dryrun_mode=ldap_dryrun_mode)
> + nosync=ldap_backend_nosync, ldap_dryrun_mode=ldap_dryrun_mode,
> + kdcconfdir=kdc_config_dir)
>
> except ProvisioningError, e:
> raise CommandError("Provision failed", e)
> diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py
> index f8e4696a2fd..b001c544fb9 100644
> --- a/python/samba/provision/__init__.py
> +++ b/python/samba/provision/__init__.py
> @@ -118,7 +118,7 @@ import samba.registry
> from samba.schema import Schema
> from samba.samdb import SamDB
> from samba.dbchecker import dbcheck
> -
> +from samba.provision.kerberos import make_kdcconf
>
> DEFAULT_POLICY_GUID = "31B2F340-016D-11D2-945F-00C04FB984F9"
> DEFAULT_DC_POLICY_GUID = "6AC1786C-016F-11D2-945F-00C04FB984F9"
> @@ -668,10 +668,9 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
>
> return names
>
> -
> def make_smbconf(smbconf, hostname, domain, realm, targetdir,
> serverrole=None, eadb=False, use_ntvfs=False, lp=None,
> - global_param=None):
> + global_param=None, kdcconfdir=None):
> """Create a new smb.conf file based on a couple of basic settings.
> """
> assert smbconf is not None
> @@ -732,6 +731,11 @@ def make_smbconf(smbconf, hostname, domain, realm, targetdir,
> statedir = lp.get("state directory")
> lp.set("xattr_tdb:file", os.path.abspath(os.path.join(statedir, "xattr.tdb")))
>
> + make_kdcconf(realm, domain, kdcconfdir, os.path.dirname(lp.get("log file")))
> + if kdcconfdir is not None:
> + kdcconf = "%s/kdc.conf" % kdcconfdir
> + lp.set("mit kdc config", kdcconf)
> +
> shares = {}
> if serverrole == "active directory domain controller":
> shares["sysvol"] = os.path.join(lp.get("state directory"), "sysvol")
> @@ -1925,7 +1929,7 @@ def provision_fake_ypserver(logger, samdb, domaindn, netbiosname, nisdomain,
> samdb.transaction_commit()
>
>
> -def provision(logger, session_info, smbconf=None,
> +def provision(logger, session_info, smbconf=None, kdcconfdir=None,
> targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None,
> domaindn=None, schemadn=None, configdn=None, serverdn=None,
> domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None,
> @@ -2009,11 +2013,13 @@ def provision(logger, session_info, smbconf=None,
> make_smbconf(smbconf, hostname, domain, realm,
> targetdir, serverrole=serverrole,
> eadb=useeadb, use_ntvfs=use_ntvfs,
> - lp=lp, global_param=global_param)
> + lp=lp, global_param=global_param,
> + kdcconfdir=kdcconfdir)
> else:
> make_smbconf(smbconf, hostname, domain, realm, targetdir,
> serverrole=serverrole,
> - eadb=useeadb, use_ntvfs=use_ntvfs, lp=lp, global_param=global_param)
> + eadb=useeadb, use_ntvfs=use_ntvfs, lp=lp, global_param=global_param,
> + kdcconfdir=kdcconfdir)
>
> if lp is None:
> lp = samba.param.LoadParm()
> diff --git a/python/samba/provision/kerberos.py b/python/samba/provision/kerberos.py
> new file mode 100644
> index 00000000000..e5b8186216c
> --- /dev/null
> +++ b/python/samba/provision/kerberos.py
> @@ -0,0 +1,101 @@
> +# Unix SMB/CIFS implementation
> +#
> +# Backend code for provisioning a Samba AD server
> +#
> +# Copyright (c) 2015 Andreas Schneider <asn at samba.org>
> +#
> +# 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/>.
> +#
> +
> +from samba.provision.kerberos_implementation import (
> + krb5_implementation,
> + kdb_modules_dir,
> + kdc_default_config_dir)
> +import os
> +
> +def make_kdcconf(realm, domain, kdcconfdir, logdir):
> +
> + if krb5_implementation is "HEIMDAL":
> + return
> +
> + # Do nothing if kdc.conf has been set
> + if 'KRB5_KDC_PROFILE' in os.environ:
> + return
> +
> + # We are in selftest
> + if 'SAMBA_SELFTEST' in os.environ and 'MITKRB5' in os.environ:
> + return
> +
> + # If not specified use the default
> + if kdcconfdir is None:
> + kdcconfdir = kdc_default_config_dir
> +
> + kdcconf = "%s/kdc.conf" % kdcconfdir
> +
> + assert domain is not None
> + domain = domain.upper()
> +
> + assert realm is not None
> + realm = realm.upper()
> +
> + f = open(kdcconf, 'w')
> + try:
> + f.write("[kdcdefaults]\n")
> +
> + f.write("\tkdc_ports = 88\n")
> + f.write("\tkdc_tcp_ports = 88\n")
> + f.write("\tkadmind_port = 464\n")
> + f.write("\n")
> +
> + f.write("[realms]\n")
> +
> + f.write("\t%s = {\n" % realm)
> + f.write("\t}\n")
> + f.write("\n")
> +
> + f.write("\t%s = {\n" % realm.lower())
> + f.write("\t}\n")
> + f.write("\n")
> +
> + f.write("\t%s = {\n" % domain)
> + f.write("\t}\n")
> + f.write("\n")
> +
> + f.write("[dbmodules]\n")
> +
> + f.write("\tdb_modules_dir = %s\n" % kdb_modules_dir)
> + f.write("\n")
> +
> + f.write("\t%s = {\n" % realm)
> + f.write("\t\tdb_library = samba\n")
> + f.write("\t}\n")
> + f.write("\n")
> +
> + f.write("\t%s = {\n" % realm.lower())
> + f.write("\t\tdb_library = samba\n")
> + f.write("\t}\n")
> + f.write("\n")
> +
> + f.write("\t%s = {\n" % domain)
> + f.write("\t\tdb_library = samba\n")
> + f.write("\t}\n")
> + f.write("\n")
> +
> + f.write("[logging]\n")
> +
> + f.write("\tkdc = FILE:%s/mit_kdc.log\n" % logdir)
> + f.write("\tadmin_server = FILE:%s/mit_kadmin.log\n" % logdir)
> + f.write("\n")
> + finally:
> + f.close()
> --
> 2.12.0
>
>
> From 1b78f1cb2f5e36b8c346649e77957ba9153de8ad Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Mon, 23 Nov 2015 15:08:54 +0100
> Subject: [PATCH 39/49] waf: Move python build instructions to wscript
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> python/wscript | 44 ++++++++++++++++++++++++++++++++++++++++++++
> python/wscript_build | 36 ------------------------------------
> 2 files changed, 44 insertions(+), 36 deletions(-)
> delete mode 100644 python/wscript_build
>
> diff --git a/python/wscript b/python/wscript
> index f85bb6c784a..cfc127a6a7b 100644
> --- a/python/wscript
> +++ b/python/wscript
> @@ -44,3 +44,47 @@ kdc_default_config_dir = "{2}"
> f.write(data.format("MIT", modulesdir, kdc_path))
> finally:
> f.close()
> +
> +def build(bld):
> + bld.SAMBA_LIBRARY('samba_python',
> + source=[],
> + deps='''
> + LIBPYTHON
> + pytalloc-util
> + pyrpc_util
> + ''',
> + grouping_library=True,
> + private_library=True,
> + pyembed=True,
> + enabled=bld.PYTHON_BUILD_IS_ENABLED())
> +
> + bld.SAMBA_SUBSYSTEM('LIBPYTHON',
> + source='modules.c',
> + public_deps='',
> + init_function_sentinel='{NULL,NULL}',
> + deps='talloc',
> + pyext=True,
> + enabled=bld.PYTHON_BUILD_IS_ENABLED())
> +
> + for env in bld.gen_python_environments():
> + pytalloc_util = bld.pyembed_libname('pytalloc-util')
> + pyparam_util = bld.pyembed_libname('pyparam_util')
> +
> + bld.SAMBA_PYTHON('python_glue',
> + source='pyglue.c',
> + deps='''
> + %s
> + samba-util
> + netif
> + %s
> + ''' % (pyparam_util, pytalloc_util),
> + realname='samba/_glue.so')
> +
> + if bld.PYTHON_BUILD_IS_ENABLED():
> + for env in bld.gen_python_environments():
> + # install out various python scripts for use by make test
> + bld.SAMBA_SCRIPT('samba_python_files',
> + pattern='samba/**/*.py',
> + installdir='python')
> +
> + bld.INSTALL_WILDCARD('${PYTHONARCHDIR}', 'samba/**/*.py', flat=False)
> diff --git a/python/wscript_build b/python/wscript_build
> deleted file mode 100644
> index 87da26f710f..00000000000
> --- a/python/wscript_build
> +++ /dev/null
> @@ -1,36 +0,0 @@
> -#!/usr/bin/env python
> -
> -bld.SAMBA_LIBRARY('samba_python',
> - source=[],
> - deps='LIBPYTHON pytalloc-util pyrpc_util',
> - grouping_library=True,
> - private_library=True,
> - pyembed=True,
> - enabled=bld.PYTHON_BUILD_IS_ENABLED())
> -
> -bld.SAMBA_SUBSYSTEM('LIBPYTHON',
> - source='modules.c',
> - public_deps='',
> - init_function_sentinel='{NULL,NULL}',
> - deps='talloc',
> - pyext=True,
> - enabled=bld.PYTHON_BUILD_IS_ENABLED())
> -
> -for env in bld.gen_python_environments():
> - pytalloc_util = bld.pyembed_libname('pytalloc-util')
> - pyparam_util = bld.pyembed_libname('pyparam_util')
> -
> - bld.SAMBA_PYTHON('python_glue',
> - source='pyglue.c',
> - deps='%s samba-util netif %s' % (pyparam_util, pytalloc_util),
> - realname='samba/_glue.so'
> - )
> -
> -if bld.PYTHON_BUILD_IS_ENABLED():
> - for env in bld.gen_python_environments():
> - # install out various python scripts for use by make test
> - bld.SAMBA_SCRIPT('samba_python_files',
> - pattern='samba/**/*.py',
> - installdir='python')
> -
> - bld.INSTALL_WILDCARD('${PYTHONARCHDIR}', 'samba/**/*.py', flat=False)
> --
> 2.12.0
>
>
> From b25a9de92c37dc15fcd579534860640aff8c79a6 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Tue, 27 Sep 2016 18:53:44 +0200
> Subject: [PATCH 40/49] s4-torture: Fix reauth tests with smaller clockskew
> grace time
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> selftest/target/Samba.pm | 2 +-
> source4/torture/raw/session.c | 8 ++++----
> source4/torture/smb2/session.c | 4 ++--
> 3 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
> index 930cb44e744..e27939e982e 100644
> --- a/selftest/target/Samba.pm
> +++ b/selftest/target/Samba.pm
> @@ -203,7 +203,7 @@ sub mk_krb5_conf($$)
> allow_weak_crypto = yes
> # Set the grace clocskew to 1 second
> # This is especially required by samba3.raw.session krb5
> - clockskew = 1
> + clockskew = 5
> # We are running on the same machine, do not correct
> # system clock differences
> kdc_timesync = 0
> diff --git a/source4/torture/raw/session.c b/source4/torture/raw/session.c
> index 6938c88f95d..26b93cca512 100644
> --- a/source4/torture/raw/session.c
> +++ b/source4/torture/raw/session.c
> @@ -304,8 +304,8 @@ static bool test_session_expire1(struct torture_context *tctx)
> torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
> "raw_fileinfo failed");
>
> - torture_comment(tctx, "sleep 5 seconds\n");
> - smb_msleep(5*1000);
> + torture_comment(tctx, "sleep 10 seconds\n");
> + smb_msleep(10*1000);
> }
>
> /*
> @@ -343,8 +343,8 @@ static bool test_session_expire1(struct torture_context *tctx)
> torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
> "raw_fileinfo failed");
>
> - torture_comment(tctx, "sleep 5 seconds\n");
> - smb_msleep(5*1000);
> + torture_comment(tctx, "sleep 10 seconds\n");
> + smb_msleep(10*1000);
>
> torture_comment(tctx, "query info => EXPIRED\n");
> ZERO_STRUCT(qfinfo.access_information.out);
> diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c
> index e35ec85c6a3..e3c5676a80a 100644
> --- a/source4/torture/smb2/session.c
> +++ b/source4/torture/smb2/session.c
> @@ -1125,8 +1125,8 @@ static bool test_session_expire1(struct torture_context *tctx)
> torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
> "smb2_getinfo_file failed");
>
> - torture_comment(tctx, "sleep 5 seconds\n");
> - smb_msleep(5*1000);
> + torture_comment(tctx, "sleep 10 seconds\n");
> + smb_msleep(10*1000);
>
> torture_comment(tctx, "query info => EXPIRED\n");
> ZERO_STRUCT(qfinfo.access_information.out);
> --
> 2.12.0
>
>
> From af75c775c2903f362c7dfb665ea0802c7e86f9bc Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 30 Sep 2016 07:41:09 +0200
> Subject: [PATCH 41/49] s4-kdc: Fix logging with the KDB driver
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit_samba.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
> index 8a2bfe9b715..0531b017fdb 100644
> --- a/source4/kdc/mit_samba.c
> +++ b/source4/kdc/mit_samba.c
> @@ -76,7 +76,7 @@ int mit_samba_context_init(struct mit_samba_context **_ctx)
> goto done;
> }
>
> - setup_logging("mitkdc", DEBUG_STDOUT);
> + setup_logging("mitkdc", DEBUG_DEFAULT_STDOUT);
>
> /* init s4 configuration */
> s4_conf_file = lpcfg_configfile(base_ctx.lp_ctx);
> --
> 2.12.0
>
>
> From a3610e6c152ce58f090cdaddc88f9c83a7366d5d Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 29 Sep 2016 02:03:35 +0200
> Subject: [PATCH 42/49] s4-kdc: Implement mit_samba_get_pac()
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit_samba.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
> source4/kdc/mit_samba.h | 6 +++++
> 2 files changed, 74 insertions(+)
>
> diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
> index 0531b017fdb..275a507e86e 100644
> --- a/source4/kdc/mit_samba.c
> +++ b/source4/kdc/mit_samba.c
> @@ -366,6 +366,74 @@ int mit_samba_get_pac_data(struct mit_samba_context *ctx,
> return 0;
> }
>
> +int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
> + krb5_context context,
> + krb5_db_entry *client,
> + krb5_keyblock *client_key,
> + krb5_pac *pac)
> +{
> + TALLOC_CTX *tmp_ctx;
> + DATA_BLOB *logon_info_blob = NULL;
> + DATA_BLOB *upn_dns_info_blob = NULL;
> + DATA_BLOB *cred_ndr = NULL;
> + DATA_BLOB **cred_ndr_ptr = NULL;
> + DATA_BLOB cred_blob = data_blob_null;
> + DATA_BLOB *pcred_blob = NULL;
> + NTSTATUS nt_status;
> + krb5_error_code code;
> + struct samba_kdc_entry *skdc_entry;
> +
> + skdc_entry = talloc_get_type_abort(client->e_data,
> + struct samba_kdc_entry);
> +
> + tmp_ctx = talloc_named(smb_ctx,
> + 0,
> + "mit_samba_get_pac_data_blobs context");
> + if (tmp_ctx == NULL) {
> + return ENOMEM;
> + }
> +
> +#if 0 /* TODO Find out if this is a pkinit_reply key */
> + /* Check if we have a PREAUTH key */
> + if (client_key != NULL) {
> + cred_ndr_ptr = &cred_ndr;
> + }
> +#endif
> +
> + nt_status = samba_kdc_get_pac_blobs(tmp_ctx,
> + skdc_entry,
> + &logon_info_blob,
> + cred_ndr_ptr,
> + &upn_dns_info_blob);
> + if (!NT_STATUS_IS_OK(nt_status)) {
> + talloc_free(tmp_ctx);
> + return EINVAL;
> + }
> +
> + if (cred_ndr != NULL) {
> + code = samba_kdc_encrypt_pac_credentials(context,
> + client_key,
> + cred_ndr,
> + tmp_ctx,
> + &cred_blob);
> + if (code != 0) {
> + talloc_free(tmp_ctx);
> + return code;
> + }
> + pcred_blob = &cred_blob;
> + }
> +
> + code = samba_make_krb5_pac(context,
> + logon_info_blob,
> + pcred_blob,
> + upn_dns_info_blob,
> + NULL,
> + pac);
> +
> + talloc_free(tmp_ctx);
> + return code;
> +}
> +
> int mit_samba_update_pac_data(struct mit_samba_context *ctx,
> krb5_db_entry *client,
> DATA_BLOB *pac_data,
> diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h
> index 277b2e57a93..5be77958dc4 100644
> --- a/source4/kdc/mit_samba.h
> +++ b/source4/kdc/mit_samba.h
> @@ -51,6 +51,12 @@ int mit_samba_get_pac_data(struct mit_samba_context *ctx,
> krb5_db_entry *client,
> DATA_BLOB *data);
>
> +int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
> + krb5_context context,
> + krb5_db_entry *client,
> + krb5_keyblock *client_key,
> + krb5_pac *pac);
> +
> int mit_samba_update_pac_data(struct mit_samba_context *ctx,
> krb5_db_entry *client,
> DATA_BLOB *pac_data,
> --
> 2.12.0
>
>
> From 89514a8e4d3936765cf1fff9f2845611c2f3f917 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 29 Sep 2016 02:04:00 +0200
> Subject: [PATCH 43/49] s4-kdc: Use mit_samba_get_pac() in ks_get_pac()
>
> This adds UPN_DNS_INFO to the PAC.
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit-kdb/kdb_samba_policies.c | 30 ++++++++----------------------
> 1 file changed, 8 insertions(+), 22 deletions(-)
>
> diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c
> index 396e6fe9d31..8c3a85b1f1f 100644
> --- a/source4/kdc/mit-kdb/kdb_samba_policies.c
> +++ b/source4/kdc/mit-kdb/kdb_samba_policies.c
> @@ -155,11 +155,10 @@ done:
>
> static krb5_error_code ks_get_pac(krb5_context context,
> krb5_db_entry *client,
> + krb5_keyblock *client_key,
> krb5_pac *pac)
> {
> struct mit_samba_context *mit_ctx;
> - DATA_BLOB pac_data;
> - krb5_data data;
> krb5_error_code code;
>
> mit_ctx = ks_get_context(context);
> @@ -167,27 +166,15 @@ static krb5_error_code ks_get_pac(krb5_context context,
> return KRB5_KDB_DBNOTINITED;
> }
>
> - code = mit_samba_get_pac_data(mit_ctx,
> - client,
> - &pac_data);
> + code = mit_samba_get_pac(mit_ctx,
> + context,
> + client,
> + client_key,
> + pac);
> if (code != 0) {
> return code;
> }
>
> - code = krb5_pac_init(context, pac);
> - if (code != 0) {
> - goto done;
> - }
> -
> - data = ks_make_data(pac_data.data, pac_data.length);
> -
> - code = krb5_pac_add_buffer(context, *pac, PAC_LOGON_INFO, &data);
> - if (code != 0) {
> - goto done;
> - }
> -
> -done:
> - free(pac_data.data);
> return code;
> }
>
> @@ -332,8 +319,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
> is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
>
> if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
> -
> - code = ks_get_pac(context, client, &pac);
> + code = ks_get_pac(context, client, client_key, &pac);
> if (code != 0) {
> goto done;
> }
> @@ -350,7 +336,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
>
> if (pac == NULL && client != NULL) {
>
> - code = ks_get_pac(context, client, &pac);
> + code = ks_get_pac(context, client, client_key, &pac);
> if (code != 0) {
> goto done;
> }
> --
> 2.12.0
>
>
> From ec0721544a89f9caa996dbf3d558590d80250864 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 26 Jan 2017 17:04:19 +0100
> Subject: [PATCH 44/49] mit-samba: Remove unused mit_samba_get_pac_data()
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit_samba.c | 35 -----------------------------------
> source4/kdc/mit_samba.h | 4 ----
> 2 files changed, 39 deletions(-)
>
> diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
> index 275a507e86e..82a6dfddbe1 100644
> --- a/source4/kdc/mit_samba.c
> +++ b/source4/kdc/mit_samba.c
> @@ -331,41 +331,6 @@ int mit_samba_get_nextkey(struct mit_samba_context *ctx,
> return ret;
> }
>
> -int mit_samba_get_pac_data(struct mit_samba_context *ctx,
> - krb5_db_entry *client,
> - DATA_BLOB *data)
> -{
> - TALLOC_CTX *tmp_ctx;
> - DATA_BLOB *pac_blob;
> - NTSTATUS nt_status;
> - struct samba_kdc_entry *skdc_entry;
> -
> - skdc_entry = talloc_get_type_abort(client->e_data,
> - struct samba_kdc_entry);
> -
> - tmp_ctx = talloc_named(ctx, 0, "mit_samba_get_pac_data context");
> - if (!tmp_ctx) {
> - return ENOMEM;
> - }
> -
> - nt_status = samba_kdc_get_pac_blob(tmp_ctx, skdc_entry, &pac_blob);
> - if (!NT_STATUS_IS_OK(nt_status)) {
> - talloc_free(tmp_ctx);
> - return EINVAL;
> - }
> -
> - data->data = (uint8_t *)malloc(pac_blob->length);
> - if (!data->data) {
> - talloc_free(tmp_ctx);
> - return ENOMEM;
> - }
> - memcpy(data->data, pac_blob->data, pac_blob->length);
> - data->length = pac_blob->length;
> -
> - talloc_free(tmp_ctx);
> - return 0;
> -}
> -
> int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
> krb5_context context,
> krb5_db_entry *client,
> diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h
> index 5be77958dc4..37e7d8d5126 100644
> --- a/source4/kdc/mit_samba.h
> +++ b/source4/kdc/mit_samba.h
> @@ -47,10 +47,6 @@ int mit_samba_get_firstkey(struct mit_samba_context *ctx,
> int mit_samba_get_nextkey(struct mit_samba_context *ctx,
> krb5_db_entry **_kentry);
>
> -int mit_samba_get_pac_data(struct mit_samba_context *ctx,
> - krb5_db_entry *client,
> - DATA_BLOB *data);
> -
> int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
> krb5_context context,
> krb5_db_entry *client,
> --
> 2.12.0
>
>
> From 89e1ad8de5fcff2cc56069605e6b1d48f791f62e Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 29 Sep 2016 08:38:58 +0200
> Subject: [PATCH 45/49] s4-pac-glue: Do not add an empty PAC_TYPE_LOGON_NAME
> with MIT
>
> MIT Kerberos will insert an empty PAC_TYPE_LOGON_NAME during
> krb5_pac_sign().
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/pac-glue.c | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
> index 079030ee5e8..60c6c8d54f0 100644
> --- a/source4/kdc/pac-glue.c
> +++ b/source4/kdc/pac-glue.c
> @@ -420,10 +420,13 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
> krb5_data cred_data;
> krb5_data upn_data;
> krb5_data deleg_data;
> - krb5_data null_data;
> krb5_error_code ret;
> -
> - ZERO_STRUCT(null_data);
> +#ifdef SAMBA4_USES_HEIMDAL
> + krb5_data null_data {
> + .length = 0,
> + .data = NULL,
> + };
> +#endif
>
> /* The user account may be set not to want the PAC */
> if (logon_blob == NULL) {
> @@ -503,10 +506,13 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
> }
> }
>
> +#ifdef SAMBA4_USES_HEIMDAL
> /*
> * null_data will be filled by the generic KDC code in the caller
> * here we just add it in order to have it before
> * PAC_TYPE_UPN_DNS_INFO
> + *
> + * Not needed with MIT Kerberos - asn
> */
> ret = krb5_pac_add_buffer(context, *pac,
> PAC_TYPE_LOGON_NAME,
> @@ -516,6 +522,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
> smb_krb5_free_data_contents(context, &deleg_data);
> return ret;
> }
> +#endif
>
> if (upn_blob != NULL) {
> ret = krb5_pac_add_buffer(context, *pac,
> --
> 2.12.0
>
>
> From 48d6a8761f307a722976111d63071674efac61c4 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 30 Sep 2016 07:43:31 +0200
> Subject: [PATCH 46/49] s4-kdc: Implement mit_samba_get_repac()
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit_samba.c | 382 ++++++++++++++++++++++++++++++++++++++++++++++++
> source4/kdc/mit_samba.h | 10 ++
> 2 files changed, 392 insertions(+)
>
> diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
> index 82a6dfddbe1..9e605f05506 100644
> --- a/source4/kdc/mit_samba.c
> +++ b/source4/kdc/mit_samba.c
> @@ -30,6 +30,7 @@
> #include "kdc/sdb.h"
> #include "kdc/sdb_kdb.h"
> #include "auth/kerberos/kerberos.h"
> +#include "auth/kerberos/pac_utils.h"
> #include "kdc/samba_kdc.h"
> #include "kdc/pac-glue.h"
> #include "kdc/db-glue.h"
> @@ -468,6 +469,387 @@ done:
> return ret;
> }
>
> +int mit_samba_reget_pac(struct mit_samba_context *ctx,
> + krb5_context context,
> + int flags,
> + krb5_const_principal client_principal,
> + krb5_db_entry *client,
> + krb5_db_entry *server,
> + krb5_db_entry *krbtgt,
> + krb5_keyblock *krbtgt_keyblock,
> + krb5_pac *pac)
> +{
> + TALLOC_CTX *tmp_ctx;
> + krb5_error_code code;
> + NTSTATUS nt_status;
> + DATA_BLOB *pac_blob = NULL;
> + DATA_BLOB *upn_blob = NULL;
> + DATA_BLOB *deleg_blob = NULL;
> + struct samba_kdc_entry *client_skdc_entry = NULL;
> + struct samba_kdc_entry *krbtgt_skdc_entry;
> + bool is_in_db = false;
> + bool is_untrusted = false;
> + size_t num_types = 0;
> + uint32_t *types = NULL;
> + uint32_t forced_next_type = 0;
> + size_t i = 0;
> + ssize_t logon_info_idx = -1;
> + ssize_t delegation_idx = -1;
> + ssize_t logon_name_idx = -1;
> + ssize_t upn_dns_info_idx = -1;
> + ssize_t srv_checksum_idx = -1;
> + ssize_t kdc_checksum_idx = -1;
> + krb5_pac new_pac = NULL;
> + bool ok;
> +
> + if (client != NULL) {
> + client_skdc_entry =
> + talloc_get_type_abort(client->e_data,
> + struct samba_kdc_entry);
> +
> + /* The user account may be set not to want the PAC */
> + ok = samba_princ_needs_pac(client_skdc_entry);
> + if (!ok) {
> + return EINVAL;
> + }
> + }
> +
> + if (krbtgt == NULL) {
> + return EINVAL;
> + }
> + krbtgt_skdc_entry =
> + talloc_get_type_abort(krbtgt->e_data,
> + struct samba_kdc_entry);
> +
> + tmp_ctx = talloc_named(ctx, 0, "mit_samba_reget_pac context");
> + if (!tmp_ctx) {
> + return ENOMEM;
> + }
> +
> + code = samba_krbtgt_is_in_db(krbtgt_skdc_entry,
> + &is_in_db,
> + &is_untrusted);
> + if (code != 0) {
> + goto done;
> + }
> +
> + if (is_untrusted) {
> + if (client == NULL) {
> + return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
> + }
> +
> + nt_status = samba_kdc_get_pac_blobs(tmp_ctx,
> + client_skdc_entry,
> + &pac_blob,
> + NULL,
> + &upn_blob);
> + if (!NT_STATUS_IS_OK(nt_status)) {
> + code = EINVAL;
> + goto done;
> + }
> + } else {
> + struct PAC_SIGNATURE_DATA *pac_srv_sig;
> + struct PAC_SIGNATURE_DATA *pac_kdc_sig;
> +
> + pac_blob = talloc_zero(tmp_ctx, DATA_BLOB);
> + if (pac_blob == NULL) {
> + code = ENOMEM;
> + goto done;
> + }
> +
> + pac_srv_sig = talloc_zero(tmp_ctx, struct PAC_SIGNATURE_DATA);
> + if (pac_srv_sig == NULL) {
> + code = ENOMEM;
> + goto done;
> + }
> +
> + pac_kdc_sig = talloc_zero(tmp_ctx, struct PAC_SIGNATURE_DATA);
> + if (pac_kdc_sig == NULL) {
> + code = ENOMEM;
> + goto done;
> + }
> +
> + nt_status = samba_kdc_update_pac_blob(tmp_ctx,
> + context,
> + *pac,
> + pac_blob,
> + pac_srv_sig,
> + pac_kdc_sig);
> + if (!NT_STATUS_IS_OK(nt_status)) {
> + DEBUG(0, ("Update PAC blob failed: %s\n",
> + nt_errstr(nt_status)));
> + code = EINVAL;
> + goto done;
> + }
> +
> + if (is_in_db) {
> + /*
> + * Now check the KDC signature, fetching the correct
> + * key based on the enc type.
> + */
> + code = check_pac_checksum(pac_srv_sig->signature,
> + pac_kdc_sig,
> + context,
> + krbtgt_keyblock);
> + if (code != 0) {
> + DBG_INFO("PAC KDC signature failed to verify\n");
> + goto done;
> + }
> + }
> + }
> +
> + if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
> + deleg_blob = talloc_zero(tmp_ctx, DATA_BLOB);
> + if (deleg_blob == NULL) {
> + code = ENOMEM;
> + goto done;
> + }
> +
> + nt_status = samba_kdc_update_delegation_info_blob(tmp_ctx,
> + context,
> + *pac,
> + server->princ,
> + discard_const(client_principal),
> + deleg_blob);
> + if (!NT_STATUS_IS_OK(nt_status)) {
> + DEBUG(0, ("Update delegation info failed: %s\n",
> + nt_errstr(nt_status)));
> + code = EINVAL;
> + goto done;
> + }
> + }
> +
> + /* Check the types of the given PAC */
> + code = krb5_pac_get_types(context, *pac, &num_types, &types);
> + if (code != 0) {
> + goto done;
> + }
> +
> + for (i = 0; i < num_types; i++) {
> + switch (types[i]) {
> + case PAC_TYPE_LOGON_INFO:
> + if (logon_info_idx != -1) {
> + DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
> + types[i],
> + logon_info_idx,
> + i);
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + logon_info_idx = i;
> + break;
> + case PAC_TYPE_CONSTRAINED_DELEGATION:
> + if (delegation_idx != -1) {
> + DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
> + types[i],
> + delegation_idx,
> + i);
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + delegation_idx = i;
> + break;
> + case PAC_TYPE_LOGON_NAME:
> + if (logon_name_idx != -1) {
> + DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
> + types[i],
> + logon_name_idx,
> + i);
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + logon_name_idx = i;
> + break;
> + case PAC_TYPE_UPN_DNS_INFO:
> + if (upn_dns_info_idx != -1) {
> + DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
> + types[i],
> + upn_dns_info_idx,
> + i);
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + upn_dns_info_idx = i;
> + break;
> + case PAC_TYPE_SRV_CHECKSUM:
> + if (srv_checksum_idx != -1) {
> + DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
> + types[i],
> + srv_checksum_idx,
> + i);
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + srv_checksum_idx = i;
> + break;
> + case PAC_TYPE_KDC_CHECKSUM:
> + if (kdc_checksum_idx != -1) {
> + DBG_WARNING("logon type[%u] twice [%zd] and [%zu]: \n",
> + types[i],
> + kdc_checksum_idx,
> + i);
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + kdc_checksum_idx = i;
> + break;
> + default:
> + continue;
> + }
> + }
> +
> + if (logon_info_idx == -1) {
> + DEBUG(1, ("PAC_TYPE_LOGON_INFO missing\n"));
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + if (logon_name_idx == -1) {
> + DEBUG(1, ("PAC_TYPE_LOGON_NAME missing\n"));
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + if (srv_checksum_idx == -1) {
> + DEBUG(1, ("PAC_TYPE_SRV_CHECKSUM missing\n"));
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> + if (kdc_checksum_idx == -1) {
> + DEBUG(1, ("PAC_TYPE_KDC_CHECKSUM missing\n"));
> + SAFE_FREE(types);
> + code = EINVAL;
> + goto done;
> + }
> +
> + /* Build an updated PAC */
> + code = krb5_pac_init(context, &new_pac);
> + if (code != 0) {
> + SAFE_FREE(types);
> + goto done;
> + }
> +
> + for (i = 0;;) {
> + krb5_data type_data;
> + DATA_BLOB type_blob = data_blob_null;
> + uint32_t type;
> +
> + if (forced_next_type != 0) {
> + /*
> + * We need to inject possible missing types
> + */
> + type = forced_next_type;
> + forced_next_type = 0;
> + } else if (i < num_types) {
> + type = types[i];
> + i++;
> + } else {
> + break;
> + }
> +
> + switch (type) {
> + case PAC_TYPE_LOGON_INFO:
> + type_blob = *pac_blob;
> +
> + if (delegation_idx == -1 && deleg_blob != NULL) {
> + /* inject CONSTRAINED_DELEGATION behind */
> + forced_next_type = PAC_TYPE_CONSTRAINED_DELEGATION;
> + }
> + break;
> + case PAC_TYPE_CONSTRAINED_DELEGATION:
> + if (deleg_blob != NULL) {
> + type_blob = *deleg_blob;
> + }
> + break;
> + case PAC_TYPE_CREDENTIAL_INFO:
> + /*
> + * Note that we copy the credential blob,
> + * as it's only usable with the PKINIT based
> + * AS-REP reply key, it's only available on the
> + * host which did the AS-REQ/AS-REP exchange.
> + *
> + * This matches Windows 2008R2...
> + */
> + break;
> + case PAC_TYPE_LOGON_NAME:
> + /*
> + * This is generated in the main KDC code
> + */
> + continue;
> + case PAC_TYPE_UPN_DNS_INFO:
> + /*
> + * Replace in the RODC case, otherwise
> + * upn_blob is NULL and we just copy.
> + */
> + if (upn_blob != NULL) {
> + type_blob = *upn_blob;
> + }
> + break;
> + case PAC_TYPE_SRV_CHECKSUM:
> + /*
> + * This is generated in the main KDC code
> + */
> + continue;
> + case PAC_TYPE_KDC_CHECKSUM:
> + /*
> + * This is generated in the main KDC code
> + */
> + continue;
> + default:
> + /* just copy... */
> + break;
> + }
> +
> + if (type_blob.length != 0) {
> + code = smb_krb5_copy_data_contents(&type_data,
> + type_blob.data,
> + type_blob.length);
> + if (code != 0) {
> + SAFE_FREE(types);
> + krb5_pac_free(context, new_pac);
> + goto done;
> + }
> + } else {
> + code = krb5_pac_get_buffer(context,
> + *pac,
> + type,
> + &type_data);
> + if (code != 0) {
> + SAFE_FREE(types);
> + krb5_pac_free(context, new_pac);
> + goto done;
> + }
> + }
> +
> + code = krb5_pac_add_buffer(context,
> + new_pac,
> + type,
> + &type_data);
> + smb_krb5_free_data_contents(context, &type_data);
> + if (code != 0) {
> + SAFE_FREE(types);
> + krb5_pac_free(context, new_pac);
> + goto done;
> + }
> + }
> +
> + SAFE_FREE(types);
> +
> + /* We now replace the pac */
> + krb5_pac_free(context, *pac);
> + *pac = new_pac;
> +done:
> + talloc_free(tmp_ctx);
> + return code;
> +}
> +
> /* provide header, function is exported but there are no public headers */
>
> krb5_error_code encode_krb5_padata_sequence(krb5_pa_data *const *rep, krb5_data **code);
> diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h
> index 37e7d8d5126..b74a2d7a971 100644
> --- a/source4/kdc/mit_samba.h
> +++ b/source4/kdc/mit_samba.h
> @@ -53,6 +53,16 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
> krb5_keyblock *client_key,
> krb5_pac *pac);
>
> +int mit_samba_reget_pac(struct mit_samba_context *ctx,
> + krb5_context context,
> + int flags,
> + krb5_const_principal client_principal,
> + krb5_db_entry *client,
> + krb5_db_entry *server,
> + krb5_db_entry *krbtgt,
> + krb5_keyblock *krbtgt_keyblock,
> + krb5_pac *pac);
> +
> int mit_samba_update_pac_data(struct mit_samba_context *ctx,
> krb5_db_entry *client,
> DATA_BLOB *pac_data,
> --
> 2.12.0
>
>
> From a31717e312e984bde6d9d9236c8745882e5bebb8 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 30 Sep 2016 07:43:47 +0200
> Subject: [PATCH 47/49] s4-kdc: Use mit_samba_reget_pac() in ks_verify_pac()
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit-kdb/kdb_samba_policies.c | 50 +++++++++++++++++---------------
> 1 file changed, 27 insertions(+), 23 deletions(-)
>
> diff --git a/source4/kdc/mit-kdb/kdb_samba_policies.c b/source4/kdc/mit-kdb/kdb_samba_policies.c
> index 8c3a85b1f1f..81140abfd50 100644
> --- a/source4/kdc/mit-kdb/kdb_samba_policies.c
> +++ b/source4/kdc/mit-kdb/kdb_samba_policies.c
> @@ -182,6 +182,8 @@ static krb5_error_code ks_verify_pac(krb5_context context,
> unsigned int flags,
> krb5_const_principal client_princ,
> krb5_db_entry *client,
> + krb5_db_entry *server,
> + krb5_db_entry *krbtgt,
> krb5_keyblock *server_key,
> krb5_keyblock *krbtgt_key,
> krb5_timestamp authtime,
> @@ -191,9 +193,7 @@ static krb5_error_code ks_verify_pac(krb5_context context,
> struct mit_samba_context *mit_ctx;
> krb5_authdata **authdata = NULL;
> krb5_pac ipac = NULL;
> - DATA_BLOB pac_data = { NULL, 0 };
> DATA_BLOB logon_data = { NULL, 0 };
> - krb5_data data;
> krb5_error_code code;
>
> mit_ctx = ks_get_context(context);
> @@ -257,28 +257,23 @@ static krb5_error_code ks_verify_pac(krb5_context context,
> }
>
> /* check and update PAC */
> - pac_data.data = authdata[0]->contents;
> - pac_data.length = authdata[0]->length;
> -
> - code = mit_samba_update_pac_data(mit_ctx,
> - client,
> - &pac_data,
> - &logon_data);
> - if (code != 0) {
> - goto done;
> - }
> -
> - code = krb5_pac_init(context, pac);
> + code = krb5_pac_parse(context,
> + authdata[0]->contents,
> + authdata[0]->length,
> + pac);
> if (code != 0) {
> goto done;
> }
>
> - data = ks_make_data(logon_data.data, logon_data.length);
> -
> - code = krb5_pac_add_buffer(context, *pac, PAC_LOGON_INFO, &data);
> - if (code != 0) {
> - goto done;
> - }
> + code = mit_samba_reget_pac(mit_ctx,
> + context,
> + flags,
> + client_princ,
> + client,
> + server,
> + krbtgt,
> + krbtgt_key,
> + pac);
>
> done:
> krb5_free_authdata(context, authdata);
> @@ -326,9 +321,17 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
> }
>
> if (!is_as_req) {
> - code = ks_verify_pac(context, flags, ks_client_princ, client,
> - server_key, krbtgt_key, authtime,
> - tgt_auth_data, &pac);
> + code = ks_verify_pac(context,
> + flags,
> + ks_client_princ,
> + client,
> + server,
> + krbtgt,
> + server_key,
> + krbtgt_key,
> + authtime,
> + tgt_auth_data,
> + &pac);
> if (code != 0) {
> goto done;
> }
> @@ -350,6 +353,7 @@ krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
> code = krb5_pac_sign(context, pac, authtime, ks_client_princ,
> server_key, krbtgt_key, &pac_data);
> if (code != 0) {
> + DBG_ERR("krb5_pac_sign failed: %d\n", code);
> goto done;
> }
>
> --
> 2.12.0
>
>
> From a2d37d5bfa2d742e658adf5acf10784819d985e5 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Thu, 26 Jan 2017 17:07:14 +0100
> Subject: [PATCH 48/49] mit-samba: Remove obsolete mit_samba_update_pac_data()
>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit_samba.c | 69 -------------------------------------------------
> source4/kdc/mit_samba.h | 10 -------
> 2 files changed, 79 deletions(-)
>
> diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
> index 9e605f05506..81189018172 100644
> --- a/source4/kdc/mit_samba.c
> +++ b/source4/kdc/mit_samba.c
> @@ -400,75 +400,6 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
> return code;
> }
>
> -int mit_samba_update_pac_data(struct mit_samba_context *ctx,
> - krb5_db_entry *client,
> - DATA_BLOB *pac_data,
> - DATA_BLOB *logon_data)
> -{
> - TALLOC_CTX *tmp_ctx;
> - DATA_BLOB *logon_blob;
> - krb5_error_code code;
> - NTSTATUS nt_status;
> - krb5_pac pac = NULL;
> - int ret;
> - struct samba_kdc_entry *skdc_entry = NULL;
> -
> - if (client) {
> - skdc_entry = talloc_get_type_abort(client->e_data,
> - struct samba_kdc_entry);
> - }
> -
> - /* The user account may be set not to want the PAC */
> - if (client && !samba_princ_needs_pac(skdc_entry)) {
> - return EINVAL;
> - }
> -
> - tmp_ctx = talloc_named(ctx, 0, "mit_samba_update_pac_data context");
> - if (!tmp_ctx) {
> - return ENOMEM;
> - }
> -
> - logon_blob = talloc_zero(tmp_ctx, DATA_BLOB);
> - if (!logon_blob) {
> - ret = ENOMEM;
> - goto done;
> - }
> -
> - code = krb5_pac_parse(ctx->context,
> - pac_data->data, pac_data->length, &pac);
> - if (code) {
> - ret = EINVAL;
> - goto done;
> - }
> -
> - /* TODO: An implementation-specific decision will need to be
> - * made as to when to check the KDC pac signature, and how to
> - * untrust untrusted RODCs */
> - nt_status = samba_kdc_update_pac_blob(tmp_ctx, ctx->context,
> - pac, logon_blob, NULL, NULL);
> - if (!NT_STATUS_IS_OK(nt_status)) {
> - DEBUG(0, ("Building PAC failed: %s\n",
> - nt_errstr(nt_status)));
> - ret = EINVAL;
> - goto done;
> - }
> -
> - logon_data->data = (uint8_t *)malloc(logon_blob->length);
> - if (!logon_data->data) {
> - ret = ENOMEM;
> - goto done;
> - }
> - memcpy(logon_data->data, logon_blob->data, logon_blob->length);
> - logon_data->length = logon_blob->length;
> -
> - ret = 0;
> -
> -done:
> - if (pac) krb5_pac_free(ctx->context, pac);
> - talloc_free(tmp_ctx);
> - return ret;
> -}
> -
> int mit_samba_reget_pac(struct mit_samba_context *ctx,
> krb5_context context,
> int flags,
> diff --git a/source4/kdc/mit_samba.h b/source4/kdc/mit_samba.h
> index b74a2d7a971..df088491ecb 100644
> --- a/source4/kdc/mit_samba.h
> +++ b/source4/kdc/mit_samba.h
> @@ -63,16 +63,6 @@ int mit_samba_reget_pac(struct mit_samba_context *ctx,
> krb5_keyblock *krbtgt_keyblock,
> krb5_pac *pac);
>
> -int mit_samba_update_pac_data(struct mit_samba_context *ctx,
> - krb5_db_entry *client,
> - DATA_BLOB *pac_data,
> - DATA_BLOB *logon_data);
> -
> -int mit_samba_update_pac_data(struct mit_samba_context *ctx,
> - krb5_db_entry *client,
> - DATA_BLOB *pac_data,
> - DATA_BLOB *logon_data);
> -
> int mit_samba_check_client_access(struct mit_samba_context *ctx,
> krb5_db_entry *client,
> const char *client_name,
> --
> 2.12.0
>
>
> From 427eb66dfbb5daddceaa6449f8a65a5865b84c57 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Fri, 27 Jan 2017 12:11:33 +0100
> Subject: [PATCH 49/49] mit_samba: Fix principal lookup for cross domain
> referral
>
> Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
>
> Signed-off-by: Stefan Metzmacher <metze at samba.org>
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
> source4/kdc/mit_samba.c | 51 +++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 43 insertions(+), 8 deletions(-)
>
> diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
> index 81189018172..677e53330a0 100644
> --- a/source4/kdc/mit_samba.c
> +++ b/source4/kdc/mit_samba.c
> @@ -188,6 +188,7 @@ int mit_samba_get_principal(struct mit_samba_context *ctx,
> krb5_db_entry *kentry;
> int ret;
> int sflags = 0;
> + krb5_principal referral_principal = NULL;
>
> kentry = calloc(1, sizeof(krb5_db_entry));
> if (kentry == NULL) {
> @@ -217,6 +218,8 @@ int mit_samba_get_principal(struct mit_samba_context *ctx,
> * backend and we will fail to parse the entry later */
> sflags |= SDB_F_ADMIN_DATA;
>
> +
> +fetch_referral_principal:
> ret = samba_kdc_fetch(ctx->context, ctx->db_ctx,
> principal, sflags, 0, &sentry);
> switch (ret) {
> @@ -225,14 +228,43 @@ int mit_samba_get_principal(struct mit_samba_context *ctx,
> case SDB_ERR_NOENTRY:
> ret = KRB5_KDB_NOENTRY;
> goto done;
> - case SDB_ERR_WRONG_REALM:
> - /*
> - * If we have a wrong realm e.g. if we try get a cross forest
> - * ticket, we return a ticket with the correct realm. The KDC
> - * will detect this an return the appropriate return code.
> - */
> - ret = 0;
> - break;
> + case SDB_ERR_WRONG_REALM: {
> + char *dest_realm = NULL;
> + const char *our_realm = lpcfg_realm(ctx->db_ctx->lp_ctx);
> +
> + if (sflags & SDB_F_FOR_AS_REQ) {
> + ret = 0;
> + break;
> + }
> +
> + if (referral_principal != NULL) {
> + sdb_free_entry(&sentry);
> + ret = KRB5_KDB_NOENTRY;
> + goto done;
> + }
> +
> + dest_realm = smb_krb5_principal_get_realm(ctx->context,
> + sentry.entry.principal);
> + sdb_free_entry(&sentry);
> + if (dest_realm == NULL) {
> + ret = KRB5_KDB_NOENTRY;
> + goto done;
> + }
> +
> + ret = smb_krb5_make_principal(ctx->context,
> + &referral_principal,
> + our_realm,
> + KRB5_TGS_NAME,
> + dest_realm,
> + NULL);
> + SAFE_FREE(dest_realm);
> + if (ret != 0) {
> + goto done;
> + }
> +
> + principal = referral_principal;
> + goto fetch_referral_principal;
> + }
> case SDB_ERR_NOT_FOUND_HERE:
> /* FIXME: RODC support */
> default:
> @@ -244,6 +276,9 @@ int mit_samba_get_principal(struct mit_samba_context *ctx,
> sdb_free_entry(&sentry);
>
> done:
> + krb5_free_principal(ctx->context, referral_principal);
> + referral_principal = NULL;
> +
> if (ret) {
> free(kentry);
> } else {
> --
> 2.12.0
>
More information about the samba-technical
mailing list