Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into 4-0-local
authorAndrew Bartlett <abartlet@samba.org>
Tue, 10 Jun 2008 03:19:56 +0000 (13:19 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 10 Jun 2008 03:19:56 +0000 (13:19 +1000)
(This used to be commit 1d52d9cc70158dbe30325220aa5c1e6203c8b72b)

23 files changed:
source4/build/m4/check_cc.m4
source4/configure.ac
source4/heimdal_build/internal.m4 [moved from source4/heimdal_build/config.m4 with 100% similarity]
source4/heimdal_build/internal.mk [moved from source4/heimdal_build/config.mk with 100% similarity]
source4/lib/replace/libreplace.m4
source4/lib/replace/win32.m4
source4/lib/tdb/tdb.i
source4/lib/tdb/tdb.py
source4/lib/tdb/tdb_wrap.c
source4/lib/tls/config.m4
source4/libcli/raw/raweas.c
source4/libcli/smb2/session.c
source4/libcli/smb2/signing.c
source4/libcli/smb2/smb2.h
source4/libcli/smb2/tcon.c
source4/libcli/smb2/transport.c
source4/librpc/rpc/dcerpc_smb2.c
source4/main.mk
source4/smb_server/smb2/negprot.c
source4/smb_server/smb2/receive.c
source4/smb_server/smb2/sesssetup.c
source4/smb_server/smb_server.h
source4/torture/gentest.c

index 569be387214b8247f38be27b54c4213387508951..51531ca7765d65ecc6425de9fe394edec812ac89 100644 (file)
@@ -30,7 +30,7 @@ fi
 # check if the compiler can handle negative enum values
 # and don't truncate the values to INT_MAX
 # a runtime test is needed here
-AC_CACHE_CHECK([that the C compiler understands negative enum values],SMB_BUILD_CC_NEGATIVE_ENUM_VALUES, [
+AC_CACHE_CHECK([that the C compiler understands negative enum values],samba_cv_CC_NEGATIVE_ENUM_VALUES, [
     AC_TRY_RUN(
 [
        #include <stdio.h>
@@ -45,8 +45,8 @@ AC_CACHE_CHECK([that the C compiler understands negative enum values],SMB_BUILD_
                return 0;
        }
 ],
-       SMB_BUILD_CC_NEGATIVE_ENUM_VALUES=yes,SMB_BUILD_CC_NEGATIVE_ENUM_VALUES=no)])
-if test x"$SMB_BUILD_CC_NEGATIVE_ENUM_VALUES" != x"yes"; then
+       samba_cv_CC_NEGATIVE_ENUM_VALUES=yes,samba_cv_CC_NEGATIVE_ENUM_VALUES=no)])
+if test x"$samba_cv_CC_NEGATIVE_ENUM_VALUES" != x"yes"; then
        AC_DEFINE(USE_UINT_ENUMS, 1, [Whether the compiler has uint enum support])
 fi
 
index 73d3ffd4d9b6c60bde0b4a91710b70a810e1f150..7690e700a5f1e7aa51331864a816b883c3d69d4a 100644 (file)
@@ -1,8 +1,7 @@
 dnl -*- mode: m4-mode -*-
 dnl Process this file with autoconf to produce a configure script.
 
-dnl disabled 2.53 requirement - we do work with 2.52 on suse 7.3 for example
-dnl AC_PREREQ(2.53)
+AC_PREREQ(2.54)
 
 AC_INIT([samba],[4],[samba-technical@samba.org])
 
@@ -14,7 +13,7 @@ AC_DEFINE(CONFIG_H_IS_FROM_SAMBA,1,[Marker for samba's config.h])
 m4_include(build/m4/env.m4)
 m4_include(lib/replace/samba.m4)
 m4_include(lib/smbreadline/readline.m4)
-m4_include(heimdal_build/config.m4)
+m4_include(heimdal_build/internal.m4)
 m4_include(lib/util/fault.m4)
 m4_include(lib/util/signal.m4)
 m4_include(lib/util/util.m4)
index 6a85ff5a82904fabfbe84e61a84f5adbc3a6bbe5..71fa0416721497d836c6bc2ca56663489df704e2 100644 (file)
@@ -299,4 +299,5 @@ m4_include(libreplace_cc.m4)
 m4_include(libreplace_ld.m4)
 m4_include(libreplace_network.m4)
 m4_include(libreplace_macros.m4)
-m4_include(autoconf-2.60.m4)
+
+m4_ifndef([AC_USE_SYSTEM_EXTENSIONS],[m4_include(autoconf-2.60.m4)])
index 9ac84cdf2ad93b0c39d733401c5ed2843eebc716..eb364e2cb9f215ba01c8da705631aaa463899f02 100644 (file)
@@ -2,7 +2,7 @@ AC_CHECK_HEADERS(direct.h windows.h winsock2.h ws2tcpip.h)
 
 #######################################
 # Check for mkdir mode
-AC_CACHE_CHECK( [whether mkdir supports mode], ac_mkdir_has_mode,
+AC_CACHE_CHECK( [whether mkdir supports mode], libreplace_cv_mkdir_has_mode,
        AC_TRY_COMPILE([
                #include <stdio.h>
                #ifdef HAVE_DIRECT_H
@@ -11,10 +11,10 @@ AC_CACHE_CHECK( [whether mkdir supports mode], ac_mkdir_has_mode,
                        mkdir("foo",0777);
                        return 0;
        ],
-    ac_mkdir_has_mode="yes",
-    ac_mkdir_has_mode="no") )
+    libreplace_cv_mkdir_has_mode="yes",
+    libreplace_cv_mkdir_has_mode="no") )
 
-if test "$ac_mkdir_has_mode" = "yes"
+if test "$libreplace_cv_mkdir_has_mode" = "yes"
 then
     AC_DEFINE(HAVE_MKDIR_MODE, 1, [Define if target mkdir supports mode option])
 fi
index 5f23568170d8a2e2f196d76bc07e9afc901298eb..3d8b697732f08b06bfb58be63773b994210de8d4 100644 (file)
@@ -160,6 +160,8 @@ typedef struct tdb_context {
         tdb(const char *name, int hash_size, int tdb_flags, int flags, mode_t mode) {
             return tdb_open(name, hash_size, tdb_flags, flags, mode);
         }
+        %feature("docstring") error "S.error() -> int\n"
+                                    "Find last error number returned by operation on this TDB.";
         enum TDB_ERROR error();
         ~tdb() { tdb_close($self); }
         %feature("docstring") close "S.close() -> None\n"
@@ -179,6 +181,8 @@ typedef struct tdb_context {
         %feature("docstring") store "S.store(key, value, flag=TDB_REPLACE) -> None\n"
                                         "Store an entry.";
         int store(TDB_DATA key, TDB_DATA dbuf, int flag);
+        %feature("docstring") exists "S.exists(key) -> bool\n"
+                                        "Check whether key exists in this database.";
         int exists(TDB_DATA key);
         %feature("docstring") firstkey "S.firstkey() -> data\n"
                                         "Return the first key in this database.";
index a8c1d06e0d9717d731ce4c348dc13173d0def648..9f306bab8c475027f426067736c9bbd800c09f85 100644 (file)
@@ -92,6 +92,13 @@ class Tdb(object):
         Open a TDB file.
         """
         _tdb.Tdb_swiginit(self,_tdb.new_Tdb(*args, **kwargs))
+    def error(*args, **kwargs):
+        """
+        S.error() -> int
+        Find last error number returned by operation on this TDB.
+        """
+        return _tdb.Tdb_error(*args, **kwargs)
+
     __swig_destroy__ = _tdb.delete_Tdb
     def close(*args, **kwargs):
         """
@@ -128,6 +135,13 @@ class Tdb(object):
         """
         return _tdb.Tdb_store(*args, **kwargs)
 
+    def exists(*args, **kwargs):
+        """
+        S.exists(key) -> bool
+        Check whether key exists in this database.
+        """
+        return _tdb.Tdb_exists(*args, **kwargs)
+
     def firstkey(*args, **kwargs):
         """
         S.firstkey() -> data
index 27da552d33a3569913b95ea1ca8dc55474657377..32665d79fd967d16aeab5d2dd0fe2ee365806dbd 100644 (file)
@@ -3628,7 +3628,10 @@ static PyMethodDef SwigMethods[] = {
                "S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600)\n"
                "Open a TDB file.\n"
                ""},
-        { (char *)"Tdb_error", (PyCFunction)_wrap_Tdb_error, METH_O, NULL},
+        { (char *)"Tdb_error", (PyCFunction)_wrap_Tdb_error, METH_O, (char *)"\n"
+               "S.error() -> int\n"
+               "Find last error number returned by operation on this TDB.\n"
+               ""},
         { (char *)"delete_Tdb", (PyCFunction)_wrap_delete_Tdb, METH_O, NULL},
         { (char *)"Tdb_close", (PyCFunction)_wrap_Tdb_close, METH_O, (char *)"\n"
                "S.close() -> None\n"
@@ -3651,7 +3654,10 @@ static PyMethodDef SwigMethods[] = {
                "S.store(key, value, flag=TDB_REPLACE) -> None\n"
                "Store an entry.\n"
                ""},
-        { (char *)"Tdb_exists", (PyCFunction) _wrap_Tdb_exists, METH_VARARGS | METH_KEYWORDS, NULL},
+        { (char *)"Tdb_exists", (PyCFunction) _wrap_Tdb_exists, METH_VARARGS | METH_KEYWORDS, (char *)"\n"
+               "S.exists(key) -> bool\n"
+               "Check whether key exists in this database.\n"
+               ""},
         { (char *)"Tdb_firstkey", (PyCFunction)_wrap_Tdb_firstkey, METH_O, (char *)"\n"
                "S.firstkey() -> data\n"
                "Return the first key in this database.\n"
index 8b6ad7dcbc0a144fb250ac95bd61934d34888825..2af9192cca3a0cfb83df87eca8078a5b556412e0 100644 (file)
@@ -1,33 +1,44 @@
 ###############################
 # start SMB_EXT_LIB_GNUTLS
 # check for gnutls/gnutls.h and -lgnutls
-SMB_EXT_LIB_FROM_PKGCONFIG(GNUTLS, gnutls, 
-                                                  [SMB_ENABLE_GNUTLS=YES], 
-                                                  [SMB_ENABLE_GNUTLS=NO])
 
-if test x$SMB_ENABLE_GNUTLS = xNO; then
-       AC_CHECK_HEADERS(gnutls/gnutls.h)
-       AC_CHECK_LIB_EXT(gnutls, GNUTLS_LIBS, gnutls_global_init)
-       AC_CHECK_DECL(gnutls_x509_crt_set_version,  
-                     [AC_DEFINE(HAVE_GNUTLS_X509_CRT_SET_VERSION,1,gnutls set_version)], [], [
-       #include <gnutls/gnutls.h>
-       #include <gnutls/x509.h>
-       ])
-       if test x"$ac_cv_header_gnutls_gnutls_h" = x"yes" -a x"$ac_cv_lib_ext_gnutls_gnutls_global_init" = x"yes" -a x"$ac_cv_have_decl_gnutls_x509_crt_set_version" = x"yes";then
-               SMB_ENABLE(GNUTLS,YES)
-               AC_CHECK_DECL(gnutls_x509_crt_set_subject_key_id,  
-                             [AC_DEFINE(HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID,1,gnutls subject_key)], [], [
-       #include <gnutls/gnutls.h>
-       #include <gnutls/x509.h>
-       ])
+use_gnutls=yes
+AC_ARG_ENABLE(gnutls,
+[  --enable-gnutls          Turn on gnutls support (default=yes)],
+    [if test x$enable_gnutls = xno; then
+        use_gnutls=no
+    fi])
+
+
+if test x$use_gnutls = xyes; then
+       SMB_EXT_LIB_FROM_PKGCONFIG(GNUTLS, gnutls, 
+                                                          [SMB_ENABLE_GNUTLS=YES], 
+                                                          [SMB_ENABLE_GNUTLS=NO])
+       
+       if test x$SMB_ENABLE_GNUTLS = xNO; then
+               AC_CHECK_HEADERS(gnutls/gnutls.h)
+               AC_CHECK_LIB_EXT(gnutls, GNUTLS_LIBS, gnutls_global_init)
+               AC_CHECK_DECL(gnutls_x509_crt_set_version,  
+                             [AC_DEFINE(HAVE_GNUTLS_X509_CRT_SET_VERSION,1,gnutls set_version)], [], [
+               #include <gnutls/gnutls.h>
+               #include <gnutls/x509.h>
+               ])
+               if test x"$ac_cv_header_gnutls_gnutls_h" = x"yes" -a x"$ac_cv_lib_ext_gnutls_gnutls_global_init" = x"yes" -a x"$ac_cv_have_decl_gnutls_x509_crt_set_version" = x"yes";then
+                       SMB_ENABLE(GNUTLS,YES)
+                       AC_CHECK_DECL(gnutls_x509_crt_set_subject_key_id,  
+                                     [AC_DEFINE(HAVE_GNUTLS_X509_CRT_SET_SUBJECT_KEY_ID,1,gnutls subject_key)], [], [
+               #include <gnutls/gnutls.h>
+               #include <gnutls/x509.h>
+               ])
+               fi
+               SMB_EXT_LIB(GNUTLS, $GNUTLS_LIBS)
+       fi
+       if test x$SMB_ENABLE_GNUTLS = xYES; then
+               #Some older versions have a different type name
+               AC_CHECK_TYPES([gnutls_datum],,,[#include "gnutls/gnutls.h"])
+               AC_CHECK_TYPES([gnutls_datum_t],,,[#include "gnutls/gnutls.h"])
+               AC_DEFINE(ENABLE_GNUTLS,1,[Whether we have gnutls support (SSL)])
        fi
-       SMB_EXT_LIB(GNUTLS, $GNUTLS_LIBS)
-fi
-if test x$SMB_ENABLE_GNUTLS = xYES; then
-       #Some older versions have a different type name
-       AC_CHECK_TYPES([gnutls_datum],,,[#include "gnutls/gnutls.h"])
-       AC_CHECK_TYPES([gnutls_datum_t],,,[#include "gnutls/gnutls.h"])
-       AC_DEFINE(ENABLE_GNUTLS,1,[Whether we have gnutls support (SSL)])
 fi
 # end SMB_EXT_LIB_GNUTLS
 ###############################
index 07b517ade3f24bec4fdfc8622bc13a9b0e6dbac0..6317c49fd764cb92c6109fdc53e81f1adf17e0bf 100644 (file)
@@ -131,6 +131,8 @@ uint_t ea_pull_struct(const DATA_BLOB *blob,
        uint8_t nlen;
        uint16_t vlen;
 
+       ZERO_STRUCTP(ea);
+
        if (blob->length < 6) {
                return 0;
        }
index 54915d85353f065b897f0f94eb0c9fdf3f16d5dc..91616319d59329438472999fb46d0e693ba5a210 100644 (file)
@@ -164,7 +164,7 @@ static void session_request_handler(struct smb2_request *req)
 
                session_key_err = gensec_session_key(session->gensec, &session_key);
                if (NT_STATUS_IS_OK(session_key_err)) {
-                       session->transport->signing.session_key = session_key;
+                       session->session_key = session_key;
                }               
        }
 
@@ -188,11 +188,13 @@ static void session_request_handler(struct smb2_request *req)
        }
 
        if (session->transport->signing.doing_signing) {
-               c->status = smb2_start_signing(session->transport);
-               if (!NT_STATUS_IS_OK(c->status)) {
-                       composite_error(c, c->status);
+               if (session->session_key.length != 16) {
+                       DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
+                                (unsigned)session->session_key.length));
+                       composite_error(c, NT_STATUS_ACCESS_DENIED);
                        return;
                }
+               session->transport->signing.signing_started = true;
        }
 
        composite_done(c);
index 16c0ff99c1bab4a243d5fa541ce07038e16c557e..fb2c22db4e2a26e37b413759eef8366029bbef17 100644 (file)
 #include "libcli/smb2/smb2_calls.h"
 #include "lib/crypto/crypto.h"
 
-/*
-  NOTE: this code does not yet interoperate with the windows SMB2
-  implementation. We are waiting on feedback on the docs to find out
-  why
- */
-
-
-/*
-  setup signing on a transport
- */
-NTSTATUS smb2_start_signing(struct smb2_transport *transport)
-{
-       if (transport->signing.session_key.length != 16) {
-               DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
-                        (unsigned)transport->signing.session_key.length));
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
-       transport->signing.signing_started = true;
-       return NT_STATUS_OK;
-}
-
 /*
   sign an outgoing message
  */
-NTSTATUS smb2_sign_message(struct smb2_request *req)
+NTSTATUS smb2_sign_message(struct smb2_request_buffer *buf, DATA_BLOB session_key)
 {
-       struct smb2_request_buffer *buf = &req->out;
-       uint64_t session_id;
        struct HMACSHA256Context m;
        uint8_t res[32];
-
-       if (!req->transport->signing.doing_signing ||
-           !req->transport->signing.signing_started) {
-               return NT_STATUS_OK;
-       }
+       uint64_t session_id;
 
        if (buf->size < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) {
                /* can't sign non-SMB2 messages */
@@ -74,9 +46,9 @@ NTSTATUS smb2_sign_message(struct smb2_request *req)
                return NT_STATUS_OK;            
        }
 
-       if (req->transport->signing.session_key.length != 16) {
+       if (session_key.length != 16) {
                DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
-                        (unsigned)req->transport->signing.session_key.length));
+                        (unsigned)session_key.length));
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -85,7 +57,7 @@ NTSTATUS smb2_sign_message(struct smb2_request *req)
        SIVAL(buf->hdr, SMB2_HDR_FLAGS, IVAL(buf->hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED);
 
        ZERO_STRUCT(m);
-       hmac_sha256_init(req->transport->signing.session_key.data, 16, &m);
+       hmac_sha256_init(session_key.data, 16, &m);
        hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m);
        hmac_sha256_final(res, &m);
 
@@ -93,66 +65,56 @@ NTSTATUS smb2_sign_message(struct smb2_request *req)
 
        memcpy(buf->hdr + SMB2_HDR_SIGNATURE, res, 16);
 
-       if (DEBUGLVL(5)) {
-               /* check our own signature */
-               smb2_check_signature(req->transport, buf->buffer, buf->size);
-       }
-
        return NT_STATUS_OK;    
 }
 
 /*
   check an incoming signature
  */
-NTSTATUS smb2_check_signature(struct smb2_transport *transport,
-                             uint8_t *buffer, uint_t length)
+NTSTATUS smb2_check_signature(struct smb2_request_buffer *buf, DATA_BLOB session_key)
 {
        uint64_t session_id;
        struct HMACSHA256Context m;
        uint8_t res[SHA256_DIGEST_LENGTH];
        uint8_t sig[16];
 
-       if (!transport->signing.signing_started ||
-           !transport->signing.doing_signing) {
-               return NT_STATUS_OK;
-       }
-
-       if (length < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) {
+       if (buf->size < NBT_HDR_SIZE + SMB2_HDR_SIGNATURE + 16) {
                /* can't check non-SMB2 messages */
                return NT_STATUS_OK;
        }
 
-       session_id = BVAL(buffer+NBT_HDR_SIZE, SMB2_HDR_SESSION_ID);
+       session_id = BVAL(buf->hdr, SMB2_HDR_SESSION_ID);
        if (session_id == 0) {
                /* don't sign messages with a zero session_id. See
                   MS-SMB2 3.2.4.1.1 */
                return NT_STATUS_OK;            
        }
 
-       if (transport->signing.session_key.length == 0) {
+       if (session_key.length == 0) {
                /* we don't have the session key yet */
                return NT_STATUS_OK;
        }
 
-       if (transport->signing.session_key.length != 16) {
+       if (session_key.length != 16) {
                DEBUG(2,("Wrong session key length %u for SMB2 signing\n",
-                        (unsigned)transport->signing.session_key.length));
+                        (unsigned)session_key.length));
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       memcpy(sig, buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, 16);
+       memcpy(sig, buf->hdr+SMB2_HDR_SIGNATURE, 16);
 
-       memset(buffer + NBT_HDR_SIZE + SMB2_HDR_SIGNATURE, 0, 16);
+       memset(buf->hdr + SMB2_HDR_SIGNATURE, 0, 16);
 
        ZERO_STRUCT(m);
-       hmac_sha256_init(transport->signing.session_key.data, 16, &m);
-       hmac_sha256_update(buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE, &m);
+       hmac_sha256_init(session_key.data, 16, &m);
+       hmac_sha256_update(buf->hdr, buf->size-NBT_HDR_SIZE, &m);
        hmac_sha256_final(res, &m);
 
-       memcpy(buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, sig, 16);
+       memcpy(buf->hdr+SMB2_HDR_SIGNATURE, sig, 16);
 
        if (memcmp(res, sig, 16) != 0) {
-               DEBUG(0,("Bad SMB2 signature for message of size %u\n", length));
+               DEBUG(0,("Bad SMB2 signature for message of size %u\n", 
+                        (unsigned)buf->size-NBT_HDR_SIZE));
                dump_data(0, sig, 16);
                dump_data(0, res, 16);
                return NT_STATUS_ACCESS_DENIED;
index 0903509528756b56714de98363c1d5f6ef9a734f..2b468d3dc9868f1a302691390c53e16e901d9d49 100644 (file)
@@ -30,7 +30,6 @@ struct smb2_handle;
 struct smb2_signing_context {
        bool doing_signing;
        bool signing_started;
-       DATA_BLOB session_key;
 };
 
 /*
@@ -98,6 +97,7 @@ struct smb2_session {
        struct smb2_transport *transport;
        struct gensec_security *gensec;
        uint64_t uid;
+       DATA_BLOB session_key;
 };
 
 
index db35669d41958a20e236d3535de321257dd51e41..ec7152b264edacdbeea34895e2e79617f0b859d6 100644 (file)
@@ -57,6 +57,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree,
        if (req == NULL) return NULL;
 
        SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, tree->session->uid);
+       req->session = tree->session;
 
        SSVAL(req->out.body, 0x02, io->in.reserved);
        status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path);
index 561b6e528eb60ddfb16dda2df3378c28875a330c..6e0d523e211f6c6b96abc5a61993a86d43cc4090 100644 (file)
@@ -205,12 +205,6 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
                goto error;
        }
 
-       status = smb2_check_signature(transport, buffer, len);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(buffer);
-               return status;
-       }
-       
        flags   = IVAL(hdr, SMB2_HDR_FLAGS);
        seqnum  = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
 
@@ -241,6 +235,17 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
        req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE);
        req->status       = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS));
 
+       if (req->session && transport->signing.doing_signing) {
+               status = smb2_check_signature(&req->in, 
+                                             req->session->session_key);
+               if (!NT_STATUS_IS_OK(status)) {
+                       /* the spec says to ignore packets with a bad signature */
+                       talloc_free(buffer);
+                       return status;
+               }
+       }
+       
+
        if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) {
                if (flags & 0x00000002) {
                        req->cancel.can_cancel = true;
@@ -346,11 +351,16 @@ void smb2_transport_send(struct smb2_request *req)
                return;
        }
 
-       status = smb2_sign_message(req);
-       if (!NT_STATUS_IS_OK(status)) {
-               req->state = SMB2_REQUEST_ERROR;
-               req->status = status;
-               return;
+       /* possibly sign the message */
+       if (req->transport->signing.doing_signing && 
+           req->transport->signing.signing_started &&
+           req->session) {
+               status = smb2_sign_message(&req->out, req->session->session_key);
+               if (!NT_STATUS_IS_OK(status)) {
+                       req->state = SMB2_REQUEST_ERROR;
+                       req->status = status;
+                       return;
+               }
        }
        
        blob = data_blob_const(req->out.buffer, req->out.size);
index 211015a4cf383ae1fe04bcd445e027312c29dc98..4767165fba8dd62596f9d3689fa763776ec62a48 100644 (file)
@@ -376,7 +376,7 @@ static NTSTATUS smb2_session_key(struct dcerpc_connection *c, DATA_BLOB *session
 {
        struct smb2_private *smb = talloc_get_type(c->transport.private_data,
                                                   struct smb2_private);
-       *session_key = smb->tree->session->transport->signing.session_key;
+       *session_key = smb->tree->session->session_key;
        if (session_key->data == NULL) {
                return NT_STATUS_NO_USER_SESSION_KEY;
        }
index 3f3aea87e67969ab5717ddc43e9d90d1db4db06e..f0ce9685f9b62c89f18d73a6a57b1edd9c849ee5 100644 (file)
@@ -1,5 +1,5 @@
 mkinclude dynconfig/config.mk
-mkinclude heimdal_build/config.mk
+mkinclude heimdal_build/internal.mk
 mkinclude config.mk
 mkinclude dsdb/config.mk
 mkinclude smbd/config.mk
index 4479ae2da1d7ff9d234acbc3ffed6118193980f2..3e6e2e1a43c9b2a222f91062bc37bc605788ec72 100644 (file)
@@ -111,7 +111,20 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
        boot_time = timeval_current(); /* TODO: fix me */
 
        ZERO_STRUCT(io->out);
-       io->out.security_mode      = 0; /* no signing yet */
+       switch (lp_server_signing(req->smb_conn->lp_ctx)) {
+       case SMB_SIGNING_OFF:
+               io->out.security_mode = 0;
+               break;
+       case SMB_SIGNING_SUPPORTED:
+       case SMB_SIGNING_AUTO:
+               io->out.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
+               break;
+       case SMB_SIGNING_REQUIRED:
+               io->out.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
+               /* force signing on immediately */
+               req->smb_conn->doing_signing = true;
+               break;
+       }
        io->out.dialect_revision   = SMB2_DIALECT_REVISION;
        io->out.capabilities       = 0;
        io->out.max_transact_size  = lp_parm_ulong(req->smb_conn->lp_ctx, NULL, 
index dea7c9e79ea25ae3d7ee049969c7e5bc9db84bc9..2f4e9df2b6ab9cb4c8692290db1348841709e324 100644 (file)
@@ -29,6 +29,8 @@
 #include "lib/stream/packet.h"
 #include "ntvfs/ntvfs.h"
 #include "param/param.h"
+#include "auth/gensec/gensec.h"
+#include "auth/auth.h"
 
 
 /* fill in the bufinfo */
@@ -233,6 +235,20 @@ void smb2srv_send_reply(struct smb2srv_request *req)
                _smb2_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
        }
 
+       /* if the request was signed or doing_signing is true, then we
+          must sign the reply */
+       if (req->session &&
+           (req->smb_conn->doing_signing ||
+            (IVAL(req->in.hdr, SMB2_HDR_FLAGS) & SMB2_HDR_FLAG_SIGNED))) {
+               status = smb2_sign_message(&req->out, 
+                                          req->session->session_info->session_key);
+               if (!NT_STATUS_IS_OK(status)) {
+                       smbsrv_terminate_connection(req->smb_conn, nt_errstr(status));
+                       return;
+               }               
+       }
+
+
        blob = data_blob_const(req->out.buffer, req->out.size);
        status = packet_send(req->smb_conn->packet, blob);
        if (!NT_STATUS_IS_OK(status)) {
@@ -275,18 +291,42 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req)
        uint16_t opcode;
        uint32_t tid;
        uint64_t uid;
+       uint32_t flags;
 
        opcode                  = SVAL(req->in.hdr, SMB2_HDR_OPCODE);
        req->chain_offset       = IVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND);
        req->seqnum             = BVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID);
        tid                     = IVAL(req->in.hdr, SMB2_HDR_TID);
        uid                     = BVAL(req->in.hdr, SMB2_HDR_SESSION_ID);
+       flags                   = IVAL(req->in.hdr, SMB2_HDR_FLAGS);
 
        req->session    = smbsrv_session_find(req->smb_conn, uid, req->request_time);
        req->tcon       = smbsrv_smb2_tcon_find(req->session, tid, req->request_time);
 
        errno = 0;
 
+       /* supporting signing is mandatory in SMB2, and is per-packet. So we 
+          should check the signature on any incoming packet that is signed, and 
+          should give a signed reply to any signed request */
+       if (flags & SMB2_HDR_FLAG_SIGNED) {
+               NTSTATUS status;
+               if (req->session == NULL) {
+                       /* we can't check signing with no session */
+                       smb2srv_send_error(req, NT_STATUS_ACCESS_DENIED);
+                       return NT_STATUS_OK;                    
+               }
+               status = smb2_check_signature(&req->in, 
+                                             req->session->session_info->session_key);
+               if (!NT_STATUS_IS_OK(status)) {
+                       smb2srv_send_error(req, status);
+                       return NT_STATUS_OK;                    
+               }
+       } else if (req->smb_conn->doing_signing && req->session != NULL) {
+               /* we require signing and this request was not signed */
+               smb2srv_send_error(req, NT_STATUS_ACCESS_DENIED);
+               return NT_STATUS_OK;                                    
+       }
+
        /* TODO: check the seqnum */
 
        switch (opcode) {
index d386bfc72d1c23c4bc28fc0f917e2f845f1e012c..9fb3220005563ab0fe65eba28f3a8d70cb812d67 100644 (file)
@@ -177,6 +177,14 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
 
        gensec_update_send(smb_sess->gensec_ctx, io->smb2.in.secblob,
                           smb2srv_sesssetup_callback, callback_ctx);
+
+       /* note that we ignore SMB2_NEGOTIATE_SIGNING_ENABLED from the client.
+          This is deliberate as windows does not set it even when it does 
+          set SMB2_NEGOTIATE_SIGNING_REQUIRED */
+       if (io->smb2.in.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
+               req->smb_conn->doing_signing = true;
+       }
+
        return;
 nomem:
        status = NT_STATUS_NO_MEMORY;
index 776fe1b71b1a50881a64c4f8ab448d88b0b1af62..ac3e0f3bd3d48da003d436768d18c487dbcd6cc4 100644 (file)
@@ -376,6 +376,8 @@ struct smbsrv_connection {
        struct share_context *share_context;
 
        struct loadparm_context *lp_ctx;
+
+       bool doing_signing;
 };
 
 struct model_ops;
index 60243a5d1b8f961e07bc2309381016225dbef004..15cf32196533e7f0bcda9c27a8c43b089165ed24 100644 (file)
@@ -1459,7 +1459,9 @@ again:
 } while(0)
 
 #define CHECK_BLOB_EQUAL(field) do { \
-       if (memcmp(parm[0].field.data, parm[1].field.data, parm[0].field.length) != 0 && !ignore_pattern(#field)) { \
+       if (((parm[0].field.data == NULL && parm[1].field.data != NULL) || \
+           (parm[1].field.data == NULL && parm[0].field.data != NULL) || \
+           (memcmp(parm[0].field.data, parm[1].field.data, parm[0].field.length) != 0)) && !ignore_pattern(#field)) { \
                current_op.mismatch = #field; \
                printf("Mismatch in %s\n", #field); \
                return false; \