mirror of
https://github.com/samba-team/samba.git
synced 2025-02-04 17:47:26 +03:00
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-gmake3
(This used to be commit e4da851bd7e7620bbf99efe20a496b1be78ba4e2)
This commit is contained in:
commit
fc2cd5ed63
@ -157,7 +157,7 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
|
||||
|
||||
acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
|
||||
|
||||
acct_expiry = samdb_result_nttime(msg, "accountExpires", 0);
|
||||
acct_expiry = samdb_result_account_expires(msg, 0);
|
||||
|
||||
/* Check for when we must change this password, taking the
|
||||
* userAccountControl flags into account */
|
||||
@ -351,7 +351,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte
|
||||
|
||||
server_info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
|
||||
server_info->last_logoff = samdb_result_nttime(msg, "lastLogoff", 0);
|
||||
server_info->acct_expiry = samdb_result_nttime(msg, "accountExpires", 0);
|
||||
server_info->acct_expiry = samdb_result_account_expires(msg, 0);
|
||||
server_info->last_password_change = samdb_result_nttime(msg, "pwdLastSet", 0);
|
||||
|
||||
ncname = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL);
|
||||
|
@ -284,6 +284,7 @@ static NTSTATUS odb_ctdb_open_file(struct odb_lock *lck,
|
||||
uint32_t stream_id, uint32_t share_access,
|
||||
uint32_t access_mask, bool delete_on_close,
|
||||
uint32_t open_disposition, bool break_to_none,
|
||||
bool allow_level_II_oplock,
|
||||
uint32_t oplock_level, uint32_t *oplock_granted)
|
||||
|
||||
{
|
||||
|
@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
dnl disabled 2.53 requirement - we do work with 2.52 on suse 7.3 for example
|
||||
dnl AC_PREREQ(2.53)
|
||||
|
||||
AC_INIT([samba],[],[samba-technical@samba.org])
|
||||
AC_INIT([samba],[4],[samba-technical@samba.org])
|
||||
|
||||
AC_CONFIG_SRCDIR([include/includes.h])
|
||||
AC_CONFIG_HEADER(include/config_tmp.h)
|
||||
|
@ -433,6 +433,30 @@ NTTIME samdb_result_nttime(struct ldb_message *msg, const char *attr, NTTIME def
|
||||
return ldb_msg_find_attr_as_uint64(msg, attr, default_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows uses both 0 and 9223372036854775807 (0x7FFFFFFFFFFFFFFFULL) to
|
||||
* indicate an account doesn't expire.
|
||||
*
|
||||
* When Windows initially creates an account, it sets
|
||||
* accountExpires = 9223372036854775807 (0x7FFFFFFFFFFFFFFF). However,
|
||||
* when changing from an account having a specific expiration date to
|
||||
* that account never expiring, it sets accountExpires = 0.
|
||||
*
|
||||
* Consolidate that logic here to allow clearer logic for account expiry in
|
||||
* the rest of the code.
|
||||
*/
|
||||
NTTIME samdb_result_account_expires(struct ldb_message *msg,
|
||||
NTTIME default_value)
|
||||
{
|
||||
NTTIME ret = ldb_msg_find_attr_as_uint64(msg, "accountExpires",
|
||||
default_value);
|
||||
|
||||
if (ret == (NTTIME)0)
|
||||
ret = 0x7FFFFFFFFFFFFFFFULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
pull a uint64_t from a result set.
|
||||
*/
|
||||
@ -493,7 +517,7 @@ NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb,
|
||||
|
||||
maxPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn, "maxPwdAge", NULL);
|
||||
if (maxPwdAge == 0) {
|
||||
return 0;
|
||||
return 0x7FFFFFFFFFFFFFFFULL;
|
||||
} else {
|
||||
attr_time -= maxPwdAge;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "librpc/gen_ndr/ndr_drsuapi.h"
|
||||
#include "librpc/gen_ndr/ndr_drsblobs.h"
|
||||
#include "lib/util/dlinklist.h"
|
||||
#include "param/param.h"
|
||||
|
||||
static int schema_fsmo_init(struct ldb_module *module)
|
||||
{
|
||||
@ -78,7 +79,7 @@ static int schema_fsmo_init(struct ldb_module *module)
|
||||
}
|
||||
module->private_data = schema_fsmo;
|
||||
|
||||
schema = talloc_zero(mem_ctx, struct dsdb_schema);
|
||||
schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(ldb_get_opaque(module->ldb, "loadparm")));
|
||||
if (!schema) {
|
||||
ldb_oom(module->ldb);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
|
@ -29,6 +29,18 @@
|
||||
#include "librpc/gen_ndr/ndr_drsblobs.h"
|
||||
#include "param/param.h"
|
||||
|
||||
struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience)
|
||||
{
|
||||
struct dsdb_schema *schema = talloc_zero(mem_ctx, struct dsdb_schema);
|
||||
if (!schema) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
schema->iconv_convenience = iconv_convenience;
|
||||
return schema;
|
||||
}
|
||||
|
||||
|
||||
WERROR dsdb_load_oid_mappings_drsuapi(struct dsdb_schema *schema, const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr)
|
||||
{
|
||||
uint32_t i,j;
|
||||
@ -1150,12 +1162,7 @@ WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf
|
||||
goto nomem;
|
||||
}
|
||||
|
||||
schema = talloc_zero(mem_ctx, struct dsdb_schema);
|
||||
if (!schema) {
|
||||
goto nomem;
|
||||
}
|
||||
|
||||
schema->iconv_convenience = lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm"));
|
||||
schema = dsdb_new_schema(mem_ctx, lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")));
|
||||
|
||||
/*
|
||||
* load the prefixMap attribute from pf
|
||||
|
@ -510,9 +510,8 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
|
||||
|
||||
entry_ex->entry.valid_start = NULL;
|
||||
|
||||
acct_expiry = samdb_result_nttime(msg, "accountExpires", (NTTIME)-1);
|
||||
if ((acct_expiry == (NTTIME)-1) ||
|
||||
(acct_expiry == 0x7FFFFFFFFFFFFFFFULL)) {
|
||||
acct_expiry = samdb_result_account_expires(msg, 0);
|
||||
if (acct_expiry == 0x7FFFFFFFFFFFFFFFULL) {
|
||||
entry_ex->entry.valid_end = NULL;
|
||||
} else {
|
||||
entry_ex->entry.valid_end = malloc(sizeof(*entry_ex->entry.valid_end));
|
||||
|
@ -276,9 +276,28 @@ krb5_error_code samba_kdc_check_client_access(void *priv,
|
||||
|
||||
/* TODO: Need a more complete mapping of NTSTATUS to krb5kdc errors */
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
/* TODO: Also need to add the appropriate e-data struct of type
|
||||
* PA-PW-SALT (3) that includes the NT_STATUS code, which gives Windows
|
||||
* the information it needs to display the appropriate dialog. */
|
||||
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_MUST_CHANGE))
|
||||
return KRB5KDC_ERR_KEY_EXPIRED;
|
||||
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED))
|
||||
return KRB5KDC_ERR_KEY_EXPIRED;
|
||||
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_EXPIRED))
|
||||
return KRB5KDC_ERR_CLIENT_REVOKED;
|
||||
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED))
|
||||
return KRB5KDC_ERR_CLIENT_REVOKED;
|
||||
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_LOGON_HOURS))
|
||||
return KRB5KDC_ERR_CLIENT_REVOKED;
|
||||
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_LOCKED_OUT))
|
||||
return KRB5KDC_ERR_CLIENT_REVOKED;
|
||||
else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_WORKSTATION))
|
||||
return KRB5KDC_ERR_POLICY;
|
||||
else if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
return KRB5KDC_ERR_POLICY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ pwdLastSet: 0
|
||||
primaryGroupID: 513
|
||||
objectSid: S-1-5-21-43662522-77495566-38969261-500
|
||||
adminCount: 1
|
||||
accountExpires: -1
|
||||
accountExpires: 9223372036854775807
|
||||
logonCount: 0
|
||||
sAMAccountName: Administrator
|
||||
sAMAccountType: 0x30000000
|
||||
|
@ -63,7 +63,7 @@ static void ldb_wrap_debug(void *context, enum ldb_debug_level level,
|
||||
};
|
||||
vasprintf(&s, fmt, ap);
|
||||
if (!s) return;
|
||||
DEBUG(level, ("ldb: %s\n", s));
|
||||
DEBUG(samba_level, ("ldb: %s\n", s));
|
||||
free(s);
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,10 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req)
|
||||
transport->negotiate.capabilities &= ~CAP_STATUS32;
|
||||
}
|
||||
|
||||
if (!transport->options.use_level2_oplocks) {
|
||||
transport->negotiate.capabilities &= ~CAP_LEVEL_II_OPLOCKS;
|
||||
}
|
||||
|
||||
failed:
|
||||
return smbcli_request_destroy(req);
|
||||
}
|
||||
|
@ -31,6 +31,19 @@ interface krb5pac
|
||||
samr_RidWithAttributeArray res_groups;
|
||||
} PAC_LOGON_INFO;
|
||||
|
||||
typedef struct {
|
||||
[value(2*strlen_m(upn_name))] uint16 upn_size;
|
||||
uint16 upn_offset;
|
||||
[value(2*strlen_m(domain_name))] uint16 domain_size;
|
||||
uint16 domain_offset;
|
||||
uint16 unknown3; /* 0x01 */
|
||||
uint16 unknown4;
|
||||
uint32 unknown5;
|
||||
[charset(UTF16)] uint8 upn_name[upn_size+2];
|
||||
[charset(UTF16)] uint8 domain_name[domain_size+2];
|
||||
uint32 unknown6; /* padding */
|
||||
} PAC_UNKNOWN_12;
|
||||
|
||||
typedef [public] struct {
|
||||
[value(0x00081001)] uint32 unknown1;
|
||||
[value(0xCCCCCCCC)] uint32 unknown2;
|
||||
@ -44,14 +57,21 @@ interface krb5pac
|
||||
PAC_TYPE_SRV_CHECKSUM = 6,
|
||||
PAC_TYPE_KDC_CHECKSUM = 7,
|
||||
PAC_TYPE_LOGON_NAME = 10,
|
||||
PAC_TYPE_CONSTRAINED_DELEGATION = 11
|
||||
PAC_TYPE_CONSTRAINED_DELEGATION = 11,
|
||||
PAC_TYPE_UNKNOWN_12 = 12
|
||||
} PAC_TYPE;
|
||||
|
||||
typedef struct {
|
||||
[flag(NDR_REMAINING)] DATA_BLOB remaining;
|
||||
} DATA_BLOB_REM;
|
||||
|
||||
typedef [public,nodiscriminant,gensize] union {
|
||||
[case(PAC_TYPE_LOGON_INFO)] PAC_LOGON_INFO_CTR logon_info;
|
||||
[case(PAC_TYPE_SRV_CHECKSUM)] PAC_SIGNATURE_DATA srv_cksum;
|
||||
[case(PAC_TYPE_KDC_CHECKSUM)] PAC_SIGNATURE_DATA kdc_cksum;
|
||||
[case(PAC_TYPE_LOGON_NAME)] PAC_LOGON_NAME logon_name;
|
||||
[case(PAC_TYPE_UNKNOWN_12)] [subcontext(0)] DATA_BLOB_REM unknown;
|
||||
/* [case(PAC_TYPE_UNKNOWN_12)] PAC_UNKNOWN_12 unknown; */
|
||||
} PAC_INFO;
|
||||
|
||||
typedef [public,nopush,nopull,noprint] struct {
|
||||
@ -67,10 +87,6 @@ interface krb5pac
|
||||
PAC_BUFFER buffers[num_buffers];
|
||||
} PAC_DATA;
|
||||
|
||||
typedef struct {
|
||||
[flag(NDR_REMAINING)] DATA_BLOB remaining;
|
||||
} DATA_BLOB_REM;
|
||||
|
||||
typedef [public] struct {
|
||||
PAC_TYPE type;
|
||||
uint32 ndr_size;
|
||||
|
@ -23,6 +23,7 @@ interface opendb
|
||||
/* we need a per-entry delete on close, as well as a per-file
|
||||
one, to cope with strange semantics on open */
|
||||
boolean8 delete_on_close;
|
||||
boolean8 allow_level_II_oplock;
|
||||
uint32 oplock_level;
|
||||
} opendb_entry;
|
||||
|
||||
|
@ -98,11 +98,13 @@ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck,
|
||||
uint32_t stream_id, uint32_t share_access,
|
||||
uint32_t access_mask, bool delete_on_close,
|
||||
uint32_t open_disposition, bool break_to_none,
|
||||
bool allow_level_II_oplock,
|
||||
uint32_t oplock_level, uint32_t *oplock_granted)
|
||||
{
|
||||
return ops->odb_open_file(lck, file_handle, path, stream_id, share_access,
|
||||
access_mask, delete_on_close, open_disposition,
|
||||
break_to_none, oplock_level, oplock_granted);
|
||||
break_to_none, allow_level_II_oplock,
|
||||
oplock_level, oplock_granted);
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@ struct opendb_ops {
|
||||
uint32_t stream_id, uint32_t share_access,
|
||||
uint32_t access_mask, bool delete_on_close,
|
||||
uint32_t open_disposition, bool break_to_none,
|
||||
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,
|
||||
|
@ -344,7 +344,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
|
||||
break request and suspending this call
|
||||
until the break is acknowledged or the file
|
||||
is closed */
|
||||
if (break_to_none) {
|
||||
if (break_to_none ||
|
||||
!file->entries[i].allow_level_II_oplock) {
|
||||
oplock_return = OPLOCK_BREAK_TO_NONE;
|
||||
}
|
||||
odb_oplock_break_send(odb, &file->entries[i],
|
||||
@ -391,7 +392,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
|
||||
* send an oplock break to the holder of the
|
||||
* oplock and tell caller to retry later
|
||||
*/
|
||||
if (break_to_none) {
|
||||
if (break_to_none ||
|
||||
!file->entries[i].allow_level_II_oplock) {
|
||||
oplock_return = OPLOCK_BREAK_TO_NONE;
|
||||
}
|
||||
odb_oplock_break_send(odb, &file->entries[i],
|
||||
@ -418,6 +420,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
|
||||
uint32_t stream_id, uint32_t share_access,
|
||||
uint32_t access_mask, bool delete_on_close,
|
||||
uint32_t open_disposition, bool break_to_none,
|
||||
bool allow_level_II_oplock,
|
||||
uint32_t oplock_level, uint32_t *oplock_granted)
|
||||
{
|
||||
struct odb_context *odb = lck->odb;
|
||||
@ -447,13 +450,14 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
/* see if it conflicts */
|
||||
e.server = odb->ntvfs_ctx->server_id;
|
||||
e.file_handle = file_handle;
|
||||
e.stream_id = stream_id;
|
||||
e.share_access = share_access;
|
||||
e.access_mask = access_mask;
|
||||
e.delete_on_close = delete_on_close;
|
||||
e.oplock_level = OPLOCK_NONE;
|
||||
e.server = odb->ntvfs_ctx->server_id;
|
||||
e.file_handle = file_handle;
|
||||
e.stream_id = stream_id;
|
||||
e.share_access = share_access;
|
||||
e.access_mask = access_mask;
|
||||
e.delete_on_close = delete_on_close;
|
||||
e.allow_level_II_oplock = allow_level_II_oplock;
|
||||
e.oplock_level = OPLOCK_NONE;
|
||||
|
||||
/*
|
||||
possibly grant an exclusive, batch or level2 oplock
|
||||
@ -466,17 +470,23 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
|
||||
if (file.num_entries == 0) {
|
||||
e.oplock_level = OPLOCK_EXCLUSIVE;
|
||||
*oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
|
||||
} else {
|
||||
} else if (allow_level_II_oplock) {
|
||||
e.oplock_level = OPLOCK_LEVEL_II;
|
||||
*oplock_granted = LEVEL_II_OPLOCK_RETURN;
|
||||
} else {
|
||||
e.oplock_level = OPLOCK_NONE;
|
||||
*oplock_granted = NO_OPLOCK_RETURN;
|
||||
}
|
||||
} else if (oplock_level == OPLOCK_BATCH) {
|
||||
if (file.num_entries == 0) {
|
||||
e.oplock_level = OPLOCK_BATCH;
|
||||
*oplock_granted = BATCH_OPLOCK_RETURN;
|
||||
} else {
|
||||
} else if (allow_level_II_oplock) {
|
||||
e.oplock_level = OPLOCK_LEVEL_II;
|
||||
*oplock_granted = LEVEL_II_OPLOCK_RETURN;
|
||||
} else {
|
||||
e.oplock_level = OPLOCK_NONE;
|
||||
*oplock_granted = NO_OPLOCK_RETURN;
|
||||
}
|
||||
} else if (oplock_level == OPLOCK_LEVEL_II) {
|
||||
e.oplock_level = OPLOCK_LEVEL_II;
|
||||
|
@ -181,6 +181,14 @@ struct ntvfs_context {
|
||||
|
||||
enum protocol_types protocol;
|
||||
|
||||
/*
|
||||
* client capabilities
|
||||
* this field doesn't use protocol specific
|
||||
* values!
|
||||
*/
|
||||
#define NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS 0x0000000000000001LLU
|
||||
uint64_t client_caps;
|
||||
|
||||
/*
|
||||
* linked list of module contexts
|
||||
*/
|
||||
@ -257,6 +265,14 @@ struct ntvfs_request {
|
||||
/* the smb pid is needed for locking contexts */
|
||||
uint16_t smbpid;
|
||||
|
||||
/*
|
||||
* client capabilities
|
||||
* this field doesn't use protocol specific
|
||||
* values!
|
||||
* see NTVFS_CLIENT_CAP_*
|
||||
*/
|
||||
uint64_t client_caps;
|
||||
|
||||
/* some statictics for the management tools */
|
||||
struct {
|
||||
/* the system time when the request arrived */
|
||||
|
@ -153,6 +153,7 @@ _PUBLIC_ bool ntvfs_interface_differs(const struct ntvfs_critical_sizes *const i
|
||||
*/
|
||||
NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, enum ntvfs_type type,
|
||||
enum protocol_types protocol,
|
||||
uint64_t ntvfs_client_caps,
|
||||
struct event_context *ev, struct messaging_context *msg,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct server_id server_id, struct ntvfs_context **_ctx)
|
||||
@ -168,6 +169,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e
|
||||
ctx = talloc_zero(mem_ctx, struct ntvfs_context);
|
||||
NT_STATUS_HAVE_NO_MEMORY(ctx);
|
||||
ctx->protocol = protocol;
|
||||
ctx->client_caps = ntvfs_client_caps;
|
||||
ctx->type = type;
|
||||
ctx->config = talloc_steal(ctx, scfg);
|
||||
ctx->event_ctx = ev;
|
||||
|
@ -42,6 +42,7 @@ _PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, T
|
||||
req->async_states = NULL;
|
||||
req->session_info = session_info;
|
||||
req->smbpid = smbpid;
|
||||
req->client_caps = ctx->client_caps;
|
||||
req->statistics.request_time = request_time;
|
||||
|
||||
async = talloc(req, struct ntvfs_async_state);
|
||||
|
@ -293,7 +293,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
|
||||
status = odb_open_file(lck, f->handle, name->full_name, name->stream_id,
|
||||
share_access, access_mask, del_on_close,
|
||||
io->generic.in.open_disposition,
|
||||
false, OPLOCK_NONE, NULL);
|
||||
false, false, OPLOCK_NONE, NULL);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
talloc_free(lck);
|
||||
@ -347,7 +347,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
|
||||
status = odb_open_file(lck, f->handle, name->full_name, name->stream_id,
|
||||
share_access, access_mask, del_on_close,
|
||||
io->generic.in.open_disposition,
|
||||
false, OPLOCK_NONE, NULL);
|
||||
false, false, OPLOCK_NONE, NULL);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto cleanup_delete;
|
||||
@ -544,6 +544,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
|
||||
bool del_on_close;
|
||||
struct pvfs_filename *parent;
|
||||
uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
|
||||
bool allow_level_II_oplock = false;
|
||||
|
||||
if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) &&
|
||||
(create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
|
||||
@ -658,10 +659,15 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
|
||||
oplock_level = OPLOCK_EXCLUSIVE;
|
||||
}
|
||||
|
||||
if (req->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS) {
|
||||
allow_level_II_oplock = true;
|
||||
}
|
||||
|
||||
status = odb_open_file(lck, f->handle, name->full_name, name->stream_id,
|
||||
share_access, access_mask, del_on_close,
|
||||
io->generic.in.open_disposition,
|
||||
false, oplock_level, &oplock_granted);
|
||||
false, allow_level_II_oplock,
|
||||
oplock_level, &oplock_granted);
|
||||
talloc_free(lck);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
/* bad news, we must have hit a race - we don't delete the file
|
||||
@ -696,21 +702,20 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
|
||||
|
||||
DLIST_ADD(pvfs->files.list, f);
|
||||
|
||||
/* setup a destructor to avoid file descriptor leaks on
|
||||
abnormal termination */
|
||||
talloc_set_destructor(f, pvfs_fnum_destructor);
|
||||
talloc_set_destructor(f->handle, pvfs_handle_destructor);
|
||||
|
||||
if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
|
||||
oplock_granted = OPLOCK_BATCH;
|
||||
} else if (oplock_granted != OPLOCK_NONE) {
|
||||
status = pvfs_setup_oplock(f, oplock_granted);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
talloc_free(lck);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup a destructor to avoid file descriptor leaks on
|
||||
abnormal termination */
|
||||
talloc_set_destructor(f, pvfs_fnum_destructor);
|
||||
talloc_set_destructor(f->handle, pvfs_handle_destructor);
|
||||
|
||||
io->generic.out.oplock_level = oplock_granted;
|
||||
io->generic.out.file.ntvfs = f->ntvfs;
|
||||
io->generic.out.create_action = NTCREATEX_ACTION_CREATED;
|
||||
@ -1048,6 +1053,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
|
||||
bool del_on_close;
|
||||
bool stream_existed, stream_truncate=false;
|
||||
uint32_t oplock_level = OPLOCK_NONE, oplock_granted;
|
||||
bool allow_level_II_oplock = false;
|
||||
|
||||
/* use the generic mapping code to avoid implementing all the
|
||||
different open calls. */
|
||||
@ -1242,11 +1248,16 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
|
||||
oplock_level = OPLOCK_EXCLUSIVE;
|
||||
}
|
||||
|
||||
if (req->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS) {
|
||||
allow_level_II_oplock = true;
|
||||
}
|
||||
|
||||
/* see if we are allowed to open at the same time as existing opens */
|
||||
status = odb_open_file(lck, f->handle, name->full_name, name->stream_id,
|
||||
share_access, access_mask, del_on_close,
|
||||
io->generic.in.open_disposition,
|
||||
false, oplock_level, &oplock_granted);
|
||||
false, allow_level_II_oplock,
|
||||
oplock_level, &oplock_granted);
|
||||
|
||||
/*
|
||||
* on a sharing violation we need to retry when the file is closed by
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "includes.h"
|
||||
#include "lib/messaging/messaging.h"
|
||||
#include "lib/messaging/irpc.h"
|
||||
#include "system/time.h"
|
||||
#include "vfs_posix.h"
|
||||
|
||||
|
||||
@ -29,9 +30,63 @@ struct pvfs_oplock {
|
||||
struct pvfs_file_handle *handle;
|
||||
struct pvfs_file *file;
|
||||
uint32_t level;
|
||||
struct timeval break_to_level_II;
|
||||
struct timeval break_to_none;
|
||||
struct messaging_context *msg_ctx;
|
||||
};
|
||||
|
||||
static NTSTATUS pvfs_oplock_release_internal(struct pvfs_file_handle *h,
|
||||
uint8_t oplock_break)
|
||||
{
|
||||
struct odb_lock *olck;
|
||||
NTSTATUS status;
|
||||
|
||||
if (h->fd == -1) {
|
||||
return NT_STATUS_FILE_IS_A_DIRECTORY;
|
||||
}
|
||||
|
||||
if (!h->have_opendb_entry) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
if (!h->oplock) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
olck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
|
||||
if (olck == NULL) {
|
||||
DEBUG(0,("Unable to lock opendb for oplock update\n"));
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
if (oplock_break == OPLOCK_BREAK_TO_NONE) {
|
||||
h->oplock->level = OPLOCK_NONE;
|
||||
} else if (oplock_break == OPLOCK_BREAK_TO_LEVEL_II) {
|
||||
h->oplock->level = OPLOCK_LEVEL_II;
|
||||
} else {
|
||||
/* fallback to level II in case of a invalid value */
|
||||
DEBUG(1,("unexpected oplock break level[0x%02X]\n", oplock_break));
|
||||
h->oplock->level = OPLOCK_LEVEL_II;
|
||||
}
|
||||
status = odb_update_oplock(olck, h, h->oplock->level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("Unable to update oplock level for '%s' - %s\n",
|
||||
h->name->full_name, nt_errstr(status)));
|
||||
talloc_free(olck);
|
||||
return status;
|
||||
}
|
||||
|
||||
talloc_free(olck);
|
||||
|
||||
/* after a break to none, we no longer have an oplock attached */
|
||||
if (h->oplock->level == OPLOCK_NONE) {
|
||||
talloc_free(h->oplock);
|
||||
h->oplock = NULL;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
receive oplock breaks and forward them to the client
|
||||
*/
|
||||
@ -41,13 +96,65 @@ static void pvfs_oplock_break(struct pvfs_oplock *opl, uint8_t level)
|
||||
struct pvfs_file *f = opl->file;
|
||||
struct pvfs_file_handle *h = opl->handle;
|
||||
struct pvfs_state *pvfs = h->pvfs;
|
||||
struct timeval cur = timeval_current();
|
||||
struct timeval *last = NULL;
|
||||
struct timeval end;
|
||||
|
||||
DEBUG(10,("pvfs_oplock_break: sending oplock break level %d for '%s' %p\n",
|
||||
level, h->name->original_name, h));
|
||||
status = ntvfs_send_oplock_break(pvfs->ntvfs, f->ntvfs, level);
|
||||
switch (level) {
|
||||
case OPLOCK_BREAK_TO_LEVEL_II:
|
||||
last = &opl->break_to_level_II;
|
||||
break;
|
||||
case OPLOCK_BREAK_TO_NONE:
|
||||
last = &opl->break_to_none;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!last) {
|
||||
DEBUG(0,("%s: got unexpected level[0x%02X]\n",
|
||||
__FUNCTION__, level));
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeval_is_zero(last)) {
|
||||
/*
|
||||
* this is the first break we for this level
|
||||
* remember the time
|
||||
*/
|
||||
*last = cur;
|
||||
|
||||
DEBUG(0,("%s: sending oplock break level %d for '%s' %p\n",
|
||||
__FUNCTION__, level, h->name->original_name, h));
|
||||
status = ntvfs_send_oplock_break(pvfs->ntvfs, f->ntvfs, level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("%s: sending oplock break failed: %s\n",
|
||||
__FUNCTION__, nt_errstr(status)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
end = timeval_add(last, pvfs->oplock_break_timeout, 0);
|
||||
|
||||
if (timeval_compare(&cur, &end) < 0) {
|
||||
/*
|
||||
* If it's not expired just ignore the break
|
||||
* as we already sent the break request to the client
|
||||
*/
|
||||
DEBUG(0,("%s: do not resend oplock break level %d for '%s' %p\n",
|
||||
__FUNCTION__, level, h->name->original_name, h));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the client did not send a release within the
|
||||
* oplock break timeout time frame we auto release
|
||||
* the oplock
|
||||
*/
|
||||
DEBUG(0,("%s: auto release oplock level %d for '%s' %p\n",
|
||||
__FUNCTION__, level, h->name->original_name, h));
|
||||
status = pvfs_oplock_release_internal(h, level);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("pvfs_oplock_break: sending oplock break failed: %s\n",
|
||||
nt_errstr(status)));
|
||||
DEBUG(0,("%s: failed to auto release the oplock[0x%02X]: %s\n",
|
||||
__FUNCTION__, level, nt_errstr(status)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +220,7 @@ NTSTATUS pvfs_setup_oplock(struct pvfs_file *f, uint32_t oplock_granted)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
opl = talloc(f->handle, struct pvfs_oplock);
|
||||
opl = talloc_zero(f->handle, struct pvfs_oplock);
|
||||
NT_STATUS_HAVE_NO_MEMORY(opl);
|
||||
|
||||
opl->handle = f->handle;
|
||||
@ -140,8 +247,6 @@ NTSTATUS pvfs_oplock_release(struct ntvfs_module_context *ntvfs,
|
||||
{
|
||||
struct pvfs_state *pvfs = ntvfs->private_data;
|
||||
struct pvfs_file *f;
|
||||
struct pvfs_file_handle *h;
|
||||
struct odb_lock *olck;
|
||||
uint8_t oplock_break;
|
||||
NTSTATUS status;
|
||||
|
||||
@ -150,52 +255,15 @@ NTSTATUS pvfs_oplock_release(struct ntvfs_module_context *ntvfs,
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
h = f->handle;
|
||||
|
||||
if (h->fd == -1) {
|
||||
return NT_STATUS_FILE_IS_A_DIRECTORY;
|
||||
}
|
||||
|
||||
if (!h->have_opendb_entry) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
if (!h->oplock) {
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
olck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
|
||||
if (olck == NULL) {
|
||||
DEBUG(0,("Unable to lock opendb for oplock update\n"));
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
oplock_break = (lck->lockx.in.mode >> 8) & 0xFF;
|
||||
if (oplock_break == OPLOCK_BREAK_TO_NONE) {
|
||||
h->oplock->level = OPLOCK_NONE;
|
||||
} else if (oplock_break == OPLOCK_BREAK_TO_LEVEL_II) {
|
||||
h->oplock->level = OPLOCK_LEVEL_II;
|
||||
} else {
|
||||
/* fallback to level II in case of a invalid value */
|
||||
DEBUG(1,("unexpected oplock break level[0x%02X]\n", oplock_break));
|
||||
h->oplock->level = OPLOCK_LEVEL_II;
|
||||
}
|
||||
status = odb_update_oplock(olck, h, h->oplock->level);
|
||||
|
||||
status = pvfs_oplock_release_internal(f->handle, oplock_break);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("Unable to update oplock level for '%s' - %s\n",
|
||||
h->name->full_name, nt_errstr(status)));
|
||||
talloc_free(olck);
|
||||
DEBUG(0,("%s: failed to release the oplock[0x%02X]: %s\n",
|
||||
__FUNCTION__, oplock_break, nt_errstr(status)));
|
||||
return status;
|
||||
}
|
||||
|
||||
talloc_free(olck);
|
||||
|
||||
/* after a break to none, we no longer have an oplock attached */
|
||||
if (h->oplock->level == OPLOCK_NONE) {
|
||||
talloc_free(h->oplock);
|
||||
h->oplock = NULL;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -205,7 +273,7 @@ NTSTATUS pvfs_break_level2_oplocks(struct pvfs_file *f)
|
||||
struct odb_lock *olck;
|
||||
NTSTATUS status;
|
||||
|
||||
if (h->oplock && h->oplock->level == OPLOCK_EXCLUSIVE) {
|
||||
if (h->oplock && h->oplock->level != OPLOCK_LEVEL_II) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -215,16 +283,6 @@ NTSTATUS pvfs_break_level2_oplocks(struct pvfs_file *f)
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
if (h->oplock && h->oplock->level == OPLOCK_BATCH) {
|
||||
status = odb_update_oplock(olck, h, OPLOCK_LEVEL_II);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("Unable to update oplock level for '%s' - %s\n",
|
||||
h->name->full_name, nt_errstr(status)));
|
||||
talloc_free(olck);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = odb_break_oplocks(olck);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("Unable to break level2 oplocks to none for '%s' - %s\n",
|
||||
|
@ -316,7 +316,9 @@ static const struct enum_list enum_smb_signing_vals[] = {
|
||||
static const struct enum_list enum_server_role[] = {
|
||||
{ROLE_STANDALONE, "standalone"},
|
||||
{ROLE_DOMAIN_MEMBER, "member server"},
|
||||
{ROLE_DOMAIN_MEMBER, "member"},
|
||||
{ROLE_DOMAIN_CONTROLLER, "domain controller"},
|
||||
{ROLE_DOMAIN_CONTROLLER, "dc"},
|
||||
{-1, NULL}
|
||||
};
|
||||
|
||||
@ -2614,6 +2616,6 @@ void lp_smbcli_options(struct loadparm_context *lp_ctx,
|
||||
options->ntstatus_support = lp_nt_status_support(lp_ctx);
|
||||
options->max_protocol = lp_cli_maxprotocol(lp_ctx);
|
||||
options->unicode = lp_unicode(lp_ctx);
|
||||
options->use_oplocks = false;
|
||||
options->use_level2_oplocks = false;
|
||||
options->use_oplocks = true;
|
||||
options->use_level2_oplocks = true;
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call,
|
||||
/* init ntvfs function pointers */
|
||||
status = ntvfs_init_connection(c, scfg, type,
|
||||
PROTOCOL_NT1,
|
||||
0,/* ntvfs_client_caps */
|
||||
dce_call->event_ctx,
|
||||
dce_call->conn->msg_ctx,
|
||||
dce_call->conn->dce_ctx->lp_ctx,
|
||||
|
@ -33,4 +33,3 @@ rpc.netlogon.*.GetTrustPasswords
|
||||
base.charset.*.Testing partial surrogate
|
||||
.*net.api.delshare.* # DelShare isn't implemented yet
|
||||
rap.*netservergetinfo
|
||||
local.torture.provision
|
||||
|
@ -147,7 +147,12 @@ class Ldb(ldb.Ldb):
|
||||
k = 0
|
||||
while ++k < 10 and (previous_remaining != current_remaining):
|
||||
# and the rest
|
||||
res2 = self.search(basedn, ldb.SCOPE_SUBTREE, "(|(objectclass=*)(distinguishedName=*))", ["distinguishedName"])
|
||||
try:
|
||||
res2 = self.search(basedn, ldb.SCOPE_SUBTREE, "(|(objectclass=*)(distinguishedName=*))", ["distinguishedName"])
|
||||
except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _):
|
||||
# Ignore missing dn errors
|
||||
return
|
||||
|
||||
previous_remaining = current_remaining
|
||||
current_remaining = len(res2)
|
||||
for msg in res2:
|
||||
|
@ -32,6 +32,7 @@ from socket import gethostname, gethostbyname
|
||||
import param
|
||||
import registry
|
||||
import samba
|
||||
from auth import system_session
|
||||
from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
|
||||
from samba.samdb import SamDB
|
||||
import security
|
||||
@ -65,7 +66,14 @@ class ProvisionPaths:
|
||||
self.dns_keytab = None
|
||||
self.dns = None
|
||||
self.winsdb = None
|
||||
self.private_dir = None
|
||||
|
||||
class ProvisionResult:
|
||||
def __init__(self):
|
||||
self.paths = None
|
||||
self.domaindn = None
|
||||
self.lp = None
|
||||
self.samdb = None
|
||||
|
||||
def check_install(lp, session_info, credentials):
|
||||
"""Check whether the current install seems ok.
|
||||
@ -197,20 +205,20 @@ def provision_paths_from_lp(lp, dnsdomain):
|
||||
:param dnsdomain: DNS Domain name
|
||||
"""
|
||||
paths = ProvisionPaths()
|
||||
private_dir = lp.get("private dir")
|
||||
paths.private_dir = lp.get("private dir")
|
||||
paths.keytab = "secrets.keytab"
|
||||
paths.dns_keytab = "dns.keytab"
|
||||
|
||||
paths.shareconf = os.path.join(private_dir, "share.ldb")
|
||||
paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb")
|
||||
paths.idmapdb = os.path.join(private_dir, lp.get("idmap database") or "idmap.ldb")
|
||||
paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb")
|
||||
paths.templates = os.path.join(private_dir, "templates.ldb")
|
||||
paths.dns = os.path.join(private_dir, dnsdomain + ".zone")
|
||||
paths.winsdb = os.path.join(private_dir, "wins.ldb")
|
||||
paths.s4_ldapi_path = os.path.join(private_dir, "ldapi")
|
||||
paths.smbconf = os.path.join(private_dir, "smb.conf")
|
||||
paths.phpldapadminconfig = os.path.join(private_dir,
|
||||
paths.shareconf = os.path.join(paths.private_dir, "share.ldb")
|
||||
paths.samdb = os.path.join(paths.private_dir, lp.get("sam database") or "samdb.ldb")
|
||||
paths.idmapdb = os.path.join(paths.private_dir, lp.get("idmap database") or "idmap.ldb")
|
||||
paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb")
|
||||
paths.templates = os.path.join(paths.private_dir, "templates.ldb")
|
||||
paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone")
|
||||
paths.winsdb = os.path.join(paths.private_dir, "wins.ldb")
|
||||
paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi")
|
||||
paths.smbconf = os.path.join(paths.private_dir, "smb.conf")
|
||||
paths.phpldapadminconfig = os.path.join(paths.private_dir,
|
||||
"phpldapadmin-config.php")
|
||||
paths.hklm = "hklm.ldb"
|
||||
paths.hkcr = "hkcr.ldb"
|
||||
@ -341,12 +349,21 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
|
||||
|
||||
if ldap_backend_type == "fedora-ds":
|
||||
backend_modules = ["nsuniqueid", "paged_searches"]
|
||||
# We can handle linked attributes here, as we don't have directory-side subtree operations
|
||||
tdb_modules_list = ["linked_attributes"]
|
||||
elif ldap_backend_type == "openldap":
|
||||
backend_modules = ["normalise", "entryuuid", "paged_searches"]
|
||||
# OpenLDAP handles subtree renames, so we don't want to do any of these things
|
||||
tdb_modules_list = None
|
||||
elif serverrole == "domain controller":
|
||||
backend_modules = ["repl_meta_data"]
|
||||
else:
|
||||
backend_modules = ["objectguid"]
|
||||
|
||||
if tdb_modules_list is None:
|
||||
tdb_modules_list_as_string = ""
|
||||
else:
|
||||
tdb_modules_list_as_string = ","+",".join(tdb_modules_list)
|
||||
|
||||
samdb.transaction_start()
|
||||
try:
|
||||
@ -362,7 +379,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
|
||||
"CONFIGDN_MOD": "naming_fsmo,instancetype",
|
||||
"DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype",
|
||||
"MODULES_LIST": ",".join(modules_list),
|
||||
"TDB_MODULES_LIST": ","+",".join(tdb_modules_list),
|
||||
"TDB_MODULES_LIST": tdb_modules_list_as_string,
|
||||
"MODULES_LIST2": ",".join(modules_list2),
|
||||
"BACKEND_MOD": ",".join(backend_modules),
|
||||
})
|
||||
@ -561,9 +578,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
|
||||
:note: This will wipe the main SAM database file!
|
||||
"""
|
||||
|
||||
assert serverrole in ("domain controller", "member server")
|
||||
|
||||
erase = (fill != FILL_DRS)
|
||||
erase = (fill != FILL_DRS)
|
||||
|
||||
# Also wipes the database
|
||||
setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn,
|
||||
@ -588,7 +603,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
|
||||
samdb = SamDB(path, session_info=session_info,
|
||||
credentials=credentials, lp=lp)
|
||||
samdb.set_domain_sid(domainsid)
|
||||
if lp.get("server role") == "domain controller":
|
||||
if serverrole == "domain controller":
|
||||
samdb.set_invocation_id(invocationid)
|
||||
|
||||
load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename)
|
||||
@ -699,7 +714,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
|
||||
"KRBTGTPASS_B64": b64encode(krbtgtpass),
|
||||
})
|
||||
|
||||
if lp.get("server role") == "domain controller":
|
||||
if serverrole == "domain controller":
|
||||
message("Setting up self join")
|
||||
setup_self_join(samdb, configdn=configdn, schemadn=schemadn,
|
||||
domaindn=domaindn, invocationid=invocationid,
|
||||
@ -725,13 +740,14 @@ FILL_FULL = "FULL"
|
||||
FILL_NT4SYNC = "NT4SYNC"
|
||||
FILL_DRS = "DRS"
|
||||
|
||||
def provision(lp, setup_dir, message, paths, session_info,
|
||||
credentials, samdb_fill=FILL_FULL, realm=None, rootdn=None,
|
||||
def provision(setup_dir, message, session_info,
|
||||
credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None,
|
||||
rootdn=None, domaindn=None, schemadn=None, configdn=None,
|
||||
domain=None, hostname=None, hostip=None, domainsid=None,
|
||||
hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None,
|
||||
policyguid=None, invocationid=None, machinepass=None,
|
||||
dnspass=None, root=None, nobody=None, nogroup=None, users=None,
|
||||
wheel=None, backup=None, aci=None, serverrole=None,
|
||||
wheel=None, backup=None, aci=None, serverrole=None,
|
||||
ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE):
|
||||
"""Provision samba4
|
||||
|
||||
@ -768,28 +784,6 @@ def provision(lp, setup_dir, message, paths, session_info,
|
||||
backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0]
|
||||
if aci is None:
|
||||
aci = "# no aci for local ldb"
|
||||
if serverrole is None:
|
||||
serverrole = lp.get("server role")
|
||||
assert serverrole in ("domain controller", "member server")
|
||||
if invocationid is None and serverrole == "domain controller":
|
||||
invocationid = uuid.random()
|
||||
|
||||
if realm is None:
|
||||
realm = lp.get("realm")
|
||||
|
||||
if lp.get("realm").upper() != realm.upper():
|
||||
raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" %
|
||||
(lp.get("realm"), realm))
|
||||
|
||||
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
|
||||
|
||||
if ldap_backend == "ldapi":
|
||||
# provision-backend will set this path suggested slapd command line / fedorads.inf
|
||||
ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="")
|
||||
|
||||
assert realm is not None
|
||||
realm = realm.upper()
|
||||
|
||||
if hostname is None:
|
||||
hostname = gethostname().split(".")[0].lower()
|
||||
|
||||
@ -800,9 +794,93 @@ def provision(lp, setup_dir, message, paths, session_info,
|
||||
if not valid_netbios_name(netbiosname):
|
||||
raise InvalidNetbiosName(netbiosname)
|
||||
|
||||
if targetdir is not None:
|
||||
if not os.path.exists(targetdir):
|
||||
os.mkdir(targetdir)
|
||||
if not os.path.exists(os.path.join(targetdir, "etc")):
|
||||
os.mkdir(os.path.join(targetdir, "etc"))
|
||||
|
||||
smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf"))
|
||||
|
||||
# only install a new smb.conf if there isn't one there already
|
||||
|
||||
if not os.path.exists(smbconf):
|
||||
message("Setting up smb.conf")
|
||||
if serverrole is None:
|
||||
serverrole = "standalone"
|
||||
|
||||
assert serverrole in ("domain controller", "member server", "standalone")
|
||||
if serverrole == "domain controller":
|
||||
smbconfsuffix = "dc"
|
||||
elif serverrole == "member server":
|
||||
smbconfsuffix = "member"
|
||||
elif serverrole == "standalone":
|
||||
smbconfsuffix = "standalone"
|
||||
|
||||
assert domain is not None
|
||||
assert realm is not None
|
||||
|
||||
default_lp = param.LoadParm()
|
||||
#Load non-existant file
|
||||
default_lp.load(smbconf)
|
||||
|
||||
if targetdir is not None:
|
||||
privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private"))
|
||||
lockdir_line = "lock dir = " + os.path.abspath(targetdir)
|
||||
|
||||
default_lp.set("lock dir", os.path.abspath(targetdir))
|
||||
|
||||
sysvol = os.path.join(default_lp.get("lock dir"), "sysvol")
|
||||
netlogon = os.path.join(os.path.join(sysvol, "scripts"))
|
||||
|
||||
setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix),
|
||||
smbconf, {
|
||||
"HOSTNAME": hostname,
|
||||
"DOMAIN": domain,
|
||||
"REALM": realm,
|
||||
"SERVERROLE": serverrole,
|
||||
"NETLOGONPATH": netlogon,
|
||||
"SYSVOLPATH": sysvol,
|
||||
"PRIVATEDIR_LINE": privatedir_line,
|
||||
"LOCKDIR_LINE": lockdir_line
|
||||
})
|
||||
|
||||
lp = param.LoadParm()
|
||||
lp.load(smbconf)
|
||||
|
||||
if serverrole is None:
|
||||
serverrole = lp.get("server role")
|
||||
assert serverrole in ("domain controller", "member server", "standalone")
|
||||
if invocationid is None and serverrole == "domain controller":
|
||||
invocationid = uuid.random()
|
||||
|
||||
if realm is None:
|
||||
realm = lp.get("realm")
|
||||
|
||||
assert realm is not None
|
||||
realm = realm.upper()
|
||||
|
||||
if lp.get("realm").upper() != realm.upper():
|
||||
raise Exception("realm '%s' in %s must match chosen realm '%s'" %
|
||||
(lp.get("realm"), smbconf, realm))
|
||||
|
||||
dnsdomain = realm.lower()
|
||||
|
||||
paths = provision_paths_from_lp(lp, dnsdomain)
|
||||
|
||||
if targetdir is not None:
|
||||
if not os.path.exists(paths.private_dir):
|
||||
os.mkdir(paths.private_dir)
|
||||
|
||||
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
|
||||
|
||||
if ldap_backend == "ldapi":
|
||||
# provision-backend will set this path suggested slapd command line / fedorads.inf
|
||||
ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="")
|
||||
|
||||
if serverrole == "domain controller":
|
||||
domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
|
||||
if domaindn is None:
|
||||
domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
|
||||
if domain is None:
|
||||
domain = lp.get("workgroup")
|
||||
|
||||
@ -815,39 +893,22 @@ def provision(lp, setup_dir, message, paths, session_info,
|
||||
if not valid_netbios_name(domain):
|
||||
raise InvalidNetbiosName(domain)
|
||||
else:
|
||||
domaindn = "CN=" + netbiosname
|
||||
if domaindn is None:
|
||||
domaindn = "CN=" + netbiosname
|
||||
domain = netbiosname
|
||||
|
||||
if rootdn is None:
|
||||
rootdn = domaindn
|
||||
|
||||
configdn = "CN=Configuration," + rootdn
|
||||
schemadn = "CN=Schema," + configdn
|
||||
if configdn is None:
|
||||
configdn = "CN=Configuration," + rootdn
|
||||
if schemadn is None:
|
||||
schemadn = "CN=Schema," + configdn
|
||||
|
||||
message("set DOMAIN SID: %s" % str(domainsid))
|
||||
message("Provisioning for %s in realm %s" % (domain, realm))
|
||||
message("Using administrator password: %s" % adminpass)
|
||||
|
||||
assert paths.smbconf is not None
|
||||
|
||||
# only install a new smb.conf if there isn't one there already
|
||||
if not os.path.exists(paths.smbconf):
|
||||
message("Setting up smb.conf")
|
||||
if serverrole == "domain controller":
|
||||
smbconfsuffix = "dc"
|
||||
elif serverrole == "member server":
|
||||
smbconfsuffix = "member"
|
||||
setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix),
|
||||
paths.smbconf, {
|
||||
"HOSTNAME": hostname,
|
||||
"DOMAIN_CONF": domain,
|
||||
"REALM_CONF": realm,
|
||||
"SERVERROLE": serverrole,
|
||||
"NETLOGONPATH": paths.netlogon,
|
||||
"SYSVOLPATH": paths.sysvol,
|
||||
})
|
||||
lp.load(paths.smbconf)
|
||||
|
||||
# only install a new shares config db if there is none
|
||||
if not os.path.exists(paths.shareconf):
|
||||
message("Setting up share.ldb")
|
||||
@ -911,32 +972,57 @@ def provision(lp, setup_dir, message, paths, session_info,
|
||||
message("Setting up sam.ldb rootDSE marking as synchronized")
|
||||
setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
|
||||
|
||||
# Only make a zone file on the first DC, it should be replicated with DNS replication
|
||||
if serverrole == "domain controller":
|
||||
samdb = SamDB(paths.samdb, session_info=session_info,
|
||||
credentials=credentials, lp=lp)
|
||||
|
||||
domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")
|
||||
assert isinstance(domainguid, str)
|
||||
hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID",
|
||||
expression="(&(objectClass=computer)(cn=%s))" % hostname,
|
||||
scope=SCOPE_SUBTREE)
|
||||
assert isinstance(hostguid, str)
|
||||
|
||||
message("Setting up DNS zone: %s" % dnsdomain)
|
||||
create_zone_file(paths.dns, setup_path, samdb,
|
||||
hostname=hostname, hostip=hostip, dnsdomain=dnsdomain,
|
||||
domaindn=domaindn, dnspass=dnspass, realm=realm,
|
||||
domainguid=domainguid, hostguid=hostguid)
|
||||
message("Please install the zone located in %s into your DNS server" % paths.dns)
|
||||
|
||||
message("Setting up phpLDAPadmin configuration")
|
||||
create_phpldapadmin_config(paths.phpldapadminconfig, setup_path,
|
||||
ldapi_url)
|
||||
|
||||
message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig)
|
||||
|
||||
if lp.get("server role") == "domain controller":
|
||||
samdb = SamDB(paths.samdb, session_info=session_info,
|
||||
credentials=credentials, lp=lp)
|
||||
result = ProvisionResult()
|
||||
result.domaindn = domaindn
|
||||
result.paths = paths
|
||||
result.lp = lp
|
||||
result.samdb = samdb
|
||||
return result
|
||||
|
||||
domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")
|
||||
assert isinstance(domainguid, str)
|
||||
hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID",
|
||||
expression="(&(objectClass=computer)(cn=%s))" % hostname,
|
||||
scope=SCOPE_SUBTREE)
|
||||
assert isinstance(hostguid, str)
|
||||
def provision_become_dc(setup_dir=None,
|
||||
smbconf=None, targetdir=None, realm=None,
|
||||
rootdn=None, domaindn=None, schemadn=None, configdn=None,
|
||||
domain=None, hostname=None, domainsid=None,
|
||||
hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None,
|
||||
policyguid=None, invocationid=None, machinepass=None,
|
||||
dnspass=None, root=None, nobody=None, nogroup=None, users=None,
|
||||
wheel=None, backup=None, aci=None, serverrole=None,
|
||||
ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE):
|
||||
|
||||
message("Setting up DNS zone: %s" % dnsdomain)
|
||||
create_zone_file(paths.dns, setup_path, samdb,
|
||||
hostname=hostname, hostip=hostip, dnsdomain=dnsdomain,
|
||||
domaindn=domaindn, dnspass=dnspass, realm=realm,
|
||||
domainguid=domainguid, hostguid=hostguid)
|
||||
message("Please install the zone located in %s into your DNS server" % paths.dns)
|
||||
|
||||
return domaindn
|
||||
def message(text):
|
||||
"""print a message if quiet is not set."""
|
||||
print text
|
||||
|
||||
provision(setup_dir, message, system_session(), None,
|
||||
smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm,
|
||||
rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn,
|
||||
domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename);
|
||||
|
||||
|
||||
def create_phpldapadmin_config(path, setup_path, ldapi_uri):
|
||||
"""Create a PHP LDAP admin configuration file.
|
||||
@ -978,7 +1064,6 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,
|
||||
"HOSTGUID": hostguid,
|
||||
})
|
||||
|
||||
|
||||
def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename):
|
||||
"""Load schema for the SamDB.
|
||||
|
||||
|
@ -207,7 +207,7 @@ def import_wins(samba4_winsdb, samba3_winsdb):
|
||||
"objectClass": "winsMaxVersion",
|
||||
"maxVersion": str(version_id)})
|
||||
|
||||
def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, paths):
|
||||
def upgrade_provision(samba3, setup_dir, message, credentials, session_info, smbconf, targetdir):
|
||||
oldconf = samba3.get_conf()
|
||||
|
||||
if oldconf.get("domain logons") == "True":
|
||||
@ -218,11 +218,9 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp,
|
||||
else:
|
||||
serverrole = "member server"
|
||||
|
||||
lp.set("server role", serverrole)
|
||||
domainname = oldconf.get("workgroup")
|
||||
if domainname:
|
||||
domainname = str(domainname)
|
||||
lp.set("workgroup", domainname)
|
||||
realm = oldconf.get("realm")
|
||||
netbiosname = oldconf.get("netbios name")
|
||||
|
||||
@ -235,7 +233,6 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp,
|
||||
if realm is None:
|
||||
realm = domainname.lower()
|
||||
message("No realm specified in smb.conf file, assuming '%s'\n" % realm)
|
||||
lp.set("realm", realm)
|
||||
|
||||
domainguid = secrets_db.get_domain_guid(domainname)
|
||||
domainsid = secrets_db.get_sid(domainname)
|
||||
@ -247,15 +244,13 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp,
|
||||
else:
|
||||
machinepass = None
|
||||
|
||||
domaindn = provision(lp=lp, setup_dir=setup_dir, message=message,
|
||||
samdb_fill=FILL_DRS, paths=paths, session_info=session_info,
|
||||
credentials=credentials, realm=realm,
|
||||
domain=domainname, domainsid=domainsid, domainguid=domainguid,
|
||||
machinepass=machinepass, serverrole=serverrole)
|
||||
result = provision(setup_dir=setup_dir, message=message,
|
||||
samdb_fill=FILL_DRS, smbconf=smbconf, session_info=session_info,
|
||||
credentials=credentials, realm=realm,
|
||||
domain=domainname, domainsid=domainsid, domainguid=domainguid,
|
||||
machinepass=machinepass, serverrole=serverrole, targetdir=targetdir)
|
||||
|
||||
samdb = SamDB(paths.samdb, credentials=credentials, lp=lp, session_info=session_info)
|
||||
|
||||
import_wins(Ldb(paths.winsdb), samba3.get_wins_db())
|
||||
import_wins(Ldb(result.paths.winsdb), samba3.get_wins_db())
|
||||
|
||||
# FIXME: import_registry(registry.Registry(), samba3.get_registry())
|
||||
|
||||
@ -271,12 +266,12 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp,
|
||||
passdb = samba3.get_sam_db()
|
||||
for name in passdb:
|
||||
user = passdb[name]
|
||||
#FIXME: import_sam_account(samdb, user, domaindn, domainsid)
|
||||
#FIXME: import_sam_account(result.samdb, user, domaindn, domainsid)
|
||||
|
||||
if hasattr(passdb, 'ldap_url'):
|
||||
message("Enabling Samba3 LDAP mappings for SAM database")
|
||||
|
||||
enable_samba3sam(samdb, passdb.ldap_url)
|
||||
enable_samba3sam(result.samdb, passdb.ldap_url)
|
||||
|
||||
|
||||
def enable_samba3sam(samdb, ldapurl):
|
||||
|
@ -217,7 +217,7 @@ 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"
|
||||
NTVFSARGS="--option=torture:sharedelay=100000 --option=torture:oplocktimeout=3"
|
||||
smb2=`$smb4torture --list | grep "^SMB2-" | xargs`
|
||||
raw=`$smb4torture --list | grep "^RAW-" | xargs`
|
||||
base=`$smb4torture --list | grep "^BASE-" | xargs`
|
||||
|
@ -30,9 +30,7 @@ import samba
|
||||
|
||||
from auth import system_session
|
||||
import samba.getopt as options
|
||||
import param
|
||||
from samba.provision import (provision,
|
||||
provision_paths_from_lp,
|
||||
FILL_FULL, FILL_NT4SYNC,
|
||||
FILL_DRS)
|
||||
|
||||
@ -90,7 +88,7 @@ parser.add_option("--ldap-backend-type", type="choice", metavar="LDAP-BACKEND-TY
|
||||
parser.add_option("--aci", type="string", metavar="ACI",
|
||||
help="An arbitary LDIF fragment, particularly useful to loading a backend ACI value into a target LDAP server. You must provide at least a realm and domain")
|
||||
parser.add_option("--server-role", type="choice", metavar="ROLE",
|
||||
choices=["domain controller", "member server"],
|
||||
choices=["domain controller", "dc", "member server", "member", "standalone"],
|
||||
help="Set server role to provision for (default standalone)")
|
||||
parser.add_option("--partitions-only",
|
||||
help="Configure Samba's partitions, but do not modify them (ie, join a BDC)", action="store_true")
|
||||
@ -112,27 +110,17 @@ if opts.realm is None or opts.domain is None:
|
||||
parser.print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
# cope with an initially blank smb.conf
|
||||
private_dir = None
|
||||
lp = sambaopts.get_loadparm()
|
||||
if opts.targetdir is not None:
|
||||
if not os.path.exists(opts.targetdir):
|
||||
os.mkdir(opts.targetdir)
|
||||
private_dir = os.path.join(opts.targetdir, "private")
|
||||
if not os.path.exists(private_dir):
|
||||
os.mkdir(private_dir)
|
||||
lp.set("private dir", os.path.abspath(private_dir))
|
||||
lp.set("lock dir", os.path.abspath(opts.targetdir))
|
||||
lp.set("realm", opts.realm)
|
||||
lp.set("workgroup", opts.domain)
|
||||
lp.set("server role", opts.server_role or "domain controller")
|
||||
smbconf = sambaopts.get_loadparm_path()
|
||||
|
||||
if opts.aci is not None:
|
||||
print "set ACI: %s" % opts.aci
|
||||
|
||||
paths = provision_paths_from_lp(lp, opts.realm.lower())
|
||||
if sambaopts.get_loadparm_path() is not None:
|
||||
paths.smbconf = sambaopts.get_loadparm_path()
|
||||
if opts.server_role == "dc":
|
||||
server_role = "domain controller"
|
||||
elif opts.server_role == "member":
|
||||
server_role = "member server"
|
||||
else:
|
||||
server_role = opts.server_role
|
||||
|
||||
creds = credopts.get_credentials()
|
||||
|
||||
@ -146,9 +134,9 @@ if opts.blank:
|
||||
elif opts.partitions_only:
|
||||
samdb_fill = FILL_DRS
|
||||
|
||||
provision(lp, setup_dir, message, paths,
|
||||
system_session(), creds,
|
||||
samdb_fill=samdb_fill, realm=opts.realm,
|
||||
provision(setup_dir, message,
|
||||
system_session(), creds, smbconf=smbconf, targetdir=opts.targetdir,
|
||||
samdb_fill=samdb_fill, realm=opts.realm, domain=opts.domain,
|
||||
domainguid=opts.domain_guid, domainsid=opts.domain_sid,
|
||||
policyguid=opts.policy_guid, hostname=opts.host_name,
|
||||
hostip=opts.host_ip, hostguid=opts.host_guid,
|
||||
@ -156,7 +144,7 @@ provision(lp, setup_dir, message, paths,
|
||||
krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass,
|
||||
dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody,
|
||||
nogroup=opts.nogroup, wheel=opts.wheel, users=opts.users,
|
||||
aci=opts.aci, serverrole=opts.server_role,
|
||||
aci=opts.aci, serverrole=server_role,
|
||||
ldap_backend=opts.ldap_backend,
|
||||
ldap_backend_type=opts.ldap_backend_type)
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
[globals]
|
||||
netbios name = ${HOSTNAME}
|
||||
workgroup = ${DOMAIN_CONF}
|
||||
realm = ${REALM_CONF}
|
||||
workgroup = ${DOMAIN}
|
||||
realm = ${REALM}
|
||||
server role = ${SERVERROLE}
|
||||
${PRIVATEDIR_LINE}
|
||||
${LOCKDIR_LINE}
|
||||
|
||||
[netlogon]
|
||||
path = ${NETLOGONPATH}
|
||||
|
@ -1,5 +1,7 @@
|
||||
[globals]
|
||||
netbios name = ${HOSTNAME}
|
||||
workgroup = ${DOMAIN_CONF}
|
||||
realm = ${REALM_CONF}
|
||||
workgroup = ${DOMAIN}
|
||||
realm = ${REALM}
|
||||
server role = ${SERVERROLE}
|
||||
${PRIVATEDIR_LINE}
|
||||
${LOCKDIR_LINE}
|
||||
|
@ -1,5 +1,7 @@
|
||||
[globals]
|
||||
netbios name = ${HOSTNAME}
|
||||
workgroup = ${DOMAIN_CONF}
|
||||
realm = ${REALM_CONF}
|
||||
workgroup = ${DOMAIN}
|
||||
realm = ${REALM}
|
||||
server role = ${SERVERROLE}
|
||||
${PRIVATEDIR_LINE}
|
||||
${LOCKDIR_LINE}
|
||||
|
@ -27,7 +27,7 @@ lastLogoff: 0
|
||||
lastLogon: 0
|
||||
pwdLastSet: 0
|
||||
primaryGroupID: 513
|
||||
accountExpires: -1
|
||||
accountExpires: 9223372036854775807
|
||||
logonCount: 0
|
||||
|
||||
dn: CN=TemplateTrustingDomain,CN=Templates
|
||||
@ -39,7 +39,7 @@ badPasswordTime: 0
|
||||
lastLogoff: 0
|
||||
lastLogon: 0
|
||||
primaryGroupID: 513
|
||||
accountExpires: -1
|
||||
accountExpires: 9223372036854775807
|
||||
logonCount: 0
|
||||
|
||||
dn: CN=TemplateGroup,CN=Templates
|
||||
|
@ -5,7 +5,7 @@ description: Built-in account for administering the computer/domain
|
||||
userAccountControl: 66048
|
||||
objectSid: ${DOMAINSID}-500
|
||||
adminCount: 1
|
||||
accountExpires: -1
|
||||
accountExpires: 9223372036854775807
|
||||
sAMAccountName: Administrator
|
||||
isCriticalSystemObject: TRUE
|
||||
sambaPassword:: ${ADMINPASS_B64}
|
||||
|
@ -27,7 +27,10 @@ testit() {
|
||||
return $status
|
||||
}
|
||||
|
||||
testit "simple" $PYTHON ./setup/provision $CONFIGURATION --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple
|
||||
testit "simple-default" $PYTHON ./setup/provision $CONFIGURATION --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-default
|
||||
testit "simple-dc" $PYTHON ./setup/provision $CONFIGURATION --server-role="dc" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-dc
|
||||
testit "simple-member" $PYTHON ./setup/provision $CONFIGURATION --server-role="member" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-member
|
||||
testit "simple-standalone" $PYTHON ./setup/provision $CONFIGURATION --server-role="standalone" --domain=FOO --realm=foo.example.com --targetdir=$PREFIX/simple-standalone
|
||||
|
||||
reprovision() {
|
||||
$PYTHON ./setup/provision $CONFIGURATION --domain=FOO --realm=foo.example.com --targetdir="$PREFIX/reprovision"
|
||||
|
@ -50,7 +50,6 @@ else:
|
||||
samba3 = Samba3(libdir, smbconf)
|
||||
|
||||
from samba.upgrade import upgrade_provision
|
||||
from samba.provision import provision_paths_from_lp
|
||||
|
||||
message("Provisioning\n")
|
||||
|
||||
@ -59,13 +58,6 @@ if setup_dir is None:
|
||||
setup_dir = "setup"
|
||||
|
||||
creds = credopts.get_credentials()
|
||||
lp = sambaopts.get_loadparm()
|
||||
if opts.targetdir is not None:
|
||||
if not os.path.exists(opts.targetdir):
|
||||
os.mkdir(opts.targetdir)
|
||||
lp.set("private dir", os.path.abspath(opts.targetdir))
|
||||
lp.set("lock dir", os.path.abspath(opts.targetdir))
|
||||
paths = provision_paths_from_lp(lp, "")
|
||||
paths.smbconf = sambaopts.get_loadparm_path()
|
||||
|
||||
upgrade_provision(samba3, setup_dir, message, credentials=creds, session_info=system_session(),
|
||||
lp=lp, paths=paths)
|
||||
smbconf=sambaopts.get_loadparm_path(), targetdir=opts.targetdir)
|
||||
|
@ -460,7 +460,7 @@ static NTSTATUS nttrans_backend(struct smbsrv_request *req,
|
||||
static void reply_nttrans_send(struct ntvfs_request *ntvfs)
|
||||
{
|
||||
struct smbsrv_request *req;
|
||||
uint16_t params_left, data_left;
|
||||
uint32_t params_left, data_left;
|
||||
uint8_t *params, *data;
|
||||
struct smb_nttrans *trans;
|
||||
struct nttrans_op *op;
|
||||
@ -502,7 +502,7 @@ static void reply_nttrans_send(struct ntvfs_request *ntvfs)
|
||||
/* we need to divide up the reply into chunks that fit into
|
||||
the negotiated buffer size */
|
||||
do {
|
||||
uint16_t this_data, this_param, max_bytes;
|
||||
uint32_t this_data, this_param, max_bytes;
|
||||
uint_t align1 = 1, align2 = (params_left ? 2 : 0);
|
||||
struct smbsrv_request *this_req;
|
||||
|
||||
@ -573,9 +573,9 @@ void smbsrv_reply_nttrans(struct smbsrv_request *req)
|
||||
{
|
||||
struct nttrans_op *op;
|
||||
struct smb_nttrans *trans;
|
||||
uint16_t param_ofs, data_ofs;
|
||||
uint16_t param_count, data_count;
|
||||
uint16_t param_total, data_total;
|
||||
uint32_t param_ofs, data_ofs;
|
||||
uint32_t param_count, data_count;
|
||||
uint32_t param_total, data_total;
|
||||
|
||||
/* parse request */
|
||||
if (req->in.wct < 19) {
|
||||
|
@ -36,6 +36,7 @@ static NTSTATUS make_connection_scfg(struct smbsrv_request *req,
|
||||
{
|
||||
struct smbsrv_tcon *tcon;
|
||||
NTSTATUS status;
|
||||
uint64_t ntvfs_caps = 0;
|
||||
|
||||
tcon = smbsrv_smb_tcon_new(req->smb_conn, scfg->name);
|
||||
if (!tcon) {
|
||||
@ -44,9 +45,14 @@ static NTSTATUS make_connection_scfg(struct smbsrv_request *req,
|
||||
}
|
||||
req->tcon = tcon;
|
||||
|
||||
if (req->smb_conn->negotiate.client_caps & CAP_LEVEL_II_OPLOCKS) {
|
||||
ntvfs_caps |= NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS;
|
||||
}
|
||||
|
||||
/* init ntvfs function pointers */
|
||||
status = ntvfs_init_connection(tcon, scfg, type,
|
||||
req->smb_conn->negotiate.protocol,
|
||||
ntvfs_caps,
|
||||
req->smb_conn->connection->event.ctx,
|
||||
req->smb_conn->connection->msg_ctx,
|
||||
req->smb_conn->lp_ctx,
|
||||
|
@ -245,6 +245,7 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon
|
||||
const char *service = io->smb2.in.path;
|
||||
struct share_config *scfg;
|
||||
const char *sharetype;
|
||||
uint64_t ntvfs_caps = 0;
|
||||
|
||||
if (strncmp(service, "\\\\", 2) == 0) {
|
||||
const char *p = strchr(service+2, '\\');
|
||||
@ -283,9 +284,12 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon
|
||||
}
|
||||
req->tcon = tcon;
|
||||
|
||||
ntvfs_caps = NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS;
|
||||
|
||||
/* init ntvfs function pointers */
|
||||
status = ntvfs_init_connection(tcon, scfg, type,
|
||||
req->smb_conn->negotiate.protocol,
|
||||
ntvfs_caps,
|
||||
req->smb_conn->connection->event.ctx,
|
||||
req->smb_conn->connection->msg_ctx,
|
||||
req->smb_conn->lp_ctx,
|
||||
|
@ -56,16 +56,9 @@ struct test_become_dc_state {
|
||||
struct drsuapi_DsReplicaObjectListItemEx *last_object;
|
||||
} schema_part;
|
||||
|
||||
struct {
|
||||
const char *samdb_ldb;
|
||||
const char *domaindn_ldb;
|
||||
const char *configdn_ldb;
|
||||
const char *schemadn_ldb;
|
||||
const char *secrets_ldb;
|
||||
const char *templates_ldb;
|
||||
const char *secrets_keytab;
|
||||
const char *dns_keytab;
|
||||
} path;
|
||||
const char *targetdir;
|
||||
|
||||
struct loadparm_context *lp_ctx;
|
||||
};
|
||||
|
||||
static NTSTATUS test_become_dc_prepare_db(void *private_data,
|
||||
@ -73,6 +66,14 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
|
||||
{
|
||||
struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
|
||||
struct provision_settings settings;
|
||||
NTSTATUS status;
|
||||
bool ok;
|
||||
struct loadparm_context *lp_ctx = loadparm_init(s);
|
||||
char *smbconf;
|
||||
|
||||
if (!lp_ctx) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
settings.dns_name = p->dest_dsa->dns_name;
|
||||
settings.site_name = p->dest_dsa->site_name;
|
||||
@ -80,21 +81,46 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
|
||||
settings.domain_dn_str = p->domain->dn_str;
|
||||
settings.config_dn_str = p->forest->config_dn_str;
|
||||
settings.schema_dn_str = p->forest->schema_dn_str;
|
||||
settings.invocation_id = &p->dest_dsa->invocation_id;
|
||||
settings.netbios_name = p->dest_dsa->netbios_name;
|
||||
settings.realm = torture_join_dom_dns_name(s->tj);
|
||||
settings.domain = torture_join_dom_netbios_name(s->tj);
|
||||
settings.ntds_guid = &p->dest_dsa->ntds_guid;
|
||||
settings.ntds_dn_str = p->dest_dsa->ntds_dn_str;
|
||||
settings.machine_password = cli_credentials_get_password(s->machine_account);
|
||||
settings.samdb_ldb = s->path.samdb_ldb;
|
||||
settings.secrets_ldb = s->path.secrets_ldb;
|
||||
settings.secrets_keytab = s->path.secrets_keytab;
|
||||
settings.schemadn_ldb = s->path.schemadn_ldb;
|
||||
settings.configdn_ldb = s->path.configdn_ldb;
|
||||
settings.domaindn_ldb = s->path.domaindn_ldb;
|
||||
settings.targetdir = s->targetdir;
|
||||
|
||||
status = provision_bare(s, s->lp_ctx, &settings);
|
||||
|
||||
smbconf = talloc_asprintf(lp_ctx, "%s/%s", s->targetdir, "/etc/smb.conf");
|
||||
|
||||
ok = lp_load(lp_ctx, smbconf);
|
||||
if (!ok) {
|
||||
DEBUG(0,("Failed load freshly generated smb.conf '%s'\n", smbconf));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
s->ldb = ldb_wrap_connect(s, lp_ctx, lp_sam_url(lp_ctx),
|
||||
system_session(s, lp_ctx),
|
||||
NULL, 0, NULL);
|
||||
if (!s->ldb) {
|
||||
DEBUG(0,("Failed to open '%s'\n", lp_sam_url(lp_ctx)));
|
||||
return NT_STATUS_INTERNAL_DB_ERROR;
|
||||
}
|
||||
|
||||
ok = samdb_set_ntds_invocation_id(s->ldb, &p->dest_dsa->invocation_id);
|
||||
if (!ok) {
|
||||
DEBUG(0,("Failed to set cached ntds invocationId\n"));
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
ok = samdb_set_ntds_objectGUID(s->ldb, &p->dest_dsa->ntds_guid);
|
||||
if (!ok) {
|
||||
DEBUG(0,("Failed to set cached ntds objectGUID\n"));
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
s->lp_ctx = lp_ctx;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
||||
|
||||
return provision_bare(s, s->tctx->lp_ctx, &settings);
|
||||
}
|
||||
|
||||
static NTSTATUS test_become_dc_check_options(void *private_data,
|
||||
@ -140,6 +166,7 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
|
||||
struct ldb_val prefixMap_val;
|
||||
struct ldb_message_element *prefixMap_el;
|
||||
struct ldb_val schemaInfo_val;
|
||||
char *sam_ldb_path;
|
||||
uint32_t i;
|
||||
int ret;
|
||||
bool ok;
|
||||
@ -325,13 +352,14 @@ static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
|
||||
talloc_free(s->ldb); /* this also free's the s->schema, because dsdb_set_schema() steals it */
|
||||
s->schema = NULL;
|
||||
|
||||
DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema: %s\n", s->path.samdb_ldb));
|
||||
s->ldb = ldb_wrap_connect(s, s->tctx->lp_ctx, s->path.samdb_ldb,
|
||||
sam_ldb_path = talloc_asprintf(s, "%s/%s", s->targetdir, "private/sam.ldb");
|
||||
DEBUG(0,("Reopen the SAM LDB with system credentials and a already stored schema: %s\n", sam_ldb_path));
|
||||
s->ldb = ldb_wrap_connect(s, s->tctx->lp_ctx, sam_ldb_path,
|
||||
system_session(s, s->tctx->lp_ctx),
|
||||
NULL, 0, NULL);
|
||||
if (!s->ldb) {
|
||||
DEBUG(0,("Failed to open '%s'\n",
|
||||
s->path.samdb_ldb));
|
||||
sam_ldb_path));
|
||||
return NT_STATUS_INTERNAL_DB_ERROR;
|
||||
}
|
||||
|
||||
@ -392,7 +420,8 @@ static NTSTATUS test_become_dc_schema_chunk(void *private_data,
|
||||
}
|
||||
|
||||
if (!s->schema) {
|
||||
s->self_made_schema = talloc_zero(s, struct dsdb_schema);
|
||||
s->self_made_schema = dsdb_new_schema(s, lp_iconv_convenience(s->lp_ctx));
|
||||
|
||||
NT_STATUS_HAVE_NO_MEMORY(s->self_made_schema);
|
||||
|
||||
status = dsdb_load_oid_mappings_drsuapi(s->self_made_schema, mapping_ctr);
|
||||
@ -564,33 +593,24 @@ bool torture_net_become_dc(struct torture_context *torture)
|
||||
struct ldb_message *msg;
|
||||
int ldb_ret;
|
||||
uint32_t i;
|
||||
char *sam_ldb_path;
|
||||
|
||||
char *location = NULL;
|
||||
torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location),
|
||||
"torture_temp_dir should return NT_STATUS_OK" );
|
||||
|
||||
s = talloc_zero(torture, struct test_become_dc_state);
|
||||
if (!s) return false;
|
||||
|
||||
s->tctx = torture;
|
||||
s->lp_ctx = torture->lp_ctx;
|
||||
|
||||
s->netbios_name = lp_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
|
||||
if (!s->netbios_name || !s->netbios_name[0]) {
|
||||
s->netbios_name = "smbtorturedc";
|
||||
}
|
||||
|
||||
s->path.samdb_ldb = talloc_asprintf(s, "%s_samdb.ldb", s->netbios_name);
|
||||
if (!s->path.samdb_ldb) return false;
|
||||
s->path.domaindn_ldb = talloc_asprintf(s, "%s_domain.ldb", s->netbios_name);
|
||||
if (!s->path.domaindn_ldb) return false;
|
||||
s->path.configdn_ldb = talloc_asprintf(s, "%s_config.ldb", s->netbios_name);
|
||||
if (!s->path.configdn_ldb) return false;
|
||||
s->path.schemadn_ldb = talloc_asprintf(s, "%s_schema.ldb", s->netbios_name);
|
||||
if (!s->path.schemadn_ldb) return false;
|
||||
s->path.secrets_ldb = talloc_asprintf(s, "%s_secrets.ldb", s->netbios_name);
|
||||
if (!s->path.secrets_ldb) return false;
|
||||
s->path.templates_ldb = talloc_asprintf(s, "%s_templates.ldb", s->netbios_name);
|
||||
if (!s->path.templates_ldb) return false;
|
||||
s->path.secrets_keytab = talloc_asprintf(s, "%s_secrets.keytab", s->netbios_name);
|
||||
if (!s->path.secrets_keytab) return false;
|
||||
s->path.dns_keytab = talloc_asprintf(s, "%s_dns.keytab", s->netbios_name);
|
||||
if (!s->path.dns_keytab) return false;
|
||||
s->targetdir = location;
|
||||
|
||||
/* Join domain as a member server. */
|
||||
s->tj = torture_join_domain(torture, s->netbios_name,
|
||||
@ -664,13 +684,14 @@ bool torture_net_become_dc(struct torture_context *torture)
|
||||
talloc_free(s->ldb); /* this also free's the s->schema, because dsdb_set_schema() steals it */
|
||||
s->schema = NULL;
|
||||
|
||||
DEBUG(0,("Reopen the SAM LDB with system credentials and all replicated data: %s\n", s->path.samdb_ldb));
|
||||
s->ldb = ldb_wrap_connect(s, torture->lp_ctx, s->path.samdb_ldb,
|
||||
system_session(s, torture->lp_ctx),
|
||||
sam_ldb_path = talloc_asprintf(s, "%s/%s", s->targetdir, "private/sam.ldb");
|
||||
DEBUG(0,("Reopen the SAM LDB with system credentials and all replicated data: %s\n", sam_ldb_path));
|
||||
s->ldb = ldb_wrap_connect(s, s->lp_ctx, sam_ldb_path,
|
||||
system_session(s, s->lp_ctx),
|
||||
NULL, 0, NULL);
|
||||
if (!s->ldb) {
|
||||
DEBUG(0,("Failed to open '%s'\n",
|
||||
s->path.samdb_ldb));
|
||||
sam_ldb_path));
|
||||
ret = false;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -682,6 +703,7 @@ bool torture_net_become_dc(struct torture_context *torture)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Make sure we get this from the command line */
|
||||
if (lp_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
|
||||
talloc_free(s);
|
||||
return ret;
|
||||
|
@ -339,9 +339,9 @@ static void set_test_changes(TALLOC_CTX *mem_ctx, struct libnet_ModifyUser *r,
|
||||
const char* logon_scripts[] = { "start_login.cmd", "login.bat", "start.cmd" };
|
||||
const char* home_dirs[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
|
||||
const char* home_drives[] = { "H:", "z:", "I:", "J:", "n:" };
|
||||
const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL),
|
||||
const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL | ACB_PW_EXPIRED),
|
||||
(ACB_NORMAL | ACB_PWNOEXP),
|
||||
(ACB_NORMAL) };
|
||||
(ACB_NORMAL | ACB_PW_EXPIRED) };
|
||||
const char *homedir, *homedrive, *logonscript;
|
||||
struct timeval now;
|
||||
int i, testfld;
|
||||
|
@ -88,9 +88,9 @@ static bool test_usermod(struct torture_context *tctx, struct dcerpc_pipe *p,
|
||||
const char* home_dirs[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
|
||||
const char* home_drives[] = { "H:", "z:", "I:", "J:", "n:" };
|
||||
const char *homedir, *homedrive, *logonscript;
|
||||
const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL),
|
||||
const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL | ACB_PW_EXPIRED),
|
||||
(ACB_NORMAL | ACB_PWNOEXP),
|
||||
(ACB_NORMAL) };
|
||||
(ACB_NORMAL | ACB_PW_EXPIRED) };
|
||||
|
||||
NTSTATUS status;
|
||||
struct timeval now;
|
||||
@ -201,7 +201,7 @@ static bool test_usermod(struct torture_context *tctx, struct dcerpc_pipe *p,
|
||||
break;
|
||||
}
|
||||
|
||||
printf(((i < num_changes - 1) ? "%s," : "%s"), fldname);
|
||||
torture_comment(tctx, ((i < num_changes - 1) ? "%s," : "%s"), fldname);
|
||||
}
|
||||
torture_comment(tctx, "]\n");
|
||||
|
||||
|
@ -43,6 +43,9 @@ static bool test_provision(struct torture_context *tctx)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct provision_settings settings;
|
||||
char *location = NULL;
|
||||
torture_assert_ntstatus_ok(tctx, torture_temp_dir(tctx, "torture_provision", &location),
|
||||
"torture_temp_dir should return NT_STATUS_OK" );
|
||||
|
||||
settings.dns_name = "example.com";
|
||||
settings.site_name = "SOME-SITE-NAME";
|
||||
@ -57,14 +60,7 @@ static bool test_provision(struct torture_context *tctx)
|
||||
settings.ntds_guid = NULL;
|
||||
settings.ntds_dn_str = NULL;
|
||||
settings.machine_password = "geheim";
|
||||
settings.samdb_ldb = NULL;
|
||||
settings.secrets_ldb = NULL;
|
||||
settings.secrets_keytab = NULL;
|
||||
settings.schemadn_ldb = NULL;
|
||||
settings.configdn_ldb = NULL;
|
||||
settings.domaindn_ldb = NULL;
|
||||
settings.templates_ldb = NULL;
|
||||
settings.dns_keytab = NULL;
|
||||
settings.targetdir = location;
|
||||
|
||||
status = provision_bare(tctx, tctx->lp_ctx, &settings);
|
||||
|
||||
|
@ -150,7 +150,7 @@ static bool test_chkpath(struct smbcli_state *cli, struct torture_context *tctx)
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\foo\\..") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\f\\o\\o\\..\\..\\..") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\foo\\\\\..\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\foo\\\\..\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR"\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR"\\\\..\\"BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR"\\\\\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
|
@ -24,6 +24,9 @@
|
||||
#include "libcli/libcli.h"
|
||||
#include "torture/util.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "param/param.h"
|
||||
#include "lib/cmdline/popt_common.h"
|
||||
#include "libcli/resolve/resolve.h"
|
||||
|
||||
#define CHECK_VAL(v, correct) do { \
|
||||
if ((v) != (correct)) { \
|
||||
@ -32,6 +35,13 @@
|
||||
ret = false; \
|
||||
}} while (0)
|
||||
|
||||
#define CHECK_RANGE(v, min, max) do { \
|
||||
if ((v) < (min) || (v) > (max)) { \
|
||||
torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got %d - should be between %d and %d\n", \
|
||||
__location__, #v, (int)v, (int)min, (int)max); \
|
||||
ret = false; \
|
||||
}} while (0)
|
||||
|
||||
#define CHECK_STRMATCH(v, correct) do { \
|
||||
if (!v || strstr((v),(correct)) == NULL) { \
|
||||
torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got '%s' - should be '%s'\n", \
|
||||
@ -61,16 +71,30 @@ static struct {
|
||||
/*
|
||||
a handler function for oplock break requests. Ack it as a break to level II if possible
|
||||
*/
|
||||
static bool oplock_handler_ack_to_levelII(struct smbcli_transport *transport,
|
||||
uint16_t tid, uint16_t fnum,
|
||||
uint8_t level, void *private)
|
||||
static bool oplock_handler_ack_to_given(struct smbcli_transport *transport,
|
||||
uint16_t tid, uint16_t fnum,
|
||||
uint8_t level, void *private)
|
||||
{
|
||||
struct smbcli_tree *tree = (struct smbcli_tree *)private;
|
||||
const char *name;
|
||||
|
||||
break_info.fnum = fnum;
|
||||
break_info.level = level;
|
||||
break_info.count++;
|
||||
|
||||
printf("Acking to level II in oplock handler\n");
|
||||
switch (level) {
|
||||
case OPLOCK_BREAK_TO_LEVEL_II:
|
||||
name = "level II";
|
||||
break;
|
||||
case OPLOCK_BREAK_TO_NONE:
|
||||
name = "none";
|
||||
break;
|
||||
default:
|
||||
name = "unknown";
|
||||
break_info.failures++;
|
||||
}
|
||||
printf("Acking to %s [0x%02X] in oplock handler\n",
|
||||
name, level);
|
||||
|
||||
return smbcli_oplock_ack(tree, fnum, level);
|
||||
}
|
||||
@ -92,6 +116,21 @@ static bool oplock_handler_ack_to_none(struct smbcli_transport *transport,
|
||||
return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
a handler function for oplock break requests. Let it timeout
|
||||
*/
|
||||
static bool oplock_handler_timeout(struct smbcli_transport *transport,
|
||||
uint16_t tid, uint16_t fnum,
|
||||
uint8_t level, void *private)
|
||||
{
|
||||
break_info.fnum = fnum;
|
||||
break_info.level = level;
|
||||
break_info.count++;
|
||||
|
||||
printf("Let oplock break timeout\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void oplock_handler_close_recv(struct smbcli_request *req)
|
||||
{
|
||||
NTSTATUS status;
|
||||
@ -131,6 +170,32 @@ static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t ti
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool open_connection_no_level2_oplocks(struct torture_context *tctx,
|
||||
struct smbcli_state **c)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
struct smbcli_options options;
|
||||
|
||||
lp_smbcli_options(tctx->lp_ctx, &options);
|
||||
|
||||
options.use_level2_oplocks = false;
|
||||
|
||||
status = smbcli_full_connection(tctx, c,
|
||||
torture_setting_string(tctx, "host", NULL),
|
||||
lp_smb_ports(tctx->lp_ctx),
|
||||
torture_setting_string(tctx, "share", NULL),
|
||||
NULL, cmdline_credentials,
|
||||
lp_resolve_context(tctx->lp_ctx),
|
||||
tctx->ev, &options);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Failed to open connection - %s\n", nt_errstr(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
|
||||
{
|
||||
const char *fname = BASEDIR "\\test_exclusive1.dat";
|
||||
@ -147,7 +212,7 @@ static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbc
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -212,7 +277,7 @@ static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbc
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -307,7 +372,7 @@ static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbc
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -376,7 +441,7 @@ static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbc
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -395,7 +460,7 @@ static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbc
|
||||
|
||||
torture_comment(tctx, "open with exclusive oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
|
||||
status = smb_raw_open(cli1->tree, tctx, &io);
|
||||
@ -440,8 +505,8 @@ static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbc
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -460,7 +525,7 @@ static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbc
|
||||
|
||||
torture_comment(tctx, "open with exclusive oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
|
||||
@ -515,7 +580,7 @@ static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbc
|
||||
smbcli_unlink(cli1->tree, fname1);
|
||||
smbcli_unlink(cli1->tree, fname2);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -588,7 +653,7 @@ static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -672,7 +737,7 @@ static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -750,7 +815,7 @@ static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -814,7 +879,7 @@ static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -833,7 +898,7 @@ static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_s
|
||||
|
||||
torture_comment(tctx, "a self read should not cause a break\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -877,7 +942,7 @@ static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -896,7 +961,7 @@ static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_s
|
||||
|
||||
torture_comment(tctx, "a 2nd open should give a break\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -942,7 +1007,7 @@ static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -961,8 +1026,8 @@ static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_s
|
||||
|
||||
torture_comment(tctx, "a 2nd open should give a break to level II if the first open allowed shared read\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
|
||||
|
||||
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
|
||||
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
|
||||
@ -1022,7 +1087,7 @@ static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1092,7 +1157,7 @@ static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1111,7 +1176,7 @@ static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_s
|
||||
|
||||
torture_comment(tctx, "open with batch oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -1161,7 +1226,7 @@ static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_s
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1193,7 +1258,7 @@ static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_s
|
||||
torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
|
||||
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -1212,8 +1277,8 @@ static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_s
|
||||
|
||||
torture_comment(tctx, "third oplocked open should grant level2 without break\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
|
||||
@ -1266,7 +1331,7 @@ static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1297,7 +1362,7 @@ static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_
|
||||
CHECK_VAL(break_info.failures, 0);
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
|
||||
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -1375,7 +1440,7 @@ static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1396,7 +1461,7 @@ static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_
|
||||
torture_comment(tctx, "Test if setpathinfo set EOF breaks oplocks.\n");
|
||||
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -1450,7 +1515,7 @@ static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1471,7 +1536,7 @@ static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_
|
||||
torture_comment(tctx, "Test if setpathinfo allocation size breaks oplocks.\n");
|
||||
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -1524,8 +1589,8 @@ static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1544,7 +1609,7 @@ static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_
|
||||
|
||||
torture_comment(tctx, "open with batch oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
@ -1602,7 +1667,7 @@ static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1621,7 +1686,7 @@ static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_
|
||||
|
||||
torture_comment(tctx, "open with batch oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -1678,7 +1743,7 @@ static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1699,7 +1764,7 @@ static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_
|
||||
torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n");
|
||||
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
@ -1750,8 +1815,8 @@ static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1770,7 +1835,7 @@ static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_
|
||||
|
||||
torture_comment(tctx, "open with batch oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
@ -1832,7 +1897,7 @@ static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_
|
||||
smbcli_unlink(cli1->tree, fname1);
|
||||
smbcli_unlink(cli1->tree, fname2);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1910,7 +1975,7 @@ static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_
|
||||
smbcli_unlink(cli1->tree, fname1);
|
||||
smbcli_unlink(cli1->tree, fname2);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -1994,7 +2059,7 @@ static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_
|
||||
smbcli_unlink(cli1->tree, fname2);
|
||||
smbcli_unlink(cli1->tree, fname3);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -2096,7 +2161,7 @@ static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_
|
||||
smbcli_unlink(cli1->tree, fname2);
|
||||
smbcli_unlink(cli1->tree, fname3);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
@ -2204,6 +2269,334 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_raw_oplock_batch21(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
|
||||
{
|
||||
const char *fname = BASEDIR "\\test_batch21.dat";
|
||||
NTSTATUS status;
|
||||
bool ret = true;
|
||||
union smb_open io;
|
||||
struct smb_echo e;
|
||||
uint16_t fnum=0;
|
||||
char c = 0;
|
||||
ssize_t wr;
|
||||
|
||||
if (!torture_setup_dir(cli1, BASEDIR)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
*/
|
||||
io.generic.level = RAW_OPEN_NTCREATEX;
|
||||
io.ntcreatex.in.root_fid = 0;
|
||||
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
|
||||
io.ntcreatex.in.alloc_size = 0;
|
||||
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
|
||||
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
|
||||
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
|
||||
io.ntcreatex.in.create_options = 0;
|
||||
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
|
||||
io.ntcreatex.in.security_flags = 0;
|
||||
io.ntcreatex.in.fname = fname;
|
||||
|
||||
/*
|
||||
with a batch oplock we get a break
|
||||
*/
|
||||
torture_comment(tctx, "open with batch oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
|
||||
status = smb_raw_open(cli1->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
fnum = io.ntcreatex.out.file.fnum;
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
|
||||
|
||||
torture_comment(tctx, "writing should not generate a break\n");
|
||||
wr = smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
|
||||
CHECK_VAL(wr, 1);
|
||||
CHECK_STATUS(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_OK);
|
||||
|
||||
ZERO_STRUCT(e);
|
||||
e.in.repeat_count = 1;
|
||||
status = smb_raw_echo(cli1->transport, &e);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
|
||||
CHECK_VAL(break_info.count, 0);
|
||||
|
||||
smbcli_close(cli1->tree, fnum);
|
||||
|
||||
done:
|
||||
smb_raw_exit(cli1->session);
|
||||
smb_raw_exit(cli2->session);
|
||||
smbcli_deltree(cli1->tree, BASEDIR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
|
||||
{
|
||||
const char *fname = BASEDIR "\\test_batch22.dat";
|
||||
NTSTATUS status;
|
||||
bool ret = true;
|
||||
union smb_open io;
|
||||
uint16_t fnum=0, fnum2=0;
|
||||
struct timeval tv;
|
||||
int timeout = torture_setting_int(tctx, "oplocktimeout", 30);
|
||||
int te;
|
||||
|
||||
if (torture_setting_bool(tctx, "samba3", false)) {
|
||||
torture_skip(tctx, "BACHT22 disabled against samba3\n");
|
||||
}
|
||||
|
||||
if (!torture_setup_dir(cli1, BASEDIR)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
*/
|
||||
io.generic.level = RAW_OPEN_NTCREATEX;
|
||||
io.ntcreatex.in.root_fid = 0;
|
||||
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
|
||||
io.ntcreatex.in.alloc_size = 0;
|
||||
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
|
||||
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
|
||||
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
|
||||
io.ntcreatex.in.create_options = 0;
|
||||
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
|
||||
io.ntcreatex.in.security_flags = 0;
|
||||
io.ntcreatex.in.fname = fname;
|
||||
|
||||
/*
|
||||
with a batch oplock we get a break
|
||||
*/
|
||||
torture_comment(tctx, "open with batch oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
|
||||
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
|
||||
NTCREATEX_SHARE_ACCESS_WRITE|
|
||||
NTCREATEX_SHARE_ACCESS_DELETE;
|
||||
status = smb_raw_open(cli1->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
fnum = io.ntcreatex.out.file.fnum;
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
|
||||
|
||||
torture_comment(tctx, "a 2nd open shoud not succeed after the oplock break timeout\n");
|
||||
tv = timeval_current();
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_timeout, cli1->tree);
|
||||
status = smb_raw_open(cli1->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
|
||||
te = (int)timeval_elapsed(&tv);
|
||||
CHECK_RANGE(te, timeout - 1, timeout + 15);
|
||||
|
||||
CHECK_VAL(break_info.count, 1);
|
||||
CHECK_VAL(break_info.fnum, fnum);
|
||||
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
|
||||
CHECK_VAL(break_info.failures, 0);
|
||||
ZERO_STRUCT(break_info);
|
||||
|
||||
torture_comment(tctx, "a 2nd open shoud succeed after the oplock release without break\n");
|
||||
tv = timeval_current();
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
status = smb_raw_open(cli1->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
|
||||
te = (int)timeval_elapsed(&tv);
|
||||
/* it should come in without delay */
|
||||
CHECK_RANGE(te+1, 0, timeout);
|
||||
fnum2 = io.ntcreatex.out.file.fnum;
|
||||
|
||||
CHECK_VAL(break_info.count, 0);
|
||||
|
||||
smbcli_close(cli1->tree, fnum);
|
||||
smbcli_close(cli1->tree, fnum2);
|
||||
|
||||
done:
|
||||
smb_raw_exit(cli1->session);
|
||||
smb_raw_exit(cli2->session);
|
||||
smbcli_deltree(cli1->tree, BASEDIR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
|
||||
{
|
||||
const char *fname = BASEDIR "\\test_batch23.dat";
|
||||
NTSTATUS status;
|
||||
bool ret = true;
|
||||
union smb_open io;
|
||||
uint16_t fnum=0, fnum2=0,fnum3=0;
|
||||
struct smbcli_state *cli3 = NULL;
|
||||
|
||||
if (torture_setting_bool(tctx, "samba3", false)) {
|
||||
torture_skip(tctx, "BACHT23 disabled against samba3\n");
|
||||
}
|
||||
|
||||
if (!torture_setup_dir(cli1, BASEDIR)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
ret = open_connection_no_level2_oplocks(tctx, &cli3);
|
||||
CHECK_VAL(ret, true);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
*/
|
||||
io.generic.level = RAW_OPEN_NTCREATEX;
|
||||
io.ntcreatex.in.root_fid = 0;
|
||||
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
|
||||
io.ntcreatex.in.alloc_size = 0;
|
||||
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
|
||||
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
|
||||
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
|
||||
io.ntcreatex.in.create_options = 0;
|
||||
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
|
||||
io.ntcreatex.in.security_flags = 0;
|
||||
io.ntcreatex.in.fname = fname;
|
||||
|
||||
torture_comment(tctx, "a open and ask for a batch oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
|
||||
smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
|
||||
|
||||
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
|
||||
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
|
||||
status = smb_raw_open(cli1->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
fnum = io.ntcreatex.out.file.fnum;
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
|
||||
|
||||
ZERO_STRUCT(break_info);
|
||||
|
||||
torture_comment(tctx, "a 2nd open without level2 oplock support should generate a break to level2\n");
|
||||
status = smb_raw_open(cli3->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
fnum3 = io.ntcreatex.out.file.fnum;
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
|
||||
|
||||
CHECK_VAL(break_info.count, 1);
|
||||
CHECK_VAL(break_info.fnum, fnum);
|
||||
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
|
||||
CHECK_VAL(break_info.failures, 0);
|
||||
|
||||
ZERO_STRUCT(break_info);
|
||||
|
||||
torture_comment(tctx, "a 3rd open with level2 oplock support should not generate a break\n");
|
||||
status = smb_raw_open(cli2->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
fnum2 = io.ntcreatex.out.file.fnum;
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
|
||||
|
||||
CHECK_VAL(break_info.count, 0);
|
||||
|
||||
smbcli_close(cli1->tree, fnum);
|
||||
smbcli_close(cli2->tree, fnum2);
|
||||
smbcli_close(cli3->tree, fnum3);
|
||||
|
||||
done:
|
||||
smb_raw_exit(cli1->session);
|
||||
smb_raw_exit(cli2->session);
|
||||
smb_raw_exit(cli3->session);
|
||||
smbcli_deltree(cli1->tree, BASEDIR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_raw_oplock_batch24(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
|
||||
{
|
||||
const char *fname = BASEDIR "\\test_batch24.dat";
|
||||
NTSTATUS status;
|
||||
bool ret = true;
|
||||
union smb_open io;
|
||||
uint16_t fnum2=0,fnum3=0;
|
||||
struct smbcli_state *cli3 = NULL;
|
||||
|
||||
if (!torture_setup_dir(cli1, BASEDIR)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
smbcli_unlink(cli1->tree, fname);
|
||||
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
|
||||
ret = open_connection_no_level2_oplocks(tctx, &cli3);
|
||||
CHECK_VAL(ret, true);
|
||||
|
||||
/*
|
||||
base ntcreatex parms
|
||||
*/
|
||||
io.generic.level = RAW_OPEN_NTCREATEX;
|
||||
io.ntcreatex.in.root_fid = 0;
|
||||
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
|
||||
io.ntcreatex.in.alloc_size = 0;
|
||||
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
|
||||
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
|
||||
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
|
||||
io.ntcreatex.in.create_options = 0;
|
||||
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
|
||||
io.ntcreatex.in.security_flags = 0;
|
||||
io.ntcreatex.in.fname = fname;
|
||||
|
||||
torture_comment(tctx, "a open without level support and ask for a batch oplock\n");
|
||||
ZERO_STRUCT(break_info);
|
||||
smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_given, cli1->tree);
|
||||
smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_given, cli2->tree);
|
||||
smbcli_oplock_handler(cli3->transport, oplock_handler_ack_to_given, cli3->tree);
|
||||
|
||||
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
|
||||
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
|
||||
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
|
||||
NTCREATEX_FLAGS_REQUEST_OPLOCK |
|
||||
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
|
||||
status = smb_raw_open(cli3->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
fnum3 = io.ntcreatex.out.file.fnum;
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
|
||||
|
||||
ZERO_STRUCT(break_info);
|
||||
|
||||
torture_comment(tctx, "a 2nd open with level2 oplock support should generate a break to none\n");
|
||||
status = smb_raw_open(cli2->tree, tctx, &io);
|
||||
CHECK_STATUS(tctx, status, NT_STATUS_OK);
|
||||
fnum2 = io.ntcreatex.out.file.fnum;
|
||||
CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
|
||||
|
||||
CHECK_VAL(break_info.count, 1);
|
||||
CHECK_VAL(break_info.fnum, fnum3);
|
||||
CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
|
||||
CHECK_VAL(break_info.failures, 0);
|
||||
|
||||
smbcli_close(cli3->tree, fnum3);
|
||||
smbcli_close(cli2->tree, fnum2);
|
||||
|
||||
done:
|
||||
smb_raw_exit(cli1->session);
|
||||
smb_raw_exit(cli2->session);
|
||||
smb_raw_exit(cli3->session);
|
||||
smbcli_deltree(cli1->tree, BASEDIR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
basic testing of oplocks
|
||||
*/
|
||||
@ -2237,6 +2630,10 @@ struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
|
||||
torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
|
||||
torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
|
||||
torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
|
||||
torture_suite_add_2smb_test(suite, "BATCH21", test_raw_oplock_batch21);
|
||||
torture_suite_add_2smb_test(suite, "BATCH22", test_raw_oplock_batch22);
|
||||
torture_suite_add_2smb_test(suite, "BATCH23", test_raw_oplock_batch23);
|
||||
torture_suite_add_2smb_test(suite, "BATCH24", test_raw_oplock_batch24);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
@ -29,19 +29,13 @@ struct provision_settings {
|
||||
const char *schema_dn_str;
|
||||
const struct GUID *invocation_id;
|
||||
const char *netbios_name;
|
||||
const char *host_ip;
|
||||
const char *realm;
|
||||
const char *domain;
|
||||
const struct GUID *ntds_guid;
|
||||
const char *ntds_dn_str;
|
||||
const char *machine_password;
|
||||
const char *samdb_ldb;
|
||||
const char *secrets_ldb;
|
||||
const char *secrets_keytab;
|
||||
const char *schemadn_ldb;
|
||||
const char *configdn_ldb;
|
||||
const char *domaindn_ldb;
|
||||
const char *templates_ldb;
|
||||
const char *dns_keytab;
|
||||
const char *targetdir;
|
||||
};
|
||||
|
||||
NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
|
||||
|
@ -18,206 +18,22 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
#include "lib/appweb/ejs/ejs.h"
|
||||
#include "lib/appweb/ejs/ejsInternal.h"
|
||||
#include "scripting/ejs/smbcalls.h"
|
||||
#include "auth/auth.h"
|
||||
#include "lib/ldb_wrap.h"
|
||||
#include "torture/util.h"
|
||||
|
||||
static EjsId eid;
|
||||
static int ejs_error;
|
||||
|
||||
static void test_ejs_exception(const char *reason)
|
||||
{
|
||||
Ejs *ep = ejsPtr(eid);
|
||||
ejsSetErrorMsg(eid, "%s", reason);
|
||||
fprintf(stderr, "%s", ep->error);
|
||||
ejs_error = 127;
|
||||
}
|
||||
|
||||
static int test_run_ejs(char *script)
|
||||
{
|
||||
EjsHandle handle = 0;
|
||||
MprVar result;
|
||||
char *emsg;
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct MprVar *return_var;
|
||||
|
||||
mprSetCtx(mem_ctx);
|
||||
|
||||
if (ejsOpen(NULL, NULL, NULL) != 0) {
|
||||
d_printf("ejsOpen(): unable to initialise EJS subsystem\n");
|
||||
ejs_error = 127;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
smb_setup_ejs_functions(test_ejs_exception);
|
||||
|
||||
if ((eid = ejsOpenEngine(handle, 0)) == (EjsId)-1) {
|
||||
d_printf("smbscript: ejsOpenEngine(): unable to initialise an EJS engine\n");
|
||||
ejs_error = 127;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
mprSetVar(ejsGetGlobalObject(eid), "ARGV", mprList("ARGV", NULL));
|
||||
|
||||
/* run the script */
|
||||
if (ejsEvalScript(eid, script, &result, &emsg) == -1) {
|
||||
d_printf("smbscript: ejsEvalScript(): %s\n", emsg);
|
||||
if (ejs_error == 0) ejs_error = 127;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return_var = ejsGetReturnValue(eid);
|
||||
ejs_error = mprVarToNumber(return_var);
|
||||
|
||||
failed:
|
||||
ejsClose();
|
||||
talloc_free(mem_ctx);
|
||||
return ejs_error;
|
||||
}
|
||||
|
||||
static NTSTATUS provision_bare_ejs(TALLOC_CTX *mem_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct provision_settings *settings)
|
||||
{
|
||||
char *ejs;
|
||||
int ret;
|
||||
bool ok;
|
||||
struct ldb_context *ldb;
|
||||
|
||||
DEBUG(0,("Provision for Become-DC test using EJS\n"));
|
||||
|
||||
DEBUG(0,("New Server[%s] in Site[%s]\n", settings->dns_name,
|
||||
settings->site_name));
|
||||
|
||||
DEBUG(0,("DSA Instance [%s]\n"
|
||||
"\tobjectGUID[%s]\n"
|
||||
"\tinvocationId[%s]\n",
|
||||
settings->ntds_dn_str,
|
||||
GUID_string(mem_ctx, settings->ntds_guid),
|
||||
GUID_string(mem_ctx, settings->invocation_id)));
|
||||
|
||||
DEBUG(0,("Pathes under PRIVATEDIR[%s]\n"
|
||||
"SAMDB[%s] SECRETS[%s] KEYTAB[%s]\n",
|
||||
lp_private_dir(lp_ctx),
|
||||
settings->samdb_ldb,
|
||||
settings->secrets_ldb,
|
||||
settings->secrets_keytab));
|
||||
|
||||
DEBUG(0,("Schema Partition[%s => %s]\n",
|
||||
settings->schema_dn_str, settings->schemadn_ldb));
|
||||
|
||||
DEBUG(0,("Config Partition[%s => %s]\n",
|
||||
settings->config_dn_str, settings->configdn_ldb));
|
||||
|
||||
DEBUG(0,("Domain Partition[%s => %s]\n",
|
||||
settings->domain_dn_str, settings->domaindn_ldb));
|
||||
|
||||
ejs = talloc_asprintf(mem_ctx,
|
||||
"libinclude(\"base.js\");\n"
|
||||
"libinclude(\"provision.js\");\n"
|
||||
"\n"
|
||||
"function message() { print(vsprintf(arguments)); }\n"
|
||||
"\n"
|
||||
"var subobj = provision_guess();\n"
|
||||
"subobj.ROOTDN = \"%s\";\n"
|
||||
"subobj.DOMAINDN = \"%s\";\n"
|
||||
"subobj.DOMAINDN_LDB = \"%s\";\n"
|
||||
"subobj.CONFIGDN = \"%s\";\n"
|
||||
"subobj.CONFIGDN_LDB = \"%s\";\n"
|
||||
"subobj.SCHEMADN = \"%s\";\n"
|
||||
"subobj.SCHEMADN_LDB = \"%s\";\n"
|
||||
"subobj.HOSTNAME = \"%s\";\n"
|
||||
"subobj.REALM = \"%s\";\n"
|
||||
"subobj.DOMAIN = \"%s\";\n"
|
||||
"subobj.DEFAULTSITE = \"%s\";\n"
|
||||
"\n"
|
||||
"subobj.KRBTGTPASS = \"_NOT_USED_\";\n"
|
||||
"subobj.MACHINEPASS = \"%s\";\n"
|
||||
"subobj.ADMINPASS = \"_NOT_USED_\";\n"
|
||||
"\n"
|
||||
"var paths = provision_default_paths(subobj);\n"
|
||||
"paths.samdb = \"%s\";\n"
|
||||
"paths.secrets = \"%s\";\n"
|
||||
"paths.templates = \"%s\";\n"
|
||||
"paths.keytab = \"%s\";\n"
|
||||
"paths.dns_keytab = \"%s\";\n"
|
||||
"\n"
|
||||
"var system_session = system_session();\n"
|
||||
"\n"
|
||||
"var ok = provision_become_dc(subobj, message, true, paths, system_session);\n"
|
||||
"assert(ok);\n"
|
||||
"\n"
|
||||
"return 0;\n",
|
||||
settings->root_dn_str, /* subobj.ROOTDN */
|
||||
settings->domain_dn_str, /* subobj.DOMAINDN */
|
||||
settings->domaindn_ldb, /* subobj.DOMAINDN_LDB */
|
||||
settings->config_dn_str, /* subobj.CONFIGDN */
|
||||
settings->configdn_ldb, /* subobj.CONFIGDN_LDB */
|
||||
settings->schema_dn_str, /* subobj.SCHEMADN */
|
||||
settings->schemadn_ldb, /* subobj.SCHEMADN_LDB */
|
||||
settings->netbios_name, /* subobj.HOSTNAME */
|
||||
settings->realm,/* subobj.REALM */
|
||||
settings->domain,/* subobj.DOMAIN */
|
||||
settings->site_name, /* subobj.DEFAULTSITE */
|
||||
settings->machine_password,/* subobj.MACHINEPASS */
|
||||
settings->samdb_ldb, /* paths.samdb */
|
||||
settings->templates_ldb, /* paths.templates */
|
||||
settings->secrets_ldb, /* paths.secrets */
|
||||
settings->secrets_keytab, /* paths.keytab */
|
||||
settings->dns_keytab); /* paths.dns_keytab */
|
||||
NT_STATUS_HAVE_NO_MEMORY(ejs);
|
||||
|
||||
ret = test_run_ejs(ejs);
|
||||
if (ret != 0) {
|
||||
DEBUG(0,("Failed to run ejs script: %d:\n%s",
|
||||
ret, ejs));
|
||||
talloc_free(ejs);
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
talloc_free(ejs);
|
||||
|
||||
DEBUG(0,("Open the SAM LDB with system credentials: %s\n",
|
||||
settings->samdb_ldb));
|
||||
|
||||
ldb = ldb_wrap_connect(mem_ctx, lp_ctx, settings->samdb_ldb,
|
||||
system_session(mem_ctx, lp_ctx),
|
||||
NULL, 0, NULL);
|
||||
if (!ldb) {
|
||||
DEBUG(0,("Failed to open '%s'\n",
|
||||
settings->samdb_ldb));
|
||||
return NT_STATUS_INTERNAL_DB_ERROR;
|
||||
}
|
||||
|
||||
ok = samdb_set_ntds_invocation_id(ldb, settings->invocation_id);
|
||||
if (!ok) {
|
||||
DEBUG(0,("Failed to set cached ntds invocationId\n"));
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
ok = samdb_set_ntds_objectGUID(ldb, settings->ntds_guid);
|
||||
if (!ok) {
|
||||
DEBUG(0,("Failed to set cached ntds objectGUID\n"));
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
#include "param/param.h"
|
||||
#include <Python.h>
|
||||
#include "scripting/python/modules.h"
|
||||
|
||||
static NTSTATUS provision_bare_py(TALLOC_CTX *mem_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct provision_settings *settings)
|
||||
NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
|
||||
struct provision_settings *settings)
|
||||
{
|
||||
bool ok;
|
||||
PyObject *provision_mod, *provision_dict, *provision_fn, *result, *parameters;
|
||||
struct ldb_context *ldb;
|
||||
|
||||
char *sam_ldb_path;
|
||||
|
||||
DEBUG(0,("Provision for Become-DC test using python\n"));
|
||||
|
||||
py_load_samba_modules();
|
||||
@ -239,10 +55,10 @@ static NTSTATUS provision_bare_py(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
provision_fn = PyDict_GetItemString(provision_dict, "provision");
|
||||
provision_fn = PyDict_GetItemString(provision_dict, "provision_become_dc");
|
||||
if (provision_fn == NULL) {
|
||||
PyErr_Print();
|
||||
DEBUG(0, ("Unable to get provision function\n"));
|
||||
DEBUG(0, ("Unable to get provision_become_dc function\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
@ -256,56 +72,45 @@ static NTSTATUS provision_bare_py(TALLOC_CTX *mem_ctx,
|
||||
settings->ntds_guid == NULL?"None":GUID_string(mem_ctx, settings->ntds_guid),
|
||||
settings->invocation_id == NULL?"None":GUID_string(mem_ctx, settings->invocation_id)));
|
||||
|
||||
DEBUG(0,("Pathes under PRIVATEDIR[%s]\n"
|
||||
"SAMDB[%s] SECRETS[%s] KEYTAB[%s]\n",
|
||||
lp_private_dir(lp_ctx),
|
||||
settings->samdb_ldb,
|
||||
settings->secrets_ldb,
|
||||
settings->secrets_keytab));
|
||||
|
||||
DEBUG(0,("Schema Partition[%s => %s]\n",
|
||||
settings->schema_dn_str, settings->schemadn_ldb));
|
||||
|
||||
DEBUG(0,("Config Partition[%s => %s]\n",
|
||||
settings->config_dn_str, settings->configdn_ldb));
|
||||
|
||||
DEBUG(0,("Domain Partition[%s => %s]\n",
|
||||
settings->domain_dn_str, settings->domaindn_ldb));
|
||||
|
||||
DEBUG(0,("Pathes under targetdir[%s]\n",
|
||||
settings->targetdir));
|
||||
parameters = PyDict_New();
|
||||
|
||||
PyDict_SetItemString(parameters, "rootdn",
|
||||
PyString_FromString(settings->root_dn_str));
|
||||
if (settings->domaindn_ldb != NULL)
|
||||
PyDict_SetItemString(parameters, "domaindn_ldb",
|
||||
PyString_FromString(settings->domaindn_ldb));
|
||||
if (settings->config_dn_str != NULL)
|
||||
PyDict_SetItemString(parameters, "configdn",
|
||||
PyString_FromString(settings->config_dn_str));
|
||||
if (settings->configdn_ldb != NULL)
|
||||
PyDict_SetItemString(parameters, "configdn_ldb",
|
||||
PyString_FromString(settings->configdn_ldb));
|
||||
if (settings->schema_dn_str != NULL)
|
||||
PyDict_SetItemString(parameters, "schema_dn_str",
|
||||
PyString_FromString(settings->schema_dn_str));
|
||||
if (settings->schemadn_ldb != NULL)
|
||||
PyDict_SetItemString(parameters, "schemadn_ldb",
|
||||
PyString_FromString(settings->schemadn_ldb));
|
||||
if (settings->targetdir != NULL)
|
||||
PyDict_SetItemString(parameters, "targetdir",
|
||||
PyString_FromString(settings->targetdir));
|
||||
PyDict_SetItemString(parameters, "setup_dir",
|
||||
PyString_FromString("setup"));
|
||||
PyDict_SetItemString(parameters, "hostname",
|
||||
PyString_FromString(settings->netbios_name));
|
||||
PyDict_SetItemString(parameters, "sitename",
|
||||
PyString_FromString(settings->site_name));
|
||||
PyDict_SetItemString(parameters, "domain",
|
||||
PyString_FromString(settings->domain));
|
||||
PyDict_SetItemString(parameters, "realm",
|
||||
PyString_FromString(settings->realm));
|
||||
if (settings->root_dn_str)
|
||||
PyDict_SetItemString(parameters, "rootdn",
|
||||
PyString_FromString(settings->root_dn_str));
|
||||
|
||||
if (settings->domain_dn_str)
|
||||
PyDict_SetItemString(parameters, "domaindn",
|
||||
PyString_FromString(settings->domain_dn_str));
|
||||
|
||||
if (settings->schema_dn_str)
|
||||
PyDict_SetItemString(parameters, "schemadn",
|
||||
PyString_FromString(settings->schema_dn_str));
|
||||
|
||||
if (settings->config_dn_str)
|
||||
PyDict_SetItemString(parameters, "configdn",
|
||||
PyString_FromString(settings->config_dn_str));
|
||||
|
||||
if (settings->site_name)
|
||||
PyDict_SetItemString(parameters, "sitename",
|
||||
PyString_FromString(settings->site_name));
|
||||
|
||||
PyDict_SetItemString(parameters, "machinepass",
|
||||
PyString_FromString(settings->machine_password));
|
||||
if (settings->samdb_ldb != NULL)
|
||||
PyDict_SetItemString(parameters, "samdb",
|
||||
PyString_FromString(settings->samdb_ldb));
|
||||
if (settings->secrets_ldb != NULL)
|
||||
PyDict_SetItemString(parameters, "secrets_ldb",
|
||||
PyString_FromString(settings->secrets_ldb));
|
||||
if (settings->secrets_keytab != NULL)
|
||||
PyDict_SetItemString(parameters, "secrets_keytab",
|
||||
PyString_FromString(settings->secrets_keytab));
|
||||
PyString_FromString(settings->machine_password));
|
||||
|
||||
result = PyEval_CallObjectWithKeywords(provision_fn, NULL, parameters);
|
||||
|
||||
@ -317,39 +122,5 @@ static NTSTATUS provision_bare_py(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DEBUG(0,("Open the SAM LDB with system credentials: %s\n",
|
||||
settings->samdb_ldb));
|
||||
|
||||
ldb = ldb_wrap_connect(mem_ctx, lp_ctx, settings->samdb_ldb,
|
||||
system_session(mem_ctx, lp_ctx),
|
||||
NULL, 0, NULL);
|
||||
if (!ldb) {
|
||||
DEBUG(0,("Failed to open '%s'\n", settings->samdb_ldb));
|
||||
return NT_STATUS_INTERNAL_DB_ERROR;
|
||||
}
|
||||
|
||||
ok = samdb_set_ntds_invocation_id(ldb, settings->invocation_id);
|
||||
if (!ok) {
|
||||
DEBUG(0,("Failed to set cached ntds invocationId\n"));
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
ok = samdb_set_ntds_objectGUID(ldb, settings->ntds_guid);
|
||||
if (!ok) {
|
||||
DEBUG(0,("Failed to set cached ntds objectGUID\n"));
|
||||
return NT_STATUS_FOOBAR;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
|
||||
struct provision_settings *settings)
|
||||
{
|
||||
if (getenv("PROVISION_EJS")) {
|
||||
return provision_bare_ejs(mem_ctx, lp_ctx, settings);
|
||||
} else {
|
||||
return provision_bare_py(mem_ctx, lp_ctx, settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -478,6 +478,9 @@ _PUBLIC_ bool torture_open_connection_share(TALLOC_CTX *mem_ctx,
|
||||
|
||||
lp_smbcli_options(tctx->lp_ctx, &options);
|
||||
|
||||
options.use_oplocks = torture_setting_bool(tctx, "use_oplocks", true);
|
||||
options.use_level2_oplocks = torture_setting_bool(tctx, "use_level2_oplocks", true);
|
||||
|
||||
status = smbcli_full_connection(mem_ctx, c, hostname,
|
||||
lp_smb_ports(tctx->lp_ctx),
|
||||
sharename, NULL,
|
||||
@ -489,9 +492,6 @@ _PUBLIC_ bool torture_open_connection_share(TALLOC_CTX *mem_ctx,
|
||||
return false;
|
||||
}
|
||||
|
||||
(*c)->transport->options.use_oplocks = torture_setting_bool(tctx, "use_oplocks", false);
|
||||
(*c)->transport->options.use_level2_oplocks = torture_setting_bool(tctx, "use_level2_oplocks", false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user