Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
authorJelmer Vernooij <jelmer@samba.org>
Thu, 5 Jun 2008 20:03:17 +0000 (22:03 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Thu, 5 Jun 2008 20:03:17 +0000 (22:03 +0200)
59 files changed:
source/cluster/ctdb/opendb_ctdb.c
source/kdc/hdb-ldb.c
source/kdc/kdc.c
source/kdc/kdc.h
source/kdc/kpasswdd.c
source/kdc/pac-glue.c
source/lib/crypto/config.mk
source/lib/crypto/crypto.h
source/lib/crypto/hmacsha1test.c [deleted file]
source/lib/crypto/hmacsha256.c [moved from source/lib/crypto/hmacsha1.c with 56% similarity]
source/lib/crypto/hmacsha256.h [moved from source/lib/crypto/hmacsha1.h with 59% similarity]
source/lib/crypto/sha1.c [deleted file]
source/lib/crypto/sha1.h [deleted file]
source/lib/crypto/sha1test.c [deleted file]
source/lib/crypto/sha256.c [new file with mode: 0644]
source/lib/crypto/sha256.h [new file with mode: 0644]
source/lib/ldb/tests/python/ldap.py
source/lib/torture/torture.h
source/libcli/raw/interfaces.h
source/libcli/raw/rawsetfileinfo.c
source/libcli/raw/trans2.h
source/libcli/smb2/signing.c
source/librpc/idl/opendb.idl
source/ntvfs/common/brlock.c
source/ntvfs/common/brlock_tdb.c
source/ntvfs/common/opendb.c
source/ntvfs/common/opendb.h
source/ntvfs/common/opendb_tdb.c
source/ntvfs/ntvfs.h
source/ntvfs/ntvfs_generic.c
source/ntvfs/posix/pvfs_fileinfo.c
source/ntvfs/posix/pvfs_lock.c
source/ntvfs/posix/pvfs_open.c
source/ntvfs/posix/pvfs_oplock.c
source/ntvfs/posix/pvfs_rename.c
source/ntvfs/posix/pvfs_resolve.c
source/ntvfs/posix/pvfs_search.c
source/ntvfs/posix/pvfs_seek.c
source/ntvfs/posix/pvfs_setfileinfo.c
source/ntvfs/posix/pvfs_unlink.c
source/ntvfs/posix/pvfs_write.c
source/ntvfs/posix/vfs_posix.c
source/ntvfs/posix/vfs_posix.h
source/samba4-knownfail
source/samba4-skip
source/selftest/samba4_tests.sh
source/selftest/target/Samba4.pm
source/setup/setpassword [changed mode: 0644->0755]
source/smb_server/smb/trans2.c
source/smb_server/smb2/fileinfo.c
source/smb_server/smb2/tcon.c
source/torture/basic/delaywrite.c
source/torture/gentest.c
source/torture/local/local.c
source/torture/nbench/nbench.c
source/torture/smb2/getinfo.c
source/torture/smb2/lock.c
source/torture/smb2/scan.c
testprogs/ejs/ldap.js

index ed09cf0bbcc9efd0e1a00f58a5c12cc02ae8c126..b1faf9e0e645f5127e14f592a2e28f23d7a4fc73 100644 (file)
@@ -283,7 +283,8 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_ent
 */
 static NTSTATUS odb_ctdb_open_file(struct odb_lock *lck,
                                   void *file_handle, const char *path,
-                                  int *fd, bool allow_level_II_oplock,
+                                  int *fd, NTTIME open_write_time,
+                                  bool allow_level_II_oplock,
                                   uint32_t oplock_level, uint32_t *oplock_granted)
 
 {
@@ -492,37 +493,30 @@ static NTSTATUS odb_ctdb_set_delete_on_close(struct odb_lock *lck, bool del_on_c
        return odb_push_record(lck, &file);
 }
 
+static NTSTATUS odb_ctdb_set_write_time(struct odb_lock *lck,
+                                       NTTIME write_time, bool force)
+{
+       /*
+        * as this file will went away and isn't used yet,
+        * copy the implementation from the tdb backend
+        * --metze
+        */
+       return NT_STATUS_FOOBAR;
+}
+
 /*
   return the current value of the delete_on_close bit, and how many
   people still have the file open
 */
-static NTSTATUS odb_ctdb_get_delete_on_close(struct odb_context *odb, 
-                                           DATA_BLOB *key, bool *del_on_close)
+static NTSTATUS odb_ctdb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
+                                       bool *del_on_close, NTTIME *write_time)
 {
-       NTSTATUS status;
-       struct opendb_file file;
-       struct odb_lock *lck;
-
-       (*del_on_close) = false;
-
-       lck = odb_lock(odb, odb, key);
-       NT_STATUS_HAVE_NO_MEMORY(lck);
-
-       status = odb_pull_record(lck, &file);
-       if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
-               talloc_free(lck);
-               return NT_STATUS_OK;
-       }
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(lck);
-               return status;
-       }
-
-       (*del_on_close) = file.delete_on_close;
-
-       talloc_free(lck);
-
-       return NT_STATUS_OK;
+       /*
+        * as this file will went away and isn't used yet,
+        * copy the implementation from the tdb backend
+        * --metze
+        */
+       return NT_STATUS_FOOBAR;
 }
 
 
@@ -589,7 +583,8 @@ static const struct opendb_ops opendb_ctdb_ops = {
        .odb_rename              = odb_ctdb_rename,
        .odb_get_path            = odb_ctdb_get_path,
        .odb_set_delete_on_close = odb_ctdb_set_delete_on_close,
-       .odb_get_delete_on_close = odb_ctdb_get_delete_on_close,
+       .odb_set_write_time      = odb_ctdb_set_write_time,
+       .odb_get_file_infos      = odb_ctdb_get_file_infos,
        .odb_can_open            = odb_ctdb_can_open,
        .odb_update_oplock       = odb_ctdb_update_oplock,
        .odb_break_oplocks       = odb_ctdb_break_oplocks
index 9c7b1f6457a85dbec24008f67de1bfb435220d6f..70e578ee0d546db5b93e6219b9c9247a5f999f3d 100644 (file)
 
 #include "includes.h"
 #include "system/time.h"
-#include "kdc.h"
 #include "dsdb/common/flags.h"
-#include "hdb.h"
-#include "krb5_locl.h"
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
 #include "librpc/gen_ndr/netlogon.h"
@@ -51,6 +48,7 @@
 #include "libcli/auth/libcli_auth.h"
 #include "param/param.h"
 #include "events/events.h"
+#include "kdc/kdc.h"
 
 enum hdb_ldb_ent_type 
 { HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER, 
index 84d9d45f5768310705877707a41dbf33f3d578d8..dfd62c55a47dff1e87a948dfba67aae0bb33255b 100644 (file)
 #include "smbd/process_model.h"
 #include "lib/events/events.h"
 #include "lib/socket/socket.h"
-#include "kdc/kdc.h"
 #include "system/network.h"
 #include "lib/util/dlinklist.h"
 #include "lib/messaging/irpc.h"
 #include "lib/stream/packet.h"
 #include "librpc/gen_ndr/samr.h"
 #include "lib/socket/netif.h"
-#include "heimdal/kdc/windc_plugin.h"
-#include "heimdal/lib/krb5/krb5_locl.h"
-#include "heimdal/kdc/kdc_locl.h"
 #include "param/param.h"
+#include "kdc/kdc.h"
 
 
 /* Disgusting hack to get a mem_ctx and lp_ctx into the hdb plugin, when 
index 9be15115d13cd88f991cb33c93ffc197150f0e9e..0943de4b007251dd05897423eb7dcf076f76dbcb 100644 (file)
@@ -24,6 +24,7 @@
 #include "auth/kerberos/kerberos.h"
 #include "heimdal/kdc/kdc.h"
 #include "heimdal/lib/hdb/hdb.h"
+#include "heimdal/kdc/windc_plugin.h"
 #include "kdc/pac_glue.h"
 
 struct kdc_server;
index 1d49a8a4bd23d726fe56754cd6fd6cd3fbfe63b1..b42769c6dcd3d64ae8f206972280e2e016b3489a 100644 (file)
@@ -24,7 +24,6 @@
 #include "smbd/service_task.h"
 #include "lib/events/events.h"
 #include "lib/socket/socket.h"
-#include "kdc/kdc.h"
 #include "system/network.h"
 #include "lib/util/dlinklist.h"
 #include "lib/ldb/include/ldb.h"
@@ -39,6 +38,7 @@
 #include "rpc_server/samr/proto.h"
 #include "libcli/security/security.h"
 #include "param/param.h"
+#include "kdc/kdc.h"
 
 /* hold information about one kdc socket */
 struct kpasswd_socket {
index 1c68d4c37de669166db55ec6cd0665358b1043cf..cab1446ff356a4e5edccaa9f6c19fc0f3260b64c 100644 (file)
@@ -21,7 +21,6 @@
 */
 
 #include "includes.h"
-#include "kdc/kdc.h"
 #include "dsdb/common/flags.h"
 #include "lib/ldb/include/ldb.h"
 #include "librpc/gen_ndr/ndr_krb5pac.h"
@@ -30,6 +29,7 @@
 #include "auth/auth_sam.h"
 #include "auth/auth_sam_reply.h"
 #include "param/param.h"
+#include "kdc/kdc.h"
 
 struct krb5_dh_moduli;
 struct _krb5_krb_auth_data;
index b9a7f7cb9ec962809fc056a5ca6e9709714455fc..ee111bd08825c2e51416e76bc79ba5b15cb03931 100644 (file)
@@ -6,14 +6,13 @@
 
 LIBCRYPTO_OBJ_FILES = $(addprefix $(libcryptosrcdir)/, \
                                         crc32.o md5.o hmacmd5.o md4.o \
-                                        arcfour.o sha1.o hmacsha1.o)
-
+                                        arcfour.o sha256.o hmacsha256.o)
 
 [MODULE::TORTURE_LIBCRYPTO]
 SUBSYSTEM = smbtorture
 PRIVATE_DEPENDENCIES = LIBCRYPTO
 
 TORTURE_LIBCRYPTO_OBJ_FILES = $(addprefix $(libcryptosrcdir)/, \
-               md4test.o md5test.o hmacmd5test.o sha1test.o hmacsha1test.o)
+               md4test.o md5test.o hmacmd5test.o)
 
 $(eval $(call proto_header_template,$(libcryptosrcdir)/test_proto.h,$(TORTURE_LIBCRYPTO_OBJ_FILES:.o=.c)))
index 10e2258fa7d1371f82381d75b782dcf2f93678eb..fc283f72ba4c0ee1bab1591fa5d3b335ee216c96 100644 (file)
@@ -21,8 +21,8 @@
 #include "lib/crypto/md4.h"
 #include "lib/crypto/md5.h"
 #include "lib/crypto/hmacmd5.h"
-#include "lib/crypto/sha1.h"
-#include "lib/crypto/hmacsha1.h"
+#include "lib/crypto/sha256.h"
+#include "lib/crypto/hmacsha256.h"
 
 struct arcfour_state {
        uint8_t sbox[256];
diff --git a/source/lib/crypto/hmacsha1test.c b/source/lib/crypto/hmacsha1test.c
deleted file mode 100644 (file)
index 6e53124..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-   HMAC SHA-1 tests
-   Copyright (C) Stefan Metzmacher
-   
-   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/>.
-*/
-#include "includes.h"
-#include "lib/crypto/crypto.h"
-
-struct torture_context;
-
-static DATA_BLOB data_blob_repeat_byte(uint8_t byte, size_t length)
-{
-       DATA_BLOB b = data_blob(NULL, length);
-       memset(b.data, byte, length);
-       return b;
-}
-
-/*
- This uses the test values from rfc2202
-*/
-bool torture_local_crypto_hmacsha1(struct torture_context *torture) 
-{
-       bool ret = true;
-       uint32_t i;
-       struct {
-               DATA_BLOB key;
-               DATA_BLOB data;
-               DATA_BLOB sha1;
-       } testarray[7];
-
-       testarray[0].key        = data_blob_repeat_byte(0x0b, 20);
-       testarray[0].data       = data_blob_string_const("Hi There");
-       testarray[0].sha1       = strhex_to_data_blob("b617318655057264e28bc0b6fb378c8ef146be00");
-
-       testarray[1].key        = data_blob_string_const("Jefe");
-       testarray[1].data       = data_blob_string_const("what do ya want for nothing?");
-       testarray[1].sha1 = strhex_to_data_blob("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79");
-
-       testarray[2].key        = data_blob_repeat_byte(0xaa, 20);
-       testarray[2].data       = data_blob_repeat_byte(0xdd, 50);
-       testarray[2].sha1       = strhex_to_data_blob("125d7342b9ac11cd91a39af48aa17b4f63f175d3");
-       
-       testarray[3].key        = strhex_to_data_blob("0102030405060708090a0b0c0d0e0f10111213141516171819");
-       testarray[3].data       = data_blob_repeat_byte(0xcd, 50);
-       testarray[3].sha1       = strhex_to_data_blob("4c9007f4026250c6bc8414f9bf50c86c2d7235da");
-
-       testarray[4].key        = data_blob_repeat_byte(0x0c, 20);
-       testarray[4].data       = data_blob_string_const("Test With Truncation");
-       testarray[4].sha1       = strhex_to_data_blob("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04");
-       /* sha1-96 =                 0x4c1a03424b55e07fe7f27be1 */
-
-       testarray[5].key        = data_blob_repeat_byte(0xaa, 80);
-       testarray[5].data       = data_blob_string_const("Test Using Larger Than Block-Size Key - Hash Key First");
-       testarray[5].sha1       = strhex_to_data_blob("aa4ae5e15272d00e95705637ce8a3b55ed402112");
-
-       testarray[6].key        = data_blob_repeat_byte(0xaa, 80);
-       testarray[6].data       = data_blob_string_const("Test Using Larger Than Block-Size Key "
-                                                        "and Larger Than One Block-Size Data");
-       testarray[6].sha1       = strhex_to_data_blob("e8e99d0f45237d786d6bbaa7965c7808bbff1a91");
-
-       for (i=0; i < ARRAY_SIZE(testarray); i++) {
-               struct HMACSHA1Context ctx;
-               uint8_t sha1[SHA1HashSize];
-               int e;
-
-               hmac_sha1_init(testarray[i].key.data, testarray[i].key.length, &ctx);
-               hmac_sha1_update(testarray[i].data.data, testarray[i].data.length, &ctx);
-               hmac_sha1_final(sha1, &ctx);
-
-               e = memcmp(testarray[i].sha1.data,
-                          sha1,
-                          MIN(testarray[i].sha1.length, sizeof(sha1)));
-               if (e != 0) {
-                       printf("hmacsha1 test[%u]: failed\n", i);
-                       dump_data(0, testarray[i].key.data, testarray[i].key.length);
-                       dump_data(0, testarray[i].data.data, testarray[i].data.length);
-                       dump_data(0, testarray[i].sha1.data, testarray[i].sha1.length);
-                       dump_data(0, sha1, sizeof(sha1));
-                       ret = false;
-               }
-       }
-
-       return ret;
-}
similarity index 56%
rename from source/lib/crypto/hmacsha1.c
rename to source/lib/crypto/hmacsha256.c
index 21ce966f60ef74eef417ee6d0db23fd45746f293..6b0af9ee8350ee1306c2c442dfca877e45dded22 100644 (file)
@@ -1,7 +1,12 @@
 /* 
    Unix SMB/CIFS implementation.
-   Interface header:    HMAC SHA-1 code
-   Copyright (C) Stefan Metzmacher
+
+   Interface header:    HMAC SHA-256 code
+
+   Copyright (C) Andrew Tridgell 2008
+
+   based in hmacsha1.c which is:
+     Copyright (C) Stefan Metzmacher
    
    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
 #include "lib/crypto/crypto.h"
 
 /***********************************************************************
- the rfc 2104/2202 version of hmac_sha1 initialisation.
+ the rfc 2104/2202 version of hmac_sha256 initialisation.
 ***********************************************************************/
-_PUBLIC_ void hmac_sha1_init(const uint8_t *key, size_t key_len, struct HMACSHA1Context *ctx)
+_PUBLIC_ void hmac_sha256_init(const uint8_t *key, size_t key_len, struct HMACSHA256Context *ctx)
 {
         int i;
-       uint8_t tk[SHA1HashSize];
+       uint8_t tk[SHA256_DIGEST_LENGTH];
 
-        /* if key is longer than 64 bytes reset it to key=MD5(key) */
+        /* if key is longer than 64 bytes reset it to key=HASH(key) */
         if (key_len > 64)
        {
-                struct SHA1Context tctx;
+                SHA256_CTX tctx;
 
-                SHA1Init(&tctx);
-                SHA1Update(&tctx, key, key_len);
-                SHA1Final(tk, &tctx);
+                SHA256_Init(&tctx);
+                SHA256_Update(&tctx, key, key_len);
+                SHA256_Final(tk, &tctx);
 
                 key = tk;
-                key_len = SHA1HashSize;
+                key_len = SHA256_DIGEST_LENGTH;
         }
 
         /* start out by storing key in pads */
@@ -58,29 +63,29 @@ _PUBLIC_ void hmac_sha1_init(const uint8_t *key, size_t key_len, struct HMACSHA1
                 ctx->k_opad[i] ^= 0x5c;
         }
 
-        SHA1Init(&ctx->ctx);
-        SHA1Update(&ctx->ctx, ctx->k_ipad, 64);  
+        SHA256_Init(&ctx->ctx);
+        SHA256_Update(&ctx->ctx, ctx->k_ipad, 64);  
 }
 
 /***********************************************************************
- update hmac_sha1 "inner" buffer
+ update hmac_sha256 "inner" buffer
 ***********************************************************************/
-_PUBLIC_ void hmac_sha1_update(const uint8_t *data, size_t data_len, struct HMACSHA1Context *ctx)
+_PUBLIC_ void hmac_sha256_update(const uint8_t *data, size_t data_len, struct HMACSHA256Context *ctx)
 {
-        SHA1Update(&ctx->ctx, data, data_len); /* then text of datagram */
+        SHA256_Update(&ctx->ctx, data, data_len); /* then text of datagram */
 }
 
 /***********************************************************************
- finish off hmac_sha1 "inner" buffer and generate outer one.
+ finish off hmac_sha256 "inner" buffer and generate outer one.
 ***********************************************************************/
-_PUBLIC_ void hmac_sha1_final(uint8_t digest[SHA1HashSize], struct HMACSHA1Context *ctx)
+_PUBLIC_ void hmac_sha256_final(uint8_t digest[SHA256_DIGEST_LENGTH], struct HMACSHA256Context *ctx)
 {
-        struct SHA1Context ctx_o;
+        SHA256_CTX ctx_o;
 
-        SHA1Final(digest, &ctx->ctx);
+        SHA256_Final(digest, &ctx->ctx);
 
-        SHA1Init(&ctx_o);
-        SHA1Update(&ctx_o, ctx->k_opad, 64);
-        SHA1Update(&ctx_o, digest, SHA1HashSize);
-        SHA1Final(digest, &ctx_o);
+        SHA256_Init(&ctx_o);
+        SHA256_Update(&ctx_o, ctx->k_opad, 64);
+        SHA256_Update(&ctx_o, digest, SHA256_DIGEST_LENGTH);
+        SHA256_Final(digest, &ctx_o);
 }
similarity index 59%
rename from source/lib/crypto/hmacsha1.h
rename to source/lib/crypto/hmacsha256.h
index 0638c66d53c4b12701ad3245c889dc5730bd1447..8960c636c1b91f20413985b8a3cd21e5042c27e8 100644 (file)
@@ -1,7 +1,13 @@
 /* 
    Unix SMB/CIFS implementation.
-   Interface header:    HMAC SHA1 code
-   Copyright (C) Stefan Metzmacher 2006
+
+   Interface header:    HMAC SHA256 code
+
+   Copyright (C) Andrew Tridgell 2008
+
+   based on hmacsha1.h which is:
+
+    Copyright (C) Stefan Metzmacher 2006
    
    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
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _HMAC_SHA1_H
+#ifndef _HMAC_SHA256_H
 
-struct HMACSHA1Context {
-        struct SHA1Context ctx;
+struct HMACSHA256Context {
+        SHA256_CTX ctx;
         uint8_t k_ipad[65];    
         uint8_t k_opad[65];
-
 };
 
-void hmac_sha1_init(const uint8_t *key, size_t key_len, struct HMACSHA1Context *ctx);
-void hmac_sha1_update(const uint8_t *data, size_t data_len, struct HMACSHA1Context *ctx);
-void hmac_sha1_final(uint8_t digest[20], struct HMACSHA1Context *ctx);
+void hmac_sha256_init(const uint8_t *key, size_t key_len, struct HMACSHA256Context *ctx);
+void hmac_sha256_update(const uint8_t *data, size_t data_len, struct HMACSHA256Context *ctx);
+void hmac_sha256_final(uint8_t digest[20], struct HMACSHA256Context *ctx);
 
-#endif /* _HMAC_SHA1_H */
+#endif /* _HMAC_SHA256_H */
diff --git a/source/lib/crypto/sha1.c b/source/lib/crypto/sha1.c
deleted file mode 100644 (file)
index 1b91f8a..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- This file contains the reference implementation of SHA-1
- from http://www.ietf.org/rfc/rfc3174.txt
-*/
-/*
- *  sha1.c
- *
- *  Description:
- *      This file implements the Secure Hashing Algorithm 1 as
- *      defined in FIPS PUB 180-1 published April 17, 1995.
- *
- *      The SHA-1, produces a 160-bit message digest for a given
- *      data stream.  It should take about 2**n steps to find a
- *      message with the same digest as a given message and
- *      2**(n/2) to find any two messages with the same digest,
- *      when n is the digest size in bits.  Therefore, this
- *      algorithm can serve as a means of providing a
- *      "fingerprint" for a message.
- *
- *  Portability Issues:
- *      SHA-1 is defined in terms of 32-bit "words".  This code
- *      uses <stdint.h> (included via "sha1.h" to define 32 and 8
- *      bit unsigned integer types.  If your C compiler does not
- *      support 32 bit unsigned integers, this code is not
- *      appropriate.
- *
- *  Caveats:
- *      SHA-1 is designed to work with messages less than 2^64 bits
- *      long.  Although SHA-1 allows a message digest to be generated
- *      for messages of any number of bits less than 2^64, this
- *      implementation only works with messages with a length that is
- *      a multiple of the size of an 8-bit character.
- *
- */
-
-#include "includes.h"
-
-#include "sha1.h"
-
-/*
- *  Define the SHA1 circular left shift macro
- */
-#define SHA1CircularShift(bits,word) \
-                (((word) << (bits)) | ((word) >> (32-(bits))))
-
-/* Local Function Prototyptes */
-static void SHA1PadMessage(struct SHA1Context *);
-static void SHA1ProcessMessageBlock(struct SHA1Context *);
-
-/*
- *  SHA1Init (SHA1Reset in the rfc)
- *
- *  Description:
- *      This function will initialize the SHA1Context in preparation
- *      for computing a new SHA1 message digest.
- *
- *  Parameters:
- *      context: [in/out]
- *          The context to reset.
- *
- *  Returns:
- *      sha Error Code.
- *
- */
-int SHA1Init(struct SHA1Context *context)
-{
-    if (!context)
-    {
-        return shaNull;
-    }
-
-    context->Length_Low             = 0;
-    context->Length_High            = 0;
-    context->Message_Block_Index    = 0;
-
-    context->Intermediate_Hash[0]   = 0x67452301;
-    context->Intermediate_Hash[1]   = 0xEFCDAB89;
-    context->Intermediate_Hash[2]   = 0x98BADCFE;
-    context->Intermediate_Hash[3]   = 0x10325476;
-    context->Intermediate_Hash[4]   = 0xC3D2E1F0;
-
-    context->Computed   = 0;
-    context->Corrupted  = 0;
-
-    return shaSuccess;
-}
-
-/*
- *  SHA1Final (SHA1Result in the rfc)
- *
- *  Description:
- *      This function will return the 160-bit message digest into the
- *      Message_Digest array  provided by the caller.
- *      NOTE: The first octet of hash is stored in the 0th element,
- *            the last octet of hash in the 19th element.
- *
- *  Parameters:
- *      context: [in/out]
- *          The context to use to calculate the SHA-1 hash.
- *      Message_Digest: [out]
- *          Where the digest is returned.
- *
- *  Returns:
- *      sha Error Code.
- *
- */
-int SHA1Final(uint8_t Message_Digest[SHA1HashSize],
-             struct SHA1Context *context)
-{
-    int i;
-
-    if (!context || !Message_Digest)
-    {
-        return shaNull;
-    }
-
-    if (context->Corrupted)
-    {
-        return context->Corrupted;
-    }
-
-    if (!context->Computed)
-    {
-        SHA1PadMessage(context);
-        for(i=0; i<64; ++i)
-        {
-            /* message may be sensitive, clear it out */
-            context->Message_Block[i] = 0;
-        }
-        context->Length_Low = 0;    /* and clear length */
-        context->Length_High = 0;
-        context->Computed = 1;
-    }
-
-    for(i = 0; i < SHA1HashSize; ++i)
-    {
-        Message_Digest[i] = context->Intermediate_Hash[i>>2]
-                            >> 8 * ( 3 - ( i & 0x03 ) );
-    }
-
-    return shaSuccess;
-}
-
-/*
- *  SHA1Update (SHA1Input in the rfc)
- *
- *  Description:
- *      This function accepts an array of octets as the next portion
- *      of the message.
- *
- *  Parameters:
- *      context: [in/out]
- *          The SHA context to update
- *      message_array: [in]
- *          An array of characters representing the next portion of
- *          the message.
- *      length: [in]
- *          The length of the message in message_array
- *
- *  Returns:
- *      sha Error Code.
- *
- */
-int SHA1Update(struct SHA1Context *context,
-               const uint8_t *message_array,
-               size_t length)
-{
-    if (!length)
-    {
-        return shaSuccess;
-    }
-
-    if (!context || !message_array)
-    {
-        return shaNull;
-    }
-
-    if (context->Computed)
-    {
-        context->Corrupted = shaStateError;
-        return shaStateError;
-    }
-
-    if (context->Corrupted)
-    {
-         return context->Corrupted;
-    }
-    while(length-- && !context->Corrupted)
-    {
-    context->Message_Block[context->Message_Block_Index++] =
-                    (*message_array & 0xFF);
-
-    context->Length_Low += 8;
-    if (context->Length_Low == 0)
-    {
-        context->Length_High++;
-        if (context->Length_High == 0)
-        {
-            /* Message is too long */
-            context->Corrupted = 1;
-        }
-    }
-
-    if (context->Message_Block_Index == 64)
-    {
-        SHA1ProcessMessageBlock(context);
-    }
-
-    message_array++;
-    }
-
-    return shaSuccess;
-}
-
-/*
- *  SHA1ProcessMessageBlock
- *
- *  Description:
- *      This function will process the next 512 bits of the message
- *      stored in the Message_Block array.
- *
- *  Parameters:
- *      None.
- *
- *  Returns:
- *      Nothing.
- *
- *  Comments:
- *      Many of the variable names in this code, especially the
- *      single character names, were used because those were the
- *      names used in the publication.
- *
- *
- */
-static void SHA1ProcessMessageBlock(struct SHA1Context *context)
-{
-    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
-                            0x5A827999,
-                            0x6ED9EBA1,
-                            0x8F1BBCDC,
-                            0xCA62C1D6
-                            };
-    int           t;                 /* Loop counter                */
-    uint32_t      temp;              /* Temporary word value        */
-    uint32_t      W[80];             /* Word sequence               */
-    uint32_t      A, B, C, D, E;     /* Word buffers                */
-
-    /*
-     *  Initialize the first 16 words in the array W
-     */
-    for(t = 0; t < 16; t++)
-    {
-        W[t] = context->Message_Block[t * 4] << 24;
-        W[t] |= context->Message_Block[t * 4 + 1] << 16;
-        W[t] |= context->Message_Block[t * 4 + 2] << 8;
-        W[t] |= context->Message_Block[t * 4 + 3];
-    }
-
-    for(t = 16; t < 80; t++)
-    {
-       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
-    }
-
-    A = context->Intermediate_Hash[0];
-    B = context->Intermediate_Hash[1];
-    C = context->Intermediate_Hash[2];
-    D = context->Intermediate_Hash[3];
-    E = context->Intermediate_Hash[4];
-
-    for(t = 0; t < 20; t++)
-    {
-        temp =  SHA1CircularShift(5,A) +
-                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
-        E = D;
-        D = C;
-        C = SHA1CircularShift(30,B);
-        B = A;
-        A = temp;
-    }
-
-    for(t = 20; t < 40; t++)
-    {
-        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
-        E = D;
-        D = C;
-        C = SHA1CircularShift(30,B);
-        B = A;
-        A = temp;
-    }
-
-    for(t = 40; t < 60; t++)
-    {
-        temp = SHA1CircularShift(5,A) +
-               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
-        E = D;
-        D = C;
-        C = SHA1CircularShift(30,B);
-        B = A;
-        A = temp;
-    }
-
-    for(t = 60; t < 80; t++)
-    {
-        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
-        E = D;
-        D = C;
-        C = SHA1CircularShift(30,B);
-        B = A;
-        A = temp;
-    }
-
-    context->Intermediate_Hash[0] += A;
-    context->Intermediate_Hash[1] += B;
-    context->Intermediate_Hash[2] += C;
-    context->Intermediate_Hash[3] += D;
-    context->Intermediate_Hash[4] += E;
-
-    context->Message_Block_Index = 0;
-}
-
-
-/*
- *  SHA1PadMessage
- *
- *  Description:
- *      According to the standard, the message must be padded to an even
- *      512 bits.  The first padding bit must be a '1'.  The last 64
- *      bits represent the length of the original message.  All bits in
- *      between should be 0.  This function will pad the message
- *      according to those rules by filling the Message_Block array
- *      accordingly.  It will also call the ProcessMessageBlock function
- *      provided appropriately.  When it returns, it can be assumed that
- *      the message digest has been computed.
- *
- *  Parameters:
- *      context: [in/out]
- *          The context to pad
- *      ProcessMessageBlock: [in]
- *          The appropriate SHA*ProcessMessageBlock function
- *  Returns:
- *      Nothing.
- *
- */
-
-static void SHA1PadMessage(struct SHA1Context *context)
-{
-    /*
-     *  Check to see if the current message block is too small to hold
-     *  the initial padding bits and length.  If so, we will pad the
-     *  block, process it, and then continue padding into a second
-     *  block.
-     */
-    if (context->Message_Block_Index > 55)
-    {
-        context->Message_Block[context->Message_Block_Index++] = 0x80;
-        while(context->Message_Block_Index < 64)
-        {
-            context->Message_Block[context->Message_Block_Index++] = 0;
-        }
-
-        SHA1ProcessMessageBlock(context);
-
-        while(context->Message_Block_Index < 56)
-        {
-            context->Message_Block[context->Message_Block_Index++] = 0;
-        }
-    }
-    else
-    {
-        context->Message_Block[context->Message_Block_Index++] = 0x80;
-        while(context->Message_Block_Index < 56)
-        {
-            context->Message_Block[context->Message_Block_Index++] = 0;
-        }
-    }
-
-    /*
-     *  Store the message length as the last 8 octets
-     */
-    context->Message_Block[56] = context->Length_High >> 24;
-    context->Message_Block[57] = context->Length_High >> 16;
-    context->Message_Block[58] = context->Length_High >> 8;
-    context->Message_Block[59] = context->Length_High;
-    context->Message_Block[60] = context->Length_Low >> 24;
-    context->Message_Block[61] = context->Length_Low >> 16;
-    context->Message_Block[62] = context->Length_Low >> 8;
-    context->Message_Block[63] = context->Length_Low;
-
-    SHA1ProcessMessageBlock(context);
-}
diff --git a/source/lib/crypto/sha1.h b/source/lib/crypto/sha1.h
deleted file mode 100644 (file)
index 4a2d448..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- This file contains the reference implementation of SHA-1
- from http://www.ietf.org/rfc/rfc3174.txt
-*/
-/*
- *  sha1.h
- *
- *  Description:
- *      This is the header file for code which implements the Secure
- *      Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
- *      April 17, 1995.
- *
- *      Many of the variable names in this code, especially the
- *      single character names, were used because those were the names
- *      used in the publication.
- *
- *      Please read the file sha1.c for more information.
- *
- */
-#ifndef _SHA1_H_
-#define _SHA1_H_
-
-#ifndef _SHA_enum_
-#define _SHA_enum_
-enum
-{
-    shaSuccess = 0,
-    shaNull,            /* Null pointer parameter */
-    shaInputTooLong,    /* input data too long */
-    shaStateError       /* called Input after Result */
-};
-#endif
-#define SHA1HashSize 20
-
-/*
- *  This structure will hold context information for the SHA-1
- *  hashing operation
- */
-struct SHA1Context
-{
-    uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest  */
-
-    uint32_t Length_Low;            /* Message length in bits      */
-    uint32_t Length_High;           /* Message length in bits      */
-
-                               /* Index into message block array   */
-    int16_t Message_Block_Index;
-    uint8_t Message_Block[64];      /* 512-bit message blocks      */
-
-    int Computed;               /* Is the digest computed?         */
-    int Corrupted;             /* Is the message digest corrupted? */
-};
-
-/*
- *  Function Prototypes
- */
-
-int SHA1Init(struct SHA1Context *);
-int SHA1Update(struct SHA1Context *, const uint8_t *data, size_t data_len);
-int SHA1Final(uint8_t Message_Digest[SHA1HashSize], struct SHA1Context *);
-
-#endif
diff --git a/source/lib/crypto/sha1test.c b/source/lib/crypto/sha1test.c
deleted file mode 100644 (file)
index 7777764..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- This file contains the reference implementation of SHA-1
- from http://www.ietf.org/rfc/rfc3174.txt
-*/
-/*
- *  sha1test.c
- *
- *  Description:
- *      This file will exercise the SHA-1 code performing the three
- *      tests documented in FIPS PUB 180-1 plus one which calls
- *      SHA1Input with an exact multiple of 512 bits, plus a few
- *      error test checks.
- *
- *  Portability Issues:
- *      None.
- *
- */
-
-#include "includes.h"
-#include "torture/torture.h"
-
-#include "lib/crypto/crypto.h"
-
-struct torture_context;
-
-/*
- *  Define patterns for testing
- */
-#define TEST1   "abc"
-#define TEST2a  "abcdbcdecdefdefgefghfghighijhi"
-#define TEST2b  "jkijkljklmklmnlmnomnopnopq"
-#define TEST2   TEST2a TEST2b
-#define TEST3   "a"
-#define TEST4a  "01234567012345670123456701234567"
-#define TEST4b  "01234567012345670123456701234567"
-    /* an exact multiple of 512 bits */
-#define TEST4   TEST4a TEST4b
-static const char *testarray[4] =
-{
-    TEST1,
-    TEST2,
-    TEST3,
-    TEST4
-};
-static int repeatcount[4] = { 1, 1, 1000000, 10 };
-static const char *resultarray[4] =
-{
-    "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D ",
-    "84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1 ",
-    "34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F ",
-    "DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52 "
-};
-
-
-bool torture_local_crypto_sha1(struct torture_context *tctx)
-{
-    struct SHA1Context sha;
-    int i, j, err;
-    uint8_t Message_Digest[20];
-    bool ret = true;
-    char tmp[60 + 10];
-
-    /*
-     *  Perform SHA-1 tests
-     */
-    for(j = 0; j < 4; ++j)
-    {
-       ZERO_STRUCT(tmp);
-        torture_comment(tctx, "Test %d: %d, '%s'\n",
-                j+1,
-                repeatcount[j],
-                testarray[j]);
-
-        err = SHA1Init(&sha);
-        torture_assert_int_equal(tctx, err, 0, "SHA1Init Error");
-
-        for(i = 0; i < repeatcount[j]; ++i)
-        {
-            err = SHA1Update(&sha,
-                  (const unsigned char *) testarray[j],
-                  strlen(testarray[j]));
-                       torture_assert_int_equal(tctx, err, 0, "SHA1Update Error");
-        }
-
-        err = SHA1Final(Message_Digest, &sha);
-               torture_assert_int_equal(tctx, err, 0, 
-            "SHA1Result Error, could not compute message digest.");
-        torture_comment(tctx, "\t");
-        for(i = 0; i < 20 ; ++i)
-        {
-               snprintf(tmp+(i*3), sizeof(tmp) - (i*3),"%02X ", Message_Digest[i]);
-            torture_comment(tctx, "%02X ", Message_Digest[i]);
-        }
-        torture_comment(tctx, "\n");
-        torture_comment(tctx, "Should match:\n\t%s\n", resultarray[j]);
-       if (strcmp(resultarray[j], tmp) != 0) {
-           ret = false;        
-       }
-    }
-
-    /* Test some error returns */
-    err = SHA1Update(&sha,(const unsigned char *) testarray[1], 1);
-    torture_assert_int_equal(tctx, err, shaStateError, "SHA1Update failed");
-    err = SHA1Init(0);
-    torture_assert_int_equal(tctx, err, shaNull, "SHA1Init failed");
-
-       return true;
-}
-
-
diff --git a/source/lib/crypto/sha256.c b/source/lib/crypto/sha256.c
new file mode 100644 (file)
index 0000000..70fe7a3
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+  based on heildal lib/hcrypto/sha256.c. Copied to lib/crypto to avoid a link
+  problem. Hopefully will be removed once we solve this link problem
+
+   (tridge)
+ */
+
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "includes.h"
+#include "heimdal/lib/hcrypto/hash.h"
+#include "sha256.h"
+
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#define ROTR(x,n)   (((x)>>(n)) | ((x) << (32 - (n))))
+
+#define Sigma0(x)      (ROTR(x,2)  ^ ROTR(x,13) ^ ROTR(x,22))
+#define Sigma1(x)      (ROTR(x,6)  ^ ROTR(x,11) ^ ROTR(x,25))
+#define sigma0(x)      (ROTR(x,7)  ^ ROTR(x,18) ^ ((x)>>3))
+#define sigma1(x)      (ROTR(x,17) ^ ROTR(x,19) ^ ((x)>>10))
+
+#define A m->counter[0]
+#define B m->counter[1]
+#define C m->counter[2]
+#define D m->counter[3]
+#define E m->counter[4]
+#define F m->counter[5]
+#define G m->counter[6]
+#define H m->counter[7]
+
+static const uint32_t constant_256[64] = {
+    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+void
+SHA256_Init (SHA256_CTX *m)
+{
+    m->sz[0] = 0;
+    m->sz[1] = 0;
+    A = 0x6a09e667;
+    B = 0xbb67ae85;
+    C = 0x3c6ef372;
+    D = 0xa54ff53a;
+    E = 0x510e527f;
+    F = 0x9b05688c;
+    G = 0x1f83d9ab;
+    H = 0x5be0cd19;
+}
+
+static void
+calc (SHA256_CTX *m, uint32_t *in)
+{
+    uint32_t AA, BB, CC, DD, EE, FF, GG, HH;
+    uint32_t data[64];
+    int i;
+
+    AA = A;
+    BB = B;
+    CC = C;
+    DD = D;
+    EE = E;
+    FF = F;
+    GG = G;
+    HH = H;
+
+    for (i = 0; i < 16; ++i)
+       data[i] = in[i];
+    for (i = 16; i < 64; ++i)
+       data[i] = sigma1(data[i-2]) + data[i-7] + 
+           sigma0(data[i-15]) + data[i - 16];
+
+    for (i = 0; i < 64; i++) {
+       uint32_t T1, T2;
+
+       T1 = HH + Sigma1(EE) + Ch(EE, FF, GG) + constant_256[i] + data[i];
+       T2 = Sigma0(AA) + Maj(AA,BB,CC);
+                            
+       HH = GG;
+       GG = FF;
+       FF = EE;
+       EE = DD + T1;
+       DD = CC;
+       CC = BB;
+       BB = AA;
+       AA = T1 + T2;
+    }
+
+    A += AA;
+    B += BB;
+    C += CC;
+    D += DD;
+    E += EE;
+    F += FF;
+    G += GG;
+    H += HH;
+}
+
+/*
+ * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>
+ */
+
+#if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
+static inline uint32_t
+swap_uint32_t (uint32_t t)
+{
+    uint32_t temp1, temp2;
+
+    temp1   = cshift(t, 16);
+    temp2   = temp1 >> 8;
+    temp1  &= 0x00ff00ff;
+    temp2  &= 0x00ff00ff;
+    temp1 <<= 8;
+    return temp1 | temp2;
+}
+#endif
+
+struct x32{
+    unsigned int a:32;
+    unsigned int b:32;
+};
+
+void
+SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
+{
+    const unsigned char *p = v;
+    size_t old_sz = m->sz[0];
+    size_t offset;
+
+    m->sz[0] += len * 8;
+    if (m->sz[0] < old_sz)
+       ++m->sz[1];
+    offset = (old_sz / 8) % 64;
+    while(len > 0){
+       size_t l = min(len, 64 - offset);
+       memcpy(m->save + offset, p, l);
+       offset += l;
+       p += l;
+       len -= l;
+       if(offset == 64){
+#if !defined(WORDS_BIGENDIAN) || defined(_CRAY)
+           int i;
+           uint32_t current[16];
+           struct x32 *u = (struct x32*)m->save;
+           for(i = 0; i < 8; i++){
+               current[2*i+0] = swap_uint32_t(u[i].a);
+               current[2*i+1] = swap_uint32_t(u[i].b);
+           }
+           calc(m, current);
+#else
+           calc(m, (uint32_t*)m->save);
+#endif
+           offset = 0;
+       }
+    }
+}
+
+void
+SHA256_Final (void *res, SHA256_CTX *m)
+{
+    unsigned char zeros[72];
+    unsigned offset = (m->sz[0] / 8) % 64;
+    unsigned int dstart = (120 - offset - 1) % 64 + 1;
+
+    *zeros = 0x80;
+    memset (zeros + 1, 0, sizeof(zeros) - 1);
+    zeros[dstart+7] = (m->sz[0] >> 0) & 0xff;
+    zeros[dstart+6] = (m->sz[0] >> 8) & 0xff;
+    zeros[dstart+5] = (m->sz[0] >> 16) & 0xff;
+    zeros[dstart+4] = (m->sz[0] >> 24) & 0xff;
+    zeros[dstart+3] = (m->sz[1] >> 0) & 0xff;
+    zeros[dstart+2] = (m->sz[1] >> 8) & 0xff;
+    zeros[dstart+1] = (m->sz[1] >> 16) & 0xff;
+    zeros[dstart+0] = (m->sz[1] >> 24) & 0xff;
+    SHA256_Update (m, zeros, dstart + 8);
+    {
+       int i;
+       unsigned char *r = (unsigned char*)res;
+
+       for (i = 0; i < 8; ++i) {
+           r[4*i+3] = m->counter[i] & 0xFF;
+           r[4*i+2] = (m->counter[i] >> 8) & 0xFF;
+           r[4*i+1] = (m->counter[i] >> 16) & 0xFF;
+           r[4*i]   = (m->counter[i] >> 24) & 0xFF;
+       }
+    }
+}
diff --git a/source/lib/crypto/sha256.h b/source/lib/crypto/sha256.h
new file mode 100644 (file)
index 0000000..4a5f2cb
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1995 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: sha.h 17450 2006-05-05 11:11:43Z lha $ */
+
+#ifndef HEIM_SHA_H
+/*
+  based on heildal lib/hcrypto/sha.h. Copied to lib/crypto to avoid a link
+  problem. Hopefully will be removed once we solve this link problem
+
+   (tridge)
+ */
+#define HEIM_SHA_H 1
+
+#if 0
+/* symbol renaming */
+#define SHA1_Init hc_SHA1_Init
+#define SHA1_Update hc_SHA1_Update
+#define SHA1_Final hc_SHA1_Final
+#define SHA256_Init hc_SHA256_Init
+#define SHA256_Update hc_SHA256_Update
+#define SHA256_Final hc_SHA256_Final
+#endif
+
+/*
+ * SHA-1
+ */
+
+#define SHA_DIGEST_LENGTH 20
+
+struct sha {
+  unsigned int sz[2];
+  uint32_t counter[5];
+  unsigned char save[64];
+};
+
+typedef struct sha SHA_CTX;
+
+void SHA1_Init (struct sha *m);
+void SHA1_Update (struct sha *m, const void *v, size_t len);
+void SHA1_Final (void *res, struct sha *m);
+
+/*
+ * SHA-2 256
+ */
+
+#define SHA256_DIGEST_LENGTH 32
+
+struct hc_sha256state {
+  unsigned int sz[2];
+  uint32_t counter[8];
+  unsigned char save[64];
+};
+
+typedef struct hc_sha256state SHA256_CTX;
+
+void SHA256_Init (SHA256_CTX *);
+void SHA256_Update (SHA256_CTX *, const void *, size_t);
+void SHA256_Final (void *, SHA256_CTX *);
+
+#endif /* HEIM_SHA_H */
index c76222c207d721379c35f29f7d32272ada02cd49..aba9581ec5775844c0c62cc5ffcac00be1ab24f2 100755 (executable)
@@ -14,7 +14,7 @@ from samba.auth import system_session
 from ldb import (SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError,
                  LDB_ERR_NO_SUCH_OBJECT, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
                  LDB_ERR_ENTRY_ALREADY_EXISTS, LDB_ERR_UNWILLING_TO_PERFORM,
-                 LDB_ERR_NOT_ALLOWED_ON_NON_LEAF, LDB_ERR_OTHER)
+                 LDB_ERR_NOT_ALLOWED_ON_NON_LEAF, LDB_ERR_OTHER, LDB_ERR_INVALID_DN_SYNTAX)
 from samba import Ldb
 from subunit import SubunitTestRunner
 from samba import param
@@ -115,6 +115,86 @@ class BasicTests(unittest.TestCase):
             "userAccountControl": "4096",
             "displayname": "ldap testy"})
 
+        self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
+        try:
+            ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
+                     "objectClass": "computer",
+                     "cn": "LDAPtest2COMPUTER"
+                     })
+            self.fail()
+        except LdbError, (num, _): 
+            self.assertEquals(num, LDB_ERR_INVALID_DN_SYNTAX)
+            
+        self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
+        try:
+            ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
+                     "objectClass": "computer",
+                     "cn": "ldaptestcomputer3",
+                     "sAMAccountType": "805306368"
+                })
+            self.fail()
+        except LdbError, (num, _): 
+            self.assertEquals(num, LDB_ERR_UNWILLING_TO_PERFORM)
+            
+        self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
+        try:
+            ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
+                     "objectClass": "computer",
+                     "cn": "ldaptestcomputer3",
+                     "userAccountControl": "0"
+                })
+            self.fail()
+        except LdbError, (num, _): 
+            self.assertEquals(num, LDB_ERR_UNWILLING_TO_PERFORM)
+            
+        self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
+        try:
+            ldb.add({"dn": "cn=ldaptestuser7,cn=users," + self.base_dn,
+                     "objectClass": "user",
+                     "cn": "LDAPtestuser7",
+                     "userAccountControl": "0"
+                })
+            self.fail()
+        except LdbError, (num, _): 
+            self.assertEquals(num, LDB_ERR_UNWILLING_TO_PERFORM)
+            
+        self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
+
+        ldb.add({"dn": "cn=ldaptestuser7,cn=users," + self.base_dn,
+                 "objectClass": "user",
+                 "cn": "LDAPtestuser7",
+                 "userAccountControl": "2"
+                 })
+            
+        self.delete_force(self.ldb, "cn=ldaptestuser7,cn=users," + self.base_dn)
+
+        self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
+        ldb.add({"dn": "cn=ldaptestcomputer3,cn=computers," + self.base_dn,
+                 "objectClass": "computer",
+                 "cn": "LDAPtestCOMPUTER3"
+                 })
+            
+       print "Testing ldb.search for (&(cn=ldaptestcomputer3)(objectClass=user))";
+        res = ldb.search(self.base_dn, expression="(&(cn=ldaptestcomputer3)(objectClass=user))");
+        self.assertEquals(len(res), 1, "Found only %d for (&(cn=ldaptestcomputer3)(objectClass=user))" % len(res))
+
+       self.assertEquals(str(res[0].dn), ("CN=ldaptestcomputer3,CN=Computers," + self.base_dn));
+       self.assertEquals(res[0]["cn"][0], "ldaptestcomputer3");
+       self.assertEquals(res[0]["name"][0], "ldaptestcomputer3");
+       self.assertEquals(res[0]["objectClass"][0], "top");
+       self.assertEquals(res[0]["objectClass"][1], "person");
+       self.assertEquals(res[0]["objectClass"][2], "organizationalPerson");
+       self.assertEquals(res[0]["objectClass"][3], "user");
+       self.assertEquals(res[0]["objectClass"][4], "computer");
+        self.assertTrue("objectGUID" in res[0])
+        self.assertTrue("whenCreated" in res[0])
+       self.assertEquals(res[0]["objectCategory"][0], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn));
+       self.assertEquals(int(res[0]["primaryGroupID"][0]), 513);
+       self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368);
+       self.assertEquals(int(res[0]["userAccountControl"][0]), 546);
+
+        self.delete_force(self.ldb, "cn=ldaptestcomputer3,cn=computers," + self.base_dn)
+
         print "Testing attribute or value exists behaviour"
         try:
             ldb.modify_ldif("""
@@ -125,34 +205,36 @@ servicePrincipalName: host/ldaptest2computer
 servicePrincipalName: host/ldaptest2computer
 servicePrincipalName: cifs/ldaptest2computer
 """)
+            self.fail()
         except LdbError, (num, msg):
             self.assertEquals(num, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS)
 
-            ldb.modify_ldif("""
+        ldb.modify_ldif("""
 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
 changetype: modify
 replace: servicePrincipalName
 servicePrincipalName: host/ldaptest2computer
 servicePrincipalName: cifs/ldaptest2computer
 """)
-            try:
-                ldb.modify_ldif("""
+        try:
+            ldb.modify_ldif("""
 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
 changetype: modify
 add: servicePrincipalName
 servicePrincipalName: host/ldaptest2computer
 """)
-            except LdbError, (num, msg):
-                self.assertEquals(num, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS)
-            
-            print "Testing ranged results"
-            ldb.modify_ldif("""
+            self.fail()
+        except LdbError, (num, msg):
+            self.assertEquals(num, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS)
+
+        print "Testing ranged results"
+        ldb.modify_ldif("""
 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
 changetype: modify
 replace: servicePrincipalName
 """)
             
-            ldb.modify_ldif("""
+        ldb.modify_ldif("""
 dn: cn=ldaptest2computer,cn=computers,""" + self.base_dn + """
 changetype: modify
 add: servicePrincipalName
@@ -188,53 +270,53 @@ servicePrincipalName: host/ldaptest2computer28
 servicePrincipalName: host/ldaptest2computer29
 """)
 
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, 
-                             attrs=["servicePrincipalName;range=0-*"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
-            #print len(res[0]["servicePrincipalName;range=0-*"])
-            self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, 
+                         attrs=["servicePrincipalName;range=0-*"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        #print len(res[0]["servicePrincipalName;range=0-*"])
+        self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
 
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-19"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
             # print res[0]["servicePrincipalName;range=0-19"].length
-            self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
+        self.assertEquals(len(res[0]["servicePrincipalName;range=0-19"]), 20)
 
             
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
-            self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-30"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
 
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
-            self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=0-40"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        self.assertEquals(len(res[0]["servicePrincipalName;range=0-*"]), 30)
 
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
-            self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=30-40"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        self.assertEquals(len(res[0]["servicePrincipalName;range=30-*"]), 0)
 
             
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
-            self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
-            # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
-
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
-            self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=10-40"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        self.assertEquals(len(res[0]["servicePrincipalName;range=10-*"]), 20)
+        # pos_11 = res[0]["servicePrincipalName;range=10-*"][18]
+
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-40"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        self.assertEquals(len(res[0]["servicePrincipalName;range=11-*"]), 19)
             # print res[0]["servicePrincipalName;range=11-*"][18]
             # print pos_11
             # self.assertEquals((res[0]["servicePrincipalName;range=11-*"][18]), pos_11)
 
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
-            self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName;range=11-15"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        self.assertEquals(len(res[0]["servicePrincipalName;range=11-15"]), 5)
             # self.assertEquals(res[0]["servicePrincipalName;range=11-15"][4], pos_11)
 
-            res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
-            self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
+        res = ldb.search(self.base_dn, expression="(cn=ldaptest2computer))", scope=SCOPE_SUBTREE, attrs=["servicePrincipalName"])
+        self.assertEquals(len(res), 1, "Could not find (cn=ldaptest2computer)")
             # print res[0]["servicePrincipalName"][18]
             # print pos_11
-            self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
+        self.assertEquals(len(res[0]["servicePrincipalName"]), 30)
             # self.assertEquals(res[0]["servicePrincipalName"][18], pos_11)
 
         self.delete_force(self.ldb, "cn=ldaptestuser2,cn=users," + self.base_dn)
@@ -322,6 +404,10 @@ servicePrincipalName: host/ldaptest2computer29
         res = ldb.search(expression="(&(anr=not ldap user2)(objectClass=user))")
         self.assertEquals(len(res), 0, "Must not find (&(anr=not ldap user2)(objectClass=user))")
 
+        # Testing ldb.search for (&(anr="testy ldap")(objectClass=user)) (ie, with quotes)
+        res = ldb.search(expression="(&(anr==\"testy ldap\")(objectClass=user))")
+        self.assertEquals(len(res), 0, "Found (&(anr==\"testy ldap\")(objectClass=user))")
+
         print "Testing Group Modifies"
         ldb.modify_ldif("""
 dn: cn=ldaptestgroup,cn=users,""" + self.base_dn + """
@@ -361,6 +447,26 @@ member: cn=ldaptestuser3,cn=users,""" + self.base_dn + """
         self.assertEquals(res[0]["cn"], "ldaptestUSER3")
         self.assertEquals(res[0]["name"], "ldaptestUSER3")
 
+       #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))"
+       res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
+        self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=*))(objectClass=user))")
+
+        self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
+        self.assertEquals(res[0]["cn"], "ldaptestUSER3")
+        self.assertEquals(res[0]["name"], "ldaptestUSER3")
+
+       #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))"
+       res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
+        self.assertEquals(len(res), 1, "(&(&(cn=ldaptestuser3)(userAccountControl=546))(objectClass=user))")
+
+        self.assertEquals(str(res[0].dn), ("CN=ldaptestUSER3,CN=Users," + self.base_dn))
+        self.assertEquals(res[0]["cn"], "ldaptestUSER3")
+        self.assertEquals(res[0]["name"], "ldaptestUSER3")
+
+       #"Testing ldb.search for (&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))"
+       res = ldb.search(expression="(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
+        self.assertEquals(len(res), 0, "(&(&(cn=ldaptestuser3)(userAccountControl=547))(objectClass=user))")
+
         # This is a Samba special, and does not exist in real AD
         #    print "Testing ldb.search for (dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")"
         #    res = ldb.search("(dn=CN=ldaptestUSER3,CN=Users," + self.base_dn + ")")
@@ -534,7 +640,7 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
         self.assertTrue("whenCreated" in res[0])
         self.assertEquals(res[0]["objectCategory"], ("CN=Person,CN=Schema,CN=Configuration," + self.base_dn))
         self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368)
-        # self.assertEquals(res[0].userAccountControl, 546)
+        self.assertEquals(int(res[0]["userAccountControl"][0]), 546)
         self.assertEquals(res[0]["memberOf"][0], ("CN=ldaptestgroup2,CN=Users," + self.base_dn))
         self.assertEquals(len(res[0]["memberOf"]), 1)
      
@@ -578,8 +684,8 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
         self.assertTrue("whenCreated" in res[0])
         self.assertEquals(res[0]["objectCategory"], ("CN=Computer,CN=Schema,CN=Configuration," + self.base_dn))
         self.assertEquals(int(res[0]["primaryGroupID"][0]), 513)
-        # self.assertEquals(res[0].sAMAccountType, 805306368)
-        # self.assertEquals(res[0].userAccountControl, 546)
+        self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306368)
+        self.assertEquals(int(res[0]["userAccountControl"][0]), 546)
         self.assertEquals(res[0]["memberOf"][0], "CN=ldaptestgroup2,CN=Users," + self.base_dn)
         self.assertEquals(len(res[0]["memberOf"]), 1)
 
@@ -641,7 +747,7 @@ member: cn=ldaptestuser4,cn=ldaptestcontainer,""" + self.base_dn + """
         self.assertTrue("whenCreated" in res[0])
         self.assertEquals(res[0]["objectCategory"][0], "CN=Computer,CN=Schema,CN=Configuration," + self.base_dn)
         self.assertEquals(int(res[0]["sAMAccountType"][0]), 805306369)
-    #    self.assertEquals(res[0].userAccountControl, 4098)
+        self.assertEquals(int(res[0]["userAccountControl"][0]), 4096)
 
         ldb.delete(res[0].dn)
 
index 15b04c23974c25edc7a5f4f729fc5ee800233498..f023f319ffe0c3802670e6fce256d27fdb55e101 100644 (file)
@@ -257,7 +257,7 @@ void torture_result(struct torture_context *test,
        do { const void *__got = (got), *__expected = (expected); \
        if (memcmp(__got, __expected, len) != 0) { \
                torture_result(torture_ctx, TORTURE_FAIL, \
-                                          __location__": "#got" of len %d did not match"#expected": %s", len, cmt); \
+                              __location__": "#got" of len %d did not match"#expected": %s", (int)len, cmt); \
                return false; \
        } \
        } while(0)
index 19d51893a616411c7f211bb3446cee38d91b9728..8e23510f0691348663ab6f7386a0fd34d6dbb849 100644 (file)
@@ -906,15 +906,24 @@ enum smb_setfileinfo_level {
        RAW_SFILEINFO_RENAME_INFORMATION      = SMB_SFILEINFO_RENAME_INFORMATION,
        RAW_SFILEINFO_DISPOSITION_INFORMATION = SMB_SFILEINFO_DISPOSITION_INFORMATION,
        RAW_SFILEINFO_POSITION_INFORMATION    = SMB_SFILEINFO_POSITION_INFORMATION,
+       RAW_SFILEINFO_FULL_EA_INFORMATION     = SMB_SFILEINFO_FULL_EA_INFORMATION,
        RAW_SFILEINFO_MODE_INFORMATION        = SMB_SFILEINFO_MODE_INFORMATION,
        RAW_SFILEINFO_ALLOCATION_INFORMATION  = SMB_SFILEINFO_ALLOCATION_INFORMATION,
        RAW_SFILEINFO_END_OF_FILE_INFORMATION = SMB_SFILEINFO_END_OF_FILE_INFORMATION,
-       RAW_SFILEINFO_1023                    = SMB_SFILEINFO_1023,
+       RAW_SFILEINFO_PIPE_INFORMATION        = SMB_SFILEINFO_PIPE_INFORMATION,
+       RAW_SFILEINFO_VALID_DATA_INFORMATION  = SMB_SFILEINFO_VALID_DATA_INFORMATION,
+       RAW_SFILEINFO_SHORT_NAME_INFORMATION  = SMB_SFILEINFO_SHORT_NAME_INFORMATION,
        RAW_SFILEINFO_1025                    = SMB_SFILEINFO_1025,
+       RAW_SFILEINFO_1027                    = SMB_SFILEINFO_1027,
        RAW_SFILEINFO_1029                    = SMB_SFILEINFO_1029,
+       RAW_SFILEINFO_1030                    = SMB_SFILEINFO_1030,
+       RAW_SFILEINFO_1031                    = SMB_SFILEINFO_1031,
        RAW_SFILEINFO_1032                    = SMB_SFILEINFO_1032,
-       RAW_SFILEINFO_1039                    = SMB_SFILEINFO_1039,
-       RAW_SFILEINFO_1040                    = SMB_SFILEINFO_1040,
+       RAW_SFILEINFO_1036                    = SMB_SFILEINFO_1036,
+       RAW_SFILEINFO_1041                    = SMB_SFILEINFO_1041,
+       RAW_SFILEINFO_1042                    = SMB_SFILEINFO_1042,
+       RAW_SFILEINFO_1043                    = SMB_SFILEINFO_1043,
+       RAW_SFILEINFO_1044                    = SMB_SFILEINFO_1044,
        
        /* cope with breakage in SMB2 */
        RAW_SFILEINFO_RENAME_INFORMATION_SMB2 = SMB_SFILEINFO_RENAME_INFORMATION|0x80000000,
@@ -1901,7 +1910,7 @@ union smb_lock {
                        uint16_t ulock_cnt;
                        uint16_t lock_cnt;
                        struct smb_lock_entry {
-                               uint16_t pid;
+                               uint32_t pid; /* 16 bits in SMB1 */
                                uint64_t offset;
                                uint64_t count;
                        } *locks; /* unlocks are first in the arrray */
index 16052e87086eaa5b9f86b9ecc46d51d4f4c0ab5d..5a4706778a4a0e2b586a634cda87c231f54d0504 100644 (file)
@@ -110,12 +110,20 @@ bool smb_raw_setfileinfo_passthru(TALLOC_CTX *mem_ctx,
        }
 
                /* Unhandled levels */
-       case RAW_SFILEINFO_1023:
+       case RAW_SFILEINFO_PIPE_INFORMATION:
+       case RAW_SFILEINFO_VALID_DATA_INFORMATION:
+       case RAW_SFILEINFO_SHORT_NAME_INFORMATION:
        case RAW_SFILEINFO_1025:
+       case RAW_SFILEINFO_1027:
        case RAW_SFILEINFO_1029:
+       case RAW_SFILEINFO_1030:
+       case RAW_SFILEINFO_1031:
        case RAW_SFILEINFO_1032:
-       case RAW_SFILEINFO_1039:
-       case RAW_SFILEINFO_1040:
+       case RAW_SFILEINFO_1036:
+       case RAW_SFILEINFO_1041:
+       case RAW_SFILEINFO_1042:
+       case RAW_SFILEINFO_1043:
+       case RAW_SFILEINFO_1044:
                break;
 
        default:
@@ -227,12 +235,21 @@ static bool smb_raw_setinfo_backend(struct smbcli_tree *tree,
                                                    parms, blob);
                
                /* Unhandled passthru levels */
-       case RAW_SFILEINFO_1023:
+       case RAW_SFILEINFO_PIPE_INFORMATION:
+       case RAW_SFILEINFO_VALID_DATA_INFORMATION:
+       case RAW_SFILEINFO_SHORT_NAME_INFORMATION:
+       case RAW_SFILEINFO_FULL_EA_INFORMATION:
        case RAW_SFILEINFO_1025:
+       case RAW_SFILEINFO_1027:
        case RAW_SFILEINFO_1029:
+       case RAW_SFILEINFO_1030:
+       case RAW_SFILEINFO_1031:
        case RAW_SFILEINFO_1032:
-       case RAW_SFILEINFO_1039:
-       case RAW_SFILEINFO_1040:
+       case RAW_SFILEINFO_1036:
+       case RAW_SFILEINFO_1041:
+       case RAW_SFILEINFO_1042:
+       case RAW_SFILEINFO_1043:
+       case RAW_SFILEINFO_1044:
                return smb_raw_setfileinfo_passthru(mem_ctx, parms->generic.level,
                                                    parms, blob);
 
index 5b7987aa8caa8d5d1fe67364a12e46accbf0b1f7..63632eb5edbda403b98afde7696a568fddd6ec76 100644 (file)
@@ -217,32 +217,37 @@ Found 13 valid levels
 #define SMB_SFILEINFO_UNIX_INFO2                       0x20b
 #define SMB_SFILEINFO_BASIC_INFORMATION                        1004
 #define SMB_SFILEINFO_RENAME_INFORMATION               1010
+#define SMB_SFILEINFO_LINK_INFORMATION                 1011
 #define SMB_SFILEINFO_DISPOSITION_INFORMATION          1013
 #define SMB_SFILEINFO_POSITION_INFORMATION             1014
+#define SMB_SFILEINFO_FULL_EA_INFORMATION              1015
 #define SMB_SFILEINFO_MODE_INFORMATION                 1016
 #define SMB_SFILEINFO_ALLOCATION_INFORMATION           1019
 #define SMB_SFILEINFO_END_OF_FILE_INFORMATION          1020
-
-/* filemon shows FilePipeInformation */
-#define SMB_SFILEINFO_1023                             1023
+#define SMB_SFILEINFO_PIPE_INFORMATION                 1023
+#define SMB_SFILEINFO_VALID_DATA_INFORMATION           1039
+#define SMB_SFILEINFO_SHORT_NAME_INFORMATION           1040
 
 /* filemon shows FilePipeRemoteInformation */
 #define SMB_SFILEINFO_1025                             1025
 
+/* vista scan responds */
+#define SMB_SFILEINFO_1027                             1027
+
 /* filemon shows CopyOnWriteInformation */
 #define SMB_SFILEINFO_1029                             1029
 
 /* filemon shows OleClassIdInformation */
 #define SMB_SFILEINFO_1032                             1032
 
-/* seems to be the file size - perhaps valid data size? 
-   filemon shows 'InheritContentIndexInfo'
-*/
-#define SMB_SFILEINFO_1039                             1039
-
-/* OLE_INFORMATION? */
-#define SMB_SFILEINFO_1040                             1040
-
+/* vista scan responds to these */
+#define SMB_SFILEINFO_1030                             1030
+#define SMB_SFILEINFO_1031                             1031
+#define SMB_SFILEINFO_1036                             1036
+#define SMB_SFILEINFO_1041                             1041
+#define SMB_SFILEINFO_1042                             1042
+#define SMB_SFILEINFO_1043                             1043
+#define SMB_SFILEINFO_1044                             1044
 
 /* trans2 findfirst levels */
 /*
index 01f7576134b67b64e16af31d2fe8fcf6b2f7b8ec..16c0ff99c1bab4a243d5fa541ce07038e16c557e 100644 (file)
@@ -23,7 +23,7 @@
 #include "libcli/raw/libcliraw.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
-#include "heimdal/lib/hcrypto/sha.h"
+#include "lib/crypto/crypto.h"
 
 /*
   NOTE: this code does not yet interoperate with the windows SMB2
@@ -54,7 +54,7 @@ NTSTATUS smb2_sign_message(struct smb2_request *req)
 {
        struct smb2_request_buffer *buf = &req->out;
        uint64_t session_id;
-       SHA256_CTX m;
+       struct HMACSHA256Context m;
        uint8_t res[32];
 
        if (!req->transport->signing.doing_signing ||
@@ -85,11 +85,9 @@ 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);
-       SHA256_Init(&m);
-       SHA256_Update(&m, req->transport->signing.session_key.data, 
-                     req->transport->signing.session_key.length);
-       SHA256_Update(&m, buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE);
-       SHA256_Final(res, &m);
+       hmac_sha256_init(req->transport->signing.session_key.data, 16, &m);
+       hmac_sha256_update(buf->buffer+NBT_HDR_SIZE, buf->size-NBT_HDR_SIZE, &m);
+       hmac_sha256_final(res, &m);
 
        DEBUG(5,("signed SMB2 message of size %u\n", (unsigned)buf->size - NBT_HDR_SIZE));
 
@@ -110,7 +108,7 @@ NTSTATUS smb2_check_signature(struct smb2_transport *transport,
                              uint8_t *buffer, uint_t length)
 {
        uint64_t session_id;
-       SHA256_CTX m;
+       struct HMACSHA256Context m;
        uint8_t res[SHA256_DIGEST_LENGTH];
        uint8_t sig[16];
 
@@ -147,10 +145,9 @@ NTSTATUS smb2_check_signature(struct smb2_transport *transport,
        memset(buffer + NBT_HDR_SIZE + SMB2_HDR_SIGNATURE, 0, 16);
 
        ZERO_STRUCT(m);
-       SHA256_Init(&m);
-       SHA256_Update(&m, transport->signing.session_key.data,    16);
-       SHA256_Update(&m, buffer+NBT_HDR_SIZE, length-NBT_HDR_SIZE);
-       SHA256_Final(res, &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_final(res, &m);
 
        memcpy(buffer+NBT_HDR_SIZE+SMB2_HDR_SIGNATURE, sig, 16);
 
index 72bf23a9b4b143d4a3d12049bc69c7782cf378d1..cdbaa6cb1b51e5d69d2c3525be8814bf7ccfb177 100644 (file)
@@ -35,6 +35,8 @@ interface opendb
 
        typedef [public] struct {
                boolean8 delete_on_close;
+               NTTIME open_write_time;
+               NTTIME changed_write_time;
                utf8string path;
                uint32 num_entries;
                opendb_entry entries[num_entries];
index c87eca8aff3371da5d389c7188c2ca6719ac19da..3b3487315206bd77ececa84560abac59bb2791f1 100644 (file)
@@ -109,7 +109,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl,
 */
 NTSTATUS brl_locktest(struct brl_context *brl,
                      struct brl_handle *brlh,
-                     uint16_t smbpid, 
+                     uint32_t smbpid, 
                      uint64_t start, uint64_t size, 
                      enum brl_type lock_type)
 {
index 362a6d01e24d6c24af0d5de59a89c2cfcacdca2e..c94b9b446e67c19d54caae2a76b41a8b707f91ef 100644 (file)
@@ -57,7 +57,7 @@ struct brl_context {
 */
 struct lock_context {
        struct server_id server;
-       uint16_t smbpid;
+       uint32_t smbpid;
        struct brl_context *ctx;
 };
 
@@ -286,7 +286,7 @@ static NTSTATUS brl_tdb_lock_failed(struct brl_handle *brlh, struct lock_struct
 */
 static NTSTATUS brl_tdb_lock(struct brl_context *brl,
                         struct brl_handle *brlh,
-                        uint16_t smbpid,
+                        uint32_t smbpid,
                         uint64_t start, uint64_t size, 
                         enum brl_type lock_type,
                         void *notify_ptr)
@@ -436,7 +436,7 @@ static void brl_tdb_notify_all(struct brl_context *brl,
 */
 static NTSTATUS brl_tdb_unlock(struct brl_context *brl,
                           struct brl_handle *brlh, 
-                          uint16_t smbpid,
+                          uint32_t smbpid,
                           uint64_t start, uint64_t size)
 {
        TDB_DATA kbuf, dbuf;
@@ -581,7 +581,7 @@ static NTSTATUS brl_tdb_remove_pending(struct brl_context *brl,
 */
 static NTSTATUS brl_tdb_locktest(struct brl_context *brl,
                             struct brl_handle *brlh,
-                            uint16_t smbpid, 
+                            uint32_t smbpid, 
                             uint64_t start, uint64_t size, 
                             enum brl_type lock_type)
 {
index 2913ea8431c0d9025bc486744d6d081379df3c25..6917bad52ab9bc7ca82f0a68499889445a63f7a8 100644 (file)
@@ -97,11 +97,13 @@ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
 */
 NTSTATUS odb_open_file(struct odb_lock *lck,
                                void *file_handle, const char *path,
-                               int *fd, bool allow_level_II_oplock,
+                               int *fd, NTTIME open_write_time,
+                               bool allow_level_II_oplock,
                                uint32_t oplock_level, uint32_t *oplock_granted)
 {
        return ops->odb_open_file(lck, file_handle, path,
-                                 fd, allow_level_II_oplock,
+                                 fd, open_write_time,
+                                 allow_level_II_oplock,
                                  oplock_level, oplock_granted);
 }
 
@@ -159,15 +161,23 @@ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_close)
 }
 
 /*
-  return the current value of the delete_on_close bit, and how many
-  people still have the file open
+  update the write time on an open file
 */
-NTSTATUS odb_get_delete_on_close(struct odb_context *odb, 
-                                         DATA_BLOB *key, bool *del_on_close)
+NTSTATUS odb_set_write_time(struct odb_lock *lck,
+                           NTTIME write_time, bool force)
 {
-       return ops->odb_get_delete_on_close(odb, key, del_on_close);
+       return ops->odb_set_write_time(lck, write_time, force);
 }
 
+/*
+  return the current value of the delete_on_close bit,
+  and the current write time.
+*/
+NTSTATUS odb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
+                           bool *del_on_close, NTTIME *write_time)
+{
+       return ops->odb_get_file_infos(odb, key, del_on_close, write_time);
+}
 
 /*
   determine if a file can be opened with the given share_access,
index 045476337abbb2bfd1acfbbd2825f3dbd6bc0a95..179db111ca06dd6e60190c996b2948a4348469e8 100644 (file)
@@ -27,7 +27,8 @@ struct opendb_ops {
        DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck);
        NTSTATUS (*odb_open_file)(struct odb_lock *lck,
                                  void *file_handle, const char *path,
-                                 int *fd, bool allow_level_II_oplock,
+                                 int *fd, NTTIME open_write_time,
+                                 bool allow_level_II_oplock,
                                  uint32_t oplock_level, uint32_t *oplock_granted);
        NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private);
        NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle,
@@ -36,8 +37,10 @@ struct opendb_ops {
        NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path);
        NTSTATUS (*odb_get_path)(struct odb_lock *lck, const char **path);
        NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close);
-       NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb, 
-                                           DATA_BLOB *key, bool *del_on_close);
+       NTSTATUS (*odb_set_write_time)(struct odb_lock *lck,
+                                      NTTIME write_time, bool force);
+       NTSTATUS (*odb_get_file_infos)(struct odb_context *odb, DATA_BLOB *key,
+                                      bool *del_on_close, NTTIME *write_time);
        NTSTATUS (*odb_can_open)(struct odb_lock *lck,
                                 uint32_t stream_id, uint32_t share_access,
                                 uint32_t access_mask, bool delete_on_close,
index 99c0a95c20a4cac21853e6b50cd1a6f9b5e60af7..d7531297eda774e85f5bcda06f200461b2ad221f 100644 (file)
@@ -452,7 +452,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
 */
 static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
                                  void *file_handle, const char *path,
-                                 int *fd, bool allow_level_II_oplock,
+                                 int *fd, NTTIME open_write_time,
+                                 bool allow_level_II_oplock,
                                  uint32_t oplock_level, uint32_t *oplock_granted)
 {
        struct odb_context *odb = lck->odb;
@@ -474,6 +475,10 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
                NT_STATUS_HAVE_NO_MEMORY(lck->file.path);
        }
 
+       if (lck->file.open_write_time == 0) {
+               lck->file.open_write_time = open_write_time;
+       }
+
        /*
          possibly grant an exclusive, batch or level2 oplock
        */
@@ -784,21 +789,54 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl
        return odb_push_record(lck, &lck->file);
 }
 
+/*
+  update the write time on an open file
+*/
+static NTSTATUS odb_tdb_set_write_time(struct odb_lock *lck,
+                                      NTTIME write_time, bool force)
+{
+       if (lck->file.path == NULL) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       if (lck->file.changed_write_time != 0 && !force) {
+               return NT_STATUS_OK;
+       }
+
+       lck->file.changed_write_time = write_time;
+
+       return odb_push_record(lck, &lck->file);
+}
+
 /*
   return the current value of the delete_on_close bit, and how many
   people still have the file open
 */
-static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, 
-                                           DATA_BLOB *key, bool *del_on_close)
+static NTSTATUS odb_tdb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
+                                      bool *del_on_close, NTTIME *write_time)
 {
        struct odb_lock *lck;
 
-       (*del_on_close) = false;
+       if (del_on_close) {
+               *del_on_close = false;
+       }
+       if (write_time) {
+               *write_time = 0;
+       }
 
        lck = odb_lock(odb, odb, key);
        NT_STATUS_HAVE_NO_MEMORY(lck);
 
-       (*del_on_close) = lck->file.delete_on_close;
+       if (del_on_close) {
+               *del_on_close = lck->file.delete_on_close;
+       }
+       if (write_time) {
+               if (lck->file.changed_write_time == 0) {
+                       *write_time = lck->file.open_write_time;
+               } else {
+                       *write_time = lck->file.changed_write_time;
+               }
+       }
 
        talloc_free(lck);
 
@@ -852,7 +890,8 @@ static const struct opendb_ops opendb_tdb_ops = {
        .odb_rename              = odb_tdb_rename,
        .odb_get_path            = odb_tdb_get_path,
        .odb_set_delete_on_close = odb_tdb_set_delete_on_close,
-       .odb_get_delete_on_close = odb_tdb_get_delete_on_close,
+       .odb_set_write_time      = odb_tdb_set_write_time,
+       .odb_get_file_infos      = odb_tdb_get_file_infos,
        .odb_can_open            = odb_tdb_can_open,
        .odb_update_oplock       = odb_tdb_update_oplock,
        .odb_break_oplocks       = odb_tdb_break_oplocks
index 7a2edc7e2c2b5570bf3616b3e2120618d2d1141b..5de8a8b6491cd7e0f81915907de5b4fbc8153a47 100644 (file)
@@ -263,7 +263,7 @@ struct ntvfs_request {
        struct auth_session_info *session_info;
 
        /* the smb pid is needed for locking contexts */
-       uint16_t smbpid;
+       uint32_t smbpid;
 
        /*
         * client capabilities
index d70575847574f6a6ca361fdf2f32e99b6bb661bd..4f3a7e21983743dc8249770c014a2827dc419488 100644 (file)
@@ -986,8 +986,8 @@ NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs,
    NTVFS lock generic to any mapper
 */
 NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
-                                struct ntvfs_request *req,
-                                union smb_lock *lck)
+                       struct ntvfs_request *req,
+                       union smb_lock *lck)
 {
        union smb_lock *lck2;
        struct smb_lock_entry *locks;
@@ -1035,7 +1035,8 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
        case RAW_LOCK_SMB2: {
                /* this is only approximate! We need to change the
                   generic structure to fix this properly */
-               int i, j;
+               int i;
+               bool isunlock;
                if (lck->smb2.in.lock_count < 1) {
                        return NT_STATUS_INVALID_PARAMETER;
                }
@@ -1051,32 +1052,28 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
                if (lck2->generic.in.locks == NULL) {
                        return NT_STATUS_NO_MEMORY;
                }
+               /* only the first lock gives the UNLOCK bit - see
+                  MS-SMB2 3.3.5.14 */
+               if (lck->smb2.in.locks[0].flags & SMB2_LOCK_FLAG_UNLOCK) {
+                       lck2->generic.in.ulock_cnt = lck->smb2.in.lock_count;
+                       isunlock = true;
+               } else {
+                       lck2->generic.in.lock_cnt = lck->smb2.in.lock_count;
+                       isunlock = false;
+               }
                for (i=0;i<lck->smb2.in.lock_count;i++) {
-                       if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) {
-                               break;
-                       }
-                       j = lck2->generic.in.ulock_cnt;
-                       if (lck->smb2.in.locks[i].flags & 
-                           (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE)) {
+                       if (isunlock && 
+                           (lck->smb2.in.locks[i].flags & 
+                            (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE))) {
                                return NT_STATUS_INVALID_PARAMETER;
                        }
-                       lck2->generic.in.ulock_cnt++;
-                       lck2->generic.in.locks[j].pid = 0;
-                       lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
-                       lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
-                       lck2->generic.in.locks[j].pid = 0;
-               }
-               for (;i<lck->smb2.in.lock_count;i++) {
-                       if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) {
-                               /* w2008 requires unlocks to come first */
+                       if (!isunlock && 
+                           (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) {
                                return NT_STATUS_INVALID_PARAMETER;
                        }
-                       j = lck2->generic.in.ulock_cnt + lck2->generic.in.lock_cnt;
-                       lck2->generic.in.lock_cnt++;
-                       lck2->generic.in.locks[j].pid = 0;
-                       lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
-                       lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
-                       lck2->generic.in.locks[j].pid = 0;
+                       lck2->generic.in.locks[i].pid    = req->smbpid;
+                       lck2->generic.in.locks[i].offset = lck->smb2.in.locks[i].offset;
+                       lck2->generic.in.locks[i].count  = lck->smb2.in.locks[i].length;
                        if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) {
                                lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK;
                        }
index 04f6ad78d0f8e44e1ca32cd3970e5a7602dcd23f..a14c8f64ae0c5fd5a98da7d1e0faac3a42f4b890 100644 (file)
@@ -52,8 +52,13 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st)
 /*
   fill in the dos file attributes for a file
 */
-NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd)
+NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name,
+                           uint_t flags, int fd)
 {
+       NTSTATUS status;
+       DATA_BLOB lkey;
+       NTTIME write_time;
+
        /* make directories appear as size 0 with 1 link */
        if (S_ISDIR(name->st.st_mode)) {
                name->st.st_size = 0;
@@ -85,7 +90,29 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name,
        name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino;
        name->dos.flags = 0;
 
-       return pvfs_dosattrib_load(pvfs, name, fd);
+       status = pvfs_dosattrib_load(pvfs, name, fd);
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       if (flags & PVFS_RESOLVE_NO_OPENDB) {
+               return NT_STATUS_OK;
+       }
+
+       status = pvfs_locking_key(name, name, &lkey);
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       status = odb_get_file_infos(pvfs->odb_context, &lkey,
+                                   NULL, &write_time);
+       data_blob_free(&lkey);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1,("WARNING: odb_get_file_infos: %s\n", nt_errstr(status)));
+               return status;
+       }
+
+       if (!null_time(write_time)) {
+               name->dos.write_time = write_time;
+       }
+
+       return NT_STATUS_OK;
 }
 
 
index 822b28246ad6f5a7a36cb8c490b78db7f0ccd26a..0054455838a98246df26b0410e20bd2666d6bd5f 100644 (file)
@@ -31,7 +31,7 @@
 */
 NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs,
                         struct pvfs_file *f,
-                        uint16_t smbpid,
+                        uint32_t smbpid,
                         uint64_t offset, uint64_t count,
                         enum brl_type rw)
 {
index dada9f503f5334ce9b2b1e86b34cc2120cbdbd84..43203086f8711de7859cad828aa2388c6f81e7eb 100644 (file)
@@ -280,6 +280,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
        f->handle->position          = 0;
        f->handle->mode              = 0;
        f->handle->oplock            = NULL;
+       ZERO_STRUCT(f->handle->write_time);
        f->handle->open_completed    = false;
 
        if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
@@ -317,7 +318,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
 
                /* now really mark the file as open */
                status = odb_open_file(lck, f->handle, name->full_name,
-                                      NULL, false, OPLOCK_NONE, NULL);
+                                      NULL, name->dos.write_time,
+                                      false, OPLOCK_NONE, NULL);
 
                if (!NT_STATUS_IS_OK(status)) {
                        talloc_free(lck);
@@ -377,7 +379,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
                }
 
                status = odb_open_file(lck, f->handle, name->full_name,
-                                      NULL, false, OPLOCK_NONE, NULL);
+                                      NULL, name->dos.write_time,
+                                      false, OPLOCK_NONE, NULL);
 
                if (!NT_STATUS_IS_OK(status)) {
                        goto cleanup_delete;
@@ -433,6 +436,9 @@ cleanup_delete:
 */
 static int pvfs_handle_destructor(struct pvfs_file_handle *h)
 {
+       talloc_free(h->write_time.update_event);
+       h->write_time.update_event = NULL;
+
        if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
            h->name->stream_name) {
                NTSTATUS status;
@@ -451,6 +457,14 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h)
                h->fd = -1;
        }
 
+       if (!h->write_time.update_forced &&
+           h->write_time.update_on_close &&
+           h->write_time.close_time == 0) {
+               struct timeval tv;
+               tv = timeval_current();
+               h->write_time.close_time = timeval_to_nttime(&tv);
+       }
+
        if (h->have_opendb_entry) {
                struct odb_lock *lck;
                NTSTATUS status;
@@ -462,6 +476,26 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h)
                        return 0;
                }
 
+               if (h->write_time.update_forced) {
+                       status = odb_get_file_infos(h->pvfs->odb_context,
+                                                   &h->odb_locking_key,
+                                                   NULL,
+                                                   &h->write_time.close_time);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DEBUG(0,("Unable get write time for '%s' - %s\n",
+                                        h->name->full_name, nt_errstr(status)));
+                       }
+
+                       h->write_time.update_forced = false;
+                       h->write_time.update_on_close = true;
+               } else if (h->write_time.update_on_close) {
+                       status = odb_set_write_time(lck, h->write_time.close_time, true);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DEBUG(0,("Unable set write time for '%s' - %s\n",
+                                        h->name->full_name, nt_errstr(status)));
+                       }
+               }
+
                status = odb_close_file(lck, h, &delete_path);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", 
@@ -484,11 +518,26 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h)
                                               FILE_NOTIFY_CHANGE_FILE_NAME,
                                               delete_path);
                        }
+                       h->write_time.update_on_close = false;
                }
 
                talloc_free(lck);
        }
 
+       if (h->write_time.update_on_close) {
+               struct timeval tv[2];
+
+               nttime_to_timeval(&tv[0], h->name->dos.access_time);
+               nttime_to_timeval(&tv[1], h->write_time.close_time);
+
+               if (!timeval_is_zero(&tv[0]) || !timeval_is_zero(&tv[1])) {
+                       if (utimes(h->name->full_name, tv) == -1) {
+                               DEBUG(0,("pvfs_handle_destructor: utimes() failed '%s' - %s\n",
+                                        h->name->full_name, strerror(errno)));
+                       }
+               }
+       }
+
        return 0;
 }
 
@@ -594,8 +643,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
                DATA_BLOB locking_key;
                status = pvfs_locking_key(parent, req, &locking_key);
                NT_STATUS_NOT_OK_RETURN(status);
-               status = odb_get_delete_on_close(pvfs->odb_context, &locking_key, 
-                                                &del_on_close);
+               status = odb_get_file_infos(pvfs->odb_context, &locking_key,
+                                           &del_on_close, NULL);
                NT_STATUS_NOT_OK_RETURN(status);
                if (del_on_close) {
                        return NT_STATUS_DELETE_PENDING;
@@ -638,7 +687,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        }
 
        /* re-resolve the open fd */
-       status = pvfs_resolve_name_fd(pvfs, fd, name);
+       status = pvfs_resolve_name_fd(pvfs, fd, name, 0);
        if (!NT_STATUS_IS_OK(status)) {
                close(fd);
                return status;
@@ -730,10 +779,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        f->handle->mode              = 0;
        f->handle->oplock            = NULL;
        f->handle->have_opendb_entry = true;
+       ZERO_STRUCT(f->handle->write_time);
        f->handle->open_completed    = false;
 
        status = odb_open_file(lck, f->handle, name->full_name,
-                              &f->handle->fd, allow_level_II_oplock,
+                              &f->handle->fd, name->dos.write_time,
+                              allow_level_II_oplock,
                               oplock_level, &oplock_granted);
        talloc_free(lck);
        if (!NT_STATUS_IS_OK(status)) {
@@ -1334,6 +1385,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
        f->handle->mode              = 0;
        f->handle->oplock            = NULL;
        f->handle->have_opendb_entry = false;
+       ZERO_STRUCT(f->handle->write_time);
        f->handle->open_completed    = false;
 
        /* form the lock context used for byte range locking and
@@ -1437,7 +1489,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 
        /* now really mark the file as open */
        status = odb_open_file(lck, f->handle, name->full_name,
-                              &f->handle->fd, allow_level_II_oplock,
+                              &f->handle->fd, name->dos.write_time,
+                              allow_level_II_oplock,
                               oplock_level, &oplock_granted);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1476,7 +1529,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
        }
 
        /* re-resolve the open fd */
-       status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name);
+       status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name, PVFS_RESOLVE_NO_OPENDB);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(lck);
                return status;
@@ -1538,7 +1591,6 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs,
 {
        struct pvfs_state *pvfs = ntvfs->private_data;
        struct pvfs_file *f;
-       struct utimbuf unix_times;
 
        if (io->generic.level == RAW_CLOSE_SPLCLOSE) {
                return NT_STATUS_DOS(ERRSRV, ERRerror);
@@ -1554,9 +1606,9 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs,
        }
 
        if (!null_time(io->generic.in.write_time)) {
-               unix_times.actime = 0;
-               unix_times.modtime = io->close.in.write_time;
-               utime(f->handle->name->full_name, &unix_times);
+               f->handle->write_time.update_forced = false;
+               f->handle->write_time.update_on_close = true;
+               unix_to_nt_time(&f->handle->write_time.close_time, io->generic.in.write_time);
        }
 
        if (io->generic.in.flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) {
@@ -1915,8 +1967,8 @@ bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *
        NTSTATUS status;
        bool del_on_close;
 
-       status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, 
-                                        &del_on_close);
+       status = odb_get_file_infos(pvfs->odb_context, &h->odb_locking_key, 
+                                   &del_on_close, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1,("WARNING: unable to determine delete on close status for open file\n"));
                return false;
index dfa3697af7b27cc868cfedaee30245e5ad91aaca..71add72987ae67226e5436fd4914ae4022bccdde 100644 (file)
@@ -177,7 +177,7 @@ static void pvfs_oplock_break_dispatch(struct messaging_context *msg,
                opb = *p;
        } else {
                DEBUG(0,("%s: ignore oplock break with length[%u]\n",
-                       __location__, data->length));
+                        __location__, (unsigned)data->length));
                return;
        }
        if (opb.file_handle != opl->handle) {
index 5c2a627084c6c98bdeddfc9d8e51623d1139a1a1..d8ea5896e560f417870d9709e8dc76559ac0743d 100644 (file)
@@ -287,7 +287,9 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs,
 
        /* get a pvfs_filename source object */
        status = pvfs_resolve_partial(pvfs, mem_ctx, 
-                                     dir_path, fname1, &name1);
+                                     dir_path, fname1,
+                                     PVFS_RESOLVE_NO_OPENDB,
+                                     &name1);
        if (!NT_STATUS_IS_OK(status)) {
                goto failed;
        }
@@ -306,7 +308,9 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs,
 
        /* get a pvfs_filename dest object */
        status = pvfs_resolve_partial(pvfs, mem_ctx, 
-                                     dir_path, fname2, &name2);
+                                     dir_path, fname2,
+                                     PVFS_RESOLVE_NO_OPENDB,
+                                     &name2);
        if (NT_STATUS_IS_OK(status)) {
                status = pvfs_can_delete(pvfs, req, name2, NULL);
                if (!NT_STATUS_IS_OK(status)) {
index 2e97925c494e735557980eda4d809030e8963998..0f19788b9731d0587f5d3e6b50bb7f7aefd326c1 100644 (file)
@@ -57,7 +57,9 @@ static int component_compare(struct pvfs_state *pvfs, const char *comp, const ch
   TODO: add a cache for previously resolved case-insensitive names
   TODO: add mangled name support
 */
-static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename *name)
+static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs,
+                                struct pvfs_filename *name,
+                                uint_t flags)
 {
        /* break into a series of components */
        int num_components;
@@ -175,7 +177,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename *
        name->full_name = partial_name;
 
        if (name->exists) {
-               return pvfs_fill_dos_info(pvfs, name, -1);
+               return pvfs_fill_dos_info(pvfs, name, flags, -1);
        }
 
        return NT_STATUS_OK;
@@ -515,7 +517,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
                /* we need to search for a matching name */
                saved_name = (*name)->full_name;
                (*name)->full_name = dir_name;
-               status = pvfs_case_search(pvfs, *name);
+               status = pvfs_case_search(pvfs, *name, flags);
                if (!NT_STATUS_IS_OK(status)) {
                        /* the directory doesn't exist */
                        (*name)->full_name = saved_name;
@@ -536,11 +538,11 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
        /* if we can stat() the full name now then we are done */
        if (stat((*name)->full_name, &(*name)->st) == 0) {
                (*name)->exists = true;
-               return pvfs_fill_dos_info(pvfs, *name, -1);
+               return pvfs_fill_dos_info(pvfs, *name, flags, -1);
        }
 
        /* search for a matching filename */
-       status = pvfs_case_search(pvfs, *name);
+       status = pvfs_case_search(pvfs, *name, flags);
 
        return status;
 }
@@ -556,7 +558,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
 */
 NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
                              const char *unix_dir, const char *fname,
-                             struct pvfs_filename **name)
+                             uint_t flags, struct pvfs_filename **name)
 {
        NTSTATUS status;
 
@@ -581,7 +583,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
        (*name)->stream_name = NULL;
        (*name)->stream_id = 0;
 
-       status = pvfs_fill_dos_info(pvfs, *name, -1);
+       status = pvfs_fill_dos_info(pvfs, *name, flags, -1);
 
        return status;
 }
@@ -593,7 +595,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
   to update the pvfs_filename stat information, and by pvfs_open()
 */
 NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd,
-                             struct pvfs_filename *name)
+                             struct pvfs_filename *name, uint_t flags)
 {
        dev_t device = (dev_t)0;
        ino_t inode = 0;
@@ -626,7 +628,7 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd,
 
        name->exists = true;
        
-       return pvfs_fill_dos_info(pvfs, name, fd);
+       return pvfs_fill_dos_info(pvfs, name, flags, fd);
 }
 
 /*
@@ -703,9 +705,17 @@ NTSTATUS pvfs_resolve_name_handle(struct pvfs_state *pvfs,
                talloc_free(lck);
        }
 
-       status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
+       /*
+        * TODO: pass PVFS_RESOLVE_NO_OPENDB and get
+        *       the write time from odb_lock() above.
+        */
+       status = pvfs_resolve_name_fd(pvfs, h->fd, h->name, 0);
        NT_STATUS_NOT_OK_RETURN(status);
 
+       if (!null_nttime(h->write_time.close_time)) {
+               h->name->dos.write_time = h->write_time.close_time;
+       }
+
        return NT_STATUS_OK;
 }
 
@@ -755,7 +765,7 @@ NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
        (*name)->stream_name = NULL;
        (*name)->stream_id = 0;
 
-       status = pvfs_fill_dos_info(pvfs, *name, -1);
+       status = pvfs_fill_dos_info(pvfs, *name, PVFS_RESOLVE_NO_OPENDB, -1);
 
        return status;
 }
index e47406dc09e46a116fe4e809075eee4f93af5882..e0fe4fb64d9ca5ebe84c2f6c1c6974652d0c2606 100644 (file)
@@ -84,7 +84,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                                                      in pvfs_list_seek_ofs() for 
                                                      how we cope with this */
 
-       status = pvfs_resolve_partial(pvfs, file, unix_path, fname, &name);
+       status = pvfs_resolve_partial(pvfs, file, unix_path, fname, 0, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index 3ea8b7cb6ecbf95d139b05fa941cc78715c43dcd..a3c4024ed7ea532bc8512280470dea68a8a34792 100644 (file)
@@ -52,7 +52,7 @@ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs,
                break;
 
        case SEEK_MODE_END:
-               status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
+               status = pvfs_resolve_name_fd(pvfs, h->fd, h->name, PVFS_RESOLVE_NO_OPENDB);
                h->seek_offset = h->name->st.st_size + io->lseek.in.offset;
                break;
        }
index 1dd2c075d9abf57254552f399ecfdee4c9763e12..2cde5f42aae3172a3c707c3dd4e0f95c93973ee4 100644 (file)
@@ -273,7 +273,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
                          union smb_setfileinfo *info)
 {
        struct pvfs_state *pvfs = ntvfs->private_data;
-       struct utimbuf unix_times;
        struct pvfs_file *f;
        struct pvfs_file_handle *h;
        struct pvfs_filename newstats;
@@ -437,23 +436,54 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
        }
 
        /* possibly change the file timestamps */
-       ZERO_STRUCT(unix_times);
        if (newstats.dos.create_time != h->name->dos.create_time) {
                change_mask |= FILE_NOTIFY_CHANGE_CREATION;
        }
        if (newstats.dos.access_time != h->name->dos.access_time) {
-               unix_times.actime = nt_time_to_unix(newstats.dos.access_time);
                change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
        }
        if (newstats.dos.write_time != h->name->dos.write_time) {
-               unix_times.modtime = nt_time_to_unix(newstats.dos.write_time);
                change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE;
        }
-       if (unix_times.actime != 0 || unix_times.modtime != 0) {
-               if (utime(h->name->full_name, &unix_times) == -1) {
-                       return pvfs_map_errno(pvfs, errno);
+       if ((change_mask & FILE_NOTIFY_CHANGE_LAST_ACCESS) ||
+           (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE)) {
+               struct timeval tv[2];
+
+               nttime_to_timeval(&tv[0], newstats.dos.access_time);
+               nttime_to_timeval(&tv[1], newstats.dos.write_time);
+
+               if (!timeval_is_zero(&tv[0]) || !timeval_is_zero(&tv[1])) {
+                       if (utimes(h->name->full_name, tv) == -1) {
+                               DEBUG(0,("pvfs_setfileinfo: utimes() failed '%s' - %s\n",
+                                        h->name->full_name, strerror(errno)));
+                               return pvfs_map_errno(pvfs, errno);
+                       }
                }
        }
+       if (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE) {
+               struct odb_lock *lck;
+
+               lck = odb_lock(req, h->pvfs->odb_context, &h->odb_locking_key);
+               if (lck == NULL) {
+                       DEBUG(0,("Unable to lock opendb for write time update\n"));
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+
+               status = odb_set_write_time(lck, newstats.dos.write_time, true);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0,("Unable to update write time: %s\n",
+                               nt_errstr(status)));
+                       talloc_free(lck);
+                       return status;
+               }
+
+               talloc_free(lck);
+
+               h->write_time.update_forced = true;
+               h->write_time.update_on_close = false;
+               talloc_free(h->write_time.update_event);
+               h->write_time.update_event = NULL;
+       }
 
        /* possibly change the attribute */
        if (newstats.dos.attrib != h->name->dos.attrib) {
@@ -570,7 +600,6 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
        struct pvfs_filename *name;
        struct pvfs_filename newstats;
        NTSTATUS status;
-       struct utimbuf unix_times;
        uint32_t access_needed;
        uint32_t change_mask = 0;
        struct odb_lock *lck = NULL;
@@ -736,21 +765,51 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
        }
 
        /* possibly change the file timestamps */
-       ZERO_STRUCT(unix_times);
        if (newstats.dos.create_time != name->dos.create_time) {
                change_mask |= FILE_NOTIFY_CHANGE_CREATION;
        }
        if (newstats.dos.access_time != name->dos.access_time) {
-               unix_times.actime = nt_time_to_unix(newstats.dos.access_time);
                change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
        }
        if (newstats.dos.write_time != name->dos.write_time) {
-               unix_times.modtime = nt_time_to_unix(newstats.dos.write_time);
                change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE;
        }
-       if (unix_times.actime != 0 || unix_times.modtime != 0) {
-               if (utime(name->full_name, &unix_times) == -1) {
-                       return pvfs_map_errno(pvfs, errno);
+       if ((change_mask & FILE_NOTIFY_CHANGE_LAST_ACCESS) ||
+           (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE)) {
+               struct timeval tv[2];
+
+               nttime_to_timeval(&tv[0], newstats.dos.access_time);
+               nttime_to_timeval(&tv[1], newstats.dos.write_time);
+
+               if (!timeval_is_zero(&tv[0]) || !timeval_is_zero(&tv[1])) {
+                       if (utimes(name->full_name, tv) == -1) {
+                               DEBUG(0,("pvfs_setpathinfo: utimes() failed '%s' - %s\n",
+                                        name->full_name, strerror(errno)));
+                               return pvfs_map_errno(pvfs, errno);
+                       }
+               }
+       }
+       if (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE) {
+               if (lck == NULL) {
+                       DATA_BLOB lkey;
+                       status = pvfs_locking_key(name, name, &lkey);
+                       NT_STATUS_NOT_OK_RETURN(status);
+
+                       lck = odb_lock(req, pvfs->odb_context, &lkey);
+                       data_blob_free(&lkey);
+                       if (lck == NULL) {
+                               DEBUG(0,("Unable to lock opendb for write time update\n"));
+                               return NT_STATUS_INTERNAL_ERROR;
+                       }
+               }
+
+               status = odb_set_write_time(lck, newstats.dos.write_time, true);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+                       /* it could be that nobody has opened the file */
+               } else if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0,("Unable to update write time: %s\n",
+                               nt_errstr(status)));
+                       return status;
                }
        }
 
index 4cb47a4f1fa330c4bb113909412e705c87dfa12a..6a5704177041ea9b1b808fa7bda36d9f3bd29ef6 100644 (file)
@@ -201,7 +201,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
 
        /* resolve the cifs name to a posix name */
        status = pvfs_resolve_name(pvfs, req, unl->unlink.in.pattern, 
-                                  PVFS_RESOLVE_WILDCARD | PVFS_RESOLVE_STREAMS, &name);
+                                  PVFS_RESOLVE_WILDCARD |
+                                  PVFS_RESOLVE_STREAMS |
+                                  PVFS_RESOLVE_NO_OPENDB,
+                                  &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -246,7 +249,9 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
                /* get a pvfs_filename object */
                status = pvfs_resolve_partial(pvfs, req,
                                              pvfs_list_unix_path(dir),
-                                             fname, &name);
+                                             fname,
+                                             PVFS_RESOLVE_NO_OPENDB,
+                                             &name);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
index 1f662f13fcdab52618bb4c5f07d8357dc9c57ef2..2da0e4bb3afc4f02c6915d5c967aca3414126551 100644 (file)
 #include "includes.h"
 #include "vfs_posix.h"
 #include "librpc/gen_ndr/security.h"
+#include "lib/events/events.h"
 
+static void pvfs_write_time_update_handler(struct event_context *ev,
+                                          struct timed_event *te,
+                                          struct timeval tv,
+                                          void *private_data)
+{
+       struct pvfs_file_handle *h = talloc_get_type(private_data,
+                                    struct pvfs_file_handle);
+       struct odb_lock *lck;
+       NTSTATUS status;
+       NTTIME write_time;
+
+       lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
+       if (lck == NULL) {
+               DEBUG(0,("Unable to lock opendb for write time update\n"));
+               return;
+       }
+
+       write_time = timeval_to_nttime(&tv);
+
+       status = odb_set_write_time(lck, write_time, false);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("Unable to update write time: %s\n",
+                       nt_errstr(status)));
+               return;
+       }
+
+       talloc_free(lck);
+
+       h->write_time.update_event = NULL;
+}
+
+static void pvfs_trigger_write_time_update(struct pvfs_file_handle *h)
+{
+       struct pvfs_state *pvfs = h->pvfs;
+       struct timeval tv;
+
+       if (h->write_time.update_triggered) {
+               return;
+       }
+
+       tv = timeval_current_ofs(0, pvfs->writetime_delay);
+
+       h->write_time.update_triggered = true;
+       h->write_time.update_on_close = true;
+       h->write_time.update_event = event_add_timed(pvfs->ntvfs->ctx->event_ctx,
+                                                    h, tv,
+                                                    pvfs_write_time_update_handler,
+                                                    h);
+       if (!h->write_time.update_event) {
+               DEBUG(0,("Failed event_add_timed\n"));
+       }
+}
 
 /*
   write to a file
@@ -61,6 +114,8 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs,
        status = pvfs_break_level2_oplocks(f);
        NT_STATUS_NOT_OK_RETURN(status);
 
+       pvfs_trigger_write_time_update(f->handle);
+
        if (f->handle->name->stream_name) {
                ret = pvfs_stream_write(pvfs,
                                        f->handle,
index 14b5210fd0e6ced1db9d99cd944b5cf13a2e984b..b5dd270346122ab5b169d28fdcf601fbce50d8ca 100644 (file)
@@ -95,6 +95,10 @@ static void pvfs_setup_options(struct pvfs_state *pvfs)
                                                      PVFS_OPLOCK_TIMEOUT,
                                                      PVFS_OPLOCK_TIMEOUT_DEFAULT);
 
+       pvfs->writetime_delay = share_int_option(scfg,
+                                                PVFS_WRITETIME_DELAY,
+                                                PVFS_WRITETIME_DELAY_DEFAULT);
+
        pvfs->share_name = talloc_strdup(pvfs, scfg->name);
 
        pvfs->fs_attribs = 
index c194698b64e23510ee486791702d284500b6520a..cf39bcf0ac0db318f0246dec8a65638b71f105db 100644 (file)
@@ -59,6 +59,9 @@ struct pvfs_state {
        /* the oplock break timeout (secs) */
        uint_t oplock_break_timeout;
 
+       /* the write time update delay (nsecs) */
+       uint_t writetime_delay;
+
        /* filesystem attributes (see FS_ATTR_*) */
        uint32_t fs_attribs;
 
@@ -169,6 +172,14 @@ struct pvfs_file_handle {
        /* we need this hook back to our parent for lock destruction */
        struct pvfs_state *pvfs;
 
+       struct {
+               bool update_triggered;
+               struct timed_event *update_event;
+               bool update_on_close;
+               NTTIME close_time;
+               bool update_forced;
+       } write_time;
+
        /* the open went through to completion */
        bool open_completed;
 };
@@ -220,6 +231,7 @@ struct pvfs_search_state {
 /* flags to pvfs_resolve_name() */
 #define PVFS_RESOLVE_WILDCARD    (1<<0)
 #define PVFS_RESOLVE_STREAMS     (1<<1)
+#define PVFS_RESOLVE_NO_OPENDB   (1<<2)
 
 /* flags in pvfs->flags */
 #define PVFS_FLAG_CI_FILESYSTEM  (1<<0) /* the filesystem is case insensitive */
@@ -249,6 +261,7 @@ struct pvfs_odb_retry;
 #define PVFS_FAKE_OPLOCKS              "posix:fakeoplocks"
 #define PVFS_SHARE_DELAY               "posix:sharedelay"
 #define PVFS_OPLOCK_TIMEOUT            "posix:oplocktimeout"
+#define PVFS_WRITETIME_DELAY           "posix:writetimeupdatedelay"
 #define PVFS_ALLOCATION_ROUNDING       "posix:allocationrounding"
 #define PVFS_SEARCH_INACTIVITY         "posix:searchinactivity"
 #define PVFS_ACL                       "posix:acl"
@@ -258,6 +271,7 @@ struct pvfs_odb_retry;
 #define PVFS_FAKE_OPLOCKS_DEFAULT              false
 #define PVFS_SHARE_DELAY_DEFAULT               1000000 /* nsecs */
 #define PVFS_OPLOCK_TIMEOUT_DEFAULT            30 /* secs */
+#define PVFS_WRITETIME_DELAY_DEFAULT           2000000 /* nsecs */
 #define PVFS_ALLOCATION_ROUNDING_DEFAULT       512
 #define PVFS_SEARCH_INACTIVITY_DEFAULT         300
 
index 67d4a4f62981cf5b571a9a31b563aca8d6928258..ded7922ec98ba054a0ca4a8fafedc32957161003 100644 (file)
@@ -5,7 +5,6 @@
 # a successful run for any of these tests an error.
 local.resolve.*.async
 local.iconv.*.next_codepoint()
-base.delaywrite.finfo update on close
 base.delete.*.deltest20a
 base.delete.*.deltest20b
 rpc.winreg.*security
index 7a6c54e9ec144e1b4dfb1e1532072a30adb6485f..bf25172c76f134198bff2ea357516012f77512ca 100644 (file)
@@ -14,7 +14,6 @@
 #
 # Please add a comment for each testsuite you disable explaining why 
 # it is being skipped.
-base.delaywrite
 raw.composite
 base.iometer
 base.casetable
@@ -28,7 +27,6 @@ samba4.ntvfs.cifs.raw.qfileinfo.ipc
 smb2.notify
 smb2.scan
 ntvfs.cifs.base.charset
-ntvfs.cifs.base.delaywrite
 ntvfs.cifs.base.iometer
 ntvfs.cifs.base.casetable
 ntvfs.cifs.base.nttrans
index b73ba5558687614fe6fb4496b63ab8af75251e32..1d550cbfe15dc145a6b5e3a63e60a539904a1da1 100755 (executable)
@@ -213,7 +213,11 @@ done
 plantest "rpc.echo on ncacn_np over smb2" dc $smb4torture ncacn_np:"\$SERVER[smb2]" -U"\$USERNAME"%"\$PASSWORD" -W \$DOMAIN RPC-ECHO "$*"
 
 # Tests against the NTVFS POSIX backend
-NTVFSARGS="--option=torture:sharedelay=100000 --option=torture:oplocktimeout=3"
+NTVFSARGS=""
+NTVFSARGS="${NTVFSARGS} --option=torture:sharedelay=100000"
+NTVFSARGS="${NTVFSARGS} --option=torture:oplocktimeout=3"
+NTVFSARGS="${NTVFSARGS} --option=torture:writetimeupdatedelay=500000"
+
 smb2=`$smb4torture --list | grep "^SMB2-" | xargs`
 #The QFILEINFO-IPC test needs to be on ipc$
 raw=`$smb4torture --list | grep "^RAW-" | grep -v "RAW-QFILEINFO-IPC"| xargs`
index 9f771ab8a3ee57118fdb622910d870a48d05eb6a..bcee9264818aa6a6fd6db8fe1f5280734f64faae 100644 (file)
@@ -581,6 +581,7 @@ sub provision($$$$$$)
        posix:sharedelay = 100000
        posix:eadb = $lockdir/eadb.tdb
        posix:oplocktimeout = 3
+       posix:writetimeupdatedelay = 500000
 
 [test1]
        path = $tmpdir/test1
@@ -589,6 +590,7 @@ sub provision($$$$$$)
        posix:sharedelay = 100000
        posix:eadb = $lockdir/eadb.tdb
        posix:oplocktimeout = 3
+       posix:writetimeupdatedelay = 500000
 
 [test2]
        path = $tmpdir/test2
@@ -597,6 +599,7 @@ sub provision($$$$$$)
        posix:sharedelay = 100000
        posix:eadb = $lockdir/eadb.tdb
        posix:oplocktimeout = 3
+       posix:writetimeupdatedelay = 500000
 
 [cifs]
        read only = no
old mode 100644 (file)
new mode 100755 (executable)
index e5ba814cb21c9f77253fb18079a2c070165471ed..711c86bb74b88b6903b36728c068b17dfd7d1a83 100644 (file)
@@ -588,12 +588,20 @@ static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req,
        case RAW_SFILEINFO_UNIX_BASIC:
        case RAW_SFILEINFO_UNIX_LINK:
        case RAW_SFILEINFO_UNIX_HLINK:
-       case RAW_SFILEINFO_1023:
+       case RAW_SFILEINFO_PIPE_INFORMATION:
+       case RAW_SFILEINFO_VALID_DATA_INFORMATION:
+       case RAW_SFILEINFO_SHORT_NAME_INFORMATION:
        case RAW_SFILEINFO_1025:
+       case RAW_SFILEINFO_1027:
        case RAW_SFILEINFO_1029:
+       case RAW_SFILEINFO_1030:
+       case RAW_SFILEINFO_1031:
        case RAW_SFILEINFO_1032:
-       case RAW_SFILEINFO_1039:
-       case RAW_SFILEINFO_1040:
+       case RAW_SFILEINFO_1036:
+       case RAW_SFILEINFO_1041:
+       case RAW_SFILEINFO_1042:
+       case RAW_SFILEINFO_1043:
+       case RAW_SFILEINFO_1044:
                return NT_STATUS_INVALID_LEVEL;
 
        default:
@@ -784,6 +792,7 @@ static NTSTATUS find_fill_info(struct find_state *state,
                                                   SMBSRV_REQ_DEFAULT_STR_FLAGS(req));
 
        case RAW_SEARCH_DATA_UNIX_INFO:
+       case RAW_SEARCH_DATA_UNIX_INFO2:
                return NT_STATUS_INVALID_LEVEL;
        }
 
index 942000133c3dfe5d378dab0e96fa9dd1a521a4f3..6c4b8f33d5b839ce604880fcc69b9199104136c7 100644 (file)
@@ -53,6 +53,11 @@ static void smb2srv_getinfo_send(struct ntvfs_request *ntvfs)
                SMB2SRV_CHECK(op->send_fn(op));
        }
 
+       if (op->info->in.output_buffer_length < op->info->out.blob.length) {
+               smb2srv_send_error(req,  NT_STATUS_INFO_LENGTH_MISMATCH);
+               return;
+       }
+
        SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x08, true, op->info->out.blob.length));
 
        SMB2SRV_CHECK(smb2_push_o16s32_blob(&req->out, 0x02, op->info->out.blob));
index 040947f84f3f7c784be796a6244728b60382d3d5..be64013bb252597b8bd644b925f68fd3e81bcaed 100644 (file)
@@ -327,7 +327,7 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon
 
        req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req,
                                          req->session->session_info,
-                                         0, /* TODO: fill in PID */
+                                         SVAL(req->in.hdr, SMB2_HDR_PID),
                                          req->request_time,
                                          req, NULL, 0);
        if (!req->ntvfs) {
index 84adfef61adba42bb7801e0e5c7ec028f328e2fb..c03e89d36eb72738ea14ed639f597bc1b5ecde6e 100644 (file)
@@ -641,7 +641,7 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
        bool err = false; \
        if (strict && (g cmp c)) { \
                err = true; \
-       } else if (gr cmp cr) { \
+       } else if ((g cmp c) && (gr cmp cr)) { \
                /* handle filesystem without high resolution timestamps */ \
                err = true; \
        } \
@@ -673,23 +673,11 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s
 } while (0)
 #define COMPARE_ACCESS_TIME_EQUAL(given,correct) \
        COMPARE_ACCESS_TIME_CMP(given,correct,!=)
-#define COMPARE_ACCESS_TIME_GREATER(given,correct) \
-       COMPARE_ACCESS_TIME_CMP(given,correct,<=)
-#define COMPARE_ACCESS_TIME_LESS(given,correct) \
-       COMPARE_ACCESS_TIME_CMP(given,correct,>=)
 
 #define COMPARE_BOTH_TIMES_EQUAL(given,correct) do { \
        COMPARE_ACCESS_TIME_EQUAL(given,correct); \
        COMPARE_WRITE_TIME_EQUAL(given,correct); \
 } while (0)
-#define COMPARE_BOTH_TIMES_GEATER(given,correct) do { \
-       COMPARE_ACCESS_TIME_GREATER(given,correct); \
-       COMPARE_WRITE_TIME_GREATER(given,correct); \
-} while (0)
-#define COMPARE_BOTH_TIMES_LESS(given,correct) do { \
-       COMPARE_ACCESS_TIME_LESS(given,correct); \
-       COMPARE_WRITE_TIME_LESS(given,correct); \
-} while (0)
 
 #define GET_INFO_FILE(finfo) do { \
        NTSTATUS _status; \
@@ -828,6 +816,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx,
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
+       COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0);
 
        /* sure any further write doesn't update the write time */
        start = timeval_current();
@@ -982,6 +971,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx,
        }
 
        GET_INFO_BOTH(finfo1,pinfo1);
+       COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0);
 
        /* sure any further write doesn't update the write time */
        start = timeval_current();
index 07d394fad6b79e12aeda17a89259eb1de2d17237..60243a5d1b8f961e07bc2309381016225dbef004 100644 (file)
@@ -2199,16 +2199,20 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
                LVL(STANDARD), LVL(ALLOCATION_INFO), LVL(END_OF_FILE_INFO), 
                LVL(SETATTR), LVL(SETATTRE), LVL(BASIC_INFORMATION),
                LVL(RENAME_INFORMATION), LVL(DISPOSITION_INFORMATION), 
-               LVL(POSITION_INFORMATION), LVL(MODE_INFORMATION),
+               LVL(POSITION_INFORMATION), LVL(FULL_EA_INFORMATION), LVL(MODE_INFORMATION),
                LVL(ALLOCATION_INFORMATION), LVL(END_OF_FILE_INFORMATION), 
-               LVL(1023), LVL(1025), LVL(1029), LVL(1032), LVL(1039), LVL(1040),
+               LVL(PIPE_INFORMATION), LVL(VALID_DATA_INFORMATION), LVL(SHORT_NAME_INFORMATION), 
+               LVL(1025), LVL(1027), LVL(1029), LVL(1030), LVL(1031), LVL(1032), LVL(1036),
+               LVL(1041), LVL(1042), LVL(1043), LVL(1044),
        };
        struct levels smb2_levels[] = {
                LVL(BASIC_INFORMATION),
                LVL(RENAME_INFORMATION), LVL(DISPOSITION_INFORMATION), 
-               LVL(POSITION_INFORMATION), LVL(MODE_INFORMATION),
+               LVL(POSITION_INFORMATION), LVL(FULL_EA_INFORMATION), LVL(MODE_INFORMATION),
                LVL(ALLOCATION_INFORMATION), LVL(END_OF_FILE_INFORMATION), 
-               LVL(1023), LVL(1025), LVL(1029), LVL(1032), LVL(1039), LVL(1040)
+               LVL(PIPE_INFORMATION), LVL(VALID_DATA_INFORMATION), LVL(SHORT_NAME_INFORMATION), 
+               LVL(1025), LVL(1027), LVL(1029), LVL(1030), LVL(1031), LVL(1032), LVL(1036),
+               LVL(1041), LVL(1042), LVL(1043), LVL(1044),
        };
        struct levels *levels = options.smb2?smb2_levels:smb_levels;
        uint32_t num_levels = options.smb2?ARRAY_SIZE(smb2_levels):ARRAY_SIZE(smb_levels);
@@ -2276,12 +2280,9 @@ static void gen_setfileinfo(int instance, union smb_setfileinfo *info)
 
        case RAW_SFILEINFO_GENERIC:
        case RAW_SFILEINFO_SEC_DESC:
-       case RAW_SFILEINFO_1023:
        case RAW_SFILEINFO_1025:
        case RAW_SFILEINFO_1029:
        case RAW_SFILEINFO_1032:
-       case RAW_SFILEINFO_1039:
-       case RAW_SFILEINFO_1040:
        case RAW_SFILEINFO_UNIX_BASIC:
        case RAW_SFILEINFO_UNIX_INFO2:
        case RAW_SFILEINFO_UNIX_LINK:
index 1c3274adcda745368540d12c632ee4b6abfe150c..bf53df4a11cebd0166fa25d68d8605957f8a3cb1 100644 (file)
@@ -68,16 +68,13 @@ NTSTATUS torture_local_init(void)
        torture_suite_add_simple_test(suite, "TALLOC", torture_local_talloc);
        torture_suite_add_simple_test(suite, "REPLACE", torture_local_replace);
        
-       torture_suite_add_simple_test(suite, "CRYPTO-SHA1", 
-                                     torture_local_crypto_sha1);
        torture_suite_add_simple_test(suite, 
                                      "CRYPTO-MD4", torture_local_crypto_md4);
        torture_suite_add_simple_test(suite, "CRYPTO-MD5", 
                                      torture_local_crypto_md5);
        torture_suite_add_simple_test(suite, "CRYPTO-HMACMD5", 
                                      torture_local_crypto_hmacmd5);
-       torture_suite_add_simple_test(suite, "CRYPTO-HMACSHA1", 
-                                     torture_local_crypto_hmacsha1);
+
        for (i = 0; suite_generators[i]; i++)
                torture_suite_add_suite(suite,
                                        suite_generators[i](talloc_autofree_context()));
index 96144c47735592b5af885c7371ce3e0588e133e5..5a4037f906d1d73dba685ae5b9922ca0ab2100de 100644 (file)
@@ -23,7 +23,6 @@
 #include "torture/smbtorture.h"
 #include "system/filesys.h"
 #include "system/locale.h"
-#include "pstring.h"
 
 #include "torture/nbench/proto.h"
 
@@ -59,7 +58,7 @@ static bool run_netbench(struct torture_context *tctx, struct smbcli_state *cli,
 {
        int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
        int i;
-       pstring line;
+       char line[1024];
        char *cname;
        FILE *f;
        bool correct = true;
index 906d6e4f8d57bb4e32d8d7082b1593097323c7de..5b35d7e693a8fc1f8c9bbfdb21204fbdc421c2ff 100644 (file)
@@ -167,6 +167,40 @@ static bool torture_smb2_fsinfo(struct smb2_tree *tree)
 }
 
 
+/*
+  test for buffer size handling
+*/
+static bool torture_smb2_buffercheck(struct smb2_tree *tree)
+{
+       NTSTATUS status;
+       struct smb2_handle handle;
+       struct smb2_getinfo b;
+
+       printf("Testing buffer size handling\n");
+       status = smb2_util_roothandle(tree, &handle);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf(__location__ " Unable to create root handle - %s\n", nt_errstr(status));
+               return false;
+       }
+
+       ZERO_STRUCT(b);
+       b.in.info_type            = SMB2_GETINFO_FS;
+       b.in.info_class           = 1;
+       b.in.output_buffer_length = 0x1;
+       b.in.input_buffer_length  = 0;
+       b.in.file.handle          = handle;
+
+       status = smb2_getinfo(tree, tree, &b);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_INFO_LENGTH_MISMATCH)) {
+               printf(__location__ " Wrong error code for small buffer %s\n",
+                      nt_errstr(status));
+               return false;
+       }
+
+       return true;
+}
+
+
 /* basic testing of all SMB2 getinfo levels
 */
 bool torture_smb2_getinfo(struct torture_context *torture)
@@ -196,6 +230,7 @@ bool torture_smb2_getinfo(struct torture_context *torture)
 
        ret &= torture_smb2_fileinfo(torture, tree);
        ret &= torture_smb2_fsinfo(tree);
+       ret &= torture_smb2_buffercheck(tree);
 
        talloc_free(mem_ctx);
 
index 35ad8396107bffde8a263c076713576650c57b3a..d820983022b35cf01e8f931cf533992ee524abde 100644 (file)
@@ -268,20 +268,12 @@ static bool test_valid_request(struct torture_context *torture, struct smb2_tree
        lck.in.lock_count       = 1;
        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
        status = smb2_lock(tree, &lck);
-       if (torture_setting_bool(torture, "windows", false)) {
-               CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
-       } else {
-               CHECK_STATUS(status, NT_STATUS_OK);
-       }
+       CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
 
        lck.in.lock_count       = 1;
        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
        status = smb2_lock(tree, &lck);
-       if (torture_setting_bool(torture, "windows", false)) {
-               CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
-       } else {
-               CHECK_STATUS(status, NT_STATUS_OK);
-       }
+       CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
 
        lck.in.lock_count       = 1;
        el[0].flags             = SMB2_LOCK_FLAG_UNLOCK;
index 1ce796be4da63194e0faa94d46ecbbc6a3b7627f..ae51af18820ed0ad97281be2a97814f3321423ef 100644 (file)
@@ -77,22 +77,20 @@ bool torture_smb2_getinfo_scan(struct torture_context *torture)
 
                        io.in.file.handle = fhandle;
                        status = smb2_getinfo(tree, torture, &io);
-                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
-                           !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
-                           !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
-                               printf("file level 0x%02x:%02x is %ld bytes - %s\n", 
+                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+                               printf("file level 0x%02x:%02x %u is %ld bytes - %s\n", 
                                       io.in.info_type, io.in.info_class, 
+                                      (unsigned)io.in.info_class, 
                                       (long)io.out.blob.length, nt_errstr(status));
                                dump_data(1, io.out.blob.data, io.out.blob.length);
                        }
 
                        io.in.file.handle = dhandle;
                        status = smb2_getinfo(tree, torture, &io);
-                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
-                           !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
-                           !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
-                               printf("dir  level 0x%02x:%02x is %ld bytes - %s\n", 
+                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+                               printf("dir  level 0x%02x:%02x %u is %ld bytes - %s\n", 
                                       io.in.info_type, io.in.info_class,
+                                      (unsigned)io.in.info_class, 
                                       (long)io.out.blob.length, nt_errstr(status));
                                dump_data(1, io.out.blob.data, io.out.blob.length);
                        }
@@ -134,8 +132,7 @@ bool torture_smb2_setinfo_scan(struct torture_context *torture)
                        io.in.level = (i<<8) | c;
                        io.in.file.handle = handle;
                        status = smb2_setinfo(tree, &io);
-                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
-                           !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+                       if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
                                printf("file level 0x%04x - %s\n", 
                                       io.in.level, nt_errstr(status));
                        }
index 44e4c83e671bca20d07729335516fe1ac4ce2fd6..a5e6ab37c4cc187508030727df5e79a52f83e724 100755 (executable)
@@ -486,11 +486,11 @@ sn: ldap user2
                assert(res.msgs.length == 2);
        }
 
-       var res = ldb.search("(&(anr=testy ldap)(objectClass=user))");
-       if (res.error != 0 || res.msgs.length != 2) {
-               println("Found only " + res.msgs.length + " for (&(anr=\"testy ldap\")(objectClass=user))");
+       var res = ldb.search("(&(anr=\"testy ldap\")(objectClass=user))");
+       if (res.error != 0 || res.msgs.length != 0) {
+               println("Found " + res.msgs.length + " for (&(anr=\"testy ldap\")(objectClass=user))");
                assert(res.error == 0);
-               assert(res.msgs.length == 2);
+               assert(res.msgs.length == 0);
        }
 
 // Testing ldb.search for (&(anr=ldap)(objectClass=user))