The branch, master has been updated
       via  401860c s3:smbd: add support for SMB_EXTENDED_SIGNATURES in SMBtconX
       via  ff75fd9 s3:smbd: setup the application session key with the first 
tcon on a session
       via  3a0db4d s3:rpc_server/wkssvc: make usage of 
session_extract_session_key()
       via  396f317 s3:rpc_server/netlogon: make usage of 
session_extract_session_key()
      from  49d0432 s3:smbd: setup session->global->signing_/application_key 
during SPNEGO SMB1 session setups

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


- Log -----------------------------------------------------------------
commit 401860cab6ab3d88659361bd333f6667da071d7b
Author: Stefan Metzmacher <[email protected]>
Date:   Fri Aug 3 08:44:39 2012 +0200

    s3:smbd: add support for SMB_EXTENDED_SIGNATURES in SMBtconX
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <[email protected]>
    Autobuild-Date(master): Sat Aug  4 14:28:04 CEST 2012 on sn-devel-104

commit ff75fd9eda805d0d937b442f8221be89504131eb
Author: Stefan Metzmacher <[email protected]>
Date:   Fri Aug 3 08:42:43 2012 +0200

    s3:smbd: setup the application session key with the first tcon on a session
    
    Look for Server.Session.SessionKeyState in [MS-SMB].
    The first SMBtconX sets the state to available, which makes it possible
    to protect the session key at that stage, if client and server
    support TREE_CONNECT_ANDX_EXTENDED_SIGNATURE.
    
    metze

commit 3a0db4d865d404ce7ab3ae787c163fef951e2dd9
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Aug 4 10:05:51 2012 +0200

    s3:rpc_server/wkssvc: make usage of session_extract_session_key()
    
    This makes sure we return NO_USER_SESSION_KEY if there's no session key.
    
    metze

commit 396f3177cafdf0ed9a42d28c60ac59579864eae1
Author: Stefan Metzmacher <[email protected]>
Date:   Sat Aug 4 10:05:51 2012 +0200

    s3:rpc_server/netlogon: make usage of session_extract_session_key()
    
    This makes sure we return NO_USER_SESSION_KEY if there's no session key.
    
    metze

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

Summary of changes:
 source3/rpc_server/netlogon/srv_netlog_nt.c |   10 +++-
 source3/rpc_server/wkssvc/srv_wkssvc_nt.c   |   26 +++++++-
 source3/smbd/reply.c                        |   96 ++++++++++++++++++++++++++-
 source3/smbd/sesssetup.c                    |   32 +--------
 4 files changed, 129 insertions(+), 35 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c 
b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 4621590..d992a65 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -1142,9 +1142,17 @@ static NTSTATUS 
netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
        struct samr_UserInfo18 info18;
        DATA_BLOB in,out;
        int rc;
+       DATA_BLOB session_key;
 
        ZERO_STRUCT(user_handle);
 
+       status = session_extract_session_key(session_info,
+                                            &session_key,
+                                            KEY_USE_16BYTES);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
        rc = tsocket_address_inet_from_strings(mem_ctx,
                                               "ip",
                                               "127.0.0.1",
@@ -1210,7 +1218,7 @@ static NTSTATUS 
netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
 
        in = data_blob_const(nt_hash->hash, 16);
        out = data_blob_talloc_zero(mem_ctx, 16);
-       sess_crypt_blob(&out, &in, &session_info->session_key, true);
+       sess_crypt_blob(&out, &in, &session_key, true);
        memcpy(info18.nt_pwd.hash, out.data, out.length);
 
        info18.nt_pwd_active = true;
diff --git a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c 
b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
index b40ca0b..ada83ea 100644
--- a/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
+++ b/source3/rpc_server/wkssvc/srv_wkssvc_nt.c
@@ -819,6 +819,8 @@ WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
        char *admin_account = NULL;
        WERROR werr;
        struct security_token *token = p->session_info->security_token;
+       NTSTATUS status;
+       DATA_BLOB session_key;
 
        if (!r->in.domain_name) {
                return WERR_INVALID_PARAM;
@@ -841,9 +843,18 @@ WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
                return WERR_NOT_SUPPORTED;
        }
 
+       status = session_extract_session_key(p->session_info,
+                                            &session_key,
+                                            KEY_USE_16BYTES);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(5,("_wkssvc_NetrJoinDomain2: no session key %s\n",
+                       nt_errstr(status)));
+               return WERR_NO_USER_SESSION_KEY;
+       }
+
        werr = decode_wkssvc_join_password_buffer(
                p->mem_ctx, r->in.encrypted_password,
-               &p->session_info->session_key, &cleartext_pwd);
+               &session_key, &cleartext_pwd);
        if (!W_ERROR_IS_OK(werr)) {
                return werr;
        }
@@ -896,6 +907,8 @@ WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
        char *admin_account = NULL;
        WERROR werr;
        struct security_token *token = p->session_info->security_token;
+       NTSTATUS status;
+       DATA_BLOB session_key;
 
        if (!r->in.account || !r->in.encrypted_password) {
                return WERR_INVALID_PARAM;
@@ -909,9 +922,18 @@ WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
                return WERR_ACCESS_DENIED;
        }
 
+       status = session_extract_session_key(p->session_info,
+                                            &session_key,
+                                            KEY_USE_16BYTES);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(5,("_wkssvc_NetrUnjoinDomain2: no session key %s\n",
+                       nt_errstr(status)));
+               return WERR_NO_USER_SESSION_KEY;
+       }
+
        werr = decode_wkssvc_join_password_buffer(
                p->mem_ctx, r->in.encrypted_password,
-               &p->session_info->session_key, &cleartext_pwd);
+               &session_key, &cleartext_pwd);
        if (!W_ERROR_IS_OK(werr)) {
                return werr;
        }
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index a893380..1b4a162 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -42,6 +42,7 @@
 #include "smbprofile.h"
 #include "../lib/tsocket/tsocket.h"
 #include "lib/tevent_wait.h"
+#include "libcli/smb/smb_signing.h"
 
 /****************************************************************************
  Ensure we check the path in *exactly* the same way as W2K for a 
findfirst/findnext
@@ -721,7 +722,11 @@ void reply_tcon_and_X(struct smb_request *req)
        int passlen;
        char *path = NULL;
        const char *p, *q;
-       uint16 tcon_flags;
+       uint16_t tcon_flags;
+       struct smbXsrv_session *session = NULL;
+       NTTIME now = timeval_to_nttime(&req->request_time);
+       bool session_key_updated = false;
+       uint16_t optional_support = 0;
        struct smbd_server_connection *sconn = req->sconn;
 
        START_PROFILE(SMBtconX);
@@ -812,11 +817,99 @@ void reply_tcon_and_X(struct smb_request *req)
 
        DEBUG(4,("Client requested device type [%s] for share [%s]\n", 
client_devicetype, service));
 
+       nt_status = smb1srv_session_lookup(req->sconn->conn,
+                                          req->vuid, now, &session);
+       if (NT_STATUS_EQUAL(nt_status, NT_STATUS_USER_SESSION_DELETED)) {
+               reply_force_doserror(req, ERRSRV, ERRbaduid);
+               END_PROFILE(SMBtconX);
+               return;
+       }
+       if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
+               reply_nterror(req, nt_status);
+               END_PROFILE(SMBtconX);
+               return;
+       }
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+               END_PROFILE(SMBtconX);
+               return;
+       }
+
+       if (session->global->auth_session_info == NULL) {
+               reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+               END_PROFILE(SMBtconX);
+               return;
+       }
+
+       /*
+        * If there is no application key defined yet
+        * we create one.
+        *
+        * This means we setup the application key on the
+        * first tcon that happens via the given session.
+        *
+        * Once the application key is defined, it does not
+        * change any more.
+        */
+       if (session->global->application_key.length == 0 &&
+           session->global->signing_key.length > 0)
+       {
+               struct smbXsrv_session *x = session;
+               struct auth_session_info *session_info =
+                       session->global->auth_session_info;
+               uint8_t session_key[16];
+
+               ZERO_STRUCT(session_key);
+               memcpy(session_key, x->global->signing_key.data,
+                      MIN(x->global->signing_key.length, sizeof(session_key)));
+
+               /*
+                * The application key is truncated/padded to 16 bytes
+                */
+               x->global->application_key = data_blob_talloc(x->global,
+                                                            session_key,
+                                                            
sizeof(session_key));
+               ZERO_STRUCT(session_key);
+               if (x->global->application_key.data == NULL) {
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       END_PROFILE(SMBtconX);
+                       return;
+               }
+
+               if (tcon_flags & TCONX_FLAG_EXTENDED_SIGNATURES) {
+                       smb_key_derivation(x->global->application_key.data,
+                                          x->global->application_key.length,
+                                          x->global->application_key.data);
+                       optional_support |= SMB_EXTENDED_SIGNATURES;
+               }
+
+               /*
+                * Place the application key into the session_info
+                */
+               data_blob_clear_free(&session_info->session_key);
+               session_info->session_key = data_blob_dup_talloc(session_info,
+                                               x->global->application_key);
+               if (session_info->session_key.data == NULL) {
+                       data_blob_clear_free(&x->global->application_key);
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       END_PROFILE(SMBtconX);
+                       return;
+               }
+               session_key_updated = true;
+       }
+
        conn = make_connection(sconn, service, client_devicetype,
                               req->vuid, &nt_status);
        req->conn =conn;
 
        if (!conn) {
+               if (session_key_updated) {
+                       struct smbXsrv_session *x = session;
+                       struct auth_session_info *session_info =
+                               session->global->auth_session_info;
+                       data_blob_clear_free(&x->global->application_key);
+                       data_blob_clear_free(&session_info->session_key);
+               }
                reply_nterror(req, nt_status);
                END_PROFILE(SMBtconX);
                return;
@@ -840,7 +933,6 @@ void reply_tcon_and_X(struct smb_request *req)
        } else {
                /* NT sets the fstype of IPC$ to the null string */
                const char *fstype = IS_IPC(conn) ? "" : lp_fstype(ctx, 
SNUM(conn));
-               uint16_t optional_support = 0;
 
                if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) {
                        /* Return permissions. */
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index cf9c2e7..f47a22d 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -301,38 +301,10 @@ static void reply_sesssetup_and_X_spnego(struct 
smb_request *req)
                        }
 
                        /*
-                        * The application key is truncated/padded to 16 bytes
-                        */
-                       ZERO_STRUCT(session_key);
-                       memcpy(session_key, x->global->signing_key.data,
-                              MIN(x->global->signing_key.length,
-                                  sizeof(session_key)));
-                       x->global->application_key =
-                               data_blob_talloc(x->global,
-                                                session_key,
-                                                sizeof(session_key));
-                       ZERO_STRUCT(session_key);
-                       if (x->global->application_key.data == NULL) {
-                               data_blob_free(&out_blob);
-                               TALLOC_FREE(session);
-                               reply_nterror(req, NT_STATUS_NO_MEMORY);
-                               return;
-                       }
-
-                       /*
-                        * Place the application key into the session_info
+                        * clear the session key
+                        * the first tcon will add setup the application key
                         */
                        data_blob_clear_free(&session_info->session_key);
-                       session_info->session_key =
-                               data_blob_dup_talloc(session_info,
-                                                    
x->global->application_key);
-                       if (session_info->session_key.data == NULL) {
-                               
data_blob_clear_free(&x->global->application_key);
-                               data_blob_free(&out_blob);
-                               TALLOC_FREE(session);
-                               reply_nterror(req, NT_STATUS_NO_MEMORY);
-                               return;
-                       }
                }
 
                session->compat = talloc_zero(session, struct user_struct);


-- 
Samba Shared Repository

Reply via email to