[SCM] Samba Shared Repository - branch v4-2-test updated

Karolin Seeger kseeger at samba.org
Tue Mar 3 16:30:10 MST 2015


The branch, v4-2-test has been updated
       via  7ad61f9 backupkey: Explain more why we use GnuTLS here
       via  19796dc torture-backupkey: Check the dcerpc call return code before calling ndr pull
       via  defd635 backupkey: replace heimdal rsa key generation with GnuTLS
       via  b39c155 build: Require GnuTLS if building with Active Directory
       via  3e03d5f torture-backupkey: Add tests that read the secret from the server, and validate
       via  c39dccc backupkey: Better handling for different wrap version headers
       via  a29cf10 backupkey: Add tests for ServerWrap protocol
       via  3b27850 backupkey: Change expected error codes to match Windows 2008R2 and Windows 2012R2
       via  ff5494a backupkey: Implement ServerWrap Decrypt
       via  2533cef backupkey: Handle more clearly the case where we find the secret, but it has no value
       via  b66edeb backupkey: Improve variable names to make clear this is client-provided data
       via  b3dd7ae backupkey: Use the name lsa_secret rather than just secret
       via  9408f0c backupkey: Implement ServerWrap Encrypt protocol
       via  a0bf67d backupkey: Improve function names and comments for clarity
       via  8d45cf5 backupkey: Move SID comparison to inside get_and_verify_access_check()
       via  9372640 backupkey: Improve IDL
       via  c6b61e1 backupkey: begin by factoring out the server wrap functions
       via  9ddd067 torture-backupkey: Assert dcerpc_bkrp_BackupKey_r call was successful
       via  bad22e6 torture-backupkey: Add consistent assertions that createRestoreGUIDStruct() suceeds
       via  3d44076 s4:torture/rpc/backupkey: Require 2048 bit RSA key
       via  2ff5c42 s4-backupkey: consistent naming of werr variable
       via  0168673 s4-backupkey: improve variable name
       via  48a659d s4-backupkey: typo fix
       via  a701eeb s4-backupkey: IDL for ServerWrap subprotocol
       via  87c525d s4-backupkey: fix ndr_pull error on empty input
       via  2ee3031 s4-backupkey: Initialize ndr->switchlist for print
       via  a03df47 s4-backupkey: Comply with [MS-BKRP] 2.2.1
       via  0d6e32f s4-backupkey: Set defined cert serialnumber
       via  0dd6cfa s4-backupkey: de-duplicate error handling
       via  c998e9d s4-backupkey: check for talloc failure
       via  0b75a0c s4-backupkey: Cert lifetime of 365 days, not secs
       via  899f4db s4-backupkey: Ensure RSA modulus is 2048 bits
      from  93fe498 Add link to the Samba User Survey 2015 to WHATSNEW.txt

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-2-test


- Log -----------------------------------------------------------------
commit 7ad61f9cf76bfa79d0e94468c31cb7d2e6afb494
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Feb 16 11:26:37 2015 +1300

    backupkey: Explain more why we use GnuTLS here
    
    Pair-programmed-with: Garming Sam <garming at catalyst.net.nz>
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 927ea9791e3d1a91516b1cec6918772da83a7fbb)
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11097
    Win8.1 Credentials Manager issue after KB2992611 on Samba domain
    
    Autobuild-User(v4-2-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-2-test): Wed Mar  4 00:28:59 CET 2015 on sn-devel-104

commit 19796dceada1db7b03a939bea1725d2711b121fb
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Fri Feb 13 16:55:07 2015 +1300

    torture-backupkey: Check the dcerpc call return code before calling ndr pull
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 5ca9a4ebe53fd225e2491a4da4635468fef60829)

commit defd63541c8e1ee852b907f26be33bdc50aea214
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Fri Feb 13 09:54:50 2015 +1300

    backupkey: replace heimdal rsa key generation with GnuTLS
    
    We use GnuTLS because it can reliably generate 2048 bit keys every time.
    
    Windows clients strictly require 2048, no more since it won't fit and no
    less either. Heimdal would almost always generate a smaller key.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10980
    (cherry picked from commit 43d3e90418b5e0ac5986e08f9483146f4f5d2357)

commit b39c15564554b3c7defc71ec900c6837593cec2b
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Fri Feb 13 16:49:58 2015 +1300

    build: Require GnuTLS if building with Active Directory
    
    Without GnuTLS, we don't have ldaps:// support and we are unable to
    readily create RSA keys of the correct length for the BackupKey
    protocol.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit a1f1db277a2c452b63b9fe2d67cabfe0df60223d)

commit 3e03d5f3ac244834c4733f928565a5f33f8494d1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Feb 13 12:59:45 2015 +1300

    torture-backupkey: Add tests that read the secret from the server, and validate
    
    These show that MS-BKRP 3.1.4.1.1 BACKUPKEY_BACKUP_GUID is incorrect when it
    states that the key must be the leading 64 bytes, it must be the whole 256 byte
    buffer.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit f7b6e696ed552f02195c87a7eede5a0090f8df1f)

commit c39dccc9c483001f64e54c82875ca00792b100d9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Feb 12 16:15:41 2015 +1300

    backupkey: Better handling for different wrap version headers
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 3254f9bc009bae3d8463035d63eb1625f23606e6)

commit a29cf10a59526e1ee0866e4b9115212f1848dca4
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Feb 11 17:46:42 2015 +1300

    backupkey: Add tests for ServerWrap protocol
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit d8cc370d01445b5120678dde02955f13f3773bb2)

commit 3b278504097c23d003f359dab9dfb54d674ce9b6
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Feb 11 13:37:16 2015 +1300

    backupkey: Change expected error codes to match Windows 2008R2 and Windows 2012R2
    
    This is done in both smbtoture and in our server
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 93510eb513598431c260cd0b85a02d0e49cc821b)

commit ff5494a79d0e17f9f96595854affbf57b2b647f3
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Feb 11 09:53:58 2015 +1300

    backupkey: Implement ServerWrap Decrypt
    
    We implement both modes in BACKUPKEY_RESTORE_GUID, as it may decrypt
    both ServerWrap and ClientWrap data, and we implement
    BACKUPKEY_RESTORE_GUID_WIN2K.
    
    BUG: https://bugzilla.samba.org/attachment.cgi?bugid=11097
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit c3c54b9bf36ef5075fdca9042296f033db8673ce)

commit 2533cefdcab9b245867bb00c483693d51175f972
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Feb 10 16:26:23 2015 +1300

    backupkey: Handle more clearly the case where we find the secret, but it has no value
    
    This happen on the RODC, a case that we try not to permit at all.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit cdecd8540a8e5ef1266684fda0dd10d72466d4d8)

commit b66edeb64e1e46139fb7e75b654ae01f3d3d2e4d
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Feb 10 16:23:17 2015 +1300

    backupkey: Improve variable names to make clear this is client-provided data
    
    The values we return here are client-provided passwords or other keys, that we decrypt for them.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 51086f30dd1f0ca656b5391e1500cc65480564e3)

commit b3dd7ae9b28124c66bd1c3d0602c219ca2eda543
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Feb 10 16:16:20 2015 +1300

    backupkey: Use the name lsa_secret rather than just secret
    
    This makes it clear that this is the data stored on the LSA secrets store
    and not the client-provided data to be encrypted.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 0ff9733479f27cf40a9cc0f749de088d33591272)

commit 9408f0c6891d0f458325499269286b2bbf043779
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Feb 10 16:02:00 2015 +1300

    backupkey: Implement ServerWrap Encrypt protocol
    
    BUG: https://bugzilla.samba.org/attachment.cgi?bugid=11097
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 33c616406726a3e144b5b4bbc2c8d3166e0c4be5)

commit a0bf67dba42463a047221d2847abb5222e588f3e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Feb 10 15:50:15 2015 +1300

    backupkey: Improve function names and comments for clarity
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit c55f3936490a89004364a203361d201bee5fce08)

commit 8d45cf538aa15102354b5a84426f6db342871816
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Feb 10 15:48:06 2015 +1300

    backupkey: Move SID comparison to inside get_and_verify_access_check()
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit f69b180cf86ad2c43dbbd89c7e906e7ab2350ee2)

commit 9372640c64dee2c0c6a56afdba8f7f8964309df6
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Feb 5 18:17:58 2015 +1300

    backupkey: Improve IDL
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit bc0b90a300654a248a08e4796133bb6b880e9789)

commit c6b61e1a8954026754e45d931252481780e89906
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Thu Feb 5 11:07:30 2015 +1300

    backupkey: begin by factoring out the server wrap functions
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit a4e6873c4356fa221a0833336413f70e7c9411ca)

commit 9ddd0671a42e7d4edf1dc847794468312bf84ab1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Feb 11 11:45:45 2015 +1300

    torture-backupkey: Assert dcerpc_bkrp_BackupKey_r call was successful
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 286223f150dbb84022d48ef845119cd47afc30d3)

commit bad22e6ec5426e40b8333842f121f6bbca4b9513
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Feb 11 09:51:27 2015 +1300

    torture-backupkey: Add consistent assertions that createRestoreGUIDStruct() suceeds
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit d9529dbab6f0482d408bf9c4ea9bd911da8897e5)

commit 3d4407671140fb9ebb9291094d8c4f3dbd4cdc51
Author: Arvid Requate <requate at univention.de>
Date:   Tue Dec 23 18:56:20 2014 +0100

    s4:torture/rpc/backupkey: Require 2048 bit RSA key
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    
    (fixed cleanup of memory)
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 16ad6de6b8d4481b1e00630c9a23895d1371d971)

commit 2ff5c42bbbffc1a84d64a536cf235cca93de7a46
Author: Arvid Requate <requate at univention.de>
Date:   Tue Jul 8 17:25:53 2014 +0200

    s4-backupkey: consistent naming of werr variable
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit e6e9e490ae1352b0d572dbd3d546c14d367cbedb)

commit 01686731f8d6e1a63dcf9c167555a429e7ba4ad5
Author: Arvid Requate <requate at univention.de>
Date:   Tue Jul 8 16:12:13 2014 +0200

    s4-backupkey: improve variable name
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit e25c61c5f17230a6932f704ed849f140b00a45aa)

commit 48a659d7c9e5b928530a8665eab3cfdc2aa2e988
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 18:56:39 2014 +0200

    s4-backupkey: typo fix
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 8473f6da6902d753ed46073e453a496aa90cb94b)

commit a701eeb89599db15f2515e53d439cea5352dec90
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 18:48:41 2014 +0200

    s4-backupkey: IDL for ServerWrap subprotocol
    
    This adds some IDL structs for the ServerWrap subprotocol, allowing
    parsing of the incoming RPC calls and returning WERR_NOT_SUPPORTED
    instead of WERR_INVALID_PARAM.
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 879b65710b266fecaca01b9dd40474b2cc35d417)

commit 87c525d1be9e3bec9f60c57ba8adadfaa8ce8548
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 18:43:05 2014 +0200

    s4-backupkey: fix ndr_pull error on empty input
    
    [MS-BKRP] 3.1.4.1 specifies for BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID that
    the server must ignore the input data. This patch fixes
      ndr_pull_error(11): Pull bytes 4 (../librpc/ndr/ndr_basic.c:148)
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 3bc3bec6d702ef62bf026ff64855edc8fb900088)

commit 2ee3031f15f1e12a88f1fbaade563d3dc5623b68
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 18:36:49 2014 +0200

    s4-backupkey: Initialize ndr->switchlist for print
    
    ndr_print_bkrp_data_in_blob requires the level to be set in the
    proper ndr->switch_list context.
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 6af3cf60e31fdaa0873f45fd821165e265335c55)

commit a03df4799f5183742c3948363006f70a3dd1821f
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 18:25:29 2014 +0200

    s4-backupkey: Comply with [MS-BKRP] 2.2.1
    
    [MS-BKRP] 2.2.1 specifies "The Common Name field of the Subject name
    field SHOULD contain the name of the DNS domain assigned to the server."
    
    In fact Windows 7 clients don't seem to care. Also in certificates
    generated by native AD the domain name (after CN=) is encoded as
    UTF-16LE. Since hx509_parse_name only supports UTF-8 strings currently
    we just leave the encoding as it is for now.
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 007c3978a46d5f50051605752a76d12f30c5a0de)

commit 0d6e32f2a52b3f1b7843ec645abe627aa3c62557
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 18:18:30 2014 +0200

    s4-backupkey: Set defined cert serialnumber
    
    [MS-BKRP] 2.2.1 specifies that the serialnumber of the certificate
    should be set identical to the subjectUniqueID. In fact certificates
    generated by native AD have this field encoded in little-endian format.
    See also
    https://www.mail-archive.com/cifs-protocol@cifs.org/msg01364.html
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 577fa69b5287b047ee2564786e19c9941a25734c)

commit 0dd6cfa91ec65ae7c6f1a6f541c737cac3fb866c
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 18:15:37 2014 +0200

    s4-backupkey: de-duplicate error handling
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 525c93caa6c264de7c0cb463d005d3dcda7e45af)

commit c998e9df62b099c0c81711616eac3e311dac34e4
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 18:12:47 2014 +0200

    s4-backupkey: check for talloc failure
    
    Check for talloc_memdup failure for uniqueid.data.
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit d633fcb5666085fef290adbe05161a2f36329abf)

commit 0b75a0cb352272fe48c286170996171fce7ed417
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 17:59:29 2014 +0200

    s4-backupkey: Cert lifetime of 365 days, not secs
    
    hx509_ca_tbs_set_notAfter_lifetime expects the lifetime value in
    in seconds. The Windows 7 client didn't seem to care that the lifetime
    was only 6'03''. Two other TODOs in this implementation:
    
    * Since notBefore is not set explicietely to "now", the heimdal code
      default of now-(24 hours) is applied.
    
    * Server side validity checks and cert renewal are missing.
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    (cherry picked from commit 89803009b957b980818aa971a0f5dd14f75cbbe1)

commit 899f4db2c2fce4d7246d6149961dfb5071efcb05
Author: Arvid Requate <requate at univention.de>
Date:   Mon Jul 7 17:39:51 2014 +0200

    s4-backupkey: Ensure RSA modulus is 2048 bits
    
    RSA_generate_key_ex doesn't always generate a modulus of requested
    bit length. Tests with Windows 7 clients showed that they decline
    x509 certificates (MS-BKRP 2.2.1) in cases where the modulus length
    is smaller than the specified 2048 bits. For the user this resulted
    in DPAPI failing to retrieve stored credentials after the user password
    has been changed at least two times. On the server side log.samba showed
    that the client also called the as yet unlimplemented ServerWrap sub-
    protocol function BACKUPKEY_BACKUP_KEY_GUID after it had called the
    ClientWarp function BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID. After
    enabling DPAPI auditing on the Windows Clients the Event Viewer showed
    Event-ID 4692 failing with a FailureReason value of 0x7a in these cases.
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=10980
    (cherry picked from commit 9b2ff26c893e5748d12d7a37a93eef7b1f4b1a1b)

-----------------------------------------------------------------------

Summary of changes:
 librpc/idl/backupkey.idl                        |   37 +-
 librpc/ndr/ndr_backupkey.c                      |    5 +
 source4/lib/tls/wscript                         |    3 +
 source4/rpc_server/backupkey/dcesrv_backupkey.c |  984 ++++++++++++++++-----
 source4/torture/rpc/backupkey.c                 | 1073 ++++++++++++++++++++++-
 5 files changed, 1860 insertions(+), 242 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/idl/backupkey.idl b/librpc/idl/backupkey.idl
index e21030b..81e0db6 100644
--- a/librpc/idl/backupkey.idl
+++ b/librpc/idl/backupkey.idl
@@ -47,6 +47,9 @@ interface backupkey
 		uint8 key[256];
 	} bkrp_dc_serverwrap_key;
 
+	[public] typedef struct {
+	} bkrp_empty;
+
 	[public,gensize] typedef struct {
 		uint32 version;
 		uint32 encrypted_secret_len;
@@ -95,15 +98,45 @@ interface backupkey
 		uint8 hash[64];
 	} bkrp_access_check_v3;
 
+	[public] typedef struct {
+		uint8 r3[32];
+		uint8 mac[20];
+		dom_sid sid;
+		[subcontext(0),flag(NDR_REMAINING)] DATA_BLOB secret_data;
+	} bkrp_rc4encryptedpayload;
+
+	[public] typedef struct {
+		[value(0x00000001)] uint32 magic;
+		uint32 payload_length;
+		uint32 ciphertext_length;
+		GUID guid;
+		uint8 r2[68];
+		uint8 rc4encryptedpayload[ciphertext_length];
+	} bkrp_server_side_wrapped;
+
+	[public] typedef struct {
+		[flag(NDR_REMAINING)] DATA_BLOB opaque;
+	} bkrp_opaque_blob;
+
+	typedef enum {
+	        BACKUPKEY_SERVER_WRAP_VERSION = 1,
+	        BACKUPKEY_CLIENT_WRAP_VERSION2 = 2,
+		BACKUPKEY_CLIENT_WRAP_VERSION3 = 3
+	} bkrp_versions;
+  
 	typedef enum {
 		BACKUPKEY_INVALID_GUID_INTEGER = 0xFFFF,
 		BACKUPKEY_RESTORE_GUID_INTEGER = 0x0000,
-		BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID_INTEGER = 0x0001
+		BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID_INTEGER = 0x0001,
+		BACKUPKEY_RESTORE_GUID_WIN2K_INTEGER = 0x0002,
+		BACKUPKEY_BACKUP_GUID_INTEGER = 0x0003
 	} bkrp_guid_to_integer;
 
 	[public] typedef [nodiscriminant] union {
 		[case(BACKUPKEY_RESTORE_GUID_INTEGER)] bkrp_client_side_wrapped restore_req;
-		[case(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID_INTEGER)] bkrp_client_side_wrapped cert_req;
+		[case(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID_INTEGER)] bkrp_empty empty;
+		[case(BACKUPKEY_RESTORE_GUID_WIN2K_INTEGER)] bkrp_server_side_wrapped unsign_req;
+		[case(BACKUPKEY_BACKUP_GUID_INTEGER)] bkrp_opaque_blob sign_req;
 	} bkrp_data_in_blob;
 
 	/******************/
diff --git a/librpc/ndr/ndr_backupkey.c b/librpc/ndr/ndr_backupkey.c
index ddbaeea..827bc69 100644
--- a/librpc/ndr/ndr_backupkey.c
+++ b/librpc/ndr/ndr_backupkey.c
@@ -71,6 +71,11 @@ _PUBLIC_ void ndr_print_bkrp_BackupKey(struct ndr_print *ndr, const char *name,
 		ndr->depth--;
 
 		level = backupkeyguid_to_uint(r->in.guidActionAgent);
+		ndr_err = ndr_print_set_switch_value(ndr, &inblob, level);
+		if (unlikely(!NDR_ERR_CODE_IS_SUCCESS(ndr_err))) {	\
+			DEBUG(0,("ERROR: ndr_print_bkrp_BackupKey ndr_print_set_switch_value failed: %d\n", ndr_err));
+			return;
+		}
 		blob.data = r->in.data_in;
 		blob.length = r->in.data_in_len;
 		ndr_err = ndr_pull_union_blob(&blob, ndr, &inblob, level,
diff --git a/source4/lib/tls/wscript b/source4/lib/tls/wscript
index 57cd894..ae96395 100644
--- a/source4/lib/tls/wscript
+++ b/source4/lib/tls/wscript
@@ -25,6 +25,9 @@ def configure(conf):
 
     if 'HAVE_GNUTLS' in conf.env:
         conf.DEFINE('ENABLE_GNUTLS', 1)
+    else:
+        if 'AD_DC_BUILD_IS_ENABLED' in conf.env:
+            conf.fatal("Building the AD DC requires GnuTLS (eg libgnutls-dev, gnutls-devel) for ldaps:// support and for the BackupKey protocol")
 
     conf.CHECK_FUNCS_IN('gnutls_global_init', 'gnutls',
                         headers='gnutls/gnutls.h')
diff --git a/source4/rpc_server/backupkey/dcesrv_backupkey.c b/source4/rpc_server/backupkey/dcesrv_backupkey.c
index 9020da7..bef4c93 100644
--- a/source4/rpc_server/backupkey/dcesrv_backupkey.c
+++ b/source4/rpc_server/backupkey/dcesrv_backupkey.c
@@ -34,12 +34,19 @@
 #include <hcrypto/rsa.h>
 #include <hcrypto/bn.h>
 #include <hcrypto/sha.h>
+#include <hcrypto/evp.h>
+#include <hcrypto/hmac.h>
 #include <der.h>
 #include "../lib/tsocket/tsocket.h"
 #include "../libcli/security/security.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "lib/crypto/arcfour.h"
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#if HAVE_GCRYPT_H
+#include <gcrypt.h>
+#endif
 
-#define BACKUPKEY_MIN_VERSION 2
-#define BACKUPKEY_MAX_VERSION 3
 
 static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 };
 /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/
@@ -50,7 +57,7 @@ static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num = {
 static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
 			       struct ldb_context *ldb,
 			       const char *name,
-			       const DATA_BLOB *secret)
+			       const DATA_BLOB *lsa_secret)
 {
 	struct ldb_message *msg;
 	struct ldb_result *res;
@@ -137,8 +144,8 @@ static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
 		talloc_free(msg);
 		return NT_STATUS_NO_MEMORY;
 	}
-	val.data = secret->data;
-	val.length = secret->length;
+	val.data = lsa_secret->data;
+	val.length = lsa_secret->length;
 	ret = ldb_msg_add_value(msg, "currentValue", &val, NULL);
 	if (ret != LDB_SUCCESS) {
 		talloc_free(msg);
@@ -172,7 +179,7 @@ static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
 static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
 			       struct ldb_context *ldb,
 			       const char *name,
-			       DATA_BLOB *secret)
+			       DATA_BLOB *lsa_secret)
 {
 	TALLOC_CTX *tmp_mem;
 	struct ldb_result *res;
@@ -186,8 +193,8 @@ static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
 	};
 	int ret;
 
-	secret->data = NULL;
-	secret->length = 0;
+	lsa_secret->data = NULL;
+	lsa_secret->length = 0;
 
 	domain_dn = ldb_get_default_basedn(ldb);
 	if (!domain_dn) {
@@ -209,18 +216,12 @@ static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
 			   "(&(cn=%s Secret)(objectclass=secret))",
 			   ldb_binary_encode_string(tmp_mem, name));
 
-	if (ret != LDB_SUCCESS || res->count == 0) {
+	if (ret != LDB_SUCCESS) {
 		talloc_free(tmp_mem);
-		/*
-		 * Important NOT to use NT_STATUS_OBJECT_NAME_NOT_FOUND
-		 * as this return value is used to detect the case
-		 * when we have the secret but without the currentValue
-		 * (case RODC)
-		 */
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	} else if (res->count == 0) {
 		return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
-	}
-
-	if (res->count > 1) {
+	} else if (res->count > 1) {
 		DEBUG(2, ("Secret %s collision\n", name));
 		talloc_free(tmp_mem);
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
@@ -232,13 +233,14 @@ static NTSTATUS get_lsa_secret(TALLOC_CTX *mem_ctx,
 		 * The secret object is here but we don't have the secret value
 		 * The most common case is a RODC
 		 */
+		*lsa_secret = data_blob_null;
 		talloc_free(tmp_mem);
-		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+		return NT_STATUS_OK;
 	}
 
 	data = val->data;
-	secret->data = talloc_move(mem_ctx, &data);
-	secret->length = val->length;
+	lsa_secret->data = talloc_move(mem_ctx, &data);
+	lsa_secret->length = val->length;
 
 	talloc_free(tmp_mem);
 	return NT_STATUS_OK;
@@ -380,7 +382,7 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
 					  uint8_t *key_and_iv,
 					  uint8_t *access_check,
 					  uint32_t access_check_len,
-					  struct dom_sid **access_sid)
+					  struct auth_session_info *session_info)
 {
 	heim_octet_string iv;
 	heim_octet_string access_check_os;
@@ -393,10 +395,12 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
 	enum ndr_err_code ndr_err;
 	hx509_context hctx;
 
+	struct dom_sid *access_sid = NULL;
+	struct dom_sid *caller_sid = NULL;
+	
 	/* This one should not be freed */
 	const AlgorithmIdentifier *alg;
 
-	*access_sid = NULL;
 	switch (version) {
 	case 2:
 		key_len = 24;
@@ -451,7 +455,9 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
 
 	hx509_crypto_destroy(crypto);
 
-	if (version == 2) {
+	switch (version) {
+	case 2:
+	{
 		uint32_t hash_size = 20;
 		uint8_t hash[hash_size];
 		struct sha sctx;
@@ -483,14 +489,11 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
 			DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
 			return WERR_INVALID_DATA;
 		}
-		*access_sid = dom_sid_dup(sub_ctx, &(uncrypted_accesscheckv2.sid));
-		if (*access_sid == NULL) {
-			return WERR_NOMEM;
-		}
-		return WERR_OK;
+		access_sid = &(uncrypted_accesscheckv2.sid);
+		break;
 	}
-
-	if (version == 3) {
+	case 3:
+	{
 		uint32_t hash_size = 64;
 		uint8_t hash[hash_size];
 		struct hc_sha512state sctx;
@@ -522,49 +525,81 @@ static WERROR get_and_verify_access_check(TALLOC_CTX *sub_ctx,
 			DEBUG(2, ("Wrong hash value in the access check in backup key remote protocol\n"));
 			return WERR_INVALID_DATA;
 		}
-		*access_sid = dom_sid_dup(sub_ctx, &(uncrypted_accesscheckv3.sid));
-		if (*access_sid == NULL) {
-			return WERR_NOMEM;
-		}
-		return WERR_OK;
+		access_sid = &(uncrypted_accesscheckv3.sid);
+		break;
 	}
-
-	/* Never reached normally as we filtered at the switch / case level */
-	return WERR_INVALID_DATA;
+	default:
+		/* Never reached normally as we filtered at the switch / case level */
+		return WERR_INVALID_DATA;
+	}
+	
+	caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
+	
+	if (!dom_sid_equal(caller_sid, access_sid)) {
+		return WERR_INVALID_ACCESS;
+	}
+	return WERR_OK;
 }
 
-static WERROR bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state *dce_call,
-					      TALLOC_CTX *mem_ctx,
-					      struct bkrp_BackupKey *r,
-					      struct ldb_context *ldb_ctx)
+/* 
+ * We have some data, such as saved website or IMAP passwords that the
+ * client has in profile on-disk.  This needs to be decrypted.  This
+ * version gives the server the data over the network (protected by
+ * the X.509 certificate and public key encryption, and asks that it
+ * be decrypted returned for short-term use, protected only by the
+ * negotiated transport encryption.
+ *
+ * The data is NOT stored in the LSA, but a X.509 certificate, public
+ * and private keys used to encrypt the data will be stored.  There is
+ * only one active encryption key pair and certificate per domain, it
+ * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store.
+ *
+ * The potentially multiple valid decrypting key pairs are in turn
+ * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString.
+ *
+ */
+static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call,
+					    TALLOC_CTX *mem_ctx,
+					    struct bkrp_BackupKey *r,
+					    struct ldb_context *ldb_ctx)
 {
 	struct bkrp_client_side_wrapped uncrypt_request;
 	DATA_BLOB blob;
 	enum ndr_err_code ndr_err;
 	char *guid_string;
 	char *cert_secret_name;
-	DATA_BLOB secret;
-	DATA_BLOB *uncrypted;
+	DATA_BLOB lsa_secret;
+	DATA_BLOB *uncrypted_data;
 	NTSTATUS status;
-
+	uint32_t requested_version;
+	
 	blob.data = r->in.data_in;
 	blob.length = r->in.data_in_len;
 
-	if (r->in.data_in_len == 0 || r->in.data_in == NULL) {
+	if (r->in.data_in_len < 4 || r->in.data_in == NULL) {
 		return WERR_INVALID_PARAM;
 	}
 
+	/* 
+	 * We check for the version here, so we can actually print the
+	 * message as we are unlikely to parse it with NDR.
+	 */
+	requested_version = IVAL(r->in.data_in, 0);
+	if ((requested_version != BACKUPKEY_CLIENT_WRAP_VERSION2)
+	    && (requested_version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
+		DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", requested_version));
+		return WERR_INVALID_PARAMETER;
+	}
+	
 	ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &uncrypt_request,
 				       (ndr_pull_flags_fn_t)ndr_pull_bkrp_client_side_wrapped);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		return WERR_INVALID_PARAM;
 	}
 
-	if (uncrypt_request.version < BACKUPKEY_MIN_VERSION) {
-		return WERR_INVALID_PARAMETER;
-	}
-
-	if (uncrypt_request.version > BACKUPKEY_MAX_VERSION) {
+	if ((uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION2)
+	    && (uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION3)) {
+		DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", uncrypt_request.version));
 		return WERR_INVALID_PARAMETER;
 	}
 
@@ -583,31 +618,25 @@ static WERROR bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state *dce_call
 	status = get_lsa_secret(mem_ctx,
 				ldb_ctx,
 				cert_secret_name,
-				&secret);
+				&lsa_secret);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name));
-		if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-			/* we do not have the real secret attribute */
-			return WERR_INVALID_PARAMETER;
-		} else {
-			return WERR_FILE_NOT_FOUND;
-		}
-	}
-
-	if (secret.length != 0) {
+		return WERR_INVALID_DATA;
+	} else if (lsa_secret.length == 0) {
+		/* we do not have the real secret attribute, like if we are an RODC */
+		return WERR_INVALID_PARAMETER;
+	} else {
 		hx509_context hctx;
 		struct bkrp_exported_RSA_key_pair keypair;
 		hx509_private_key pk;
 		uint32_t i, res;
-		struct dom_sid *access_sid = NULL;
 		heim_octet_string reversed_secret;
 		heim_octet_string uncrypted_secret;
 		AlgorithmIdentifier alg;
-		struct dom_sid *caller_sid;
 		DATA_BLOB blob_us;
 		WERROR werr;
 
-		ndr_err = ndr_pull_struct_blob(&secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
+		ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 			DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name));
 			return WERR_FILE_NOT_FOUND;
@@ -645,7 +674,7 @@ static WERROR bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state *dce_call
 		hx509_private_key_free(&pk);
 		if (res != 0) {
 			/* We are not able to decrypt the secret, looks like something is wrong */
-			return WERR_INVALID_DATA;
+			return WERR_INVALID_PARAMETER;
 		}
 		blob_us.data = uncrypted_secret.data;
 		blob_us.length = uncrypted_secret.length;
@@ -669,17 +698,17 @@ static WERROR bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state *dce_call
 							   uncrypted_secretv2.payload_key,
 							   uncrypt_request.access_check,
 							   uncrypt_request.access_check_len,
-							   &access_sid);
+							   dce_call->conn->auth_state.session_info);
 			if (!W_ERROR_IS_OK(werr)) {
 				return werr;
 			}
-			uncrypted = talloc(mem_ctx, DATA_BLOB);
-			if (uncrypted == NULL) {
+			uncrypted_data = talloc(mem_ctx, DATA_BLOB);
+			if (uncrypted_data == NULL) {
 				return WERR_INVALID_DATA;
 			}
 
-			uncrypted->data = uncrypted_secretv2.secret;
-			uncrypted->length = uncrypted_secretv2.secret_len;
+			uncrypted_data->data = uncrypted_secretv2.secret;
+			uncrypted_data->length = uncrypted_secretv2.secret_len;
 		}
 		if (uncrypt_request.version == 3) {
 			struct bkrp_encrypted_secret_v3 uncrypted_secretv3;
@@ -700,29 +729,31 @@ static WERROR bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state *dce_call
 				return WERR_INVALID_DATA;
 			}
 
+			/* 
+			 * Confirm that the caller is permitted to
+			 * read this particular data.  Because one key
+			 * pair is used per domain, the caller could
+			 * have stolen the profile data on-disk and
+			 * would otherwise be able to read the
+			 * passwords.
+			 */
+			
 			werr = get_and_verify_access_check(mem_ctx, 3,
 							   uncrypted_secretv3.payload_key,
 							   uncrypt_request.access_check,
 							   uncrypt_request.access_check_len,
-							   &access_sid);
+							   dce_call->conn->auth_state.session_info);
 			if (!W_ERROR_IS_OK(werr)) {
 				return werr;
 			}
 
-			uncrypted = talloc(mem_ctx, DATA_BLOB);
-			if (uncrypted == NULL) {
+			uncrypted_data = talloc(mem_ctx, DATA_BLOB);
+			if (uncrypted_data == NULL) {
 				return WERR_INVALID_DATA;
 			}
 
-			uncrypted->data = uncrypted_secretv3.secret;
-			uncrypted->length = uncrypted_secretv3.secret_len;
-		}
-
-		caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
-
-		if (!dom_sid_equal(caller_sid, access_sid)) {
-			talloc_free(uncrypted);
-			return WERR_INVALID_ACCESS;
+			uncrypted_data->data = uncrypted_secretv3.secret;
+			uncrypted_data->length = uncrypted_secretv3.secret_len;
 		}
 
 		/*
@@ -733,7 +764,7 @@ static WERROR bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state *dce_call
 		 */
 	}
 
-	if (uncrypted->data == NULL) {
+	if (uncrypted_data->data == NULL) {
 		return WERR_INVALID_DATA;
 	}
 
@@ -742,65 +773,95 @@ static WERROR bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state *dce_call
 	 * parent structure is just an array of bytes it a lot of work
 	 * work just prepending 4 bytes
 	 */
-	*(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted->length + 4);
+	*(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted_data->length + 4);
 	W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out));
-	memcpy(4+*(r->out.data_out), uncrypted->data, uncrypted->length);
-	*(r->out.data_out_len) = uncrypted->length + 4;
+	memcpy(4+*(r->out.data_out), uncrypted_data->data, uncrypted_data->length);
+	*(r->out.data_out_len) = uncrypted_data->length + 4;
 
 	return WERR_OK;
 }
 
+/*
+ * Strictly, this function no longer uses Heimdal in order to generate an RSA
+ * key, but GnuTLS.
+ *
+ * The resulting key is then imported into Heimdal's RSA structure.
+ *


-- 
Samba Shared Repository


More information about the samba-cvs mailing list