summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/cluster/ctdb/opendb_ctdb.c51
-rw-r--r--source4/kdc/hdb-ldb.c4
-rw-r--r--source4/kdc/kdc.c5
-rw-r--r--source4/kdc/kdc.h1
-rw-r--r--source4/kdc/kpasswdd.c2
-rw-r--r--source4/kdc/pac-glue.c2
-rw-r--r--source4/lib/crypto/config.mk5
-rw-r--r--source4/lib/crypto/crypto.h4
-rw-r--r--source4/lib/crypto/hmacsha1test.c97
-rw-r--r--source4/lib/crypto/hmacsha256.c (renamed from source4/lib/crypto/hmacsha1.c)53
-rw-r--r--source4/lib/crypto/hmacsha256.h (renamed from source4/lib/crypto/hmacsha1.h)25
-rw-r--r--source4/lib/crypto/sha1.c390
-rw-r--r--source4/lib/crypto/sha1.h62
-rw-r--r--source4/lib/crypto/sha1test.c110
-rw-r--r--source4/lib/crypto/sha256.c234
-rw-r--r--source4/lib/crypto/sha256.h91
-rwxr-xr-xsource4/lib/ldb/tests/python/ldap.py196
-rw-r--r--source4/lib/torture/torture.h2
-rw-r--r--source4/libcli/raw/interfaces.h17
-rw-r--r--source4/libcli/raw/rawsetfileinfo.c29
-rw-r--r--source4/libcli/raw/trans2.h27
-rw-r--r--source4/libcli/smb2/signing.c21
-rw-r--r--source4/librpc/idl/opendb.idl2
-rw-r--r--source4/ntvfs/common/brlock.c2
-rw-r--r--source4/ntvfs/common/brlock_tdb.c8
-rw-r--r--source4/ntvfs/common/opendb.c24
-rw-r--r--source4/ntvfs/common/opendb.h9
-rw-r--r--source4/ntvfs/common/opendb_tdb.c51
-rw-r--r--source4/ntvfs/ntvfs.h2
-rw-r--r--source4/ntvfs/ntvfs_generic.c45
-rw-r--r--source4/ntvfs/posix/pvfs_fileinfo.c31
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c2
-rw-r--r--source4/ntvfs/posix/pvfs_open.c80
-rw-r--r--source4/ntvfs/posix/pvfs_oplock.c2
-rw-r--r--source4/ntvfs/posix/pvfs_rename.c8
-rw-r--r--source4/ntvfs/posix/pvfs_resolve.c32
-rw-r--r--source4/ntvfs/posix/pvfs_search.c2
-rw-r--r--source4/ntvfs/posix/pvfs_seek.c2
-rw-r--r--source4/ntvfs/posix/pvfs_setfileinfo.c87
-rw-r--r--source4/ntvfs/posix/pvfs_unlink.c9
-rw-r--r--source4/ntvfs/posix/pvfs_write.c55
-rw-r--r--source4/ntvfs/posix/vfs_posix.c4
-rw-r--r--source4/ntvfs/posix/vfs_posix.h14
-rw-r--r--source4/samba4-knownfail1
-rw-r--r--source4/samba4-skip2
-rwxr-xr-xsource4/selftest/samba4_tests.sh6
-rw-r--r--source4/selftest/target/Samba4.pm3
-rwxr-xr-x[-rw-r--r--]source4/setup/setpassword0
-rw-r--r--source4/smb_server/smb/trans2.c15
-rw-r--r--source4/smb_server/smb2/fileinfo.c5
-rw-r--r--source4/smb_server/smb2/tcon.c2
-rw-r--r--source4/torture/basic/delaywrite.c16
-rw-r--r--source4/torture/gentest.c15
-rw-r--r--source4/torture/local/local.c5
-rw-r--r--source4/torture/nbench/nbench.c3
-rw-r--r--source4/torture/smb2/getinfo.c35
-rw-r--r--source4/torture/smb2/lock.c12
-rw-r--r--source4/torture/smb2/scan.c17
-rwxr-xr-xtestprogs/ejs/ldap.js8
59 files changed, 1077 insertions, 967 deletions
diff --git a/source4/cluster/ctdb/opendb_ctdb.c b/source4/cluster/ctdb/opendb_ctdb.c
index ed09cf0bbc..b1faf9e0e6 100644
--- a/source4/cluster/ctdb/opendb_ctdb.c
+++ b/source4/cluster/ctdb/opendb_ctdb.c
@@ -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
diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c
index 9c7b1f6457..70e578ee0d 100644
--- a/source4/kdc/hdb-ldb.c
+++ b/source4/kdc/hdb-ldb.c
@@ -34,10 +34,7 @@
#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,
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index 84d9d45f57..dfd62c55a4 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -28,17 +28,14 @@
#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
diff --git a/source4/kdc/kdc.h b/source4/kdc/kdc.h
index 9be15115d1..0943de4b00 100644
--- a/source4/kdc/kdc.h
+++ b/source4/kdc/kdc.h
@@ -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;
diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c
index 1d49a8a4bd..b42769c6dc 100644
--- a/source4/kdc/kpasswdd.c
+++ b/source4/kdc/kpasswdd.c
@@ -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 {
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
index 1c68d4c37d..cab1446ff3 100644
--- a/source4/kdc/pac-glue.c
+++ b/source4/kdc/pac-glue.c
@@ -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;
diff --git a/source4/lib/crypto/config.mk b/source4/lib/crypto/config.mk
index b9a7f7cb9e..ee111bd088 100644
--- a/source4/lib/crypto/config.mk
+++ b/source4/lib/crypto/config.mk
@@ -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)))
diff --git a/source4/lib/crypto/crypto.h b/source4/lib/crypto/crypto.h
index 10e2258fa7..fc283f72ba 100644
--- a/source4/lib/crypto/crypto.h
+++ b/source4/lib/crypto/crypto.h
@@ -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/source4/lib/crypto/hmacsha1test.c b/source4/lib/crypto/hmacsha1test.c
deleted file mode 100644
index 6e53124d21..0000000000
--- a/source4/lib/crypto/hmacsha1test.c
+++ /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;
-}
diff --git a/source4/lib/crypto/hmacsha1.c b/source4/lib/crypto/hmacsha256.c
index 21ce966f60..6b0af9ee83 100644
--- a/source4/lib/crypto/hmacsha1.c
+++ b/source4/lib/crypto/hmacsha256.c
@@ -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
@@ -25,24 +30,24 @@
#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);
}
diff --git a/source4/lib/crypto/hmacsha1.h b/source4/lib/crypto/hmacsha256.h
index 0638c66d53..8960c636c1 100644
--- a/source4/lib/crypto/hmacsha1.h
+++ b/source4/lib/crypto/hmacsha256.h
@@ -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
@@ -17,17 +23,16 @@
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/source4/lib/crypto/sha1.c b/source4/lib/crypto/sha1.c
deleted file mode 100644
index 1b91f8a949..0000000000
--- a/source4/lib/crypto/sha1.c
+++ /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/source4/lib/crypto/sha1.h b/source4/lib/crypto/sha1.h
deleted file mode 100644
index 4a2d448bfc..0000000000
--- a/source4/lib/crypto/sha1.h
+++ /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/source4/lib/crypto/sha1test.c b/source4/lib/crypto/sha1test.c
deleted file mode 100644
index 7777764277..0000000000
--- a/source4/lib/crypto/sha1test.c
+++ /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/source4/lib/crypto/sha256.c b/source4/lib/crypto/sha256.c
new file mode 100644
index 0000000000..70fe7a3099
--- /dev/null
+++ b/source4/lib/crypto/sha256.c
@@ -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/source4/lib/crypto/sha256.h b/source4/lib/crypto/sha256.h
new file mode 100644
index 0000000000..4a5f2cbe94
--- /dev/null
+++ b/source4/lib/crypto/sha256.h
@@ -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 */
diff --git a/source4/lib/ldb/tests/python/ldap.py b/source4/lib/ldb/tests/python/ldap.py
index c76222c207..aba9581ec5 100755
--- a/source4/lib/ldb/tests/python/ldap.py
+++ b/source4/lib/ldb/tests/python/ldap.py
@@ -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)
diff --git a/source4/lib/torture/torture.h b/source4/lib/torture/torture.h
index 15b04c2397..f023f319ff 100644
--- a/source4/lib/torture/torture.h
+++ b/source4/lib/torture/torture.h
@@ -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)
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 19d51893a6..8e23510f06 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -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 */
diff --git a/source4/libcli/raw/rawsetfileinfo.c b/source4/libcli/raw/rawsetfileinfo.c
index 16052e8708..5a4706778a 100644
--- a/source4/libcli/raw/rawsetfileinfo.c
+++ b/source4/libcli/raw/rawsetfileinfo.c
@@ -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);
diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h
index 5b7987aa8c..63632eb5ed 100644
--- a/source4/libcli/raw/trans2.h
+++ b/source4/libcli/raw/trans2.h
@@ -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 */
/*
diff --git a/source4/libcli/smb2/signing.c b/source4/libcli/smb2/signing.c
index 01f7576134..16c0ff99c1 100644
--- a/source4/libcli/smb2/signing.c
+++ b/source4/libcli/smb2/signing.c
@@ -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);
diff --git a/source4/librpc/idl/opendb.idl b/source4/librpc/idl/opendb.idl
index 72bf23a9b4..cdbaa6cb1b 100644
--- a/source4/librpc/idl/opendb.idl
+++ b/source4/librpc/idl/opendb.idl
@@ -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];
diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c
index c87eca8aff..3b34873152 100644
--- a/source4/ntvfs/common/brlock.c
+++ b/source4/ntvfs/common/brlock.c
@@ -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)
{
diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c
index 362a6d01e2..c94b9b446e 100644
--- a/source4/ntvfs/common/brlock_tdb.c
+++ b/source4/ntvfs/common/brlock_tdb.c
@@ -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)
{
diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c
index 2913ea8431..6917bad52a 100644
--- a/source4/ntvfs/common/opendb.c
+++ b/source4/ntvfs/common/opendb.c
@@ -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,
diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h
index 045476337a..179db111ca 100644
--- a/source4/ntvfs/common/opendb.h
+++ b/source4/ntvfs/common/opendb.h
@@ -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,
diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c
index 99c0a95c20..d7531297ed 100644
--- a/source4/ntvfs/common/opendb_tdb.c
+++ b/source4/ntvfs/common/opendb_tdb.c
@@ -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
*/
@@ -785,20 +790,53 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl
}
/*
+ 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
diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h
index 7a2edc7e2c..5de8a8b649 100644
--- a/source4/ntvfs/ntvfs.h
+++ b/source4/ntvfs/ntvfs.h
@@ -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
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index d705758475..4f3a7e2198 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c
index 04f6ad78d0..a14c8f64ae 100644
--- a/source4/ntvfs/posix/pvfs_fileinfo.c
+++ b/source4/ntvfs/posix/pvfs_fileinfo.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c
index 822b28246a..0054455838 100644
--- a/source4/ntvfs/posix/pvfs_lock.c
+++ b/source4/ntvfs/posix/pvfs_lock.c
@@ -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)
{
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index dada9f503f..43203086f8 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -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;
diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c
index dfa3697af7..71add72987 100644
--- a/source4/ntvfs/posix/pvfs_oplock.c
+++ b/source4/ntvfs/posix/pvfs_oplock.c
@@ -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) {
diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c
index 5c2a627084..d8ea5896e5 100644
--- a/source4/ntvfs/posix/pvfs_rename.c
+++ b/source4/ntvfs/posix/pvfs_rename.c
@@ -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)) {
diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c
index 2e97925c49..0f19788b97 100644
--- a/source4/ntvfs/posix/pvfs_resolve.c
+++ b/source4/ntvfs/posix/pvfs_resolve.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c
index e47406dc09..e0fe4fb64d 100644
--- a/source4/ntvfs/posix/pvfs_search.c
+++ b/source4/ntvfs/posix/pvfs_search.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c
index 3ea8b7cb6e..a3c4024ed7 100644
--- a/source4/ntvfs/posix/pvfs_seek.c
+++ b/source4/ntvfs/posix/pvfs_seek.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c
index 1dd2c075d9..2cde5f42aa 100644
--- a/source4/ntvfs/posix/pvfs_setfileinfo.c
+++ b/source4/ntvfs/posix/pvfs_setfileinfo.c
@@ -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;
}
}
diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c
index 4cb47a4f1f..6a57041770 100644
--- a/source4/ntvfs/posix/pvfs_unlink.c
+++ b/source4/ntvfs/posix/pvfs_unlink.c
@@ -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;
}
diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c
index 1f662f13fc..2da0e4bb3a 100644
--- a/source4/ntvfs/posix/pvfs_write.c
+++ b/source4/ntvfs/posix/pvfs_write.c
@@ -22,7 +22,60 @@
#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,
diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c
index 14b5210fd0..b5dd270346 100644
--- a/source4/ntvfs/posix/vfs_posix.c
+++ b/source4/ntvfs/posix/vfs_posix.c
@@ -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 =
diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h
index c194698b64..cf39bcf0ac 100644
--- a/source4/ntvfs/posix/vfs_posix.h
+++ b/source4/ntvfs/posix/vfs_posix.h
@@ -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
diff --git a/source4/samba4-knownfail b/source4/samba4-knownfail
index 67d4a4f629..ded7922ec9 100644
--- a/source4/samba4-knownfail
+++ b/source4/samba4-knownfail
@@ -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
diff --git a/source4/samba4-skip b/source4/samba4-skip
index 7a6c54e9ec..bf25172c76 100644
--- a/source4/samba4-skip
+++ b/source4/samba4-skip
@@ -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
diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh
index b73ba55586..1d550cbfe1 100755
--- a/source4/selftest/samba4_tests.sh
+++ b/source4/selftest/samba4_tests.sh
@@ -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`
diff --git a/source4/selftest/target/Samba4.pm b/source4/selftest/target/Samba4.pm
index 9f771ab8a3..bcee926481 100644
--- a/source4/selftest/target/Samba4.pm
+++ b/source4/selftest/target/Samba4.pm
@@ -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
diff --git a/source4/setup/setpassword b/source4/setup/setpassword
index 65770e1f4d..65770e1f4d 100644..100755
--- a/source4/setup/setpassword
+++ b/source4/setup/setpassword
diff --git a/source4/smb_server/smb/trans2.c b/source4/smb_server/smb/trans2.c
index e5ba814cb2..711c86bb74 100644
--- a/source4/smb_server/smb/trans2.c
+++ b/source4/smb_server/smb/trans2.c
@@ -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;
}
diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c
index 942000133c..6c4b8f33d5 100644
--- a/source4/smb_server/smb2/fileinfo.c
+++ b/source4/smb_server/smb2/fileinfo.c
@@ -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));
diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c
index 040947f84f..be64013bb2 100644
--- a/source4/smb_server/smb2/tcon.c
+++ b/source4/smb_server/smb2/tcon.c
@@ -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) {
diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c
index 84adfef61a..c03e89d36e 100644
--- a/source4/torture/basic/delaywrite.c
+++ b/source4/torture/basic/delaywrite.c
@@ -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();
diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c
index 07d394fad6..60243a5d1b 100644
--- a/source4/torture/gentest.c
+++ b/source4/torture/gentest.c
@@ -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:
diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c
index 1c3274adcd..bf53df4a11 100644
--- a/source4/torture/local/local.c
+++ b/source4/torture/local/local.c
@@ -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()));
diff --git a/source4/torture/nbench/nbench.c b/source4/torture/nbench/nbench.c
index 96144c4773..5a4037f906 100644
--- a/source4/torture/nbench/nbench.c
+++ b/source4/torture/nbench/nbench.c
@@ -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;
diff --git a/source4/torture/smb2/getinfo.c b/source4/torture/smb2/getinfo.c
index 906d6e4f8d..5b35d7e693 100644
--- a/source4/torture/smb2/getinfo.c
+++ b/source4/torture/smb2/getinfo.c
@@ -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);
diff --git a/source4/torture/smb2/lock.c b/source4/torture/smb2/lock.c
index 35ad839610..d820983022 100644
--- a/source4/torture/smb2/lock.c
+++ b/source4/torture/smb2/lock.c
@@ -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;
diff --git a/source4/torture/smb2/scan.c b/source4/torture/smb2/scan.c
index 1ce796be4d..ae51af1882 100644
--- a/source4/torture/smb2/scan.c
+++ b/source4/torture/smb2/scan.c
@@ -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));
}
diff --git a/testprogs/ejs/ldap.js b/testprogs/ejs/ldap.js
index 44e4c83e67..a5e6ab37c4 100755
--- a/testprogs/ejs/ldap.js
+++ b/testprogs/ejs/ldap.js
@@ -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))