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

Jule Anger janger at samba.org
Sun Sep 18 17:47:01 UTC 2022


The branch, v4-16-test has been updated
       via  6a0280d9553 CVE-2021-20251 dsdb/common: Remove transaction logic from samdb_set_password()
       via  d0cd367da4c s4:rpc_server: Add transaction for dcesrv_samr_SetUserInfo()
       via  f7f1106b2ed s4:rpc_server: Use sam_ctx consistently in dcesrv_samr_SetUserInfo()
       via  c56e2e2e700 s3:rpc_server: Use a done goto label for dcesrv_samr_SetUserInfo()
       via  f78ff75c51f CVE-2021-20251 s4-rpc_server: Extend scope of transaction for ChangePasswordUser3
       via  317d36710b5 s3:rpc_server: Use BURN_STR() to zero password
       via  d9a144e8c4e lib:replace: Add macro BURN_STR() to zero memory of a string
       via  3cab9f6a34e libcli:auth: Keep passwords from convert_string_talloc() secret
       via  a3aebea4893 lib:util: Check memset_s() error code in talloc_keep_secret_destructor()
       via  ae3b615236c CVE-2021-20251 s3: Ensure bad password count atomic updates for SAMR password change
       via  69abe0c2b0a CVE-2021-20251 s3: ensure bad password count atomic updates
       via  05447dfb201 CVE-2021-20251 s4:auth_winbind: Check return status of authsam_logon_success_accounting()
       via  96c24b58b8c CVE-2021-20251 s4-rpc_server: Check badPwdCount update return status
       via  74d8c3d5843 CVE-2021-20251 s4:kdc: Check badPwdCount update return status
       via  5eb5daaa152 CVE-2021-20251 s4:kdc: Check return status of authsam_logon_success_accounting()
       via  29b31129fd3 CVE-2021-20251 s4:kdc: Move logon success accounting code into existing branch
       via  f58d7e42009 CVE-2021-20251 s4:dsdb: Make badPwdCount update atomic
       via  f725f2f2442 CVE-2021-20251 s4:dsdb: Update bad password count inside transaction
       via  2fe2485b93d CVE-2021-20251 s4-auth: Pass through error code from badPwdCount update
       via  6a70d006917 CVE-2021-20251 auth4: Avoid reading the database twice by precaculating some variables
       via  dd38fae8c8d CVE-2021-20251 auth4: Inline samdb_result_effective_badPwdCount() in authsam_logon_success_accounting()
       via  0d6da5250be CVE-2021-20251 auth4: Split authsam_calculate_lastlogon_sync_interval() out
       via  6b826a375a1 CVE-2021-20251 auth4: Return only the result message and free the surrounding result
       via  a9aae34d5a9 CVE-2021-20251 auth4: Add missing newline to debug message on PSO read failure
       via  79f791ff0eb CVE-2021-20251 s4 auth: make bad password count increment atomic
       via  a1a440c1014 CVE-2021-20251 auth4: Detect ACCOUNT_LOCKED_OUT error for password change
       via  8580b90a87b CVE-2021-20251 s4 auth test: Unit tests for source4/auth/sam.c
       via  9dcf447d822 CVE-2021-20251 auth4: Reread the user record if a bad password is noticed.
       via  831335aaaad CVE-2021-20251 s4 auth: Prepare to make bad password count increment atomic
       via  740c4c2b953 CVE-2021-20251 auth4: split samdb_result_msds_LockoutObservationWindow() out
       via  bc30ca2117c CVE-2021-20251 s4-rpc_server: Use authsam_search_account() to find the user
       via  0e3ac110df7 CVE-2021-20251 tests/krb5: Convert password lockout tests to use os.fork() and os.pipe()
       via  63020bf13c0 CVE-2021-20251 tests/krb5: Add tests for password lockout race
       via  b7351888e82 CVE-2021-20251 lib:crypto: Add md4_hash_blob() for hashing data with MD4
       via  3542483de3f CVE-2021-20251 lib:crypto: Add des_crypt_blob_16() for encrypting data with DES
       via  f0c44d9e53d CVE-2021-20251 tests/krb5: Add PasswordKey_from_creds()
       via  d41566d1bd0 third_party: Update socket_wrapper to version 1.3.4
      from  1b4f98ef870 VERSION: Bump version up to Samba 4.16.5...

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


- Log -----------------------------------------------------------------
commit 6a0280d9553db535601c71c1be475f85949d5b83
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Tue Aug 2 14:40:01 2022 +1200

    CVE-2021-20251 dsdb/common: Remove transaction logic from samdb_set_password()
    
    All of its callers, where necessary, take out a transaction covering the
    entire password set or change operation, so a transaction is no longer
    needed here.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 7981cba87e3a7256b12bfc5fdd89b136c12979ff)
    
    Autobuild-User(v4-16-test): Jule Anger <janger at samba.org>
    Autobuild-Date(v4-16-test): Sun Sep 18 17:46:29 UTC 2022 on sn-devel-184

commit d0cd367da4c9a7041541315aa104309c6cb28e05
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jul 26 11:04:29 2022 +0200

    s4:rpc_server: Add transaction for dcesrv_samr_SetUserInfo()
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 1aa403517ffc0d43df72ddc9fa2ce86ab5c33873)

commit f7f1106b2edafc25ddd9c6f98b04c048e1c85dd4
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jul 26 10:59:13 2022 +0200

    s4:rpc_server: Use sam_ctx consistently in dcesrv_samr_SetUserInfo()
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 1b3d7f811680f9ac66ca5822950b3eee081a06b0)

commit c56e2e2e700cb1b4a75f5bb3224ecf4657dd2a99
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jul 26 10:57:19 2022 +0200

    s3:rpc_server: Use a done goto label for dcesrv_samr_SetUserInfo()
    
    This will be used in the following commits.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit a246ae993fd8553bf66aa8ee1700eb68b85f2857)

commit f78ff75c51f6cd15b476de373f11b1c87f962970
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Tue Aug 2 14:39:43 2022 +1200

    CVE-2021-20251 s4-rpc_server: Extend scope of transaction for ChangePasswordUser3
    
    Now the initial account search is performed under the transaction,
    ensuring the overall password change is atomic. We set DSDB_SESSION_INFO
    to drop our privileges to those of the user before we perform the actual
    password change, and restore them afterwards if we need to update the
    bad password count.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit fcabcb326d385c1e1daaa8dae9820e33a3868f56)
    
    [jsutton at samba.org Included dsdb/common/util.h header for
     DSDB_SESSION_INFO define]

commit 317d36710b59ed6f4c72433de950b5a1d77a6c12
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Tue Sep 6 14:54:08 2022 +1200

    s3:rpc_server: Use BURN_STR() to zero password
    
    This ensures these calls are not optimised away.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 1258746ba85b8702628f95a19aba9afea96eab8b)

commit d9a144e8c4ea1488dcec981279d7d22347730ad0
Author: Pavel Filipenský <pfilipensky at samba.org>
Date:   Mon Aug 8 17:47:28 2022 +0200

    lib:replace: Add macro BURN_STR() to zero memory of a string
    
    Signed-off-by: Pavel Filipenský <pfilipensky at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 8564380346ace981b957bb8464f2ecf007032062)
    
    [jsutton at samba.org Fixed conflict]

commit 3cab9f6a34ed7091059d4aa4221d5a6a712d4c25
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Tue Aug 2 14:35:50 2022 +1200

    libcli:auth: Keep passwords from convert_string_talloc() secret
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 6edf88f5c40421b9881666a2e78038ea9c547c24)
    
    [jsutton at samba.org Removed change to decode_pwd_string_from_buffer514()
     that is not present in 4.16]

commit a3aebea4893256b8953101ed06bf4ce1afc381a2
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Tue Aug 2 14:35:33 2022 +1200

    lib:util: Check memset_s() error code in talloc_keep_secret_destructor()
    
    Panic if memset_s() fails.
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 03a50d8f7d872b6ef701d1207061c88b73d171bb)

commit ae3b615236c4cc773be30f34ec9b794a25253449
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Tue Jul 5 20:17:33 2022 +1200

    CVE-2021-20251 s3: Ensure bad password count atomic updates for SAMR password change
    
    The bad password count is supposed to limit the number of failed login
    attempt a user can make before being temporarily locked out, but race
    conditions between processes have allowed determined attackers to make
    many more than the specified number of attempts.  This is especially
    bad on constrained or overcommitted hardware.
    
    To fix this, once a bad password is detected, we reload the sam account
    information under a user-specific mutex, ensuring we have an up to
    date bad password count.
    
    Derived from a similar patch to source3/auth/check_samsec.c by
    Jeremy Allison <jra at samba.org>
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 65c473d4a53fc8a22a0d531aff45203ea3a4d99b)

commit 69abe0c2b0aeeb8ac1fb93baae41f1452ac4a5fc
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Jan 11 12:11:35 2021 -0800

    CVE-2021-20251 s3: ensure bad password count atomic updates
    
    The bad password count is supposed to limit the number of failed login
    attempt a user can make before being temporarily locked out, but race
    conditions between processes have allowed determined attackers to make
    many more than the specified number of attempts.  This is especially
    bad on constrained or overcommitted hardware.
    
    To fix this, once a bad password is detected, we reload the sam account
    information under a user-specific mutex, ensuring we have an up to
    date bad password count.
    
    Discovered by Nathaniel W. Turner.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 8587734bf989aeaafa9d09d78d0f381caf52d285)

commit 05447dfb2016d32fdfffb42fdb02cc4db68b18a9
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Mon Jul 4 20:51:38 2022 +1200

    CVE-2021-20251 s4:auth_winbind: Check return status of authsam_logon_success_accounting()
    
    This may return an error if we find the account is locked out.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 268ea7bef5af4b9c8a02f4f5856113ff0664d9e8)

commit 96c24b58b8cc2301007f0bf586184fd2d264b028
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Jul 9 15:55:02 2022 +1200

    CVE-2021-20251 s4-rpc_server: Check badPwdCount update return status
    
    If the account has been locked out in the meantime (indicated by
    NT_STATUS_ACCOUNT_LOCKED_OUT), we should return the appropriate error
    code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit a268a1a0e304d0702469e4ac146d8af5e7384c39)

commit 74d8c3d5843f2ba285bc1a6ace1eba5080c0e99c
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Jul 9 15:54:52 2022 +1200

    CVE-2021-20251 s4:kdc: Check badPwdCount update return status
    
    If the account has been locked out in the meantime (indicated by
    NT_STATUS_ACCOUNT_LOCKED_OUT), we should return the appropriate error
    code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit bdfc9d96f8fe5070ab8a189bbf42ccb7e77afb73)
    
    [jsutton at samba.org Fixed knownfail conflicts due to not having claims
     tests]
    
    [jsutton at samba.org Fixed knownfail conflicts]

commit 5eb5daaa1521d424ebde5a4d06ad05c9cdfc7996
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Fri Jul 1 15:04:41 2022 +1200

    CVE-2021-20251 s4:kdc: Check return status of authsam_logon_success_accounting()
    
    If we find that the user has been locked out sometime during the request
    (due to a race), we will now return an error code.
    
    Note that we cannot avoid the MIT KDC aspect of the issue by checking
    the return status of mit_samba_zero_bad_password_count(), because
    kdb_vftabl::audit_as_req() returning void means we cannot pass on the
    result.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit b1e740896ebae14ba64250da2f718e1d707e9eed)

commit 29b31129fd372513ad24e56ec4caab6844e2ed72
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Jul 6 11:11:43 2022 +1200

    CVE-2021-20251 s4:kdc: Move logon success accounting code into existing branch
    
    This simplifies the code for the following commit.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 2b593c34c4f5cb82440b940766e53626c1cbec5b)

commit f58d7e42009180dba67832149123a19237d388b2
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Jul 9 15:54:12 2022 +1200

    CVE-2021-20251 s4:dsdb: Make badPwdCount update atomic
    
    We reread the account details inside the transaction in case the account
    has been locked out in the meantime. If it has, we return the
    appropriate error code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 96479747bdb5bc5f33d903085f5f69793f369e3a)
    
    [jsutton at samba.org Fixed conflict due to lack of dbg_ret variable]

commit f725f2f2442b3cef0fb51ad2af5248147524873b
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Jul 9 15:44:21 2022 +1200

    CVE-2021-20251 s4:dsdb: Update bad password count inside transaction
    
    Previously, there was a gap between calling dsdb_update_bad_pwd_count()
    and dsdb_module_modify() where no transaction was in effect. Another
    process could slip in and modify badPwdCount, only for our update to
    immediately overwrite it. Doing the update inside the transaction will
    help for the following commit when we make it atomic.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit a65147a9e98ead70869cdfa20ffcc9c167dbf535)
    
    [jsutton at samba.org Fixed conflicts due to lack of dbg_ret variable]

commit 2fe2485b93d589620684f79b61d3da222accfb1e
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Sat Jul 9 15:53:51 2022 +1200

    CVE-2021-20251 s4-auth: Pass through error code from badPwdCount update
    
    The error code may be NT_STATUS_ACCOUNT_LOCKED_OUT, which we use in
    preference to NT_STATUS_WRONG_PASSWORD.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit d8a862cb811489abb67d4cf3a7fbd83d05c7e5cb)

commit 6a70d006917486e4f1bf9333ab8a4961e79ef51a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 30 16:48:31 2021 +1300

    CVE-2021-20251 auth4: Avoid reading the database twice by precaculating some variables
    
    These variables are not important to protect against a race with
    and a double-read can easily be avoided by moving them up the file
    a little.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit b5f78b7b895a6b92cfdc9221b18d67ab18bc2a24)

commit dd38fae8c8d7d47c75f03b6bc94bed8d47012cb6
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 25 15:33:08 2021 +1300

    CVE-2021-20251 auth4: Inline samdb_result_effective_badPwdCount() in authsam_logon_success_accounting()
    
    By bringing this function inline it can then be split out in a
    subsequent commit.
    
    Based on work by Gary Lockyer <gary at catalyst.net.nz>
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 712181032a47318576ef35f6a6cf0f958aa538fb)

commit 0d6da5250be44888b3eaeb94aad7cee77f44d095
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 25 14:42:39 2021 +1300

    CVE-2021-20251 auth4: Split authsam_calculate_lastlogon_sync_interval() out
    
    authsam_calculate_lastlogon_sync_interval() is split out of authsam_update_lastlogon_timestamp()
    
    Based on work by Gary Lockyer <gary at catalyst.net.nz>
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 55147335aec8194b6439169b040556a96db22e95)

commit 6b826a375a13f44a0486024ee09564cf3b1528ca
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Thu Mar 25 11:30:59 2021 +1300

    CVE-2021-20251 auth4: Return only the result message and free the surrounding result
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit b954acfde258a1909ed60c1c3e1015701582719f)

commit a9aae34d5a97081dff9126328167678cfc4601c7
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 30 16:35:44 2021 +1300

    CVE-2021-20251 auth4: Add missing newline to debug message on PSO read failure
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 4a9e0fdccfa218fbb2c3eb87e1a955ade0364b98)

commit 79f791ff0ebe0a8a6787c74ad20870ce41907844
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 30 18:01:39 2021 +1300

    CVE-2021-20251 s4 auth: make bad password count increment atomic
    
    Ensure that the bad password count is incremented atomically,
    and that the successful logon accounting data is updated atomically.
    
    Use bad password indicator (in a distinct TDB) to determine if to open a transaction
    
    We open a transaction when we have seen the hint that this user
    has recorded a bad password.  This allows us to avoid always
    needing one, while not missing a possible lockout.
    
    We also go back and get a transation if we did not take out
    one out but we chose to do a write (eg for lastLogonTimestamp)
    
    Based on patches by Gary Lockyer <gary at catalyst.net.nz>
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit de4cc0a3dae89f3e51a099282615cf80c8539e11)

commit a1a440c10148d19d3b9ac47ade2fa36ab0e39e33
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Tue Jul 5 20:17:49 2022 +1200

    CVE-2021-20251 auth4: Detect ACCOUNT_LOCKED_OUT error for password change
    
    This is more specific than NT_STATUS_UNSUCCESSFUL, and for the SAMR
    password change, matches the result the call to samdb_result_passwords()
    would give.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 336e303cf1962b56b64c0d9d2b05ac15d00e8692)

commit 8580b90a87b0a18dad8d9808e6d85ccbe5ecf107
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Feb 9 11:59:05 2021 +1300

    CVE-2021-20251 s4 auth test: Unit tests for source4/auth/sam.c
    
    cmocka unit tests for the authsam_reread_user_logon_data in
    source4/auth/sam.c
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit d6cf245b96fb02edb3bcc52733d040d5f03fb918)

commit 9dcf447d82238816f6056d64c68e85ddd8808660
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 30 17:57:10 2021 +1300

    CVE-2021-20251 auth4: Reread the user record if a bad password is noticed.
    
    As is, this is pointless, as we need a transaction to make this
    any less of a race, but this provides the steps towards that goal.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 7b8e32efc336fb728e0c7e3dd6fbe2ed54122124)

commit 831335aaaad6eead7ebd7dc3ed89c5f33c2a3e35
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Jan 27 14:24:58 2021 +1300

    CVE-2021-20251 s4 auth: Prepare to make bad password count increment atomic
    
    To ensure that the bad password count is incremented atomically,
    and that the successful logon accounting data is updated atomically,
    without always opening a transaction, we will need to make a note
    of all bad and successful passwords in a side-DB outside the
    transaction lock.
    
    This provides the functions needed for that and hooks them in
    (future commits will handle errors and use the results).
    
    Based on patches by Gary Lockyer <gary at catalyst.net.nz>
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 408717242aad8adf4551f2394eee2d80a06c7e63)

commit 740c4c2b95367793c557085e3cc5b4e367e2e0bb
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Mar 16 10:52:58 2021 +1300

    CVE-2021-20251 auth4: split samdb_result_msds_LockoutObservationWindow() out
    
    samdb_result_msds_LockoutObservationWindow() is split out of
    samdb_result_effective_badPwdCount()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 2087b0cd986b8959b2a402b9a1891472e47ca0b0)

commit bc30ca2117c75aa57c8a8b11420678cc8eea294b
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 30 10:51:26 2021 +1300

    CVE-2021-20251 s4-rpc_server: Use authsam_search_account() to find the user
    
    This helps the bad password and audit log handling code as it
    allows assumptions to be made about the attributes found in
    the variable "msg", such as that DSDB_SEARCH_SHOW_EXTENDED_DN
    was used.
    
    This ensures we can re-search on the DN via the embedded GUID,
    which in in turn rename-proof.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    (cherry picked from commit 439f96a2cfe77f6cbf331d965a387512c2db91c6)
    
    [jsutton at samba.org Adapted to LM hash still being present]

commit 0e3ac110df7e08823407006aa82e6300524212ee
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Sep 15 16:18:10 2022 +1200

    CVE-2021-20251 tests/krb5: Convert password lockout tests to use os.fork() and os.pipe()
    
    Running the password lockout tests on Fedora 35 occasionally results in
    errors similar to the following:
    
        [1(0)/1 at 0s] samba.tests.krb5.lockout_tests(ad_dc:local)
        EPOLL_CTL_DEL EBADF for fde[0x5569dc76c670] mpx_fde[(nil)] fd[14] - disabling
    
        EPOLL_CTL_DEL EBADF for fde[0x5569dc6089c0] mpx_fde[(nil)] fd[14] - disabling
    
        EPOLL_CTL_DEL EBADF for fde[0x5569dbbe58e0] mpx_fde[(nil)] fd[14] - disabling
    
        UNEXPECTED(error): samba.tests.krb5.lockout_tests.samba.tests.krb5.lockout_tests.LockoutTests.test_lockout_race_kdc(ad_dc:local)
        REASON: Exception: Exception: concurrent.futures.process._RemoteTraceback:
        """
        Traceback (most recent call last):
          File "/usr/lib64/python3.10/concurrent/futures/process.py", line 243, in _process_worker
            r = call_item.fn(*call_item.args, **call_item.kwargs)
          File "/home/samba/src/bin/python/samba/tests/krb5/lockout_tests.py", line 141, in connect_kdc
            pipe.send_bytes(b'0')
          File "/usr/lib64/python3.10/multiprocessing/connection.py", line 205, in send_bytes
            self._send_bytes(m[offset:offset + size])
          File "/usr/lib64/python3.10/multiprocessing/connection.py", line 416, in _send_bytes
            self._send(header + buf)
          File "/usr/lib64/python3.10/multiprocessing/connection.py", line 373, in _send
            n = write(self._handle, buf)
        OSError: [Errno 9] Bad file descriptor
        """
    
        The above exception was the direct cause of the following exception:
    
        Traceback (most recent call last):
          File "/home/samba/src/bin/python/samba/tests/krb5/lockout_tests.py", line 537, in test_lockout_race_kdc
            self.do_lockout_race(connect_kdc)
          File "/home/samba/src/bin/python/samba/tests/krb5/lockout_tests.py", line 863, in do_lockout_race
            self.wait_for_ready(our_pipe, connect_future)
          File "/home/samba/src/bin/python/samba/tests/krb5/lockout_tests.py", line 471, in wait_for_ready
            raise exception
        OSError: [Errno 9] Bad file descriptor
    
    Such messages can be seen to come from epoll_del_event(). By resorting
    to lower-level facilites such as fork() and OS pipes, we lose helpful
    features such as timeouts and propagation of exceptions from child
    processes, but we may avoid interactions with the event system that lead
    to failures.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>

commit 63020bf13c04f7a8604b8f4a02dba48b8aeed769
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Mon Jul 4 20:48:48 2022 +1200

    CVE-2021-20251 tests/krb5: Add tests for password lockout race
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 91e2e5616ccd507fcaf097533c5fc25974119c1e)
    
    [jsutton at samba.org Fixed conflicts in usage.py, knownfails, and tests.py
     due to not having claims tests]
    
    [jsutton at samba.org Removed tests for unsupported SAMR AES password
     change, removed related GNUTLS_PBKDF2_SUPPORT environment variable, and
     fixed knownfail conflicts; marked all password lockout tests as
     flapping due to sporadic failures seen with Fedora 35]

commit b7351888e82c5d2ae6222aede762609c02da2905
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Jul 13 14:20:59 2022 +1200

    CVE-2021-20251 lib:crypto: Add md4_hash_blob() for hashing data with MD4
    
    This lets us access MD4, which might not be available in hashlib, from
    Python. This function is used in a following commit for hashing a
    password to obtain the verifier for a SAMR password change.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 17b8d164f69a5ed79d9b7b7fc2f3f84f8ea534c8)

commit 3542483de3f07806d78ea018852092516582c71d
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Jul 6 15:36:26 2022 +1200

    CVE-2021-20251 lib:crypto: Add des_crypt_blob_16() for encrypting data with DES
    
    This lets us access single-DES from Python. This function is used in a
    following commit for encrypting an NT hash to obtain the verifier for a
    SAMR password change.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit b27a67af0216811d330d8a4c52390cf4fc04b5fd)
    
    [jsutton at samba.org Fixed wscript conflict introduced by commit
     61aeb7740764b202db0ddba559e83c3b2953ae36]

commit f0c44d9e53dbeb9a8ebc387635f6146cb292882f
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Thu Jul 28 10:13:45 2022 +1200

    CVE-2021-20251 tests/krb5: Add PasswordKey_from_creds()
    
    This is needed for generating a key when we don't have ETYPE-INFO2.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14611
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>

commit d41566d1bd0a5452d15925b5c9db66b7b139f06f
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Jul 21 14:55:31 2022 +0200

    third_party: Update socket_wrapper to version 1.3.4
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 5dcb49bbd80abf6f3f082ef9c1d5452991c74c87)

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

Summary of changes:
 buildtools/wafsamba/samba_third_party.py       |    2 +-
 lib/crypto/py_crypto.c                         |  100 +
 lib/crypto/wscript_build                       |    2 +-
 lib/replace/replace.h                          |   11 +
 lib/util/talloc_keep_secret.c                  |   15 +-
 libcli/auth/smbencrypt.c                       |    1 +
 python/samba/tests/krb5/lockout_tests.py       | 1068 +++++++++
 python/samba/tests/krb5/raw_testcase.py        |   27 +-
 python/samba/tests/krb5/rfc4120_constants.py   |    1 +
 python/samba/tests/usage.py                    |    1 +
 selftest/knownfail_mit_kdc                     |   10 +
 selftest/tests.py                              |    2 +
 source3/auth/check_samsec.c                    |   77 +
 source3/rpc_server/samr/srv_samr_chgpasswd.c   |   83 +-
 source3/rpc_server/samr/srv_samr_nt.c          |    6 +-
 source4/auth/ntlm/auth_sam.c                   |    6 +-
 source4/auth/ntlm/auth_winbind.c               |    5 +-
 source4/auth/sam.c                             |  707 +++++-
 source4/auth/tests/sam.c                       | 2746 ++++++++++++++++++++++++
 source4/auth/wscript_build                     |   11 +
 source4/dsdb/common/util.c                     |   57 +-
 source4/dsdb/samdb/ldb_modules/password_hash.c |   62 +-
 source4/kdc/hdb-samba4.c                       |   51 +-
 source4/rpc_server/samr/dcesrv_samr.c          |  124 +-
 source4/rpc_server/samr/samr_password.c        |   83 +-
 source4/selftest/tests.py                      |    4 +
 third_party/socket_wrapper/socket_wrapper.c    |   18 +-
 third_party/socket_wrapper/wscript             |    2 +-
 28 files changed, 5027 insertions(+), 255 deletions(-)
 create mode 100755 python/samba/tests/krb5/lockout_tests.py
 create mode 100644 source4/auth/tests/sam.c


Changeset truncated at 500 lines:

diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py
index f046ebc96da..10635a3d46b 100644
--- a/buildtools/wafsamba/samba_third_party.py
+++ b/buildtools/wafsamba/samba_third_party.py
@@ -24,7 +24,7 @@ Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA
 
 @conf
 def CHECK_SOCKET_WRAPPER(conf):
-    return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.3.3')
+    return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.3.4')
 Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER
 
 @conf
diff --git a/lib/crypto/py_crypto.c b/lib/crypto/py_crypto.c
index ad18d3ada0f..40b0cb9e9c0 100644
--- a/lib/crypto/py_crypto.c
+++ b/lib/crypto/py_crypto.c
@@ -25,6 +25,8 @@
 #include <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
 #include "lib/crypto/gnutls_helpers.h"
+#include "lib/crypto/md4.h"
+#include "libcli/auth/libcli_auth.h"
 
 static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args)
 {
@@ -100,13 +102,111 @@ static PyObject *py_crypto_set_strict_mode(PyObject *module)
 	Py_RETURN_NONE;
 }
 
+static PyObject *py_crypto_des_crypt_blob_16(PyObject *self, PyObject *args)
+{
+	PyObject *py_data = NULL;
+	uint8_t *data = NULL;
+	Py_ssize_t data_size;
+
+	PyObject *py_key = NULL;
+	uint8_t *key = NULL;
+	Py_ssize_t key_size;
+
+	uint8_t result[16];
+
+	bool ok;
+	int ret;
+
+	ok = PyArg_ParseTuple(args, "SS",
+			      &py_data, &py_key);
+	if (!ok) {
+		return NULL;
+	}
+
+	ret = PyBytes_AsStringAndSize(py_data,
+				      (char **)&data,
+				      &data_size);
+	if (ret != 0) {
+		return NULL;
+	}
+
+	ret = PyBytes_AsStringAndSize(py_key,
+				      (char **)&key,
+				      &key_size);
+	if (ret != 0) {
+		return NULL;
+	}
+
+	if (data_size != 16) {
+		return PyErr_Format(PyExc_ValueError,
+				    "Expected data size of 16 bytes; got %zd",
+				    data_size);
+	}
+
+	if (key_size != 14) {
+		return PyErr_Format(PyExc_ValueError,
+				    "Expected key size of 14 bytes; got %zd",
+				    key_size);
+	}
+
+	ret = des_crypt112_16(result, data, key,
+			      SAMBA_GNUTLS_ENCRYPT);
+	if (ret != 0) {
+		return PyErr_Format(PyExc_RuntimeError,
+				    "des_crypt112_16() failed: %d",
+				    ret);
+	}
+
+	return PyBytes_FromStringAndSize((const char *)result,
+					 sizeof(result));
+}
+
+static PyObject *py_crypto_md4_hash_blob(PyObject *self, PyObject *args)
+{
+	PyObject *py_data = NULL;
+	uint8_t *data = NULL;
+	Py_ssize_t data_size;
+
+	uint8_t result[16];
+
+	bool ok;
+	int ret;
+
+	ok = PyArg_ParseTuple(args, "S",
+			      &py_data);
+	if (!ok) {
+		return NULL;
+	}
+
+	ret = PyBytes_AsStringAndSize(py_data,
+				      (char **)&data,
+				      &data_size);
+	if (ret != 0) {
+		return NULL;
+	}
+
+	mdfour(result, data, data_size);
+
+	return PyBytes_FromStringAndSize((const char *)result,
+					 sizeof(result));
+}
+
 static const char py_crypto_arcfour_crypt_blob_doc[] = "arcfour_crypt_blob(data, key)\n"
 					 "Encrypt the data with RC4 algorithm using the key";
 
+static const char py_crypto_des_crypt_blob_16_doc[] = "des_crypt_blob_16(data, key) -> bytes\n"
+						      "Encrypt the 16-byte data with DES using "
+						      "the 14-byte key";
+
+static const char py_crypto_md4_hash_blob_doc[] = "md4_hash_blob(data) -> bytes\n"
+						  "Hash the data with MD4 algorithm";
+
 static PyMethodDef py_crypto_methods[] = {
 	{ "arcfour_crypt_blob", (PyCFunction)py_crypto_arcfour_crypt_blob, METH_VARARGS, py_crypto_arcfour_crypt_blob_doc },
 	{ "set_relax_mode", (PyCFunction)py_crypto_set_relax_mode, METH_NOARGS, "Set fips to relax mode" },
 	{ "set_strict_mode", (PyCFunction)py_crypto_set_strict_mode, METH_NOARGS, "Set fips to strict mode" },
+	{ "des_crypt_blob_16", (PyCFunction)py_crypto_des_crypt_blob_16, METH_VARARGS, py_crypto_des_crypt_blob_16_doc },
+	{ "md4_hash_blob", (PyCFunction)py_crypto_md4_hash_blob, METH_VARARGS, py_crypto_md4_hash_blob_doc },
 	{0},
 };
 
diff --git a/lib/crypto/wscript_build b/lib/crypto/wscript_build
index e5766042541..0d5b548e7f8 100644
--- a/lib/crypto/wscript_build
+++ b/lib/crypto/wscript_build
@@ -50,5 +50,5 @@ bld.SAMBA_SUBSYSTEM('TORTURE_LIBCRYPTO',
 
 bld.SAMBA_PYTHON('python_crypto',
                  source='py_crypto.c',
-                 deps='gnutls talloc',
+                 deps='gnutls talloc LIBCLI_AUTH',
                  realname='samba/crypto.so')
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index 8609d84322c..3c938f26240 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -846,6 +846,17 @@ typedef unsigned long long ptrdiff_t ;
  */
 #define ZERO_ARRAY_LEN(x, l) memset_s((char *)(x), (l), 0, (l))
 
+/**
+ * Explicitly zero data in string. This is guaranteed to be not optimized
+ * away.
+ */
+#define BURN_STR(x)	do { \
+				if ((x) != NULL) { \
+					size_t s = strlen(x); \
+					memset_s((x), s, 0, s); \
+				} \
+			} while(0)
+
 /**
  * Work out how many elements there are in a static array.
  */
diff --git a/lib/util/talloc_keep_secret.c b/lib/util/talloc_keep_secret.c
index d6aa38265f6..c427406cbba 100644
--- a/lib/util/talloc_keep_secret.c
+++ b/lib/util/talloc_keep_secret.c
@@ -20,13 +20,26 @@
 
 static int talloc_keep_secret_destructor(void *ptr)
 {
+	int ret;
 	size_t size = talloc_get_size(ptr);
 
 	if (unlikely(size == 0)) {
 		return 0;
 	}
 
-	memset_s(ptr, size, 0, size);
+	ret = memset_s(ptr, size, 0, size);
+	if (unlikely(ret != 0)) {
+		char *msg = NULL;
+		int ret2;
+		ret2 = asprintf(&msg,
+				"talloc_keep_secret_destructor: memset_s() failed: %s",
+				strerror(ret));
+		if (ret2 != -1) {
+			smb_panic(msg);
+		} else {
+			smb_panic("talloc_keep_secret_destructor: memset_s() failed");
+		}
+	}
 
 	return 0;
 }
diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c
index fe20fe4e2a3..c4339272fb6 100644
--- a/libcli/auth/smbencrypt.c
+++ b/libcli/auth/smbencrypt.c
@@ -937,6 +937,7 @@ bool decode_pw_buffer(TALLOC_CTX *ctx,
 		DEBUG(0, ("decode_pw_buffer: failed to convert incoming password\n"));
 		return false;
 	}
+	talloc_keep_secret(*pp_new_pwrd);
 
 #ifdef DEBUG_PASSWORD
 	DEBUG(100,("decode_pw_buffer: new_pwrd: "));
diff --git a/python/samba/tests/krb5/lockout_tests.py b/python/samba/tests/krb5/lockout_tests.py
new file mode 100755
index 00000000000..19131feb543
--- /dev/null
+++ b/python/samba/tests/krb5/lockout_tests.py
@@ -0,0 +1,1068 @@
+#!/usr/bin/env python3
+# Unix SMB/CIFS implementation.
+# Copyright (C) Stefan Metzmacher 2020
+# Copyright (C) Catalyst.Net Ltd
+#
+# 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 enum import Enum
+from functools import partial
+import os
+import sys
+import time
+
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives.ciphers.base import Cipher
+from cryptography.hazmat.primitives.ciphers import algorithms
+
+import ldb
+
+from samba import (
+    NTSTATUSError,
+    dsdb,
+    generate_random_password,
+    ntstatus,
+    unix2nttime,
+    werror,
+)
+from samba.credentials import DONT_USE_KERBEROS, MUST_USE_KERBEROS
+from samba.crypto import (
+    des_crypt_blob_16,
+    md4_hash_blob,
+)
+from samba.dcerpc import lsa, samr
+from samba.samdb import SamDB
+
+from samba.tests import connect_samdb, env_get_var_value, env_loadparm
+
+from samba.tests.krb5.as_req_tests import AsReqBaseTest
+from samba.tests.krb5 import kcrypto
+from samba.tests.krb5.kdc_base_test import KDCBaseTest
+from samba.tests.krb5.raw_testcase import KerberosCredentials
+import samba.tests.krb5.rfc4120_pyasn1 as krb5_asn1
+from samba.tests.krb5.rfc4120_constants import (
+    KDC_ERR_CLIENT_REVOKED,
+    KDC_ERR_PREAUTH_FAILED,
+    KRB_AS_REP,
+    KRB_ERROR,
+    NT_PRINCIPAL,
+    NT_SRV_INST,
+)
+
+sys.path.insert(0, 'bin/python')
+os.environ['PYTHONUNBUFFERED'] = '1'
+
+global_asn1_print = False
+global_hexdump = False
+
+
+class ConnectionResult(Enum):
+    LOCKED_OUT = 1
+    WRONG_PASSWORD = 2
+    SUCCESS = 3
+    ERROR = 4
+
+
+def fork_connect_fn(connect_fn,
+                    read_pipe,
+                    write_pipe,
+                    *args,
+                    **kwargs):
+    pid = os.fork()
+    if pid == 0:
+        result = ConnectionResult.ERROR
+        msg = b'done'
+        try:
+            result = connect_fn(
+                read_pipe=read_pipe,
+                write_pipe=write_pipe,
+                *args,
+                **kwargs)
+        except Exception as err:
+            msg = repr(err).encode('utf8')
+        finally:
+            # Write something to the pipe to provide some information if we
+            # fail, and so the main process won't wait forever.
+            os.write(write_pipe, msg)
+
+            # Return result via the exit status.
+            os._exit(result.value)
+
+    return pid
+
+
+def connect_kdc(read_pipe,
+                write_pipe,
+                url,
+                hostname,
+                username,
+                password,
+                domain,
+                realm,
+                workstation,
+                dn,
+                expect_error=True):
+    AsReqBaseTest.setUpClass()
+    as_req_base = AsReqBaseTest()
+    as_req_base.setUp()
+
+    user_creds = KerberosCredentials()
+    user_creds.set_username(username)
+    user_creds.set_password(password)
+    user_creds.set_domain(domain)
+    user_creds.set_realm(realm)
+    user_creds.set_workstation(workstation)
+    user_creds.set_kerberos_state(DONT_USE_KERBEROS)
+
+    user_name = user_creds.get_username()
+    cname = as_req_base.PrincipalName_create(name_type=NT_PRINCIPAL,
+                                             names=user_name.split('/'))
+
+    krbtgt_creds = as_req_base.get_krbtgt_creds()
+    krbtgt_supported_etypes = krbtgt_creds.tgs_supported_enctypes
+    realm = krbtgt_creds.get_realm()
+
+    krbtgt_account = krbtgt_creds.get_username()
+    sname = as_req_base.PrincipalName_create(name_type=NT_SRV_INST,
+                                             names=[krbtgt_account, realm])
+
+    expected_salt = user_creds.get_salt()
+
+    till = as_req_base.get_KerberosTime(offset=36000)
+
+    kdc_options = krb5_asn1.KDCOptions('postdated')
+
+    preauth_key = as_req_base.PasswordKey_from_creds(user_creds,
+                                                     kcrypto.Enctype.AES256)
+
+    ts_enc_padata = as_req_base.get_enc_timestamp_pa_data_from_key(preauth_key)
+    padata = [ts_enc_padata]
+
+    krbtgt_decryption_key = (
+        as_req_base.TicketDecryptionKey_from_creds(krbtgt_creds))
+
+    etypes = as_req_base.get_default_enctypes()
+
+    if expect_error:
+        expected_error_modes = (KDC_ERR_CLIENT_REVOKED,
+                                KDC_ERR_PREAUTH_FAILED)
+    else:
+        expected_error_modes = 0
+
+    # Remove the LDAP connection.
+    del type(as_req_base)._ldb
+
+    # Indicate that we're ready. This ensures we hit the right transaction
+    # lock.
+    if os.write(write_pipe, b'ready') != 5:
+        raise AssertionError('we failed to indicate readiness')
+
+    # Wait for the main process to take out a transaction lock.
+    if os.read(read_pipe, 5) != b'ready':
+        raise AssertionError('main process failed to indicate readiness')
+
+    # Try making a Kerberos AS-REQ to the KDC. This should fail, either due to
+    # the user's account being locked out or due to using the wrong password.
+    as_rep, kdc_exchange_dict = as_req_base._test_as_exchange(
+        cname=cname,
+        realm=realm,
+        sname=sname,
+        till=till,
+        client_as_etypes=etypes,
+        expected_error_mode=expected_error_modes,
+        expected_crealm=realm,
+        expected_cname=cname,
+        expected_srealm=realm,
+        expected_sname=sname,
+        expected_salt=expected_salt,
+        etypes=etypes,
+        padata=padata,
+        kdc_options=kdc_options,
+        expected_supported_etypes=krbtgt_supported_etypes,
+        expected_account_name=user_name,
+        preauth_key=preauth_key,
+        ticket_decryption_key=krbtgt_decryption_key,
+        pac_request=True)
+    as_req_base.assertIsNotNone(as_rep)
+
+    msg_type = as_rep['msg-type']
+    if expect_error and msg_type != KRB_ERROR or (
+            not expect_error and msg_type != KRB_AS_REP):
+        raise AssertionError(f'wrong message type {msg_type}')
+
+    if not expect_error:
+        return ConnectionResult.SUCCESS
+
+    error_code = as_rep['error-code']
+    if error_code == KDC_ERR_CLIENT_REVOKED:
+        return ConnectionResult.LOCKED_OUT
+    elif error_code == KDC_ERR_PREAUTH_FAILED:
+        return ConnectionResult.WRONG_PASSWORD
+    else:
+        raise AssertionError(f'wrong error code {error_code}')
+
+
+def connect_ntlm(read_pipe,
+                 write_pipe,
+                 url,
+                 hostname,
+                 username,
+                 password,
+                 domain,
+                 realm,
+                 workstation,
+                 dn):
+    user_creds = KerberosCredentials()
+    user_creds.set_username(username)
+    user_creds.set_password(password)
+    user_creds.set_domain(domain)
+    user_creds.set_workstation(workstation)
+    user_creds.set_kerberos_state(DONT_USE_KERBEROS)
+
+    # Indicate that we're ready. This ensures we hit the right transaction
+    # lock.
+    if os.write(write_pipe, b'ready') != 5:
+        raise AssertionError('we failed to indicate readiness')
+
+    # Wait for the main process to take out a transaction lock.
+    if os.read(read_pipe, 5) != b'ready':
+        raise AssertionError('main process failed to indicate readiness')
+
+    try:
+        # Try connecting to SamDB. This should fail, either due to our
+        # account being locked out or due to using the wrong password.
+        SamDB(url=url,
+              credentials=user_creds,
+              lp=env_loadparm())
+    except ldb.LdbError as err:
+        num, estr = err.args
+
+        if num != ldb.ERR_INVALID_CREDENTIALS:
+            raise AssertionError(f'connection raised wrong error code '
+                                 f'({err})')
+
+        if f'data {werror.WERR_ACCOUNT_LOCKED_OUT:x},' in estr:
+            return ConnectionResult.LOCKED_OUT
+        elif f'data {werror.WERR_LOGON_FAILURE:x},' in estr:
+            return ConnectionResult.WRONG_PASSWORD
+        else:
+            raise AssertionError(f'connection raised wrong error code '
+                                 f'({estr})')
+    else:
+        return ConnectionResult.SUCCESS
+
+
+def connect_samr(read_pipe,
+                 write_pipe,
+                 url,
+                 hostname,
+                 username,
+                 password,
+                 domain,
+                 realm,
+                 workstation,
+                 dn):
+    # Get the user's NT hash.
+    user_creds = KerberosCredentials()
+    user_creds.set_password(password)


-- 
Samba Shared Repository



More information about the samba-cvs mailing list