Quantcast

[PATCHSET] Samba AD with MIT Kerberos

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCHSET] Samba AD with MIT Kerberos

Samba - samba-technical mailing list
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!


Thanks,



        Andreas



[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                             [hidden email]
www.samba.org

samba_ad_mit_kdc.patch (212K) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCHSET] Samba AD with MIT Kerberos

Samba - samba-technical mailing list
On Mon, 2017-03-13 at 08:29 +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!

Congratulations!

> 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!

I'm really, really impressed.  I'll look again, but I have no
objections so far, other than for:

>
> 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 <[hidden email]>

For this patch, are we sure old Samba versions are not picky?  My gut
feeling at 6:30am is that our code there was pretty fragile, but it
seems that if so, the additions of LOGON_CREDS and the upn dns info
would have broken it anyway.

Very, very well done.  Thank you for your persistence, congratulations
and many thanks for meeting the challenges given you, particularly
those landed on you (like the horror kdc and kdc-canon test still to
go) without much notice.

Finally, from here, what do you see as the procedure to add features to
the MIT KDC?  

Specifically, about the time you land this, I hope to land the NTLM
logging patches Gary is working on, and follow up shortly  with similar
patches for Heimdal's KDC, so we spit out a similar JSON structure on
failure, and send it over Samba's message bus (that helps us write
tests).  

The hooks we have in Heimdal are not quite good enough for what we want
(can't catch unknown user), so we will need to add some more.  Assuming
the same applies in MIT, how should we get such hooks, and given
Samba's needs remain a moving target, how do you expect the engineering
pattern to work long term?   Will we try to support multiple MIT
versions with #ifdefs, or just the latest?  

Will it be OK for features to be Heimdal-only?  (And vice-versa).  

Thanks,

Andrew Bartlett

--
Andrew Bartlett                       http://samba.org/~abartlet/
Authentication Developer, Samba Team  http://samba.org
Samba Developer, Catalyst IT          http://catalyst.net.nz/services/samba


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCHSET] Samba AD with MIT Kerberos

Samba - samba-technical mailing list
In reply to this post by Samba - samba-technical mailing list
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                             [hidden email]
> www.samba.org

> From 1351b58987c672bfc576b0d36baaeed3a5531534 Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> Date: Tue, 13 Sep 2016 08:24:06 +0200
> Subject: [PATCH 02/49] testprogs: Add common kinit function
>
> Signed-off-by: Andreas Schneider <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  .../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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> Date: Thu, 23 Jul 2015 13:49:09 +0200
> Subject: [PATCH 08/49] waf: Check for MIT KDC binary
>
> Signed-off-by: Andreas Schneider <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> +
> +   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 <[hidden email]>
> 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 <[hidden email]>
> Signed-off-by: Andreas Schneider <[hidden email]>
> Signed-off-by: Guenther Deschner <[hidden email]>
> ---
>  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 <[hidden email]>
> + *
> + * 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 <[hidden email]>
> + *
> + * 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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> Date: Wed, 30 Apr 2014 09:32:49 +0200
> Subject: [PATCH 17/49] selftest: Setup configs for MIT KDC
>
> Signed-off-by: Andreas Schneider <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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?= <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> +
> +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@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@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@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@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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> +# Copyright (c) 2016 Andreas Schneider <[hidden email]>
> +
> +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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> +# Copyright (C) 2006-2008 Andrew Bartlett <[hidden email]>
> +# Copyright (C) 2016      Andreas Schneider <[hidden email]>
> +
> +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@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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> +
> +   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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> +# Copyright (c) 2006-2008 Andrew Bartlett <[hidden email]>
> +# Copyright (c) 2016      Andreas Schneider <[hidden email]>
> +
> +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@00%"
> +TEST_PASSWORD_NEW="testPaSS@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@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@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@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@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@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@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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  .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 <[hidden email]>
> +#
> +# 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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> +#
> +# 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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
> ---
>  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 <[hidden email]>
> 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 <[hidden email]>
>
> Signed-off-by: Stefan Metzmacher <[hidden email]>
> Signed-off-by: Andreas Schneider <[hidden email]>
> ---
>  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
>


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCHSET] Samba AD with MIT Kerberos

Samba - samba-technical mailing list
In reply to this post by Samba - samba-technical mailing list
On Monday, 13 March 2017 18:40:21 CET Andrew Bartlett wrote:

> On Mon, 2017-03-13 at 08:29 +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!
>
> Congratulations!
>
> > 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!
>
> I'm really, really impressed.  I'll look again, but I have no
>
> objections so far, other than for:
> > 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 <[hidden email]>
>
> For this patch, are we sure old Samba versions are not picky?  My gut
> feeling at 6:30am is that our code there was pretty fragile, but it
> seems that if so, the additions of LOGON_CREDS and the upn dns info
> would have broken it anyway.

I didn't find any issue. Also Microsoft doesn't care about the order so we
would have noticed I guess.
 
> Very, very well done.  Thank you for your persistence, congratulations
> and many thanks for meeting the challenges given you, particularly
> those landed on you (like the horror kdc and kdc-canon test still to
> go) without much notice.

The KDC tests are already done and I've added new once to confirm that some
bugs I've fixed are working correctly.

I will look into kdc-canon test soon.

> Finally, from here, what do you see as the procedure to add features to
> the MIT KDC?

Implement it and create a pull request on github. You get very good feedback
and changes are merged pretty quickly. I've implemented quite some stuff in
MIT Kerberos to get to this point. The last thing was fixing a KDB issue where
they changed the API and removed the possiblity to free memory. So talloc
memory was not freed. I've implemented it in a sane way and Greg helped to
improve it and merged it quickly.

The only issue is that we need to wait for a major release to get new
features. Greg and I already agreed to work on a libkdc. We need that for RODC
support. I haven't had the time to think about an API yet.


>
> Specifically, about the time you land this, I hope to land the NTLM
> logging patches Gary is working on, and follow up shortly  with similar
> patches for Heimdal's KDC, so we spit out a similar JSON structure on
> failure, and send it over Samba's message bus (that helps us write
> tests).  
>
> The hooks we have in Heimdal are not quite good enough for what we want
> (can't catch unknown user), so we will need to add some more.  Assuming
> the same applies in MIT, how should we get such hooks, and given
> Samba's needs remain a moving target, how do you expect the engineering
> pattern to work long term?   Will we try to support multiple MIT
> versions with #ifdefs, or just the latest?  
>
> Will it be OK for features to be Heimdal-only?  (And vice-versa).

I will continue to work on MIT Kerberos support.


        Andreas


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCHSET] Samba AD with MIT Kerberos

Samba - samba-technical mailing list
Does this mean I'll be seeing a samba-dc that actually has something more
than a readme file in fedora rawhide soon?

On Mon, Mar 13, 2017 at 3:59 PM, Andreas Schneider via samba-technical <
[hidden email]> wrote:

> On Monday, 13 March 2017 18:40:21 CET Andrew Bartlett wrote:
> > On Mon, 2017-03-13 at 08:29 +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!
> >
> > Congratulations!
> >
> > > 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!
> >
> > I'm really, really impressed.  I'll look again, but I have no
> >
> > objections so far, other than for:
> > > 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 <[hidden email]>
> >
> > For this patch, are we sure old Samba versions are not picky?  My gut
> > feeling at 6:30am is that our code there was pretty fragile, but it
> > seems that if so, the additions of LOGON_CREDS and the upn dns info
> > would have broken it anyway.
>
> I didn't find any issue. Also Microsoft doesn't care about the order so we
> would have noticed I guess.
>
> > Very, very well done.  Thank you for your persistence, congratulations
> > and many thanks for meeting the challenges given you, particularly
> > those landed on you (like the horror kdc and kdc-canon test still to
> > go) without much notice.
>
> The KDC tests are already done and I've added new once to confirm that some
> bugs I've fixed are working correctly.
>
> I will look into kdc-canon test soon.
>
> > Finally, from here, what do you see as the procedure to add features to
> > the MIT KDC?
>
> Implement it and create a pull request on github. You get very good
> feedback
> and changes are merged pretty quickly. I've implemented quite some stuff in
> MIT Kerberos to get to this point. The last thing was fixing a KDB issue
> where
> they changed the API and removed the possiblity to free memory. So talloc
> memory was not freed. I've implemented it in a sane way and Greg helped to
> improve it and merged it quickly.
>
> The only issue is that we need to wait for a major release to get new
> features. Greg and I already agreed to work on a libkdc. We need that for
> RODC
> support. I haven't had the time to think about an API yet.
>
>
> >
> > Specifically, about the time you land this, I hope to land the NTLM
> > logging patches Gary is working on, and follow up shortly  with similar
> > patches for Heimdal's KDC, so we spit out a similar JSON structure on
> > failure, and send it over Samba's message bus (that helps us write
> > tests).
> >
> > The hooks we have in Heimdal are not quite good enough for what we want
> > (can't catch unknown user), so we will need to add some more.  Assuming
> > the same applies in MIT, how should we get such hooks, and given
> > Samba's needs remain a moving target, how do you expect the engineering
> > pattern to work long term?   Will we try to support multiple MIT
> > versions with #ifdefs, or just the latest?
> >
> > Will it be OK for features to be Heimdal-only?  (And vice-versa).
>
> I will continue to work on MIT Kerberos support.
>
>
>         Andreas
>
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCHSET] Samba AD with MIT Kerberos

Samba - samba-technical mailing list
On Friday, 17 March 2017 17:00:36 CET Jeff Sadowski wrote:
> Does this mean I'll be seeing a samba-dc that actually has something more
> than a readme file in fedora rawhide soon?

It will be shipped the next major Samba release


--
Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             [hidden email]
www.samba.org

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCHSET] Samba AD with MIT Kerberos

Samba - samba-technical mailing list
In reply to this post by Samba - samba-technical mailing list
On 2017-03-13 at 08:29 +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!

Congratulation!
And kudos to everyone who contributed to this effort.
This is a major achievement indeed.

Cheers - Michael


signature.asc (169 bytes) Download Attachment
Loading...