mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
(This used to be commit dcdfee611ccc0ae798e3eea2cfdf3c7642dc5677)
This commit is contained in:
commit
d51904c489
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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)))
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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 */
|
@ -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);
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
234
source4/lib/crypto/sha256.c
Normal file
234
source4/lib/crypto/sha256.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
91
source4/lib/crypto/sha256.h
Normal file
91
source4/lib/crypto/sha256.h
Normal file
@ -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 */
|
@ -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=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=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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -452,7 +452,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
|
||||
*/
|
||||
static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
|
||||
void *file_handle, const char *path,
|
||||
int *fd, bool allow_level_II_oplock,
|
||||
int *fd, NTTIME open_write_time,
|
||||
bool allow_level_II_oplock,
|
||||
uint32_t oplock_level, uint32_t *oplock_granted)
|
||||
{
|
||||
struct odb_context *odb = lck->odb;
|
||||
@ -474,6 +475,10 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
|
||||
NT_STATUS_HAVE_NO_MEMORY(lck->file.path);
|
||||
}
|
||||
|
||||
if (lck->file.open_write_time == 0) {
|
||||
lck->file.open_write_time = open_write_time;
|
||||
}
|
||||
|
||||
/*
|
||||
possibly grant an exclusive, batch or level2 oplock
|
||||
*/
|
||||
@ -784,21 +789,54 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl
|
||||
return odb_push_record(lck, &lck->file);
|
||||
}
|
||||
|
||||
/*
|
||||
update the write time on an open file
|
||||
*/
|
||||
static NTSTATUS odb_tdb_set_write_time(struct odb_lock *lck,
|
||||
NTTIME write_time, bool force)
|
||||
{
|
||||
if (lck->file.path == NULL) {
|
||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (lck->file.changed_write_time != 0 && !force) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
lck->file.changed_write_time = write_time;
|
||||
|
||||
return odb_push_record(lck, &lck->file);
|
||||
}
|
||||
|
||||
/*
|
||||
return the current value of the delete_on_close bit, and how many
|
||||
people still have the file open
|
||||
*/
|
||||
static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb,
|
||||
DATA_BLOB *key, bool *del_on_close)
|
||||
static NTSTATUS odb_tdb_get_file_infos(struct odb_context *odb, DATA_BLOB *key,
|
||||
bool *del_on_close, NTTIME *write_time)
|
||||
{
|
||||
struct odb_lock *lck;
|
||||
|
||||
(*del_on_close) = false;
|
||||
if (del_on_close) {
|
||||
*del_on_close = false;
|
||||
}
|
||||
if (write_time) {
|
||||
*write_time = 0;
|
||||
}
|
||||
|
||||
lck = odb_lock(odb, odb, key);
|
||||
NT_STATUS_HAVE_NO_MEMORY(lck);
|
||||
|
||||
(*del_on_close) = lck->file.delete_on_close;
|
||||
if (del_on_close) {
|
||||
*del_on_close = lck->file.delete_on_close;
|
||||
}
|
||||
if (write_time) {
|
||||
if (lck->file.changed_write_time == 0) {
|
||||
*write_time = lck->file.open_write_time;
|
||||
} else {
|
||||
*write_time = lck->file.changed_write_time;
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(lck);
|
||||
|
||||
@ -852,7 +890,8 @@ static const struct opendb_ops opendb_tdb_ops = {
|
||||
.odb_rename = odb_tdb_rename,
|
||||
.odb_get_path = odb_tdb_get_path,
|
||||
.odb_set_delete_on_close = odb_tdb_set_delete_on_close,
|
||||
.odb_get_delete_on_close = odb_tdb_get_delete_on_close,
|
||||
.odb_set_write_time = odb_tdb_set_write_time,
|
||||
.odb_get_file_infos = odb_tdb_get_file_infos,
|
||||
.odb_can_open = odb_tdb_can_open,
|
||||
.odb_update_oplock = odb_tdb_update_oplock,
|
||||
.odb_break_oplocks = odb_tdb_break_oplocks
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
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)) {
|
||||
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;
|
||||
/* 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<lck->smb2.in.lock_count;i++) {
|
||||
if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) {
|
||||
/* w2008 requires unlocks to come first */
|
||||
for (i=0;i<lck->smb2.in.lock_count;i++) {
|
||||
if (isunlock &&
|
||||
(lck->smb2.in.locks[i].flags &
|
||||
(SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE))) {
|
||||
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;
|
||||
if (!isunlock &&
|
||||
(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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`
|
||||
|
@ -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
|
||||
|
0
source4/setup/setpassword
Normal file → Executable file
0
source4/setup/setpassword
Normal file → Executable file
@ -588,12 +588,20 @@ static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req,
|
||||
case RAW_SFILEINFO_UNIX_BASIC:
|
||||
case RAW_SFILEINFO_UNIX_LINK:
|
||||
case RAW_SFILEINFO_UNIX_HLINK:
|
||||
case RAW_SFILEINFO_1023:
|
||||
case RAW_SFILEINFO_PIPE_INFORMATION:
|
||||
case RAW_SFILEINFO_VALID_DATA_INFORMATION:
|
||||
case RAW_SFILEINFO_SHORT_NAME_INFORMATION:
|
||||
case RAW_SFILEINFO_1025:
|
||||
case RAW_SFILEINFO_1027:
|
||||
case RAW_SFILEINFO_1029:
|
||||
case RAW_SFILEINFO_1030:
|
||||
case RAW_SFILEINFO_1031:
|
||||
case RAW_SFILEINFO_1032:
|
||||
case RAW_SFILEINFO_1039:
|
||||
case RAW_SFILEINFO_1040:
|
||||
case RAW_SFILEINFO_1036:
|
||||
case RAW_SFILEINFO_1041:
|
||||
case RAW_SFILEINFO_1042:
|
||||
case RAW_SFILEINFO_1043:
|
||||
case RAW_SFILEINFO_1044:
|
||||
return NT_STATUS_INVALID_LEVEL;
|
||||
|
||||
default:
|
||||
@ -784,6 +792,7 @@ static NTSTATUS find_fill_info(struct find_state *state,
|
||||
SMBSRV_REQ_DEFAULT_STR_FLAGS(req));
|
||||
|
||||
case RAW_SEARCH_DATA_UNIX_INFO:
|
||||
case RAW_SEARCH_DATA_UNIX_INFO2:
|
||||
return NT_STATUS_INVALID_LEVEL;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
@ -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()));
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user