[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Feb 20 06:44:02 UTC 2019


The branch, master has been updated
       via  d4baed454fb WHATSNEW: winbind authentication logging
       via  c8b7b7918b4 winbind: Log PAM and NTLM authentications.
       via  0e2acf6cfb3 winbind: Generate and pass logon ID
       via  e8e4f35bb1d kdc hdb: Generate and pass logon ID
       via  62e4f8f3b2a s4 rpc netlogon: Pass logon_id to auth logging
       via  d486a199598 auth log: Log the netlogon logon id.
       via  96e6adedcd9 librpc idl: netlogon netr_identity_info logon_id to 64 bit
       via  87e63a8665f lib util: Add function to generate random uint64_t
       via  826d930aa4d s3 auth: Create messaging and lp contexts.
       via  47cebbe2152 s3 winbind auth_log: Tests for logon id logging.
       via  e3693bc2ff7 wbinfo: fix --ntlmv1 option
       via  853ad870255 auth_log tests: Allow the remote address to be None
      from  96472306bf1 selftest: Add basic sanity-check tests for nopython target

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d4baed454fb45466f29a19518991be5200a08bde
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Thu Feb 7 09:57:14 2019 +1300

    WHATSNEW: winbind authentication logging
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Feb 20 07:43:10 CET 2019 on sn-devel-144

commit c8b7b7918b49f3598706190975a82be258aa9c44
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jan 28 15:31:46 2019 +1300

    winbind: Log PAM and NTLM authentications.
    
    Generate JSON authentication messages for winbind PAM_AUTH and
    PAM_AUTH_CRAP requests.  The logon_id in these messages can be used to
    link them to the SamLogon messages.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0e2acf6cfb3dc6e0be9130e20890551ee88fcf60
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Fri Feb 1 13:49:49 2019 +1300

    winbind: Generate and pass logon ID
    
    Generate a random logon_id and pass it in the SamLogon calls.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e8e4f35bb1d7328ef7871c02d7fbb78d970fa71d
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Fri Feb 1 13:46:01 2019 +1300

    kdc hdb: Generate and pass logon ID
    
    Generate and pass the logon_id in SamLogon calls
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 62e4f8f3b2ad570f584a2b666cb6a53d53f9d5de
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Fri Feb 1 09:41:18 2019 +1300

    s4 rpc netlogon: Pass logon_id to auth logging
    
    Pass the logon_id passed in the netlogon identity information to
    auth_logging.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d486a199598b75014c5e897543aff51b5af8d0a1
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Fri Feb 1 09:40:10 2019 +1300

    auth log: Log the netlogon logon id.
    
    Add code to log the logonId in the JSON Authentication messages.
    
    The version number for Authentication messages changes from 1.1 to 1.2
    to reflect this.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 96e6adedcd9dfb7556f503a9d7602ac04fe870c1
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Thu Dec 20 15:02:30 2018 +1300

    librpc idl: netlogon netr_identity_info logon_id to 64 bit
    
    Fold the two 32 bit values logon_id_high and logon_id_low into a single
    64 bit logon_id in netr_identity_info.  This will be used to tie
    together winbind and SamLogon requests in audit logging.
    
    Summary of the of the Query and Response from Microsoft on it's usage.
    
    [REG:119013019612095] [MS-NRPC]: NETLOGON_LOGON_IDENTITY_INFO: Does
    the Reserved field have LogonId meaning?
    
    Questions:
      In NetrLogonSamLogonEx does the Reserved field
      (of NETLOGON_LOGON_IDENTITY_INFO) have LogonId meaning?
    
      What is a valid LogonID, and does have any audit usage?
    
      Samba is sending a constant "deadbeef" in hex and would like to
      understand any usage of this field.
    
    Response:
      The NRPC spec is accurate in defining the field as Reserved, and without
      protocol significance. In the header file in our source code, it is
      defined as LogonId and commented as such, but it’s effectively not used.
      This is probably why the API structure has that field name. It may have
      been intended as such but it’s not used.
    
    Samba will send a random value in this field.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 87e63a8665ffb5547140b4bbc25529e20e345a6c
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Fri Feb 1 09:33:53 2019 +1300

    lib util: Add function to generate random uint64_t
    
    Generate a random uint64_t , which will be used for the netlogon
    logon_id.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 826d930aa4de588c84b7c7f993b148c3e7cc757f
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jan 28 15:30:23 2019 +1300

    s3 auth: Create messaging and lp contexts.
    
    If 'auth event notifications' are enabled create an imessaging_context
    and a loadparm_context that can be passed to log_authentication_event.
    
    This will allow the generated authentication messages to be tested.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 47cebbe215298ea4f9fb2e6337930e4a19c859a9
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Jan 22 09:16:05 2019 +1300

    s3 winbind auth_log: Tests for logon id logging.
    
    Tests to validate that winbind generates a random logon_id and passes it
    in the netlogon call.
    
    This will allow the linking of the windbind authentication requests and
    the SamLogon request on the DC.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit e3693bc2ff79b0411dba159a1e8ca626ca57732f
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Thu Jan 31 10:52:07 2019 +1300

    wbinfo: fix --ntlmv1 option
    
    Currently using the --ntlmv1 option fails with an unknown option error.
    This patch ensures that the option is correctly supported.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 853ad870255483c4caea1bebc5e11f1059422172
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Jan 28 15:27:29 2019 +1300

    auth_log tests: Allow the remote address to be None
    
    Allow self.remoteAddress to be None, remote address filtering is not
    required for the winbind auth logging tests.
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 WHATSNEW.txt                                  |  21 ++
 auth/auth_log.c                               |  11 +-
 auth/common_auth.h                            |   1 +
 lib/util/genrand_util.c                       |  11 +
 lib/util/samba_util.h                         |   5 +
 librpc/idl/netlogon.idl                       |  28 +-
 nsswitch/wbinfo.c                             |   1 +
 python/samba/tests/auth_log_base.py           |   3 +
 python/samba/tests/auth_log_winbind.py        | 442 ++++++++++++++++++++++++++
 selftest/target/Samba3.pm                     |   3 +
 source3/auth/auth.c                           |  18 +-
 source3/auth/wscript_build                    |   2 +-
 source3/rpc_client/cli_netlogon.c             |  15 +-
 source3/rpc_client/cli_netlogon.h             |   3 +
 source3/rpcclient/cmd_netlogon.c              |   3 +
 source3/winbindd/winbindd_dual_srv.c          |   5 +
 source3/winbindd/winbindd_pam.c               | 261 +++++++++++++--
 source3/winbindd/winbindd_proto.h             |   5 +
 source4/auth/ntlm/auth_winbind.c              |   3 +-
 source4/kdc/hdb-samba4.c                      |   7 +-
 source4/rpc_server/netlogon/dcerpc_netlogon.c |   9 +
 source4/selftest/tests.py                     |   4 +
 source4/torture/ndr/netlogon.c                |   3 +-
 source4/torture/rpc/netlogon.c                |   3 +-
 source4/torture/rpc/remote_pac.c              |   6 +-
 source4/torture/rpc/samba3rpc.c               |   3 +-
 source4/torture/rpc/samlogon.c                |   6 +-
 source4/torture/rpc/samr.c                    |   3 +-
 source4/torture/rpc/samsync.c                 |   3 +-
 source4/torture/rpc/schannel.c                |   6 +-
 30 files changed, 833 insertions(+), 61 deletions(-)
 create mode 100644 python/samba/tests/auth_log_winbind.py


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 85c417a61a9..79d114883c0 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -30,6 +30,27 @@ worker processes at startup and share the client connections amongst these
 workers. The number of worker processes can be configured by the 'prefork
 children' setting in the smb.conf (the default is 4).
 
+Authentication Logging.
+-----------------------
+
+Winbind now logs PAM_AUTH and NTLM_AUTH events, a new attribute "logonId" has
+been added to the Authentication JSON log messages.  This contains a random
+logon id that is generated for each PAM_AUTH and NTLM_AUTH request and is passed
+to SamLogon, linking the windbind and SamLogon requests.
+
+The serviceDescription of the messages is set to "winbind", the authDescription
+is set to one of:
+   "PASSDB, <command>, <pid>"
+   "PAM_AUTH, <command>, <pid>"
+   "NTLM_AUTH, <command>, <pid>"
+where:
+   <command> is the name of the command makinmg the winbind request i.e. wbinfo
+   <pid>     is the process id of the requesting process.
+
+The version of the JSON Authentication messages has been changed to 1.2 from 1.1
+
+
+
 REMOVED FEATURES
 ================
 
diff --git a/auth/auth_log.c b/auth/auth_log.c
index 8f1ae61a99e..d9b83b0ea0d 100644
--- a/auth/auth_log.c
+++ b/auth/auth_log.c
@@ -41,7 +41,7 @@
  * increment the major version.
  */
 #define AUTH_MAJOR 1
-#define AUTH_MINOR 1
+#define AUTH_MINOR 2
 #define AUTHZ_MAJOR 1
 #define AUTHZ_MINOR 1
 
@@ -151,6 +151,7 @@ static void log_authentication_event_json(
 	struct json_object wrapper = json_empty_object;
 	struct json_object authentication = json_empty_object;
 	char negotiate_flags[11];
+	char logon_id[19];
 	int rc = 0;
 
 	authentication = json_new_object();
@@ -167,6 +168,14 @@ static void log_authentication_event_json(
 	if (rc != 0) {
 		goto failure;
 	}
+	snprintf(logon_id,
+		 sizeof( logon_id),
+		 "%"PRIx64"",
+		 ui->logon_id);
+	rc = json_add_string(&authentication, "logonId", logon_id);
+	if (rc != 0) {
+		goto failure;
+	}
 	rc = json_add_int(&authentication, "logonType", get_logon_type(ui));
 	if (rc != 0) {
 		goto failure;
diff --git a/auth/common_auth.h b/auth/common_auth.h
index d8377eb5347..0443c4e8044 100644
--- a/auth/common_auth.h
+++ b/auth/common_auth.h
@@ -51,6 +51,7 @@ struct auth_usersupplied_info
 
 	bool mapped_state;
 	bool was_mapped;
+	uint64_t logon_id;
 	/* the values the client gives us */
 	struct {
 		const char *account_name;
diff --git a/lib/util/genrand_util.c b/lib/util/genrand_util.c
index 76b7cd91890..d7b74c6cf1a 100644
--- a/lib/util/genrand_util.c
+++ b/lib/util/genrand_util.c
@@ -37,6 +37,17 @@ _PUBLIC_ uint32_t generate_random(void)
 	return IVAL(v, 0);
 }
 
+/**
+  @brief generate a random uint64
+**/
+_PUBLIC_ uint64_t generate_random_u64(void)
+{
+	uint8_t v[8];
+	generate_random_buffer(v, 8);
+	return BVAL(v, 0);
+}
+
+
 
 /**
   Microsoft composed the following rules (among others) for quality
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index 615bb13d6c2..20adae39bcf 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -92,6 +92,11 @@ _PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
 **/
 _PUBLIC_ uint32_t generate_random(void);
 
+/**
+  generate a single random uint64_t
+**/
+_PUBLIC_ uint64_t generate_random_u64(void);
+
 /**
   very basic password quality checker
 **/
diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl
index 22f86b92076..b4474f7ec49 100644
--- a/librpc/idl/netlogon.idl
+++ b/librpc/idl/netlogon.idl
@@ -133,11 +133,35 @@ interface netlogon
 		MSV1_0_SUBAUTHENTICATION_DLL_EX		= 0x00100000
 	} netr_LogonParameterControl;
 
+	/* Summary of the of the Query and Response from Microsoft on
+	 * the usage of logon_id in netr_IdendityInfo
+	 *
+	 * [REG:119013019612095] [MS-NRPC]: NETLOGON_LOGON_IDENTITY_INFO: Does
+	 * the Reserved field have LogonId meaning?
+	 *
+	 * Questions:
+	 *   In NetrLogonSamLogonEx does the Reserved field
+	 *   (of NETLOGON_LOGON_IDENTITY_INFO) have LogonId meaning?
+	 *
+	 *   What is a valid LogonID, and does have any audit usage?
+	 *
+	 *   Samba is sending a constant "deadbeef" in hex and would like to
+	 *   understand any usage of this field.
+	 *
+	 * Response:
+	 *   The NRPC spec is accurate in defining the field as Reserved, and
+	 *   without protocol significance. In the header file in our source
+	 *   code, it is defined as LogonId and commented as such, but it’s
+	 *   effectively not used. This is probably why the API structure has
+	 *   that field name. It may have been intended as such but it’s not
+	 *    used.
+	 *
+	 * Samba now sends a random value in this field.
+	 */
 	typedef struct {
 		lsa_String  domain_name;
 		netr_LogonParameterControl parameter_control; /* see MSV1_0_* */
-		uint32      logon_id_low;
-		uint32      logon_id_high;
+		udlong logon_id;
 		lsa_String  account_name;
 		lsa_String  workstation;
 	} netr_IdentityInfo;
diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index b6f0ff8ccbf..6a1dbd9b56b 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -3243,6 +3243,7 @@ int main(int argc, const char **argv, char **envp)
 		/* generic configuration options */
 		case OPT_DOMAIN_NAME:
 		case OPT_VERBOSE:
+		case OPT_NTLMV1:
 		case OPT_NTLMV2:
 		case OPT_LANMAN:
 		case OPT_LOGOFF_USER:
diff --git a/python/samba/tests/auth_log_base.py b/python/samba/tests/auth_log_base.py
index 38f5eb5175d..c1391080566 100644
--- a/python/samba/tests/auth_log_base.py
+++ b/python/samba/tests/auth_log_base.py
@@ -77,6 +77,9 @@ class AuthLogTestBase(samba.tests.TestCase):
             return False
 
         def isRemote(message):
+            if self.remoteAddress is None:
+                return True
+
             remote = None
             if message["type"] == "Authorization":
                 remote = message["Authorization"]["remoteAddress"]
diff --git a/python/samba/tests/auth_log_winbind.py b/python/samba/tests/auth_log_winbind.py
new file mode 100644
index 00000000000..219b5b8cfc8
--- /dev/null
+++ b/python/samba/tests/auth_log_winbind.py
@@ -0,0 +1,442 @@
+# Unix SMB/CIFS implementation.
+# Copyright (C) Andrew Bartlett <abartlet at samba.org> 2019
+#
+# 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/>.
+#
+
+"""
+    auth logging tests that exercise winbind
+"""
+
+import json
+import os
+from random import SystemRandom
+import string
+import time
+
+from samba.auth import system_session
+from samba.credentials import Credentials
+from samba.compat import get_string, get_bytes
+from samba.dcerpc.messaging import AUTH_EVENT_NAME, MSG_AUTH_LOG
+from samba.dsdb import UF_NORMAL_ACCOUNT
+from samba.messaging import Messaging
+from samba.param import LoadParm
+from samba.samdb import SamDB
+from samba.tests import delete_force, BlackboxProcessError, BlackboxTestCase
+from samba.tests.auth_log_base import AuthLogTestBase
+
+USER_NAME = "WBALU"
+
+
+class AuthLogTestsWinbind(AuthLogTestBase, BlackboxTestCase):
+
+    #
+    # Helper function to watch for authentication messages on the
+    # Domain Controller.
+    #
+    def dc_watcher(self):
+
+        (r1, w1) = os.pipe()
+        pid = os.fork()
+        if pid != 0:
+            # Parent process return the result socket to the caller.
+            return r1
+
+        # Load the lp context for the Domain Controller, rather than the
+        # member server.
+        config_file = os.environ["DC_SERVERCONFFILE"]
+        lp_ctx = LoadParm()
+        lp_ctx.load(config_file)
+
+        #
+        # Is the message a SamLogon authentication?
+        def is_sam_logon(m):
+            if m is None:
+                return False
+            msg = json.loads(m)
+            return (
+                msg["type"] == "Authentication" and
+                msg["Authentication"]["serviceDescription"] == "SamLogon" and
+                msg["Authentication"]["authDescription"] == "interactive")
+
+        #
+        # Handler function for received authentication messages.
+        def message_handler(context, msgType, src, message):
+            # Print the message to help debugging the tests.
+            # as it's a JSON message it does not look like a sub-unit message.
+            print(message)
+            self.dc_msg = message
+
+        # Set up a messaging context to listen for authentication events on
+        # the domain controller.
+        msg_ctx = Messaging((1,), lp_ctx=lp_ctx)
+        msg_ctx.irpc_add_name(AUTH_EVENT_NAME)
+        msg_handler_and_context = (message_handler, None)
+        msg_ctx.register(msg_handler_and_context, msg_type=MSG_AUTH_LOG)
+
+        # Wait for the SamLogon message.
+        # As the SamLogon is the only message we're interested ignore any other
+        # messages.
+        self.dc_msg = None
+        start_time = time.time()
+        while not is_sam_logon(self.dc_msg) and (time.time() - start_time < 1):
+            msg_ctx.loop_once(0.1)
+
+        if self.dc_msg is None:
+            os.write(w1, get_bytes("None"))
+        else:
+            os.write(w1, get_bytes(self.dc_msg))
+
+        msg_ctx.deregister(msg_handler_and_context, msg_type=MSG_AUTH_LOG)
+        msg_ctx.irpc_remove_name(AUTH_EVENT_NAME)
+
+        os._exit(0)
+
+    # Remove any DCE/RPC ncacn_np messages
+    # these only get triggered once per session, and stripping them out
+    # avoids ordering dependencies in the tests
+    #
+    def filter_messages(self, messages):
+        def keep(msg):
+            if (msg["type"] == "Authorization" and
+                msg["Authorization"]["serviceDescription"] == "DCE/RPC" and
+                msg["Authorization"]["authType"] == "ncacn_np"):
+                    return False
+            else:
+                return True
+
+        return list(filter(keep, messages))
+
+    def setUp(self):
+        super(AuthLogTestsWinbind, self).setUp()
+        self.domain = os.environ["DOMAIN"]
+        self.host = os.environ["SERVER"]
+        self.dc = os.environ["DC_SERVER"]
+        self.lp = self.get_loadparm()
+        self.credentials = self.get_credentials()
+        self.session = system_session()
+
+        self.ldb = SamDB(
+            url="ldap://{0}".format(self.dc),
+            session_info=self.session,
+            credentials=self.credentials,
+            lp=self.lp)
+        self.create_user_account()
+
+    def tearDown(self):
+        super(AuthLogTestsWinbind, self).tearDown()
+        delete_force(self.ldb, self.user_dn)
+
+    #
+    # Create a test user account
+    def create_user_account(self):
+        self.user_pass = self.random_password()
+        self.user_name = USER_NAME
+        self.user_dn = "cn=%s,%s" % (self.user_name, self.ldb.domain_dn())
+
+        # remove the account if it exists, this will happen if a previous test
+        # run failed
+        delete_force(self.ldb, self.user_dn)
+
+        utf16pw = ('"%s"' % get_string(self.user_pass)).encode('utf-16-le')
+        self.ldb.add({
+           "dn": self.user_dn,
+           "objectclass": "user",
+           "sAMAccountName": "%s" % self.user_name,
+           "userAccountControl": str(UF_NORMAL_ACCOUNT),
+           "unicodePwd": utf16pw})
+
+        self.user_creds = Credentials()
+        self.user_creds.guess(self.get_loadparm())
+        self.user_creds.set_password(self.user_pass)
+        self.user_creds.set_username(self.user_name)
+        self.user_creds.set_workstation(self.server)
+
+    def test_ntlm_auth(self):
+
+        def isLastExpectedMessage(msg):
+            DESC = "PAM_AUTH, ntlm_auth"
+            return (
+                msg["type"] == "Authentication" and
+                msg["Authentication"]["serviceDescription"] == "winbind" and
+                msg["Authentication"]["authDescription"] is not None and
+                msg["Authentication"]["authDescription"].startswith(DESC))
+
+        pipe = self.dc_watcher()
+        COMMAND = "bin/ntlm_auth"
+        self.check_run("{0} --username={1} --password={2}".format(
+            COMMAND,
+            self.credentials.get_username(),
+            self.credentials.get_password()),
+            msg="ntlm_auth failed")
+
+        messages = self.waitForMessages(isLastExpectedMessage)
+        messages = self.filter_messages(messages)
+        expected_messages = 1
+        self.assertEquals(expected_messages,
+                          len(messages),
+                          "Did not receive the expected number of messages")
+
+        # Check the first message it should be an Authentication
+        msg = messages[0]
+        self.assertEquals("Authentication", msg["type"])
+        self.assertTrue(
+            msg["Authentication"]["authDescription"].startswith(
+                "PAM_AUTH, ntlm_auth,"))
+        self.assertEquals("winbind",
+                          msg["Authentication"]["serviceDescription"])
+        self.assertEquals("Plaintext", msg["Authentication"]["passwordType"])
+        # Logon type should be NetworkCleartext
+        self.assertEquals(8, msg["Authentication"]["logonType"])
+        # Event code should be Successful logon
+        self.assertEquals(4624, msg["Authentication"]["eventId"])
+        self.assertEquals("unix:", msg["Authentication"]["remoteAddress"])
+        self.assertEquals("unix:", msg["Authentication"]["localAddress"])
+        self.assertEquals(self.domain, msg["Authentication"]["clientDomain"])
+        self.assertEquals("NT_STATUS_OK", msg["Authentication"]["status"])
+        self.assertEquals(self.credentials.get_username(),
+                          msg["Authentication"]["clientAccount"])
+        self.assertEquals(self.credentials.get_domain(),
+                          msg["Authentication"]["clientDomain"])
+        self.assertTrue(msg["Authentication"]["workstation"] is None)
+
+        logon_id = msg["Authentication"]["logonId"]
+
+        message = os.read(pipe, 4096)
+        msg = json.loads(get_string(message))
+        self.assertEquals("Authentication", msg["type"])
+        self.assertEquals(logon_id, msg["Authentication"]["logonId"])
+        self.assertEquals("SamLogon",
+                          msg["Authentication"]["serviceDescription"])
+        self.assertEquals("interactive",
+                          msg["Authentication"]["authDescription"])
+
+    def test_wbinfo(self):
+        def isLastExpectedMessage(msg):
+            DESC = "NTLM_AUTH, wbinfo"
+            return (
+                msg["type"] == "Authentication" and
+                msg["Authentication"]["serviceDescription"] == "winbind" and
+                msg["Authentication"]["authDescription"] is not None and
+                msg["Authentication"]["authDescription"].startswith(DESC))
+
+        pipe = self.dc_watcher()
+        COMMAND = "bin/wbinfo"
+        try:
+            self.check_run("{0} -a {1}%{2}".format(
+                COMMAND,
+                self.credentials.get_username(),
+                self.credentials.get_password()),
+                msg="ntlm_auth failed")
+        except BlackboxProcessError:
+            pass
+
+        messages = self.waitForMessages(isLastExpectedMessage)
+        messages = self.filter_messages(messages)
+        expected_messages = 3
+        self.assertEquals(expected_messages,
+                          len(messages),
+                          "Did not receive the expected number of messages")
+
+        # The 1st message should be an Authentication against the local
+        # password database
+        msg = messages[0]
+        self.assertEquals("Authentication", msg["type"])
+        self.assertTrue(msg["Authentication"]["authDescription"].startswith(
+            "PASSDB, wbinfo,"))
+        self.assertEquals("winbind",
+                          msg["Authentication"]["serviceDescription"])
+        # Logon type should be Interactive
+        self.assertEquals(2, msg["Authentication"]["logonType"])
+        # Event code should be Unsuccessful logon
+        self.assertEquals(4625, msg["Authentication"]["eventId"])
+        self.assertEquals("unix:", msg["Authentication"]["remoteAddress"])
+        self.assertEquals("unix:", msg["Authentication"]["localAddress"])
+        self.assertEquals('', msg["Authentication"]["clientDomain"])
+        # This is what the existing winbind implementation returns.
+        self.assertEquals("NT_STATUS_NO_SUCH_USER",
+                          msg["Authentication"]["status"])
+        self.assertEquals("NTLMv2", msg["Authentication"]["passwordType"])
+        self.assertEquals(self.credentials.get_username(),
+                          msg["Authentication"]["clientAccount"])
+        self.assertEquals("", msg["Authentication"]["clientDomain"])
+
+        logon_id = msg["Authentication"]["logonId"]
+
+        # The 2nd message should be a PAM_AUTH with the same logon id as the
+        # 1st message
+        msg = messages[1]
+        self.assertEquals("Authentication", msg["type"])
+        self.assertTrue(msg["Authentication"]["authDescription"].startswith(
+            "PAM_AUTH"))
+        self.assertEquals("winbind",
+                          msg["Authentication"]["serviceDescription"])
+        self.assertEquals(logon_id, msg["Authentication"]["logonId"])
+        # Logon type should be NetworkCleartext
+        self.assertEquals(8, msg["Authentication"]["logonType"])
+        # Event code should be Unsuccessful logon
+        self.assertEquals(4625, msg["Authentication"]["eventId"])
+        self.assertEquals("unix:", msg["Authentication"]["remoteAddress"])
+        self.assertEquals("unix:", msg["Authentication"]["localAddress"])
+        self.assertEquals('', msg["Authentication"]["clientDomain"])
+        # This is what the existing winbind implementation returns.
+        self.assertEquals("NT_STATUS_INVALID_HANDLE",
+                          msg["Authentication"]["status"])
+        self.assertEquals(self.credentials.get_username(),
+                          msg["Authentication"]["clientAccount"])
+        self.assertEquals("", msg["Authentication"]["clientDomain"])
+
+        # The 3rd message should be an NTLM_AUTH
+        msg = messages[2]
+        self.assertEquals("Authentication", msg["type"])
+        self.assertTrue(msg["Authentication"]["authDescription"].startswith(
+            "NTLM_AUTH, wbinfo,"))
+        self.assertEquals("winbind",
+                          msg["Authentication"]["serviceDescription"])
+        # Logon type should be Network
+        self.assertEquals(3, msg["Authentication"]["logonType"])


-- 
Samba Shared Repository



More information about the samba-cvs mailing list