mirror of
https://github.com/samba-team/samba.git
synced 2025-02-28 01:58:17 +03:00
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into manpage
(This used to be commit 7e90cc197c4fb2884f368cd72f391d0d8016fb96)
This commit is contained in:
commit
72d2bea916
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
Summary: The Samba4 CIFS and AD client and server suite
|
Summary: The Samba4 CIFS and AD client and server suite
|
||||||
Name: samba4
|
Name: samba4
|
||||||
Epoch: 0
|
|
||||||
Version: 4.0.0
|
Version: 4.0.0
|
||||||
Release: 0.%{main_release}.alpha%{alpha_version}%{?dist}
|
Release: 0.%{main_release}.alpha%{alpha_version}%{?dist}
|
||||||
License: GPLv3+, LGPLv3+, BSD
|
License: GPLv3+, LGPLv3+, BSD
|
||||||
@ -25,7 +24,7 @@ Source1: %{name}.log
|
|||||||
Source4: %{name}.sysconfig
|
Source4: %{name}.sysconfig
|
||||||
Source5: %{name}.init
|
Source5: %{name}.init
|
||||||
|
|
||||||
Requires(pre): %{name}-common = %{epoch}:%{version}-%{release}
|
Requires(pre): %{name}-common = %{version}-%{release}
|
||||||
Requires: pam >= 0:0.64
|
Requires: pam >= 0:0.64
|
||||||
Requires: logrotate >= 0:3.4
|
Requires: logrotate >= 0:3.4
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||||
@ -33,7 +32,7 @@ Requires(pre): /usr/sbin/groupadd
|
|||||||
Requires(post): /sbin/chkconfig, /sbin/service
|
Requires(post): /sbin/chkconfig, /sbin/service
|
||||||
Requires(preun): /sbin/chkconfig, /sbin/service
|
Requires(preun): /sbin/chkconfig, /sbin/service
|
||||||
BuildRequires: pam-devel, readline-devel, ncurses-devel, libacl-devel, e2fsprogs-devel
|
BuildRequires: pam-devel, readline-devel, ncurses-devel, libacl-devel, e2fsprogs-devel
|
||||||
BuildRequires: popt-devel, libattr-devel, libaio-devel, sed, ldconfig
|
BuildRequires: popt-devel, libattr-devel, libaio-devel, sed
|
||||||
BuildRequires: perl(ExtUtils::MakeMaker)
|
BuildRequires: perl(ExtUtils::MakeMaker)
|
||||||
BuildRequires: libtalloc-devel >= %{talloc_version}
|
BuildRequires: libtalloc-devel >= %{talloc_version}
|
||||||
BuildRequires: libtdb-devel >= %{tdb_version}
|
BuildRequires: libtdb-devel >= %{tdb_version}
|
||||||
@ -48,8 +47,8 @@ by Windows 2000 and above.
|
|||||||
%package client
|
%package client
|
||||||
Summary: Samba client programs
|
Summary: Samba client programs
|
||||||
Group: Applications/System
|
Group: Applications/System
|
||||||
Requires: %{name}-common = %{epoch}:%{version}-%{release}
|
Requires: %{name}-common = %{version}-%{release}
|
||||||
Requires: %{name}-libs = %{epoch}:%{version}-%{release}
|
Requires: %{name}-libs = %{version}-%{release}
|
||||||
|
|
||||||
%description client
|
%description client
|
||||||
The %{name}-client package provides some SMB/CIFS clients to complement
|
The %{name}-client package provides some SMB/CIFS clients to complement
|
||||||
@ -59,10 +58,6 @@ of SMB/CIFS shares and printing to SMB/CIFS printers.
|
|||||||
%package libs
|
%package libs
|
||||||
Summary: Samba libraries
|
Summary: Samba libraries
|
||||||
Group: Applications/System
|
Group: Applications/System
|
||||||
Requires: libtdb >= 0:%{tdb_version}
|
|
||||||
Requires: libtalloc >= 0:%{talloc_version}
|
|
||||||
Requires(post): /sbin/ldconfig
|
|
||||||
Requires(postun): /sbin/ldconfig
|
|
||||||
|
|
||||||
%description libs
|
%description libs
|
||||||
The %{name}-libs package contains the libraries needed by programs
|
The %{name}-libs package contains the libraries needed by programs
|
||||||
@ -71,7 +66,7 @@ that link against the SMB, RPC and other protocols provided by the Samba suite.
|
|||||||
%package python
|
%package python
|
||||||
Summary: Samba python libraries
|
Summary: Samba python libraries
|
||||||
Group: Applications/System
|
Group: Applications/System
|
||||||
Requires: %{name}-libs = %{epoch}:%{version}-%{release}
|
Requires: %{name}-libs = %{version}-%{release}
|
||||||
|
|
||||||
%description python
|
%description python
|
||||||
The %{name}-python package contains the python libraries needed by programs
|
The %{name}-python package contains the python libraries needed by programs
|
||||||
@ -80,7 +75,7 @@ that use SMB, RPC and other Samba provided protocols in python programs/
|
|||||||
%package devel
|
%package devel
|
||||||
Summary: Developer tools for Samba libraries
|
Summary: Developer tools for Samba libraries
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
Requires: %{name}-libs = %{epoch}:%{version}-%{release}
|
Requires: %{name}-libs = %{version}-%{release}
|
||||||
|
|
||||||
%description devel
|
%description devel
|
||||||
The %{name}-devel package contains the header files for the libraries
|
The %{name}-devel package contains the header files for the libraries
|
||||||
@ -99,8 +94,8 @@ and Wireshark to parse IDL and similar protocols
|
|||||||
%package common
|
%package common
|
||||||
Summary: Files used by both Samba servers and clients
|
Summary: Files used by both Samba servers and clients
|
||||||
Group: Applications/System
|
Group: Applications/System
|
||||||
Requires: %{name}-libs = %{epoch}:%{version}-%{release}
|
Requires: %{name}-libs = %{version}-%{release}
|
||||||
Requires(post): /sbin/chkconfig, /sbin/service, coreutils
|
Requires(post): /sbin/chkconfig, /sbin/service
|
||||||
Requires(preun): /sbin/chkconfig, /sbin/service
|
Requires(preun): /sbin/chkconfig, /sbin/service
|
||||||
|
|
||||||
%description common
|
%description common
|
||||||
@ -110,7 +105,7 @@ packages of Samba.
|
|||||||
%package winbind
|
%package winbind
|
||||||
Summary: Samba winbind
|
Summary: Samba winbind
|
||||||
Group: Applications/System
|
Group: Applications/System
|
||||||
Requires: %{name} = %{epoch}:%{version}-%{release}
|
Requires: %{name} = %{version}-%{release}
|
||||||
|
|
||||||
%description winbind
|
%description winbind
|
||||||
The samba-winbind package provides the winbind NSS library, and some
|
The samba-winbind package provides the winbind NSS library, and some
|
||||||
|
@ -360,6 +360,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
|
|||||||
struct gssapi_creds_container *gcc;
|
struct gssapi_creds_container *gcc;
|
||||||
struct ccache_container *ccache;
|
struct ccache_container *ccache;
|
||||||
gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
|
||||||
|
krb5_enctype *etypes = NULL;
|
||||||
|
|
||||||
if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold &&
|
if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold &&
|
||||||
cred->client_gss_creds_obtained > CRED_UNINITIALISED) {
|
cred->client_gss_creds_obtained > CRED_UNINITIALISED) {
|
||||||
@ -391,6 +392,28 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* transfer the enctypes from the smb_krb5_context to the gssapi layer */
|
||||||
|
min_stat = krb5_get_default_in_tkt_etypes(ccache->smb_krb5_context->krb5_context,
|
||||||
|
&etypes);
|
||||||
|
if (min_stat == 0) {
|
||||||
|
OM_uint32 num_ktypes;
|
||||||
|
|
||||||
|
for (num_ktypes = 0; etypes[num_ktypes]; num_ktypes++);
|
||||||
|
|
||||||
|
maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, gcc->creds,
|
||||||
|
num_ktypes, etypes);
|
||||||
|
krb5_xfree (etypes);
|
||||||
|
if (maj_stat) {
|
||||||
|
talloc_free(gcc);
|
||||||
|
if (min_stat) {
|
||||||
|
ret = min_stat;
|
||||||
|
} else {
|
||||||
|
ret = EINVAL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG */
|
/* don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG */
|
||||||
maj_stat = gss_set_cred_option(&min_stat, &gcc->creds,
|
maj_stat = gss_set_cred_option(&min_stat, &gcc->creds,
|
||||||
GSS_KRB5_CRED_NO_CI_FLAGS_X,
|
GSS_KRB5_CRED_NO_CI_FLAGS_X,
|
||||||
|
@ -1034,35 +1034,22 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit
|
|||||||
= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
|
= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
|
||||||
OM_uint32 maj_stat, min_stat;
|
OM_uint32 maj_stat, min_stat;
|
||||||
gss_buffer_desc input_token, output_token;
|
gss_buffer_desc input_token, output_token;
|
||||||
int conf_state;
|
|
||||||
ssize_t sig_length = 0;
|
|
||||||
|
|
||||||
input_token.length = length;
|
input_token.length = length;
|
||||||
input_token.value = discard_const_p(uint8_t *, data);
|
input_token.value = discard_const_p(uint8_t *, data);
|
||||||
|
|
||||||
maj_stat = gss_wrap(&min_stat,
|
maj_stat = gss_get_mic(&min_stat,
|
||||||
gensec_gssapi_state->gssapi_context,
|
gensec_gssapi_state->gssapi_context,
|
||||||
0,
|
|
||||||
GSS_C_QOP_DEFAULT,
|
GSS_C_QOP_DEFAULT,
|
||||||
&input_token,
|
&input_token,
|
||||||
&conf_state,
|
|
||||||
&output_token);
|
&output_token);
|
||||||
if (GSS_ERROR(maj_stat)) {
|
if (GSS_ERROR(maj_stat)) {
|
||||||
DEBUG(1, ("GSS Wrap failed: %s\n",
|
DEBUG(1, ("GSS GetMic failed: %s\n",
|
||||||
gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
|
gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
|
||||||
return NT_STATUS_ACCESS_DENIED;
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_token.length < input_token.length) {
|
*sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, output_token.length);
|
||||||
DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n",
|
|
||||||
(long)output_token.length, (long)length));
|
|
||||||
return NT_STATUS_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Caller must pad to right boundary */
|
|
||||||
sig_length = output_token.length - input_token.length;
|
|
||||||
|
|
||||||
*sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length);
|
|
||||||
|
|
||||||
dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
|
dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
|
||||||
|
|
||||||
@ -1080,39 +1067,29 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi
|
|||||||
struct gensec_gssapi_state *gensec_gssapi_state
|
struct gensec_gssapi_state *gensec_gssapi_state
|
||||||
= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
|
= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
|
||||||
OM_uint32 maj_stat, min_stat;
|
OM_uint32 maj_stat, min_stat;
|
||||||
gss_buffer_desc input_token, output_token;
|
gss_buffer_desc input_token;
|
||||||
int conf_state;
|
gss_buffer_desc input_message;
|
||||||
gss_qop_t qop_state;
|
gss_qop_t qop_state;
|
||||||
DATA_BLOB in;
|
|
||||||
|
|
||||||
dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
|
dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length);
|
||||||
|
|
||||||
in = data_blob_talloc(mem_ctx, NULL, sig->length + length);
|
input_message.length = length;
|
||||||
|
input_message.value = data;
|
||||||
|
|
||||||
memcpy(in.data, sig->data, sig->length);
|
input_token.length = sig->length;
|
||||||
memcpy(in.data + sig->length, data, length);
|
input_token.value = sig->data;
|
||||||
|
|
||||||
input_token.length = in.length;
|
maj_stat = gss_verify_mic(&min_stat,
|
||||||
input_token.value = in.data;
|
|
||||||
|
|
||||||
maj_stat = gss_unwrap(&min_stat,
|
|
||||||
gensec_gssapi_state->gssapi_context,
|
gensec_gssapi_state->gssapi_context,
|
||||||
|
&input_message,
|
||||||
&input_token,
|
&input_token,
|
||||||
&output_token,
|
|
||||||
&conf_state,
|
|
||||||
&qop_state);
|
&qop_state);
|
||||||
if (GSS_ERROR(maj_stat)) {
|
if (GSS_ERROR(maj_stat)) {
|
||||||
DEBUG(1, ("GSS UnWrap failed: %s\n",
|
DEBUG(1, ("GSS VerifyMic failed: %s\n",
|
||||||
gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
|
gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
|
||||||
return NT_STATUS_ACCESS_DENIED;
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_token.length != length) {
|
|
||||||
return NT_STATUS_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
gss_release_buffer(&min_stat, &output_token);
|
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,3 +122,4 @@
|
|||||||
#define DS_BEHAVIOR_WIN2000 0
|
#define DS_BEHAVIOR_WIN2000 0
|
||||||
#define DS_BEHAVIOR_WIN2003_INTERIM 1
|
#define DS_BEHAVIOR_WIN2003_INTERIM 1
|
||||||
#define DS_BEHAVIOR_WIN2003 2
|
#define DS_BEHAVIOR_WIN2003 2
|
||||||
|
#define DS_BEHAVIOR_WIN2008 3
|
||||||
|
@ -142,10 +142,19 @@ static void dreplsrv_out_drsuapi_bind_recv(struct rpc_request *req)
|
|||||||
info24 = &st->bind_r.out.bind_info->info.info24;
|
info24 = &st->bind_r.out.bind_info->info.info24;
|
||||||
st->drsuapi->remote_info28.supported_extensions = info24->supported_extensions;
|
st->drsuapi->remote_info28.supported_extensions = info24->supported_extensions;
|
||||||
st->drsuapi->remote_info28.site_guid = info24->site_guid;
|
st->drsuapi->remote_info28.site_guid = info24->site_guid;
|
||||||
st->drsuapi->remote_info28.u1 = info24->u1;
|
st->drsuapi->remote_info28.pid = info24->pid;
|
||||||
st->drsuapi->remote_info28.repl_epoch = 0;
|
st->drsuapi->remote_info28.repl_epoch = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 48: {
|
||||||
|
struct drsuapi_DsBindInfo48 *info48;
|
||||||
|
info48 = &st->bind_r.out.bind_info->info.info48;
|
||||||
|
st->drsuapi->remote_info28.supported_extensions = info48->supported_extensions;
|
||||||
|
st->drsuapi->remote_info28.site_guid = info48->site_guid;
|
||||||
|
st->drsuapi->remote_info28.pid = info48->pid;
|
||||||
|
st->drsuapi->remote_info28.repl_epoch = info48->repl_epoch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 28:
|
case 28:
|
||||||
st->drsuapi->remote_info28 = st->bind_r.out.bind_info->info.info28;
|
st->drsuapi->remote_info28 = st->bind_r.out.bind_info->info.info28;
|
||||||
break;
|
break;
|
||||||
|
@ -104,7 +104,7 @@ static WERROR dreplsrv_connect_samdb(struct dreplsrv_service *service, struct lo
|
|||||||
/* TODO: fill in site_guid */
|
/* TODO: fill in site_guid */
|
||||||
bind_info28->site_guid = GUID_zero();
|
bind_info28->site_guid = GUID_zero();
|
||||||
/* TODO: find out how this is really triggered! */
|
/* TODO: find out how this is really triggered! */
|
||||||
bind_info28->u1 = 0;
|
bind_info28->pid = 0;
|
||||||
bind_info28->repl_epoch = 0;
|
bind_info28->repl_epoch = 0;
|
||||||
|
|
||||||
return WERR_OK;
|
return WERR_OK;
|
||||||
|
@ -699,6 +699,50 @@ static int partition_extended_replicated_objects(struct ldb_module *module, stru
|
|||||||
return partition_replicate(module, req, ext->partition_dn);
|
return partition_replicate(module, req, ext->partition_dn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int partition_extended_schema_update_now(struct ldb_module *module, struct ldb_request *req)
|
||||||
|
{
|
||||||
|
struct dsdb_control_current_partition *partition;
|
||||||
|
struct partition_private_data *data;
|
||||||
|
struct ldb_dn *schema_dn;
|
||||||
|
struct partition_context *ac;
|
||||||
|
struct ldb_module *backend;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
schema_dn = talloc_get_type(req->op.extended.data, struct ldb_dn);
|
||||||
|
if (!schema_dn) {
|
||||||
|
ldb_debug(module->ldb, LDB_DEBUG_FATAL, "partition_extended: invalid extended data\n");
|
||||||
|
return LDB_ERR_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = talloc_get_type(module->private_data, struct partition_private_data);
|
||||||
|
if (!data) {
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
partition = find_partition( data, schema_dn );
|
||||||
|
if (!partition) {
|
||||||
|
return ldb_next_request(module, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
ac = partition_init_handle(req, module);
|
||||||
|
if (!ac) {
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
backend = make_module_for_next_request(req, module->ldb, partition->module);
|
||||||
|
if (!backend) {
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ldb_next_request(backend, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* extended */
|
/* extended */
|
||||||
static int partition_extended(struct ldb_module *module, struct ldb_request *req)
|
static int partition_extended(struct ldb_module *module, struct ldb_request *req)
|
||||||
{
|
{
|
||||||
@ -708,6 +752,11 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req
|
|||||||
return partition_extended_replicated_objects(module, req);
|
return partition_extended_replicated_objects(module, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* forward schemaUpdateNow operation to schema_fsmo module*/
|
||||||
|
if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) == 0) {
|
||||||
|
return partition_extended_schema_update_now( module, req );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* as the extended operation has no dn
|
* as the extended operation has no dn
|
||||||
* we need to send it to all partitions
|
* we need to send it to all partitions
|
||||||
|
@ -140,6 +140,11 @@ struct setup_password_fields_io {
|
|||||||
struct samr_Password *nt_history;
|
struct samr_Password *nt_history;
|
||||||
uint32_t lm_history_len;
|
uint32_t lm_history_len;
|
||||||
struct samr_Password *lm_history;
|
struct samr_Password *lm_history;
|
||||||
|
const char *salt;
|
||||||
|
DATA_BLOB aes_256;
|
||||||
|
DATA_BLOB aes_128;
|
||||||
|
DATA_BLOB des_md5;
|
||||||
|
DATA_BLOB des_crc;
|
||||||
struct ldb_val supplemental;
|
struct ldb_val supplemental;
|
||||||
NTTIME last_set;
|
NTTIME last_set;
|
||||||
uint32_t kvno;
|
uint32_t kvno;
|
||||||
@ -216,21 +221,12 @@ static int setup_lm_fields(struct setup_password_fields_io *io)
|
|||||||
return LDB_SUCCESS;
|
return LDB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
static int setup_kerberos_keys(struct setup_password_fields_io *io)
|
||||||
const struct supplementalCredentialsBlob *old_scb,
|
|
||||||
struct package_PrimaryKerberosBlob *pkb)
|
|
||||||
{
|
{
|
||||||
krb5_error_code krb5_ret;
|
krb5_error_code krb5_ret;
|
||||||
Principal *salt_principal;
|
Principal *salt_principal;
|
||||||
krb5_salt salt;
|
krb5_salt salt;
|
||||||
krb5_keyblock key;
|
krb5_keyblock key;
|
||||||
uint32_t k=0;
|
|
||||||
struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3;
|
|
||||||
struct supplementalCredentialsPackage *old_scp = NULL;
|
|
||||||
struct package_PrimaryKerberosBlob _old_pkb;
|
|
||||||
struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL;
|
|
||||||
uint32_t i;
|
|
||||||
enum ndr_err_code ndr_err;
|
|
||||||
|
|
||||||
/* Many, many thanks to lukeh@padl.com for this
|
/* Many, many thanks to lukeh@padl.com for this
|
||||||
* algorithm, described in his Nov 10 2004 mail to
|
* algorithm, described in his Nov 10 2004 mail to
|
||||||
@ -290,7 +286,7 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
|||||||
}
|
}
|
||||||
if (krb5_ret) {
|
if (krb5_ret) {
|
||||||
ldb_asprintf_errstring(io->ac->module->ldb,
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
"setup_primary_kerberos: "
|
"setup_kerberos_keys: "
|
||||||
"generation of a salting principal failed: %s",
|
"generation of a salting principal failed: %s",
|
||||||
smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
|
smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
@ -304,55 +300,23 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
|||||||
krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal);
|
krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal);
|
||||||
if (krb5_ret) {
|
if (krb5_ret) {
|
||||||
ldb_asprintf_errstring(io->ac->module->ldb,
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
"setup_primary_kerberos: "
|
"setup_kerberos_keys: "
|
||||||
"generation of krb5_salt failed: %s",
|
"generation of krb5_salt failed: %s",
|
||||||
smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
|
smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
/* create a talloc copy */
|
/* create a talloc copy */
|
||||||
pkb3->salt.string = talloc_strndup(io->ac,
|
io->g.salt = talloc_strndup(io->ac,
|
||||||
salt.saltvalue.data,
|
salt.saltvalue.data,
|
||||||
salt.saltvalue.length);
|
salt.saltvalue.length);
|
||||||
krb5_free_salt(io->smb_krb5_context->krb5_context, salt);
|
krb5_free_salt(io->smb_krb5_context->krb5_context, salt);
|
||||||
if (!pkb3->salt.string) {
|
if (!io->g.salt) {
|
||||||
ldb_oom(io->ac->module->ldb);
|
ldb_oom(io->ac->module->ldb);
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
salt.saltvalue.data = discard_const(pkb3->salt.string);
|
salt.saltvalue.data = discard_const(io->g.salt);
|
||||||
salt.saltvalue.length = strlen(pkb3->salt.string);
|
salt.saltvalue.length = strlen(io->g.salt);
|
||||||
|
|
||||||
/*
|
|
||||||
* prepare generation of keys
|
|
||||||
*
|
|
||||||
* ENCTYPE_AES256_CTS_HMAC_SHA1_96 (disabled by default)
|
|
||||||
* ENCTYPE_DES_CBC_MD5
|
|
||||||
* ENCTYPE_DES_CBC_CRC
|
|
||||||
*
|
|
||||||
* NOTE: update num_keys when you add another enctype!
|
|
||||||
*/
|
|
||||||
pkb3->num_keys = 3;
|
|
||||||
pkb3->keys = talloc_array(io->ac, struct package_PrimaryKerberosKey, pkb3->num_keys);
|
|
||||||
if (!pkb3->keys) {
|
|
||||||
ldb_oom(io->ac->module->ldb);
|
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
|
||||||
}
|
|
||||||
pkb3->unknown3 = talloc_zero_array(io->ac, uint64_t, pkb3->num_keys);
|
|
||||||
if (!pkb3->unknown3) {
|
|
||||||
ldb_oom(io->ac->module->ldb);
|
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lp_parm_bool(ldb_get_opaque(io->ac->module->ldb, "loadparm"), NULL, "password_hash", "create_aes_key", false)) {
|
|
||||||
/*
|
|
||||||
* TODO:
|
|
||||||
*
|
|
||||||
* w2k and w2k3 doesn't support AES, so we'll not include
|
|
||||||
* the AES key here yet.
|
|
||||||
*
|
|
||||||
* Also we don't have an example supplementalCredentials blob
|
|
||||||
* from Windows Longhorn Server with AES support
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/*
|
/*
|
||||||
* create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
|
* create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
|
||||||
* the salt and the cleartext password
|
* the salt and the cleartext password
|
||||||
@ -362,22 +326,45 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
|||||||
io->n.cleartext,
|
io->n.cleartext,
|
||||||
salt,
|
salt,
|
||||||
&key);
|
&key);
|
||||||
pkb3->keys[k].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
|
if (krb5_ret) {
|
||||||
pkb3->keys[k].value = talloc(pkb3->keys, DATA_BLOB);
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
if (!pkb3->keys[k].value) {
|
"setup_kerberos_keys: "
|
||||||
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
"generation of a aes256-cts-hmac-sha1-96 key failed: %s",
|
||||||
ldb_oom(io->ac->module->ldb);
|
smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
*pkb3->keys[k].value = data_blob_talloc(pkb3->keys[k].value,
|
io->g.aes_256 = data_blob_talloc(io->ac,
|
||||||
key.keyvalue.data,
|
key.keyvalue.data,
|
||||||
key.keyvalue.length);
|
key.keyvalue.length);
|
||||||
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
||||||
if (!pkb3->keys[k].value->data) {
|
if (!io->g.aes_256.data) {
|
||||||
ldb_oom(io->ac->module->ldb);
|
ldb_oom(io->ac->module->ldb);
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
k++;
|
|
||||||
|
/*
|
||||||
|
* create ENCTYPE_AES128_CTS_HMAC_SHA1_96 key out of
|
||||||
|
* the salt and the cleartext password
|
||||||
|
*/
|
||||||
|
krb5_ret = krb5_string_to_key_salt(io->smb_krb5_context->krb5_context,
|
||||||
|
ENCTYPE_AES128_CTS_HMAC_SHA1_96,
|
||||||
|
io->n.cleartext,
|
||||||
|
salt,
|
||||||
|
&key);
|
||||||
|
if (krb5_ret) {
|
||||||
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
|
"setup_kerberos_keys: "
|
||||||
|
"generation of a aes128-cts-hmac-sha1-96 key failed: %s",
|
||||||
|
smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
io->g.aes_128 = data_blob_talloc(io->ac,
|
||||||
|
key.keyvalue.data,
|
||||||
|
key.keyvalue.length);
|
||||||
|
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
||||||
|
if (!io->g.aes_128.data) {
|
||||||
|
ldb_oom(io->ac->module->ldb);
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -389,22 +376,21 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
|||||||
io->n.cleartext,
|
io->n.cleartext,
|
||||||
salt,
|
salt,
|
||||||
&key);
|
&key);
|
||||||
pkb3->keys[k].keytype = ENCTYPE_DES_CBC_MD5;
|
if (krb5_ret) {
|
||||||
pkb3->keys[k].value = talloc(pkb3->keys, DATA_BLOB);
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
if (!pkb3->keys[k].value) {
|
"setup_kerberos_keys: "
|
||||||
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
"generation of a des-cbc-md5 key failed: %s",
|
||||||
ldb_oom(io->ac->module->ldb);
|
smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
*pkb3->keys[k].value = data_blob_talloc(pkb3->keys[k].value,
|
io->g.des_md5 = data_blob_talloc(io->ac,
|
||||||
key.keyvalue.data,
|
key.keyvalue.data,
|
||||||
key.keyvalue.length);
|
key.keyvalue.length);
|
||||||
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
||||||
if (!pkb3->keys[k].value->data) {
|
if (!io->g.des_md5.data) {
|
||||||
ldb_oom(io->ac->module->ldb);
|
ldb_oom(io->ac->module->ldb);
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
k++;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create ENCTYPE_DES_CBC_CRC key out of
|
* create ENCTYPE_DES_CBC_CRC key out of
|
||||||
@ -415,30 +401,61 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
|||||||
io->n.cleartext,
|
io->n.cleartext,
|
||||||
salt,
|
salt,
|
||||||
&key);
|
&key);
|
||||||
pkb3->keys[k].keytype = ENCTYPE_DES_CBC_CRC;
|
if (krb5_ret) {
|
||||||
pkb3->keys[k].value = talloc(pkb3->keys, DATA_BLOB);
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
if (!pkb3->keys[k].value) {
|
"setup_kerberos_keys: "
|
||||||
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
"generation of a des-cbc-crc key failed: %s",
|
||||||
ldb_oom(io->ac->module->ldb);
|
smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
*pkb3->keys[k].value = data_blob_talloc(pkb3->keys[k].value,
|
io->g.des_crc = data_blob_talloc(io->ac,
|
||||||
key.keyvalue.data,
|
key.keyvalue.data,
|
||||||
key.keyvalue.length);
|
key.keyvalue.length);
|
||||||
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
|
||||||
if (!pkb3->keys[k].value->data) {
|
if (!io->g.des_crc.data) {
|
||||||
ldb_oom(io->ac->module->ldb);
|
ldb_oom(io->ac->module->ldb);
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
k++;
|
|
||||||
|
|
||||||
/* fix up key number */
|
return LDB_SUCCESS;
|
||||||
pkb3->num_keys = k;
|
}
|
||||||
|
|
||||||
|
static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
||||||
|
const struct supplementalCredentialsBlob *old_scb,
|
||||||
|
struct package_PrimaryKerberosBlob *pkb)
|
||||||
|
{
|
||||||
|
struct package_PrimaryKerberosCtr3 *pkb3 = &pkb->ctr.ctr3;
|
||||||
|
struct supplementalCredentialsPackage *old_scp = NULL;
|
||||||
|
struct package_PrimaryKerberosBlob _old_pkb;
|
||||||
|
struct package_PrimaryKerberosCtr3 *old_pkb3 = NULL;
|
||||||
|
uint32_t i;
|
||||||
|
enum ndr_err_code ndr_err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prepare generation of keys
|
||||||
|
*
|
||||||
|
* ENCTYPE_DES_CBC_MD5
|
||||||
|
* ENCTYPE_DES_CBC_CRC
|
||||||
|
*/
|
||||||
|
pkb->version = 3;
|
||||||
|
pkb3->salt.string = io->g.salt;
|
||||||
|
pkb3->num_keys = 2;
|
||||||
|
pkb3->keys = talloc_array(io->ac,
|
||||||
|
struct package_PrimaryKerberosKey3,
|
||||||
|
pkb3->num_keys);
|
||||||
|
if (!pkb3->keys) {
|
||||||
|
ldb_oom(io->ac->module->ldb);
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkb3->keys[0].keytype = ENCTYPE_DES_CBC_MD5;
|
||||||
|
pkb3->keys[0].value = &io->g.des_md5;
|
||||||
|
pkb3->keys[1].keytype = ENCTYPE_DES_CBC_CRC;
|
||||||
|
pkb3->keys[1].value = &io->g.des_crc;
|
||||||
|
|
||||||
/* initialize the old keys to zero */
|
/* initialize the old keys to zero */
|
||||||
pkb3->num_old_keys = 0;
|
pkb3->num_old_keys = 0;
|
||||||
pkb3->old_keys = NULL;
|
pkb3->old_keys = NULL;
|
||||||
pkb3->unknown3_old = NULL;
|
|
||||||
|
|
||||||
/* if there're no old keys, then we're done */
|
/* if there're no old keys, then we're done */
|
||||||
if (!old_scb) {
|
if (!old_scb) {
|
||||||
@ -446,10 +463,6 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i < old_scb->sub.num_packages; i++) {
|
for (i=0; i < old_scb->sub.num_packages; i++) {
|
||||||
if (old_scb->sub.packages[i].unknown1 != 0x00000001) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) {
|
if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -503,7 +516,124 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
|
|||||||
/* fill in the old keys */
|
/* fill in the old keys */
|
||||||
pkb3->num_old_keys = old_pkb3->num_keys;
|
pkb3->num_old_keys = old_pkb3->num_keys;
|
||||||
pkb3->old_keys = old_pkb3->keys;
|
pkb3->old_keys = old_pkb3->keys;
|
||||||
pkb3->unknown3_old = old_pkb3->unknown3;
|
|
||||||
|
return LDB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setup_primary_kerberos_newer(struct setup_password_fields_io *io,
|
||||||
|
const struct supplementalCredentialsBlob *old_scb,
|
||||||
|
struct package_PrimaryKerberosBlob *pkb)
|
||||||
|
{
|
||||||
|
struct package_PrimaryKerberosCtr4 *pkb4 = &pkb->ctr.ctr4;
|
||||||
|
struct supplementalCredentialsPackage *old_scp = NULL;
|
||||||
|
struct package_PrimaryKerberosBlob _old_pkb;
|
||||||
|
struct package_PrimaryKerberosCtr4 *old_pkb4 = NULL;
|
||||||
|
uint32_t i;
|
||||||
|
enum ndr_err_code ndr_err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prepare generation of keys
|
||||||
|
*
|
||||||
|
* ENCTYPE_AES256_CTS_HMAC_SHA1_96
|
||||||
|
* ENCTYPE_AES128_CTS_HMAC_SHA1_96
|
||||||
|
* ENCTYPE_DES_CBC_MD5
|
||||||
|
* ENCTYPE_DES_CBC_CRC
|
||||||
|
*/
|
||||||
|
pkb->version = 4;
|
||||||
|
pkb4->salt.string = io->g.salt;
|
||||||
|
pkb4->default_iteration_count = 4096;
|
||||||
|
pkb4->num_keys = 4;
|
||||||
|
|
||||||
|
pkb4->keys = talloc_array(io->ac,
|
||||||
|
struct package_PrimaryKerberosKey4,
|
||||||
|
pkb4->num_keys);
|
||||||
|
if (!pkb4->keys) {
|
||||||
|
ldb_oom(io->ac->module->ldb);
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkb4->keys[0].iteration_count = 4096;
|
||||||
|
pkb4->keys[0].keytype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
|
||||||
|
pkb4->keys[0].value = &io->g.aes_256;
|
||||||
|
pkb4->keys[1].iteration_count = 4096;
|
||||||
|
pkb4->keys[1].keytype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
|
||||||
|
pkb4->keys[1].value = &io->g.aes_128;
|
||||||
|
pkb4->keys[2].iteration_count = 4096;
|
||||||
|
pkb4->keys[2].keytype = ENCTYPE_DES_CBC_MD5;
|
||||||
|
pkb4->keys[2].value = &io->g.des_md5;
|
||||||
|
pkb4->keys[3].iteration_count = 4096;
|
||||||
|
pkb4->keys[3].keytype = ENCTYPE_DES_CBC_CRC;
|
||||||
|
pkb4->keys[3].value = &io->g.des_crc;
|
||||||
|
|
||||||
|
/* initialize the old keys to zero */
|
||||||
|
pkb4->num_old_keys = 0;
|
||||||
|
pkb4->old_keys = NULL;
|
||||||
|
pkb4->num_older_keys = 0;
|
||||||
|
pkb4->older_keys = NULL;
|
||||||
|
|
||||||
|
/* if there're no old keys, then we're done */
|
||||||
|
if (!old_scb) {
|
||||||
|
return LDB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < old_scb->sub.num_packages; i++) {
|
||||||
|
if (strcmp("Primary:Kerberos-Newer-Keys", old_scb->sub.packages[i].name) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!old_scb->sub.packages[i].data || !old_scb->sub.packages[i].data[0]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_scp = &old_scb->sub.packages[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Primary:Kerberos-Newer-Keys element of supplementalCredentials */
|
||||||
|
if (old_scp) {
|
||||||
|
DATA_BLOB blob;
|
||||||
|
|
||||||
|
blob = strhex_to_data_blob(old_scp->data);
|
||||||
|
if (!blob.data) {
|
||||||
|
ldb_oom(io->ac->module->ldb);
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
talloc_steal(io->ac, blob.data);
|
||||||
|
|
||||||
|
/* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
|
||||||
|
ndr_err = ndr_pull_struct_blob(&blob, io->ac,
|
||||||
|
lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")),
|
||||||
|
&_old_pkb,
|
||||||
|
(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
|
||||||
|
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
|
||||||
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
|
"setup_primary_kerberos_newer: "
|
||||||
|
"failed to pull old package_PrimaryKerberosBlob: %s",
|
||||||
|
nt_errstr(status));
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_old_pkb.version != 4) {
|
||||||
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
|
"setup_primary_kerberos_newer: "
|
||||||
|
"package_PrimaryKerberosBlob version[%u] expected[4]",
|
||||||
|
_old_pkb.version);
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_pkb4 = &_old_pkb.ctr.ctr4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we didn't found the old keys we're done */
|
||||||
|
if (!old_pkb4) {
|
||||||
|
return LDB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill in the old keys */
|
||||||
|
pkb4->num_old_keys = old_pkb4->num_keys;
|
||||||
|
pkb4->old_keys = old_pkb4->keys;
|
||||||
|
pkb4->num_older_keys = old_pkb4->num_old_keys;
|
||||||
|
pkb4->older_keys = old_pkb4->old_keys;
|
||||||
|
|
||||||
return LDB_SUCCESS;
|
return LDB_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -845,30 +975,48 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
|
|||||||
struct supplementalCredentialsBlob scb;
|
struct supplementalCredentialsBlob scb;
|
||||||
struct supplementalCredentialsBlob _old_scb;
|
struct supplementalCredentialsBlob _old_scb;
|
||||||
struct supplementalCredentialsBlob *old_scb = NULL;
|
struct supplementalCredentialsBlob *old_scb = NULL;
|
||||||
/* Packages + (Kerberos, WDigest and maybe CLEARTEXT) */
|
/* Packages + (Kerberos-Newer-Keys, Kerberos, WDigest and CLEARTEXT) */
|
||||||
uint32_t num_packages = 1 + 2;
|
uint32_t num_names = 0;
|
||||||
struct supplementalCredentialsPackage packages[1+3];
|
const char *names[1+4];
|
||||||
struct supplementalCredentialsPackage *pp = &packages[0];
|
uint32_t num_packages = 0;
|
||||||
struct supplementalCredentialsPackage *pk = &packages[1];
|
struct supplementalCredentialsPackage packages[1+4];
|
||||||
struct supplementalCredentialsPackage *pd = &packages[2];
|
/* Packages */
|
||||||
struct supplementalCredentialsPackage *pc = NULL;
|
struct supplementalCredentialsPackage *pp = NULL;
|
||||||
struct package_PackagesBlob pb;
|
struct package_PackagesBlob pb;
|
||||||
DATA_BLOB pb_blob;
|
DATA_BLOB pb_blob;
|
||||||
char *pb_hexstr;
|
char *pb_hexstr;
|
||||||
|
/* Primary:Kerberos-Newer-Keys */
|
||||||
|
const char **nkn = NULL;
|
||||||
|
struct supplementalCredentialsPackage *pkn = NULL;
|
||||||
|
struct package_PrimaryKerberosBlob pknb;
|
||||||
|
DATA_BLOB pknb_blob;
|
||||||
|
char *pknb_hexstr;
|
||||||
|
/* Primary:Kerberos */
|
||||||
|
const char **nk = NULL;
|
||||||
|
struct supplementalCredentialsPackage *pk = NULL;
|
||||||
struct package_PrimaryKerberosBlob pkb;
|
struct package_PrimaryKerberosBlob pkb;
|
||||||
DATA_BLOB pkb_blob;
|
DATA_BLOB pkb_blob;
|
||||||
char *pkb_hexstr;
|
char *pkb_hexstr;
|
||||||
|
/* Primary:WDigest */
|
||||||
|
const char **nd = NULL;
|
||||||
|
struct supplementalCredentialsPackage *pd = NULL;
|
||||||
struct package_PrimaryWDigestBlob pdb;
|
struct package_PrimaryWDigestBlob pdb;
|
||||||
DATA_BLOB pdb_blob;
|
DATA_BLOB pdb_blob;
|
||||||
char *pdb_hexstr;
|
char *pdb_hexstr;
|
||||||
|
/* Primary:CLEARTEXT */
|
||||||
|
const char **nc = NULL;
|
||||||
|
struct supplementalCredentialsPackage *pc = NULL;
|
||||||
struct package_PrimaryCLEARTEXTBlob pcb;
|
struct package_PrimaryCLEARTEXTBlob pcb;
|
||||||
DATA_BLOB pcb_blob;
|
DATA_BLOB pcb_blob;
|
||||||
char *pcb_hexstr;
|
char *pcb_hexstr;
|
||||||
int ret;
|
int ret;
|
||||||
enum ndr_err_code ndr_err;
|
enum ndr_err_code ndr_err;
|
||||||
uint8_t zero16[16];
|
uint8_t zero16[16];
|
||||||
|
bool do_newer_keys = false;
|
||||||
|
bool do_cleartext = false;
|
||||||
|
|
||||||
ZERO_STRUCT(zero16);
|
ZERO_STRUCT(zero16);
|
||||||
|
ZERO_STRUCT(names);
|
||||||
|
|
||||||
if (!io->n.cleartext) {
|
if (!io->n.cleartext) {
|
||||||
/*
|
/*
|
||||||
@ -880,7 +1028,9 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
|
|||||||
|
|
||||||
/* if there's an old supplementaCredentials blob then parse it */
|
/* if there's an old supplementaCredentials blob then parse it */
|
||||||
if (io->o.supplemental) {
|
if (io->o.supplemental) {
|
||||||
ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac, lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), &_old_scb,
|
ndr_err = ndr_pull_struct_blob_all(io->o.supplemental, io->ac,
|
||||||
|
lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")),
|
||||||
|
&_old_scb,
|
||||||
(ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
|
(ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
|
||||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
|
NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
|
||||||
@ -891,22 +1041,101 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
|
|||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_old_scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
|
||||||
old_scb = &_old_scb;
|
old_scb = &_old_scb;
|
||||||
|
} else {
|
||||||
|
ldb_debug(io->ac->module->ldb, LDB_DEBUG_ERROR,
|
||||||
|
"setup_supplemental_field: "
|
||||||
|
"supplementalCredentialsBlob signature[0x%04X] expected[0x%04X]",
|
||||||
|
_old_scb.sub.signature, SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: do the correct check for this, it maybe depends on the functional level? */
|
||||||
|
do_newer_keys = lp_parm_bool(ldb_get_opaque(io->ac->module->ldb, "loadparm"),
|
||||||
|
NULL, "password_hash", "create_aes_key", false);
|
||||||
|
|
||||||
if (io->domain->store_cleartext &&
|
if (io->domain->store_cleartext &&
|
||||||
(io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
|
(io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
|
||||||
pc = &packages[3];
|
do_cleartext = true;
|
||||||
num_packages++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kerberos, WDigest, CLEARTEXT and termination(counted by the Packages element) */
|
/*
|
||||||
pb.names = talloc_zero_array(io->ac, const char *, num_packages);
|
* The ordering is this
|
||||||
|
*
|
||||||
|
* Primary:Kerberos-Newer-Keys (optional)
|
||||||
|
* Primary:Kerberos
|
||||||
|
* Primary:WDigest
|
||||||
|
* Primary:CLEARTEXT (optional)
|
||||||
|
*
|
||||||
|
* And the 'Packages' package is insert before the last
|
||||||
|
* other package.
|
||||||
|
*/
|
||||||
|
if (do_newer_keys) {
|
||||||
|
/* Primary:Kerberos-Newer-Keys */
|
||||||
|
nkn = &names[num_names++];
|
||||||
|
pkn = &packages[num_packages++];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary:Kerberos */
|
||||||
|
nk = &names[num_names++];
|
||||||
|
pk = &packages[num_packages++];
|
||||||
|
|
||||||
|
if (!do_cleartext) {
|
||||||
|
/* Packages */
|
||||||
|
pp = &packages[num_packages++];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Primary:WDigest */
|
||||||
|
nd = &names[num_names++];
|
||||||
|
pd = &packages[num_packages++];
|
||||||
|
|
||||||
|
if (do_cleartext) {
|
||||||
|
/* Packages */
|
||||||
|
pp = &packages[num_packages++];
|
||||||
|
|
||||||
|
/* Primary:CLEARTEXT */
|
||||||
|
nc = &names[num_names++];
|
||||||
|
pc = &packages[num_packages++];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkn) {
|
||||||
|
/*
|
||||||
|
* setup 'Primary:Kerberos-Newer-Keys' element
|
||||||
|
*/
|
||||||
|
*nkn = "Kerberos-Newer-Keys";
|
||||||
|
|
||||||
|
ret = setup_primary_kerberos_newer(io, old_scb, &pknb);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndr_err = ndr_push_struct_blob(&pknb_blob, io->ac,
|
||||||
|
lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")),
|
||||||
|
&pknb,
|
||||||
|
(ndr_push_flags_fn_t)ndr_push_package_PrimaryKerberosBlob);
|
||||||
|
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
|
||||||
|
ldb_asprintf_errstring(io->ac->module->ldb,
|
||||||
|
"setup_supplemental_field: "
|
||||||
|
"failed to push package_PrimaryKerberosNeverBlob: %s",
|
||||||
|
nt_errstr(status));
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
pknb_hexstr = data_blob_hex_string(io->ac, &pknb_blob);
|
||||||
|
if (!pknb_hexstr) {
|
||||||
|
ldb_oom(io->ac->module->ldb);
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
pkn->name = "Primary:Kerberos-Newer-Keys";
|
||||||
|
pkn->reserved = 1;
|
||||||
|
pkn->data = pknb_hexstr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setup 'Primary:Kerberos' element
|
* setup 'Primary:Kerberos' element
|
||||||
*/
|
*/
|
||||||
pb.names[0] = "Kerberos";
|
*nk = "Kerberos";
|
||||||
|
|
||||||
ret = setup_primary_kerberos(io, old_scb, &pkb);
|
ret = setup_primary_kerberos(io, old_scb, &pkb);
|
||||||
if (ret != LDB_SUCCESS) {
|
if (ret != LDB_SUCCESS) {
|
||||||
@ -925,29 +1154,19 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
|
|||||||
nt_errstr(status));
|
nt_errstr(status));
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* TODO:
|
|
||||||
*
|
|
||||||
* This is ugly, but we want to generate the same blob as
|
|
||||||
* w2k and w2k3...we should handle this in the idl
|
|
||||||
*/
|
|
||||||
if (!data_blob_append(io->ac, &pkb_blob, zero16, sizeof(zero16))) {
|
|
||||||
ldb_oom(io->ac->module->ldb);
|
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
|
||||||
}
|
|
||||||
pkb_hexstr = data_blob_hex_string(io->ac, &pkb_blob);
|
pkb_hexstr = data_blob_hex_string(io->ac, &pkb_blob);
|
||||||
if (!pkb_hexstr) {
|
if (!pkb_hexstr) {
|
||||||
ldb_oom(io->ac->module->ldb);
|
ldb_oom(io->ac->module->ldb);
|
||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
pk->name = "Primary:Kerberos";
|
pk->name = "Primary:Kerberos";
|
||||||
pk->unknown1 = 1;
|
pk->reserved = 1;
|
||||||
pk->data = pkb_hexstr;
|
pk->data = pkb_hexstr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setup 'Primary:WDigest' element
|
* setup 'Primary:WDigest' element
|
||||||
*/
|
*/
|
||||||
pb.names[1] = "WDigest";
|
*nd = "WDigest";
|
||||||
|
|
||||||
ret = setup_primary_wdigest(io, old_scb, &pdb);
|
ret = setup_primary_wdigest(io, old_scb, &pdb);
|
||||||
if (ret != LDB_SUCCESS) {
|
if (ret != LDB_SUCCESS) {
|
||||||
@ -972,14 +1191,14 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
|
|||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
pd->name = "Primary:WDigest";
|
pd->name = "Primary:WDigest";
|
||||||
pd->unknown1 = 1;
|
pd->reserved = 1;
|
||||||
pd->data = pdb_hexstr;
|
pd->data = pdb_hexstr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setup 'Primary:CLEARTEXT' element
|
* setup 'Primary:CLEARTEXT' element
|
||||||
*/
|
*/
|
||||||
if (pc) {
|
if (pc) {
|
||||||
pb.names[2] = "CLEARTEXT";
|
*nc = "CLEARTEXT";
|
||||||
|
|
||||||
pcb.cleartext = io->n.cleartext;
|
pcb.cleartext = io->n.cleartext;
|
||||||
|
|
||||||
@ -1001,13 +1220,14 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
|
|||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
pc->name = "Primary:CLEARTEXT";
|
pc->name = "Primary:CLEARTEXT";
|
||||||
pc->unknown1 = 1;
|
pc->reserved = 1;
|
||||||
pc->data = pcb_hexstr;
|
pc->data = pcb_hexstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setup 'Packages' element
|
* setup 'Packages' element
|
||||||
*/
|
*/
|
||||||
|
pb.names = names;
|
||||||
ndr_err = ndr_push_struct_blob(&pb_blob, io->ac,
|
ndr_err = ndr_push_struct_blob(&pb_blob, io->ac,
|
||||||
lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")),
|
lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")),
|
||||||
&pb,
|
&pb,
|
||||||
@ -1026,12 +1246,13 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
|
|||||||
return LDB_ERR_OPERATIONS_ERROR;
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
}
|
}
|
||||||
pp->name = "Packages";
|
pp->name = "Packages";
|
||||||
pp->unknown1 = 2;
|
pp->reserved = 2;
|
||||||
pp->data = pb_hexstr;
|
pp->data = pb_hexstr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setup 'supplementalCredentials' value
|
* setup 'supplementalCredentials' value
|
||||||
*/
|
*/
|
||||||
|
ZERO_STRUCT(scb);
|
||||||
scb.sub.num_packages = num_packages;
|
scb.sub.num_packages = num_packages;
|
||||||
scb.sub.packages = packages;
|
scb.sub.packages = packages;
|
||||||
|
|
||||||
@ -1083,7 +1304,7 @@ static int setup_password_fields(struct setup_password_fields_io *io)
|
|||||||
return LDB_ERR_UNWILLING_TO_PERFORM;
|
return LDB_ERR_UNWILLING_TO_PERFORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (io->n.cleartext && !io->n.nt_hash) {
|
if (io->n.cleartext) {
|
||||||
struct samr_Password *hash;
|
struct samr_Password *hash;
|
||||||
|
|
||||||
hash = talloc(io->ac, struct samr_Password);
|
hash = talloc(io->ac, struct samr_Password);
|
||||||
@ -1104,7 +1325,7 @@ static int setup_password_fields(struct setup_password_fields_io *io)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (io->n.cleartext && !io->n.lm_hash) {
|
if (io->n.cleartext) {
|
||||||
struct samr_Password *hash;
|
struct samr_Password *hash;
|
||||||
|
|
||||||
hash = talloc(io->ac, struct samr_Password);
|
hash = talloc(io->ac, struct samr_Password);
|
||||||
@ -1122,6 +1343,13 @@ static int setup_password_fields(struct setup_password_fields_io *io)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (io->n.cleartext) {
|
||||||
|
ret = setup_kerberos_keys(io);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = setup_nt_fields(io);
|
ret = setup_nt_fields(io);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -263,9 +263,10 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
|
|||||||
struct ldb_request *down_req;
|
struct ldb_request *down_req;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* see if its for the rootDSE */
|
/* see if its for the rootDSE - only a base search on the "" DN qualifies */
|
||||||
if (req->op.search.scope != LDB_SCOPE_BASE ||
|
if (req->op.search.scope != LDB_SCOPE_BASE ||
|
||||||
( ! ldb_dn_is_null(req->op.search.base))) {
|
( ! ldb_dn_is_null(req->op.search.base))) {
|
||||||
|
/* Otherwise, pass down to the rest of the stack */
|
||||||
return ldb_next_request(module, req);
|
return ldb_next_request(module, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,9 +392,50 @@ static int rootdse_init(struct ldb_module *module)
|
|||||||
return ldb_next_init(module);
|
return ldb_next_init(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rootdse_modify(struct ldb_module *module, struct ldb_request *req)
|
||||||
|
{
|
||||||
|
struct ldb_result *ext_res;
|
||||||
|
int ret;
|
||||||
|
struct ldb_dn *schema_dn;
|
||||||
|
struct ldb_message_element *schemaUpdateNowAttr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
If dn is not "" we should let it pass through
|
||||||
|
*/
|
||||||
|
if (!ldb_dn_is_null(req->op.mod.message->dn)) {
|
||||||
|
return ldb_next_request(module, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
dn is empty so check for schemaUpdateNow attribute
|
||||||
|
"The type of modification and values specified in the LDAP modify operation do not matter." MSDN
|
||||||
|
*/
|
||||||
|
schemaUpdateNowAttr = ldb_msg_find_element(req->op.mod.message, "schemaUpdateNow");
|
||||||
|
if (!schemaUpdateNowAttr) {
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
schema_dn = samdb_schema_dn(module->ldb);
|
||||||
|
if (!schema_dn) {
|
||||||
|
ldb_reset_err_string(module->ldb);
|
||||||
|
ldb_debug(module->ldb, LDB_DEBUG_WARNING,
|
||||||
|
"rootdse_modify: no schema dn present: (skip ldb_extended call)\n");
|
||||||
|
return ldb_next_request(module, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_extended(module->ldb, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID, schema_dn, &ext_res);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
talloc_free(ext_res);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
_PUBLIC_ const struct ldb_module_ops ldb_rootdse_module_ops = {
|
_PUBLIC_ const struct ldb_module_ops ldb_rootdse_module_ops = {
|
||||||
.name = "rootdse",
|
.name = "rootdse",
|
||||||
.init_context = rootdse_init,
|
.init_context = rootdse_init,
|
||||||
.search = rootdse_search,
|
.search = rootdse_search,
|
||||||
.request = rootdse_request
|
.request = rootdse_request,
|
||||||
|
.modify = rootdse_modify
|
||||||
};
|
};
|
||||||
|
@ -148,8 +148,70 @@ static int schema_fsmo_add(struct ldb_module *module, struct ldb_request *req)
|
|||||||
return ldb_next_request(module, req);
|
return ldb_next_request(module, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *req)
|
||||||
|
{
|
||||||
|
WERROR status;
|
||||||
|
struct ldb_dn *schema_dn;
|
||||||
|
struct dsdb_schema *schema;
|
||||||
|
char *error_string = NULL;
|
||||||
|
int ret;
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
|
||||||
|
if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) {
|
||||||
|
return ldb_next_request(module, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
schema_dn = samdb_schema_dn(module->ldb);
|
||||||
|
if (!schema_dn) {
|
||||||
|
ldb_reset_err_string(module->ldb);
|
||||||
|
ldb_debug(module->ldb, LDB_DEBUG_WARNING,
|
||||||
|
"schema_fsmo_extended: no schema dn present: (skip schema loading)\n");
|
||||||
|
return ldb_next_request(module, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_ctx = talloc_new(module);
|
||||||
|
if (!mem_ctx) {
|
||||||
|
ldb_oom(module->ldb);
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dsdb_schema_from_schema_dn(mem_ctx, module->ldb,
|
||||||
|
lp_iconv_convenience(ldb_get_opaque(module->ldb, "loadparm")),
|
||||||
|
schema_dn, &schema, &error_string);
|
||||||
|
|
||||||
|
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||||
|
ldb_reset_err_string(module->ldb);
|
||||||
|
ldb_debug(module->ldb, LDB_DEBUG_WARNING,
|
||||||
|
"schema_fsmo_extended: no schema head present: (skip schema loading)\n");
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return ldb_next_request(module, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_asprintf_errstring(module->ldb,
|
||||||
|
"schema_fsmo_extended: dsdb_schema load failed: %s",
|
||||||
|
error_string);
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return ldb_next_request(module, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace the old schema*/
|
||||||
|
ret = dsdb_set_schema(module->ldb, schema);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
|
||||||
|
"schema_fsmo_extended: dsdb_set_schema() failed: %d:%s",
|
||||||
|
ret, ldb_strerror(ret));
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return LDB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
_PUBLIC_ const struct ldb_module_ops ldb_schema_fsmo_module_ops = {
|
_PUBLIC_ const struct ldb_module_ops ldb_schema_fsmo_module_ops = {
|
||||||
.name = "schema_fsmo",
|
.name = "schema_fsmo",
|
||||||
.init_context = schema_fsmo_init,
|
.init_context = schema_fsmo_init,
|
||||||
.add = schema_fsmo_add
|
.add = schema_fsmo_add,
|
||||||
|
.extended = schema_fsmo_extended
|
||||||
};
|
};
|
||||||
|
@ -90,4 +90,10 @@ struct dsdb_pdc_fsmo {
|
|||||||
struct ldb_dn *master_dn;
|
struct ldb_dn *master_dn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the schema_dn is passed as struct ldb_dn in
|
||||||
|
* req->op.extended.data
|
||||||
|
*/
|
||||||
|
#define DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID "1.3.6.1.4.1.7165.4.4.2"
|
||||||
|
|
||||||
#endif /* __SAMDB_H__ */
|
#endif /* __SAMDB_H__ */
|
||||||
|
@ -268,49 +268,9 @@ WERROR dsdb_verify_oid_mappings_drsuapi(const struct dsdb_schema *schema, const
|
|||||||
|
|
||||||
WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32_t *out)
|
WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32_t *out)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
return dsdb_find_prefix_for_oid(schema->num_prefixes, schema->prefixes, in, out);
|
||||||
|
|
||||||
for (i=0; i < schema->num_prefixes; i++) {
|
|
||||||
const char *val_str;
|
|
||||||
char *end_str;
|
|
||||||
unsigned val;
|
|
||||||
|
|
||||||
if (strncmp(schema->prefixes[i].oid, in, schema->prefixes[i].oid_len) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val_str = in + schema->prefixes[i].oid_len;
|
|
||||||
end_str = NULL;
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
if (val_str[0] == '\0') {
|
|
||||||
return WERR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* two '.' chars are invalid */
|
|
||||||
if (val_str[0] == '.') {
|
|
||||||
return WERR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = strtoul(val_str, &end_str, 10);
|
|
||||||
if (end_str[0] == '.' && end_str[1] != '\0') {
|
|
||||||
/*
|
|
||||||
* if it's a '.' and not the last char
|
|
||||||
* then maybe an other mapping apply
|
|
||||||
*/
|
|
||||||
continue;
|
|
||||||
} else if (end_str[0] != '\0') {
|
|
||||||
return WERR_INVALID_PARAM;
|
|
||||||
} else if (val > 0xFFFF) {
|
|
||||||
return WERR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out = schema->prefixes[i].id | val;
|
|
||||||
return WERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return WERR_DS_NO_MSDS_INTID;
|
|
||||||
}
|
|
||||||
|
|
||||||
WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out)
|
WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out)
|
||||||
{
|
{
|
||||||
@ -339,22 +299,281 @@ WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CT
|
|||||||
*/
|
*/
|
||||||
WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *schema, const char *full_oid)
|
WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *schema, const char *full_oid)
|
||||||
{
|
{
|
||||||
|
WERROR status;
|
||||||
|
uint32_t num_prefixes;
|
||||||
|
struct dsdb_schema_oid_prefix *prefixes;
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
uint32_t out;
|
||||||
|
|
||||||
|
mem_ctx = talloc_new(ldb);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(mem_ctx);
|
||||||
|
|
||||||
|
/* Read prefixes from disk*/
|
||||||
|
status = dsdb_read_prefixes_from_ldb( mem_ctx, ldb, &num_prefixes, &prefixes );
|
||||||
|
if (!W_ERROR_IS_OK(status)) {
|
||||||
|
DEBUG(0,("dsdb_create_prefix_mapping: dsdb_read_prefixes_from_ldb: %s\n",
|
||||||
|
win_errstr(status)));
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there is a prefix for the oid in the prefixes array*/
|
||||||
|
status = dsdb_find_prefix_for_oid( num_prefixes, prefixes, full_oid, &out );
|
||||||
|
if (W_ERROR_IS_OK(status)) {
|
||||||
|
/* prefix found*/
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return status;
|
||||||
|
} else if (!W_ERROR_EQUAL(WERR_DS_NO_MSDS_INTID, status)) {
|
||||||
|
/* error */
|
||||||
|
DEBUG(0,("dsdb_create_prefix_mapping: dsdb_find_prefix_for_oid: %s\n",
|
||||||
|
win_errstr(status)));
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the new mapping for the prefix of full_oid */
|
||||||
|
status = dsdb_prefix_map_update(mem_ctx, &num_prefixes, &prefixes, full_oid);
|
||||||
|
if (!W_ERROR_IS_OK(status)) {
|
||||||
|
DEBUG(0,("dsdb_create_prefix_mapping: dsdb_prefix_map_update: %s\n",
|
||||||
|
win_errstr(status)));
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update prefixMap in ldb*/
|
||||||
|
status = dsdb_write_prefixes_to_ldb(mem_ctx, ldb, num_prefixes, prefixes);
|
||||||
|
if (!W_ERROR_IS_OK(status)) {
|
||||||
|
DEBUG(0,("dsdb_create_prefix_mapping: dsdb_write_prefixes_to_ldb: %s\n",
|
||||||
|
win_errstr(status)));
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR dsdb_prefix_map_update(TALLOC_CTX *mem_ctx, uint32_t *num_prefixes, struct dsdb_schema_oid_prefix **prefixes, const char *oid)
|
||||||
|
{
|
||||||
|
uint32_t new_num_prefixes, index_new_prefix, new_entry_id;
|
||||||
|
const char* lastDotOffset;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
new_num_prefixes = *num_prefixes + 1;
|
||||||
|
index_new_prefix = *num_prefixes;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* this is the algorithm we use to create new mappings for now
|
||||||
* - (maybe) read the old prefixMap attribute and parse it
|
|
||||||
*
|
*
|
||||||
* - recheck the prefix doesn't exist (because the ldb
|
* TODO: find what algorithm windows use
|
||||||
* has maybe a more uptodate value than schem->prefixes
|
|
||||||
*
|
|
||||||
* - calculate a new mapping for the oid prefix of full_oid
|
|
||||||
* - store the new prefixMap attribute
|
|
||||||
*
|
|
||||||
* - (maybe) update schema->prefixes
|
|
||||||
* or
|
|
||||||
* - better find a way to indicate a schema reload,
|
|
||||||
* so that other processes also notice the schema change
|
|
||||||
*/
|
*/
|
||||||
return WERR_NOT_SUPPORTED;
|
new_entry_id = (*num_prefixes)<<16;
|
||||||
|
|
||||||
|
/* Extract the prefix from the oid*/
|
||||||
|
lastDotOffset = strrchr(oid, '.');
|
||||||
|
if (lastDotOffset == NULL) {
|
||||||
|
DEBUG(0,("dsdb_prefix_map_update: failed to find the last dot\n"));
|
||||||
|
return WERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the size of the remainig string that should be the prefix of it */
|
||||||
|
size = strlen(oid) - strlen(lastDotOffset);
|
||||||
|
if (size <= 0) {
|
||||||
|
DEBUG(0,("dsdb_prefix_map_update: size of the remaining string invalid\n"));
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
/* Add one because we need to copy the dot */
|
||||||
|
size += 1;
|
||||||
|
|
||||||
|
/* Create a spot in the prefixMap for one more prefix*/
|
||||||
|
(*prefixes) = talloc_realloc(mem_ctx, *prefixes, struct dsdb_schema_oid_prefix, new_num_prefixes);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(*prefixes);
|
||||||
|
|
||||||
|
/* Add the new prefix entry*/
|
||||||
|
(*prefixes)[index_new_prefix].id = new_entry_id;
|
||||||
|
(*prefixes)[index_new_prefix].oid = talloc_strndup(mem_ctx, oid, size);
|
||||||
|
(*prefixes)[index_new_prefix].oid_len = strlen((*prefixes)[index_new_prefix].oid);
|
||||||
|
|
||||||
|
/* Increase num_prefixes because new prefix has been added */
|
||||||
|
++(*num_prefixes);
|
||||||
|
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR dsdb_find_prefix_for_oid(uint32_t num_prefixes, const struct dsdb_schema_oid_prefix *prefixes, const char *in, uint32_t *out)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i=0; i < num_prefixes; i++) {
|
||||||
|
const char *val_str;
|
||||||
|
char *end_str;
|
||||||
|
unsigned val;
|
||||||
|
|
||||||
|
if (strncmp(prefixes[i].oid, in, prefixes[i].oid_len) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
val_str = in + prefixes[i].oid_len;
|
||||||
|
end_str = NULL;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
if (val_str[0] == '\0') {
|
||||||
|
return WERR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* two '.' chars are invalid */
|
||||||
|
if (val_str[0] == '.') {
|
||||||
|
return WERR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = strtoul(val_str, &end_str, 10);
|
||||||
|
if (end_str[0] == '.' && end_str[1] != '\0') {
|
||||||
|
/*
|
||||||
|
* if it's a '.' and not the last char
|
||||||
|
* then maybe an other mapping apply
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
} else if (end_str[0] != '\0') {
|
||||||
|
return WERR_INVALID_PARAM;
|
||||||
|
} else if (val > 0xFFFF) {
|
||||||
|
return WERR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = prefixes[i].id | val;
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WERR_DS_NO_MSDS_INTID;
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR dsdb_write_prefixes_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
|
||||||
|
uint32_t num_prefixes,
|
||||||
|
const struct dsdb_schema_oid_prefix *prefixes)
|
||||||
|
{
|
||||||
|
struct ldb_message msg;
|
||||||
|
struct ldb_dn *schema_dn;
|
||||||
|
struct ldb_message_element el;
|
||||||
|
struct prefixMapBlob pm;
|
||||||
|
struct ldb_val ndr_blob;
|
||||||
|
enum ndr_err_code ndr_err;
|
||||||
|
uint32_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
schema_dn = samdb_schema_dn(ldb);
|
||||||
|
if (!schema_dn) {
|
||||||
|
DEBUG(0,("dsdb_write_prefixes_to_ldb: no schema dn present\n"));
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm.version = PREFIX_MAP_VERSION_DSDB;
|
||||||
|
pm.ctr.dsdb.num_mappings = num_prefixes;
|
||||||
|
pm.ctr.dsdb.mappings = talloc_array(mem_ctx,
|
||||||
|
struct drsuapi_DsReplicaOIDMapping,
|
||||||
|
pm.ctr.dsdb.num_mappings);
|
||||||
|
if (!pm.ctr.dsdb.mappings) {
|
||||||
|
return WERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < num_prefixes; i++) {
|
||||||
|
pm.ctr.dsdb.mappings[i].id_prefix = prefixes[i].id>>16;
|
||||||
|
pm.ctr.dsdb.mappings[i].oid.oid = talloc_strdup(pm.ctr.dsdb.mappings, prefixes[i].oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ndr_err = ndr_push_struct_blob(&ndr_blob, ldb,
|
||||||
|
lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
|
||||||
|
&pm,
|
||||||
|
(ndr_push_flags_fn_t)ndr_push_prefixMapBlob);
|
||||||
|
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
el.num_values = 1;
|
||||||
|
el.values = &ndr_blob;
|
||||||
|
el.flags = LDB_FLAG_MOD_REPLACE;
|
||||||
|
el.name = talloc_strdup(mem_ctx, "prefixMap");
|
||||||
|
|
||||||
|
msg.dn = ldb_dn_copy(mem_ctx, schema_dn);
|
||||||
|
msg.num_elements = 1;
|
||||||
|
msg.elements = ⪙
|
||||||
|
|
||||||
|
ret = ldb_modify( ldb, &msg );
|
||||||
|
if (ret != 0) {
|
||||||
|
DEBUG(0,("dsdb_write_prefixes_to_ldb: ldb_modify failed\n"));
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes)
|
||||||
|
{
|
||||||
|
struct prefixMapBlob *blob;
|
||||||
|
enum ndr_err_code ndr_err;
|
||||||
|
uint32_t i;
|
||||||
|
const struct ldb_val *prefix_val;
|
||||||
|
struct ldb_dn *schema_dn;
|
||||||
|
struct ldb_result *schema_res;
|
||||||
|
int ret;
|
||||||
|
static const char *schema_attrs[] = {
|
||||||
|
"prefixMap",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
schema_dn = samdb_schema_dn(ldb);
|
||||||
|
if (!schema_dn) {
|
||||||
|
DEBUG(0,("dsdb_read_prefixes_from_ldb: no schema dn present\n"));
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ldb_search(ldb, schema_dn, LDB_SCOPE_BASE,NULL, schema_attrs,&schema_res);
|
||||||
|
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||||
|
DEBUG(0,("dsdb_read_prefixes_from_ldb: no prefix map present\n"));
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
} else if (ret != LDB_SUCCESS) {
|
||||||
|
DEBUG(0,("dsdb_read_prefixes_from_ldb: failed to search the schema head\n"));
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix_val = ldb_msg_find_ldb_val(schema_res->msgs[0], "prefixMap");
|
||||||
|
if (!prefix_val) {
|
||||||
|
DEBUG(0,("dsdb_read_prefixes_from_ldb: no prefixMap attribute found\n"));
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
blob = talloc(mem_ctx, struct prefixMapBlob);
|
||||||
|
W_ERROR_HAVE_NO_MEMORY(blob);
|
||||||
|
|
||||||
|
ndr_err = ndr_pull_struct_blob(prefix_val, blob,
|
||||||
|
lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
|
||||||
|
blob,
|
||||||
|
(ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob);
|
||||||
|
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
DEBUG(0,("dsdb_read_prefixes_from_ldb: ndr_pull_struct_blob failed\n"));
|
||||||
|
talloc_free(blob);
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blob->version != PREFIX_MAP_VERSION_DSDB) {
|
||||||
|
DEBUG(0,("dsdb_read_prefixes_from_ldb: blob->version incorect\n"));
|
||||||
|
talloc_free(blob);
|
||||||
|
return WERR_FOOBAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*num_prefixes = blob->ctr.dsdb.num_mappings;
|
||||||
|
*prefixes = talloc_array(mem_ctx, struct dsdb_schema_oid_prefix, *num_prefixes);
|
||||||
|
if(!(*prefixes)) {
|
||||||
|
talloc_free(blob);
|
||||||
|
return WERR_NOMEM;
|
||||||
|
}
|
||||||
|
for (i=0; i < blob->ctr.dsdb.num_mappings; i++) {
|
||||||
|
(*prefixes)[i].id = blob->ctr.dsdb.mappings[i].id_prefix<<16;
|
||||||
|
(*prefixes)[i].oid = talloc_strdup(mem_ctx, blob->ctr.dsdb.mappings[i].oid.oid);
|
||||||
|
(*prefixes)[i].oid = talloc_asprintf_append((*prefixes)[i].oid, ".");
|
||||||
|
(*prefixes)[i].oid_len = strlen(blob->ctr.dsdb.mappings[i].oid.oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
talloc_free(blob);
|
||||||
|
return WERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \
|
#define GET_STRING_LDB(msg, attr, mem_ctx, p, elem, strict) do { \
|
||||||
@ -1534,6 +1753,11 @@ int dsdb_set_global_schema(struct ldb_context *ldb)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Keep a reference to this schema, just incase the global copy is replaced */
|
||||||
|
if (talloc_reference(ldb, global_schema) == NULL) {
|
||||||
|
return LDB_ERR_OPERATIONS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return LDB_SUCCESS;
|
return LDB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1571,6 +1795,10 @@ void dsdb_make_schema_global(struct ldb_context *ldb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (global_schema) {
|
||||||
|
talloc_unlink(talloc_autofree_context(), schema);
|
||||||
|
}
|
||||||
|
|
||||||
talloc_steal(talloc_autofree_context(), schema);
|
talloc_steal(talloc_autofree_context(), schema);
|
||||||
global_schema = schema;
|
global_schema = schema;
|
||||||
|
|
||||||
|
@ -190,9 +190,11 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
|
|||||||
struct samr_Password *hash;
|
struct samr_Password *hash;
|
||||||
const struct ldb_val *sc_val;
|
const struct ldb_val *sc_val;
|
||||||
struct supplementalCredentialsBlob scb;
|
struct supplementalCredentialsBlob scb;
|
||||||
struct supplementalCredentialsPackage *scp = NULL;
|
struct supplementalCredentialsPackage *scpk = NULL;
|
||||||
|
bool newer_keys = false;
|
||||||
struct package_PrimaryKerberosBlob _pkb;
|
struct package_PrimaryKerberosBlob _pkb;
|
||||||
struct package_PrimaryKerberosCtr3 *pkb3 = NULL;
|
struct package_PrimaryKerberosCtr3 *pkb3 = NULL;
|
||||||
|
struct package_PrimaryKerberosCtr4 *pkb4 = NULL;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint32_t allocated_keys = 0;
|
uint32_t allocated_keys = 0;
|
||||||
|
|
||||||
@ -221,35 +223,48 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scb.sub.signature != SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
|
||||||
|
NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
|
||||||
|
ret = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i < scb.sub.num_packages; i++) {
|
for (i=0; i < scb.sub.num_packages; i++) {
|
||||||
if (scb.sub.packages[i].unknown1 != 0x00000001) {
|
if (strcmp("Primary:Kerberos-Newer-Keys", scb.sub.packages[i].name) == 0) {
|
||||||
|
scpk = &scb.sub.packages[i];
|
||||||
|
if (!scpk->data || !scpk->data[0]) {
|
||||||
|
scpk = NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
newer_keys = true;
|
||||||
if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!scb.sub.packages[i].data || !scb.sub.packages[i].data[0]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
scp = &scb.sub.packages[i];
|
|
||||||
break;
|
break;
|
||||||
|
} else if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) == 0) {
|
||||||
|
scpk = &scb.sub.packages[i];
|
||||||
|
if (!scpk->data || !scpk->data[0]) {
|
||||||
|
scpk = NULL;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* we don't break here in hope to find
|
||||||
|
* a Kerberos-Newer-Keys package
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Primary:Kerberos element of supplementalCredentials */
|
}
|
||||||
if (scp) {
|
/*
|
||||||
|
* Primary:Kerberos-Newer-Keys or Primary:Kerberos element
|
||||||
|
* of supplementalCredentials
|
||||||
|
*/
|
||||||
|
if (scpk) {
|
||||||
DATA_BLOB blob;
|
DATA_BLOB blob;
|
||||||
|
|
||||||
blob = strhex_to_data_blob(scp->data);
|
blob = strhex_to_data_blob(scpk->data);
|
||||||
if (!blob.data) {
|
if (!blob.data) {
|
||||||
ret = ENOMEM;
|
ret = ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
talloc_steal(mem_ctx, blob.data);
|
talloc_steal(mem_ctx, blob.data);
|
||||||
|
|
||||||
/* TODO: use ndr_pull_struct_blob_all(), when the ndr layer handles it correct with relative pointers */
|
/* we cannot use ndr_pull_struct_blob_all() here, as w2k and w2k3 add padding bytes */
|
||||||
ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb,
|
ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, iconv_convenience, &_pkb,
|
||||||
(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
|
(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
|
||||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
@ -259,17 +274,28 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_pkb.version != 3) {
|
if (newer_keys && _pkb.version != 4) {
|
||||||
krb5_set_error_string(context, "LDB_message2entry_keys: could not parse PrimaryKerberos not version 3");
|
krb5_set_error_string(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
|
||||||
krb5_warnx(context, "LDB_message2entry_keys: could not parse PrimaryKerberos not version 3");
|
krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
|
||||||
ret = EINVAL;
|
ret = EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkb3 = &_pkb.ctr.ctr3;
|
if (!newer_keys && _pkb.version != 3) {
|
||||||
|
krb5_set_error_string(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
|
||||||
|
krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
|
||||||
|
ret = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pkb.version == 4) {
|
||||||
|
pkb4 = &_pkb.ctr.ctr4;
|
||||||
|
allocated_keys += pkb4->num_keys;
|
||||||
|
} else if (_pkb.version == 3) {
|
||||||
|
pkb3 = &_pkb.ctr.ctr3;
|
||||||
allocated_keys += pkb3->num_keys;
|
allocated_keys += pkb3->num_keys;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (allocated_keys == 0) {
|
if (allocated_keys == 0) {
|
||||||
/* oh, no password. Apparently (comment in
|
/* oh, no password. Apparently (comment in
|
||||||
@ -304,7 +330,70 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
|
|||||||
entry_ex->entry.keys.len++;
|
entry_ex->entry.keys.len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkb3) {
|
if (pkb4) {
|
||||||
|
for (i=0; i < pkb4->num_keys; i++) {
|
||||||
|
bool use = true;
|
||||||
|
Key key;
|
||||||
|
|
||||||
|
if (!pkb4->keys[i].value) continue;
|
||||||
|
|
||||||
|
if (userAccountControl & UF_USE_DES_KEY_ONLY) {
|
||||||
|
switch (pkb4->keys[i].keytype) {
|
||||||
|
case ENCTYPE_DES_CBC_CRC:
|
||||||
|
case ENCTYPE_DES_CBC_MD5:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
use = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!use) continue;
|
||||||
|
|
||||||
|
key.mkvno = 0;
|
||||||
|
key.salt = NULL;
|
||||||
|
|
||||||
|
if (pkb4->salt.string) {
|
||||||
|
DATA_BLOB salt;
|
||||||
|
|
||||||
|
salt = data_blob_string_const(pkb4->salt.string);
|
||||||
|
|
||||||
|
key.salt = calloc(1, sizeof(*key.salt));
|
||||||
|
if (key.salt == NULL) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
key.salt->type = hdb_pw_salt;
|
||||||
|
|
||||||
|
ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length);
|
||||||
|
if (ret) {
|
||||||
|
free(key.salt);
|
||||||
|
key.salt = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: maybe pass the iteration_count somehow... */
|
||||||
|
|
||||||
|
ret = krb5_keyblock_init(context,
|
||||||
|
pkb4->keys[i].keytype,
|
||||||
|
pkb4->keys[i].value->data,
|
||||||
|
pkb4->keys[i].value->length,
|
||||||
|
&key.key);
|
||||||
|
if (ret) {
|
||||||
|
if (key.salt) {
|
||||||
|
free_Salt(key.salt);
|
||||||
|
free(key.salt);
|
||||||
|
key.salt = NULL;
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
|
||||||
|
entry_ex->entry.keys.len++;
|
||||||
|
}
|
||||||
|
} else if (pkb3) {
|
||||||
for (i=0; i < pkb3->num_keys; i++) {
|
for (i=0; i < pkb3->num_keys; i++) {
|
||||||
bool use = true;
|
bool use = true;
|
||||||
Key key;
|
Key key;
|
||||||
@ -325,6 +414,7 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
|
|||||||
if (!use) continue;
|
if (!use) continue;
|
||||||
|
|
||||||
key.mkvno = 0;
|
key.mkvno = 0;
|
||||||
|
key.salt = NULL;
|
||||||
|
|
||||||
if (pkb3->salt.string) {
|
if (pkb3->salt.string) {
|
||||||
DATA_BLOB salt;
|
DATA_BLOB salt;
|
||||||
|
@ -46,15 +46,15 @@ struct sigcounter {
|
|||||||
the poor design of signals means that this table must be static global
|
the poor design of signals means that this table must be static global
|
||||||
*/
|
*/
|
||||||
static struct sig_state {
|
static struct sig_state {
|
||||||
struct signal_event *sig_handlers[NUM_SIGNALS];
|
struct signal_event *sig_handlers[NUM_SIGNALS+1];
|
||||||
struct sigaction *oldact[NUM_SIGNALS];
|
struct sigaction *oldact[NUM_SIGNALS+1];
|
||||||
struct sigcounter signal_count[NUM_SIGNALS];
|
struct sigcounter signal_count[NUM_SIGNALS+1];
|
||||||
struct sigcounter got_signal;
|
struct sigcounter got_signal;
|
||||||
int pipe_hack[2];
|
int pipe_hack[2];
|
||||||
#ifdef SA_SIGINFO
|
#ifdef SA_SIGINFO
|
||||||
/* with SA_SIGINFO we get quite a lot of info per signal */
|
/* with SA_SIGINFO we get quite a lot of info per signal */
|
||||||
siginfo_t *sig_info[NUM_SIGNALS];
|
siginfo_t *sig_info[NUM_SIGNALS+1];
|
||||||
struct sigcounter sig_blocked[NUM_SIGNALS];
|
struct sigcounter sig_blocked[NUM_SIGNALS+1];
|
||||||
#endif
|
#endif
|
||||||
} *sig_state;
|
} *sig_state;
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb,
|
|||||||
#if (_SAMBA_BUILD_ >= 4)
|
#if (_SAMBA_BUILD_ >= 4)
|
||||||
POPT_COMMON_SAMBA
|
POPT_COMMON_SAMBA
|
||||||
POPT_COMMON_CREDENTIALS
|
POPT_COMMON_CREDENTIALS
|
||||||
|
POPT_COMMON_CONNECTION
|
||||||
POPT_COMMON_VERSION
|
POPT_COMMON_VERSION
|
||||||
#endif
|
#endif
|
||||||
{ NULL }
|
{ NULL }
|
||||||
|
@ -126,6 +126,8 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
|
|||||||
__asm__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
|
__asm__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
|
||||||
}
|
}
|
||||||
#define HAVE_ASM_BYTEORDER 1
|
#define HAVE_ASM_BYTEORDER 1
|
||||||
|
#else
|
||||||
|
#define HAVE_ASM_BYTEORDER 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -172,7 +174,7 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
|
|||||||
#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16_t)(val)))
|
#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16_t)(val)))
|
||||||
#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32_t)(val)))
|
#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32_t)(val)))
|
||||||
|
|
||||||
#else /* CAREFUL_ALIGNMENT */
|
#else /* not CAREFUL_ALIGNMENT */
|
||||||
|
|
||||||
/* this handles things for architectures like the 386 that can handle
|
/* this handles things for architectures like the 386 that can handle
|
||||||
alignment errors */
|
alignment errors */
|
||||||
@ -197,7 +199,7 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
|
|||||||
#define SSVALS(buf,pos,val) SVALS_NC(buf,pos)=((int16_t)(val))
|
#define SSVALS(buf,pos,val) SVALS_NC(buf,pos)=((int16_t)(val))
|
||||||
#define SIVALS(buf,pos,val) IVALS_NC(buf,pos)=((int32_t)(val))
|
#define SIVALS(buf,pos,val) IVALS_NC(buf,pos)=((int32_t)(val))
|
||||||
|
|
||||||
#endif /* CAREFUL_ALIGNMENT */
|
#endif /* not CAREFUL_ALIGNMENT */
|
||||||
|
|
||||||
/* now the reverse routines - these are used in nmb packets (mostly) */
|
/* now the reverse routines - these are used in nmb packets (mostly) */
|
||||||
#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
|
#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
|
||||||
|
@ -1516,13 +1516,30 @@ static void becomeDC_drsuapi_connect_send(struct libnet_BecomeDC_state *s,
|
|||||||
drsuapi->s = s;
|
drsuapi->s = s;
|
||||||
|
|
||||||
if (!drsuapi->binding) {
|
if (!drsuapi->binding) {
|
||||||
if (lp_parm_bool(s->libnet->lp_ctx, NULL, "become_dc", "print", false)) {
|
char *krb5_str = "";
|
||||||
binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[krb5,print,seal]", s->source_dsa.dns_name);
|
char *print_str = "";
|
||||||
if (composite_nomem(binding_str, c)) return;
|
/*
|
||||||
} else {
|
* Note: Replication only works with Windows 2000 when 'krb5' is
|
||||||
binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[krb5,seal]", s->source_dsa.dns_name);
|
* passed as auth_type here. If NTLMSSP is used, Windows
|
||||||
if (composite_nomem(binding_str, c)) return;
|
* 2000 returns garbage in the DsGetNCChanges() response
|
||||||
|
* if encrypted password attributes would be in the response.
|
||||||
|
* That means the replication of the schema and configuration
|
||||||
|
* partition works fine, but it fails for the domain partition.
|
||||||
|
*/
|
||||||
|
if (lp_parm_bool(s->libnet->lp_ctx, NULL, "become_dc",
|
||||||
|
"force krb5", true))
|
||||||
|
{
|
||||||
|
krb5_str = "krb5,";
|
||||||
}
|
}
|
||||||
|
if (lp_parm_bool(s->libnet->lp_ctx, NULL, "become_dc",
|
||||||
|
"print", false))
|
||||||
|
{
|
||||||
|
print_str = "print,";
|
||||||
|
}
|
||||||
|
binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[%s%sseal]",
|
||||||
|
s->source_dsa.dns_name,
|
||||||
|
krb5_str, print_str);
|
||||||
|
if (composite_nomem(binding_str, c)) return;
|
||||||
c->status = dcerpc_parse_binding(s, binding_str, &drsuapi->binding);
|
c->status = dcerpc_parse_binding(s, binding_str, &drsuapi->binding);
|
||||||
talloc_free(binding_str);
|
talloc_free(binding_str);
|
||||||
if (!composite_is_ok(c)) return;
|
if (!composite_is_ok(c)) return;
|
||||||
@ -1602,12 +1619,7 @@ static void becomeDC_drsuapi_bind_send(struct libnet_BecomeDC_state *s,
|
|||||||
bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
|
bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
|
||||||
#endif
|
#endif
|
||||||
bind_info28->site_guid = s->dest_dsa.site_guid;
|
bind_info28->site_guid = s->dest_dsa.site_guid;
|
||||||
if (s->domain.behavior_version == 2) {
|
bind_info28->pid = 0;
|
||||||
/* TODO: find out how this is really triggered! */
|
|
||||||
bind_info28->u1 = 528;
|
|
||||||
} else {
|
|
||||||
bind_info28->u1 = 516;
|
|
||||||
}
|
|
||||||
bind_info28->repl_epoch = 0;
|
bind_info28->repl_epoch = 0;
|
||||||
|
|
||||||
drsuapi->bind_info_ctr.length = 28;
|
drsuapi->bind_info_ctr.length = 28;
|
||||||
@ -1636,10 +1648,19 @@ static WERROR becomeDC_drsuapi_bind_recv(struct libnet_BecomeDC_state *s,
|
|||||||
info24 = &drsuapi->bind_r.out.bind_info->info.info24;
|
info24 = &drsuapi->bind_r.out.bind_info->info.info24;
|
||||||
drsuapi->remote_info28.supported_extensions = info24->supported_extensions;
|
drsuapi->remote_info28.supported_extensions = info24->supported_extensions;
|
||||||
drsuapi->remote_info28.site_guid = info24->site_guid;
|
drsuapi->remote_info28.site_guid = info24->site_guid;
|
||||||
drsuapi->remote_info28.u1 = info24->u1;
|
drsuapi->remote_info28.pid = info24->pid;
|
||||||
drsuapi->remote_info28.repl_epoch = 0;
|
drsuapi->remote_info28.repl_epoch = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 48: {
|
||||||
|
struct drsuapi_DsBindInfo48 *info48;
|
||||||
|
info48 = &drsuapi->bind_r.out.bind_info->info.info48;
|
||||||
|
drsuapi->remote_info28.supported_extensions = info48->supported_extensions;
|
||||||
|
drsuapi->remote_info28.site_guid = info48->site_guid;
|
||||||
|
drsuapi->remote_info28.pid = info48->pid;
|
||||||
|
drsuapi->remote_info28.repl_epoch = info48->repl_epoch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 28:
|
case 28:
|
||||||
drsuapi->remote_info28 = drsuapi->bind_r.out.bind_info->info.info28;
|
drsuapi->remote_info28 = drsuapi->bind_r.out.bind_info->info.info28;
|
||||||
break;
|
break;
|
||||||
@ -2083,7 +2104,7 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s)
|
|||||||
vd[0] = data_blob_talloc(vd, NULL, 4);
|
vd[0] = data_blob_talloc(vd, NULL, 4);
|
||||||
if (composite_nomem(vd[0].data, c)) return;
|
if (composite_nomem(vd[0].data, c)) return;
|
||||||
|
|
||||||
SIVAL(vd[0].data, 0, DS_BEHAVIOR_WIN2003);
|
SIVAL(vd[0].data, 0, DS_BEHAVIOR_WIN2008);
|
||||||
|
|
||||||
vs[0].blob = &vd[0];
|
vs[0].blob = &vd[0];
|
||||||
|
|
||||||
|
@ -574,7 +574,7 @@ static void unbecomeDC_drsuapi_bind_send(struct libnet_UnbecomeDC_state *s)
|
|||||||
bind_info28 = &s->drsuapi.local_info28;
|
bind_info28 = &s->drsuapi.local_info28;
|
||||||
bind_info28->supported_extensions = 0;
|
bind_info28->supported_extensions = 0;
|
||||||
bind_info28->site_guid = GUID_zero();
|
bind_info28->site_guid = GUID_zero();
|
||||||
bind_info28->u1 = 508;
|
bind_info28->pid = 0;
|
||||||
bind_info28->repl_epoch = 0;
|
bind_info28->repl_epoch = 0;
|
||||||
|
|
||||||
s->drsuapi.bind_info_ctr.length = 28;
|
s->drsuapi.bind_info_ctr.length = 28;
|
||||||
@ -612,10 +612,19 @@ static void unbecomeDC_drsuapi_bind_recv(struct rpc_request *req)
|
|||||||
info24 = &s->drsuapi.bind_r.out.bind_info->info.info24;
|
info24 = &s->drsuapi.bind_r.out.bind_info->info.info24;
|
||||||
s->drsuapi.remote_info28.supported_extensions = info24->supported_extensions;
|
s->drsuapi.remote_info28.supported_extensions = info24->supported_extensions;
|
||||||
s->drsuapi.remote_info28.site_guid = info24->site_guid;
|
s->drsuapi.remote_info28.site_guid = info24->site_guid;
|
||||||
s->drsuapi.remote_info28.u1 = info24->u1;
|
s->drsuapi.remote_info28.pid = info24->pid;
|
||||||
s->drsuapi.remote_info28.repl_epoch = 0;
|
s->drsuapi.remote_info28.repl_epoch = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 48: {
|
||||||
|
struct drsuapi_DsBindInfo48 *info48;
|
||||||
|
info48 = &s->drsuapi.bind_r.out.bind_info->info.info48;
|
||||||
|
s->drsuapi.remote_info28.supported_extensions = info48->supported_extensions;
|
||||||
|
s->drsuapi.remote_info28.site_guid = info48->site_guid;
|
||||||
|
s->drsuapi.remote_info28.pid = info48->pid;
|
||||||
|
s->drsuapi.remote_info28.repl_epoch = info48->repl_epoch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 28:
|
case 28:
|
||||||
s->drsuapi.remote_info28 = s->drsuapi.bind_r.out.bind_info->info.info28;
|
s->drsuapi.remote_info28 = s->drsuapi.bind_r.out.bind_info->info.info28;
|
||||||
break;
|
break;
|
||||||
|
@ -253,6 +253,7 @@ interface dcerpc
|
|||||||
const uint8 DCERPC_PFC_FLAG_FIRST = 0x01; /* First fragment */
|
const uint8 DCERPC_PFC_FLAG_FIRST = 0x01; /* First fragment */
|
||||||
const uint8 DCERPC_PFC_FLAG_LAST = 0x02; /* Last fragment */
|
const uint8 DCERPC_PFC_FLAG_LAST = 0x02; /* Last fragment */
|
||||||
const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL = 0x04; /* Cancel was pending at sender */
|
const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL = 0x04; /* Cancel was pending at sender */
|
||||||
|
const uint8 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN = DCERPC_PFC_FLAG_PENDING_CANCEL; /* depends on the pdu type */
|
||||||
const uint8 DCERPC_PFC_FLAG_CONC_MPX = 0x10; /* supports concurrent multiplexing of a single connection. */
|
const uint8 DCERPC_PFC_FLAG_CONC_MPX = 0x10; /* supports concurrent multiplexing of a single connection. */
|
||||||
const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20; /* on a fault it means the server hasn't done anything */
|
const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20; /* on a fault it means the server hasn't done anything */
|
||||||
const uint8 DCERPC_PFC_FLAG_MAYBE = 0x40; /* `maybe' call semantics requested */
|
const uint8 DCERPC_PFC_FLAG_MAYBE = 0x40; /* `maybe' call semantics requested */
|
||||||
|
@ -205,7 +205,7 @@ interface drsblobs {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
[value(2*strlen_m(name))] uint16 name_len;
|
[value(2*strlen_m(name))] uint16 name_len;
|
||||||
[value(strlen(data))] uint16 data_len;
|
[value(strlen(data))] uint16 data_len;
|
||||||
uint16 unknown1; /* 2 for name = 'Packages', 1 for name = 'Primary:*' */
|
uint16 reserved; /* 2 for 'Packages', 1 for 'Primary:*', but should be ignored */
|
||||||
[charset(UTF16)] uint8 name[name_len];
|
[charset(UTF16)] uint8 name[name_len];
|
||||||
/*
|
/*
|
||||||
* the data field contains data as HEX strings
|
* the data field contains data as HEX strings
|
||||||
@ -215,6 +215,9 @@ interface drsblobs {
|
|||||||
* as non termiated UTF16 strings with
|
* as non termiated UTF16 strings with
|
||||||
* a UTF16 NULL byte as separator
|
* a UTF16 NULL byte as separator
|
||||||
*
|
*
|
||||||
|
* 'Primary:Kerberos-Newer-Keys':
|
||||||
|
* ...
|
||||||
|
*
|
||||||
* 'Primary:Kerberos':
|
* 'Primary:Kerberos':
|
||||||
* ...
|
* ...
|
||||||
*
|
*
|
||||||
@ -228,11 +231,16 @@ interface drsblobs {
|
|||||||
[charset(DOS)] uint8 data[data_len];
|
[charset(DOS)] uint8 data[data_len];
|
||||||
} supplementalCredentialsPackage;
|
} supplementalCredentialsPackage;
|
||||||
|
|
||||||
/* this are 0x30 (48) whitespaces (0x20) followed by 'P' (0x50) */
|
/* this are 0x30 (48) whitespaces (0x20) */
|
||||||
const string SUPPLEMENTAL_CREDENTIALS_PREFIX = " P";
|
const string SUPPLEMENTAL_CREDENTIALS_PREFIX = " ";
|
||||||
|
|
||||||
|
typedef [flag(NDR_PAHEX)] enum {
|
||||||
|
SUPPLEMENTAL_CREDENTIALS_SIGNATURE = 0x0050
|
||||||
|
} supplementalCredentialsSignature;
|
||||||
|
|
||||||
typedef [gensize] struct {
|
typedef [gensize] struct {
|
||||||
[value(SUPPLEMENTAL_CREDENTIALS_PREFIX),charset(UTF16)] uint16 prefix[0x31];
|
[value(SUPPLEMENTAL_CREDENTIALS_PREFIX),charset(UTF16)] uint16 prefix[0x30];
|
||||||
|
[value(SUPPLEMENTAL_CREDENTIALS_SIGNATURE)] supplementalCredentialsSignature signature;
|
||||||
uint16 num_packages;
|
uint16 num_packages;
|
||||||
supplementalCredentialsPackage packages[num_packages];
|
supplementalCredentialsPackage packages[num_packages];
|
||||||
} supplementalCredentialsSubBlob;
|
} supplementalCredentialsSubBlob;
|
||||||
@ -264,31 +272,58 @@ interface drsblobs {
|
|||||||
} package_PrimaryKerberosString;
|
} package_PrimaryKerberosString;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
[value(0)] uint16 reserved1;
|
||||||
|
[value(0)] uint16 reserved2;
|
||||||
|
[value(0)] uint32 reserved3;
|
||||||
uint32 keytype;
|
uint32 keytype;
|
||||||
[value((value?value->length:0))] uint32 value_len;
|
[value((value?value->length:0))] uint32 value_len;
|
||||||
[relative,subcontext(0),subcontext_size(value_len),flag(NDR_REMAINING)] DATA_BLOB *value;
|
[relative,subcontext(0),subcontext_size(value_len),flag(NDR_REMAINING)] DATA_BLOB *value;
|
||||||
[value(0)] uint32 unknown1;
|
} package_PrimaryKerberosKey3;
|
||||||
[value(0)] uint32 unknown2;
|
|
||||||
} package_PrimaryKerberosKey;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16 num_keys;
|
uint16 num_keys;
|
||||||
uint16 num_old_keys;
|
uint16 num_old_keys;
|
||||||
package_PrimaryKerberosString salt;
|
package_PrimaryKerberosString salt;
|
||||||
[value(0)] uint32 unknown1;
|
package_PrimaryKerberosKey3 keys[num_keys];
|
||||||
[value(0)] uint32 unknown2;
|
package_PrimaryKerberosKey3 old_keys[num_old_keys];
|
||||||
package_PrimaryKerberosKey keys[num_keys];
|
[value(0)] uint32 padding1;
|
||||||
package_PrimaryKerberosKey old_keys[num_old_keys];
|
[value(0)] uint32 padding2;
|
||||||
udlong unknown3[num_keys];
|
[value(0)] uint32 padding3;
|
||||||
udlong unknown3_old[num_old_keys];
|
[value(0)] uint32 padding4;
|
||||||
|
[value(0)] uint32 padding5;
|
||||||
} package_PrimaryKerberosCtr3;
|
} package_PrimaryKerberosCtr3;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
[value(0)] uint16 reserved1;
|
||||||
|
[value(0)] uint16 reserved2;
|
||||||
|
[value(0)] uint32 reserved3;
|
||||||
|
uint32 iteration_count;
|
||||||
|
uint32 keytype;
|
||||||
|
[value((value?value->length:0))] uint32 value_len;
|
||||||
|
[relative,subcontext(0),subcontext_size(value_len),flag(NDR_REMAINING)] DATA_BLOB *value;
|
||||||
|
} package_PrimaryKerberosKey4;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16 num_keys;
|
||||||
|
[value(0)] uint16 num_service_keys;
|
||||||
|
uint16 num_old_keys;
|
||||||
|
uint16 num_older_keys;
|
||||||
|
package_PrimaryKerberosString salt;
|
||||||
|
uint32 default_iteration_count;
|
||||||
|
package_PrimaryKerberosKey4 keys[num_keys];
|
||||||
|
package_PrimaryKerberosKey4 service_keys[num_service_keys];
|
||||||
|
package_PrimaryKerberosKey4 old_keys[num_old_keys];
|
||||||
|
package_PrimaryKerberosKey4 older_keys[num_older_keys];
|
||||||
|
} package_PrimaryKerberosCtr4;
|
||||||
|
|
||||||
typedef [nodiscriminant] union {
|
typedef [nodiscriminant] union {
|
||||||
[case(3)] package_PrimaryKerberosCtr3 ctr3;
|
[case(3)] package_PrimaryKerberosCtr3 ctr3;
|
||||||
|
[case(4)] package_PrimaryKerberosCtr4 ctr4;
|
||||||
} package_PrimaryKerberosCtr;
|
} package_PrimaryKerberosCtr;
|
||||||
|
|
||||||
typedef [public] struct {
|
typedef [public] struct {
|
||||||
[value(3)] uint32 version;
|
uint16 version;
|
||||||
|
[value(0)] uint16 flags;
|
||||||
[switch_is(version)] package_PrimaryKerberosCtr ctr;
|
[switch_is(version)] package_PrimaryKerberosCtr ctr;
|
||||||
} package_PrimaryKerberosBlob;
|
} package_PrimaryKerberosBlob;
|
||||||
|
|
||||||
|
@ -58,21 +58,36 @@ interface drsuapi
|
|||||||
DRSUAPI_SUPPORTED_EXTENSION_80000000 = 0x80000000
|
DRSUAPI_SUPPORTED_EXTENSION_80000000 = 0x80000000
|
||||||
} drsuapi_SupportedExtensions;
|
} drsuapi_SupportedExtensions;
|
||||||
|
|
||||||
|
typedef [bitmap32bit] bitmap {
|
||||||
|
DRSUAPI_SUPPORTED_EXTENSION_ADAM = 0x00000001,
|
||||||
|
DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2 = 0x00000002
|
||||||
|
} drsuapi_SupportedExtensionsExt;
|
||||||
|
|
||||||
/* this is used by w2k */
|
/* this is used by w2k */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
drsuapi_SupportedExtensions supported_extensions;
|
drsuapi_SupportedExtensions supported_extensions;
|
||||||
GUID site_guid;
|
GUID site_guid;
|
||||||
uint32 u1;
|
uint32 pid;
|
||||||
} drsuapi_DsBindInfo24;
|
} drsuapi_DsBindInfo24;
|
||||||
|
|
||||||
/* this is used by w2k3 */
|
/* this is used by w2k3 */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
drsuapi_SupportedExtensions supported_extensions;
|
drsuapi_SupportedExtensions supported_extensions;
|
||||||
GUID site_guid;
|
GUID site_guid;
|
||||||
uint32 u1;
|
uint32 pid;
|
||||||
uint32 repl_epoch;
|
uint32 repl_epoch;
|
||||||
} drsuapi_DsBindInfo28;
|
} drsuapi_DsBindInfo28;
|
||||||
|
|
||||||
|
/* this is used by w2k8 */
|
||||||
|
typedef struct {
|
||||||
|
drsuapi_SupportedExtensions supported_extensions;
|
||||||
|
GUID site_guid;
|
||||||
|
uint32 pid;
|
||||||
|
uint32 repl_epoch;
|
||||||
|
drsuapi_SupportedExtensionsExt supported_extensions_ext;
|
||||||
|
GUID config_dn_guid;
|
||||||
|
} drsuapi_DsBindInfo48;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
[flag(NDR_REMAINING)] DATA_BLOB info;
|
[flag(NDR_REMAINING)] DATA_BLOB info;
|
||||||
} drsuapi_DsBindInfoFallBack;
|
} drsuapi_DsBindInfoFallBack;
|
||||||
@ -80,6 +95,7 @@ interface drsuapi
|
|||||||
typedef [nodiscriminant] union {
|
typedef [nodiscriminant] union {
|
||||||
[case(24)][subcontext(4)] drsuapi_DsBindInfo24 info24;
|
[case(24)][subcontext(4)] drsuapi_DsBindInfo24 info24;
|
||||||
[case(28)][subcontext(4)] drsuapi_DsBindInfo28 info28;
|
[case(28)][subcontext(4)] drsuapi_DsBindInfo28 info28;
|
||||||
|
[case(48)][subcontext(4)] drsuapi_DsBindInfo48 info48;
|
||||||
[default][subcontext(4)] drsuapi_DsBindInfoFallBack FallBack;
|
[default][subcontext(4)] drsuapi_DsBindInfoFallBack FallBack;
|
||||||
} drsuapi_DsBindInfo;
|
} drsuapi_DsBindInfo;
|
||||||
|
|
||||||
@ -1409,7 +1425,7 @@ interface drsuapi
|
|||||||
GUID bind_guid;
|
GUID bind_guid;
|
||||||
NTTIME_1sec bind_time;
|
NTTIME_1sec bind_time;
|
||||||
[flag(NDR_BIG_ENDIAN)] ipv4address client_ip_address;
|
[flag(NDR_BIG_ENDIAN)] ipv4address client_ip_address;
|
||||||
uint32 u5; /* this is the same value the client used as u1 in the DsBindInfoX struct */
|
uint32 u5; /* this is the same value the client used as pid in the DsBindInfoX struct */
|
||||||
} drsuapi_DsReplicaConnection04;
|
} drsuapi_DsReplicaConnection04;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -647,11 +647,21 @@ NTSTATUS dcerpc_generic_session_key(struct dcerpc_connection *c,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
fetch the user session key - may be default (above) or the SMB session key
|
fetch the user session key - may be default (above) or the SMB session key
|
||||||
|
|
||||||
|
The key is always truncated to 16 bytes
|
||||||
*/
|
*/
|
||||||
_PUBLIC_ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p,
|
_PUBLIC_ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p,
|
||||||
DATA_BLOB *session_key)
|
DATA_BLOB *session_key)
|
||||||
{
|
{
|
||||||
return p->conn->security_state.session_key(p->conn, session_key);
|
NTSTATUS status;
|
||||||
|
status = p->conn->security_state.session_key(p->conn, session_key);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
session_key->length = MIN(session_key->length, 16);
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -631,12 +631,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
|
|||||||
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
|
status = pvfs_access_check_create(pvfs, req, name, &access_mask);
|
||||||
NT_STATUS_NOT_OK_RETURN(status);
|
NT_STATUS_NOT_OK_RETURN(status);
|
||||||
|
|
||||||
if (io->generic.in.query_maximal_access) {
|
|
||||||
status = pvfs_access_maximal_allowed(pvfs, req, name,
|
|
||||||
&io->generic.out.maximal_access);
|
|
||||||
NT_STATUS_NOT_OK_RETURN(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check that the parent isn't opened with delete on close set */
|
/* check that the parent isn't opened with delete on close set */
|
||||||
status = pvfs_resolve_parent(pvfs, req, name, &parent);
|
status = pvfs_resolve_parent(pvfs, req, name, &parent);
|
||||||
if (NT_STATUS_IS_OK(status)) {
|
if (NT_STATUS_IS_OK(status)) {
|
||||||
@ -707,6 +701,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
|
|||||||
goto cleanup_delete;
|
goto cleanup_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (io->generic.in.query_maximal_access) {
|
||||||
|
status = pvfs_access_maximal_allowed(pvfs, req, name,
|
||||||
|
&io->generic.out.maximal_access);
|
||||||
|
NT_STATUS_NOT_OK_RETURN(status);
|
||||||
|
}
|
||||||
|
|
||||||
/* form the lock context used for byte range locking and
|
/* form the lock context used for byte range locking and
|
||||||
opendb locking */
|
opendb locking */
|
||||||
status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
|
status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
|
||||||
|
@ -74,7 +74,7 @@ again:
|
|||||||
return NT_STATUS_NOT_FOUND;
|
return NT_STATUS_NOT_FOUND;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* if not this was probably a legittimate error
|
/* if not this was probably a legitimate error
|
||||||
* reset ret and errno to the correct values */
|
* reset ret and errno to the correct values */
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -153,7 +153,6 @@ sub ParseFunction($$$)
|
|||||||
$self->pidl("");
|
$self->pidl("");
|
||||||
$self->pidl("status = cli_do_rpc_ndr(cli,");
|
$self->pidl("status = cli_do_rpc_ndr(cli,");
|
||||||
$self->pidl("\t\t\tmem_ctx,");
|
$self->pidl("\t\t\tmem_ctx,");
|
||||||
$self->pidl("\t\t\tPI_$uif,");
|
|
||||||
$self->pidl("\t\t\t&ndr_table_$if,");
|
$self->pidl("\t\t\t&ndr_table_$if,");
|
||||||
$self->pidl("\t\t\t$ufn,");
|
$self->pidl("\t\t\t$ufn,");
|
||||||
$self->pidl("\t\t\t&r);");
|
$self->pidl("\t\t\t&r);");
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include "libcli/security/security.h"
|
#include "libcli/security/security.h"
|
||||||
#include "param/param.h"
|
#include "param/param.h"
|
||||||
|
|
||||||
|
#define SAMBA_ACCOC_GROUP 0x12345678
|
||||||
|
|
||||||
extern const struct dcesrv_interface dcesrv_mgmt_interface;
|
extern const struct dcesrv_interface dcesrv_mgmt_interface;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -270,11 +272,20 @@ NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
fetch the user session key - may be default (above) or the SMB session key
|
fetch the user session key - may be default (above) or the SMB session key
|
||||||
|
|
||||||
|
The key is always truncated to 16 bytes
|
||||||
*/
|
*/
|
||||||
_PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
|
_PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
|
||||||
DATA_BLOB *session_key)
|
DATA_BLOB *session_key)
|
||||||
{
|
{
|
||||||
return p->auth_state.session_key(p, session_key);
|
NTSTATUS status = p->auth_state.session_key(p, session_key);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
session_key->length = MIN(session_key->length, 16);
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -534,7 +545,18 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
|
|||||||
uint32_t context_id;
|
uint32_t context_id;
|
||||||
const struct dcesrv_interface *iface;
|
const struct dcesrv_interface *iface;
|
||||||
|
|
||||||
if (call->pkt.u.bind.assoc_group_id != 0) {
|
/*
|
||||||
|
* Association groups allow policy handles to be shared across
|
||||||
|
* multiple client connections. We don't implement this yet.
|
||||||
|
*
|
||||||
|
* So we just allow 0 if the client wants to create a new
|
||||||
|
* association group.
|
||||||
|
*
|
||||||
|
* And we allow the 0x12345678 value, we give away as
|
||||||
|
* assoc_group_id back to the clients
|
||||||
|
*/
|
||||||
|
if (call->pkt.u.bind.assoc_group_id != 0 &&
|
||||||
|
call->pkt.u.bind.assoc_group_id != SAMBA_ACCOC_GROUP) {
|
||||||
return dcesrv_bind_nak(call, 0);
|
return dcesrv_bind_nak(call, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,7 +631,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
|
|||||||
pkt.u.bind_ack.max_xmit_frag = 0x2000;
|
pkt.u.bind_ack.max_xmit_frag = 0x2000;
|
||||||
pkt.u.bind_ack.max_recv_frag = 0x2000;
|
pkt.u.bind_ack.max_recv_frag = 0x2000;
|
||||||
/* we need to send a non zero assoc_group_id here to make longhorn happy, it also matches samba3 */
|
/* we need to send a non zero assoc_group_id here to make longhorn happy, it also matches samba3 */
|
||||||
pkt.u.bind_ack.assoc_group_id = 0x12345678;
|
pkt.u.bind_ack.assoc_group_id = SAMBA_ACCOC_GROUP;
|
||||||
if (iface) {
|
if (iface) {
|
||||||
/* FIXME: Use pipe name as specified by endpoint instead of interface name */
|
/* FIXME: Use pipe name as specified by endpoint instead of interface name */
|
||||||
pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name);
|
pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name);
|
||||||
|
@ -45,7 +45,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
|
|||||||
struct ldb_result *ntds_res;
|
struct ldb_result *ntds_res;
|
||||||
struct ldb_dn *ntds_dn;
|
struct ldb_dn *ntds_dn;
|
||||||
static const char *ntds_attrs[] = { "ms-DS-ReplicationEpoch", NULL };
|
static const char *ntds_attrs[] = { "ms-DS-ReplicationEpoch", NULL };
|
||||||
uint32_t u1;
|
uint32_t pid;
|
||||||
uint32_t repl_epoch;
|
uint32_t repl_epoch;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -98,9 +98,12 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
|
|||||||
repl_epoch = samdb_result_uint(ntds_res->msgs[0], "ms-DS-ReplicationEpoch", 0);
|
repl_epoch = samdb_result_uint(ntds_res->msgs[0], "ms-DS-ReplicationEpoch", 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: find out what this is...
|
* The "process identifier" of the client.
|
||||||
|
* According to the WSPP docs, sectin 5.35, this is
|
||||||
|
* for informational and debugging purposes only.
|
||||||
|
* The assignment is implementation specific.
|
||||||
*/
|
*/
|
||||||
u1 = 0;
|
pid = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* store the clients bind_guid
|
* store the clients bind_guid
|
||||||
@ -119,7 +122,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
|
|||||||
info24 = &r->in.bind_info->info.info24;
|
info24 = &r->in.bind_info->info.info24;
|
||||||
b_state->remote_info28.supported_extensions = info24->supported_extensions;
|
b_state->remote_info28.supported_extensions = info24->supported_extensions;
|
||||||
b_state->remote_info28.site_guid = info24->site_guid;
|
b_state->remote_info28.site_guid = info24->site_guid;
|
||||||
b_state->remote_info28.u1 = info24->u1;
|
b_state->remote_info28.pid = info24->pid;
|
||||||
b_state->remote_info28.repl_epoch = 0;
|
b_state->remote_info28.repl_epoch = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -171,7 +174,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
|
|||||||
b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
|
b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
|
||||||
#endif
|
#endif
|
||||||
b_state->local_info28.site_guid = site_guid;
|
b_state->local_info28.site_guid = site_guid;
|
||||||
b_state->local_info28.u1 = u1;
|
b_state->local_info28.pid = pid;
|
||||||
b_state->local_info28.repl_epoch = repl_epoch;
|
b_state->local_info28.repl_epoch = repl_epoch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
61
source4/scripting/bin/mymachinepw
Executable file
61
source4/scripting/bin/mymachinepw
Executable file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Unix SMB/CIFS implementation.
|
||||||
|
# Copyright (C) Volker Lendecke 2008
|
||||||
|
# Copyright (C) Stefan Metzmacher 2008
|
||||||
|
#
|
||||||
|
# Extract our own machine pw from secrets.ldb
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
import samba.param as param, ldb, sys, getopt
|
||||||
|
|
||||||
|
optlist, args = getopt.getopt(sys.argv[1:], "s:")
|
||||||
|
|
||||||
|
conf = param.LoadParm()
|
||||||
|
loaded = False
|
||||||
|
|
||||||
|
for o, v in optlist:
|
||||||
|
if o == "-s":
|
||||||
|
if not conf.load(v):
|
||||||
|
print(v + " not found")
|
||||||
|
exit(1)
|
||||||
|
loaded = True
|
||||||
|
|
||||||
|
if not loaded:
|
||||||
|
conf.load_default()
|
||||||
|
|
||||||
|
path=conf.get("private dir") + "/secrets.ldb"
|
||||||
|
netbios=conf.get("netbios name")
|
||||||
|
|
||||||
|
secrets = ldb.Ldb()
|
||||||
|
secrets.connect(path)
|
||||||
|
|
||||||
|
search = "(&(objectclass=primaryDomain)(samaccountname=" + \
|
||||||
|
netbios + "$))"
|
||||||
|
|
||||||
|
msg = secrets.search(expression=search, attrs=['secret'])
|
||||||
|
|
||||||
|
if not msg:
|
||||||
|
error = "Error:\n"
|
||||||
|
error += "Password for host[" + netbios + "] not found in path[" + path + "].\n"
|
||||||
|
error += "You may want to pass the smb.conf location via the -s option."
|
||||||
|
print error
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
password=msg[0]['secret'][0];
|
||||||
|
|
||||||
|
print(password)
|
||||||
|
exit(0)
|
@ -244,6 +244,7 @@ def provision_paths_from_lp(lp, dnsdomain):
|
|||||||
paths.templates = os.path.join(paths.private_dir, "templates.ldb")
|
paths.templates = os.path.join(paths.private_dir, "templates.ldb")
|
||||||
paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone")
|
paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone")
|
||||||
paths.namedconf = os.path.join(paths.private_dir, "named.conf")
|
paths.namedconf = os.path.join(paths.private_dir, "named.conf")
|
||||||
|
paths.namedtxt = os.path.join(paths.private_dir, "named.txt")
|
||||||
paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf")
|
paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf")
|
||||||
paths.winsdb = os.path.join(paths.private_dir, "wins.ldb")
|
paths.winsdb = os.path.join(paths.private_dir, "wins.ldb")
|
||||||
paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi")
|
paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi")
|
||||||
@ -503,6 +504,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
|
|||||||
backend_modules = ["normalise", "entryuuid", "paged_searches"]
|
backend_modules = ["normalise", "entryuuid", "paged_searches"]
|
||||||
# OpenLDAP handles subtree renames, so we don't want to do any of these things
|
# OpenLDAP handles subtree renames, so we don't want to do any of these things
|
||||||
tdb_modules_list = None
|
tdb_modules_list = None
|
||||||
|
elif ldap_backend is not None:
|
||||||
|
raise "LDAP Backend specified, but LDAP Backend Type not specified"
|
||||||
elif serverrole == "domain controller":
|
elif serverrole == "domain controller":
|
||||||
backend_modules = ["repl_meta_data"]
|
backend_modules = ["repl_meta_data"]
|
||||||
else:
|
else:
|
||||||
@ -1043,6 +1046,7 @@ def provision(setup_dir, message, session_info,
|
|||||||
policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies",
|
policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies",
|
||||||
"{" + policyguid + "}")
|
"{" + policyguid + "}")
|
||||||
os.makedirs(policy_path, 0755)
|
os.makedirs(policy_path, 0755)
|
||||||
|
open(os.path.join(policy_path, "GPT.INI"), 'w').write("")
|
||||||
os.makedirs(os.path.join(policy_path, "Machine"), 0755)
|
os.makedirs(os.path.join(policy_path, "Machine"), 0755)
|
||||||
os.makedirs(os.path.join(policy_path, "User"), 0755)
|
os.makedirs(os.path.join(policy_path, "User"), 0755)
|
||||||
if not os.path.isdir(paths.netlogon):
|
if not os.path.isdir(paths.netlogon):
|
||||||
@ -1081,12 +1085,15 @@ def provision(setup_dir, message, session_info,
|
|||||||
hostip6=hostip6, hostname=names.hostname,
|
hostip6=hostip6, hostname=names.hostname,
|
||||||
dnspass=dnspass, realm=names.realm,
|
dnspass=dnspass, realm=names.realm,
|
||||||
domainguid=domainguid, hostguid=hostguid)
|
domainguid=domainguid, hostguid=hostguid)
|
||||||
message("Please install the zone located in %s into your DNS server" % paths.dns)
|
|
||||||
|
|
||||||
create_named_conf(paths.namedconf, setup_path, realm=names.realm,
|
create_named_conf(paths.namedconf, setup_path, realm=names.realm,
|
||||||
|
dnsdomain=names.dnsdomain, private_dir=paths.private_dir)
|
||||||
|
|
||||||
|
create_named_txt(paths.namedtxt, setup_path, realm=names.realm,
|
||||||
dnsdomain=names.dnsdomain, private_dir=paths.private_dir,
|
dnsdomain=names.dnsdomain, private_dir=paths.private_dir,
|
||||||
keytab_name=paths.dns_keytab)
|
keytab_name=paths.dns_keytab)
|
||||||
message("See %s for example configuration statements for secure GSS-TSIG updates" % paths.namedconf)
|
message("See %s for an example configuration include file for BIND" % paths.namedconf)
|
||||||
|
message("and %s for further documentation required for secure DNS updates" % paths.namedtxt)
|
||||||
|
|
||||||
create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain,
|
create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain,
|
||||||
hostname=names.hostname, realm=names.realm)
|
hostname=names.hostname, realm=names.realm)
|
||||||
@ -1376,7 +1383,7 @@ def create_zone_file(path, setup_path, dnsdomain, domaindn,
|
|||||||
|
|
||||||
|
|
||||||
def create_named_conf(path, setup_path, realm, dnsdomain,
|
def create_named_conf(path, setup_path, realm, dnsdomain,
|
||||||
private_dir, keytab_name):
|
private_dir):
|
||||||
"""Write out a file containing zone statements suitable for inclusion in a
|
"""Write out a file containing zone statements suitable for inclusion in a
|
||||||
named.conf file (including GSS-TSIG configuration).
|
named.conf file (including GSS-TSIG configuration).
|
||||||
|
|
||||||
@ -1392,8 +1399,28 @@ def create_named_conf(path, setup_path, realm, dnsdomain,
|
|||||||
"DNSDOMAIN": dnsdomain,
|
"DNSDOMAIN": dnsdomain,
|
||||||
"REALM": realm,
|
"REALM": realm,
|
||||||
"REALM_WC": "*." + ".".join(realm.split(".")[1:]),
|
"REALM_WC": "*." + ".".join(realm.split(".")[1:]),
|
||||||
|
"PRIVATE_DIR": private_dir
|
||||||
|
})
|
||||||
|
|
||||||
|
def create_named_txt(path, setup_path, realm, dnsdomain,
|
||||||
|
private_dir, keytab_name):
|
||||||
|
"""Write out a file containing zone statements suitable for inclusion in a
|
||||||
|
named.conf file (including GSS-TSIG configuration).
|
||||||
|
|
||||||
|
:param path: Path of the new named.conf file.
|
||||||
|
:param setup_path: Setup path function.
|
||||||
|
:param realm: Realm name
|
||||||
|
:param dnsdomain: DNS Domain name
|
||||||
|
:param private_dir: Path to private directory
|
||||||
|
:param keytab_name: File name of DNS keytab file
|
||||||
|
"""
|
||||||
|
|
||||||
|
setup_file(setup_path("named.txt"), path, {
|
||||||
|
"DNSDOMAIN": dnsdomain,
|
||||||
|
"REALM": realm,
|
||||||
"DNS_KEYTAB": keytab_name,
|
"DNS_KEYTAB": keytab_name,
|
||||||
"DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name),
|
"DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name),
|
||||||
|
"PRIVATE_DIR": private_dir
|
||||||
})
|
})
|
||||||
|
|
||||||
def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm):
|
def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm):
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
|
# This file should be included in your main BIND configuration file
|
||||||
#
|
#
|
||||||
# Insert these snippets into your named.conf or bind.conf to configure
|
# For example with
|
||||||
# the BIND nameserver.
|
# include "${PRIVATE_DIR}/named.conf";
|
||||||
#
|
|
||||||
|
|
||||||
# You should always include the actual forward zone configuration:
|
|
||||||
zone "${DNSDOMAIN}." IN {
|
zone "${DNSDOMAIN}." IN {
|
||||||
type master;
|
type master;
|
||||||
file "${DNSDOMAIN}.zone";
|
file "${PRIVATE_DIR}/${DNSDOMAIN}.zone";
|
||||||
|
/*
|
||||||
|
* Attention: Not all BIND versions support "ms-self". The instead use
|
||||||
|
* of allow-update { any; }; is another, but less secure possibility.
|
||||||
|
*/
|
||||||
update-policy {
|
update-policy {
|
||||||
/*
|
/*
|
||||||
* A rather long description here, as the "ms-self" option does
|
* A rather long description here, as the "ms-self" option does
|
||||||
@ -44,6 +47,8 @@ zone "${DNSDOMAIN}." IN {
|
|||||||
|
|
||||||
# The reverse zone configuration is optional. The following example assumes a
|
# The reverse zone configuration is optional. The following example assumes a
|
||||||
# subnet of 192.168.123.0/24:
|
# subnet of 192.168.123.0/24:
|
||||||
|
|
||||||
|
/*
|
||||||
zone "123.168.192.in-addr.arpa" in {
|
zone "123.168.192.in-addr.arpa" in {
|
||||||
type master;
|
type master;
|
||||||
file "123.168.192.in-addr.arpa.zone";
|
file "123.168.192.in-addr.arpa.zone";
|
||||||
@ -51,54 +56,12 @@ zone "123.168.192.in-addr.arpa" in {
|
|||||||
grant ${REALM_WC} wildcard *.123.168.192.in-addr.arpa. PTR;
|
grant ${REALM_WC} wildcard *.123.168.192.in-addr.arpa. PTR;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
# Note that the reverse zone file is not created during the provision process.
|
# Note that the reverse zone file is not created during the provision process.
|
||||||
|
|
||||||
# The most recent BIND version (9.5.0a5 or later) supports secure GSS-TSIG
|
# The most recent BIND versions (9.5.0a5 or later) support secure GSS-TSIG
|
||||||
# updates. If you are running an earlier version of BIND, or if you do not wish
|
# updates. If you are running an earlier version of BIND, or if you do not wish
|
||||||
# to use secure GSS-TSIG updates, you may remove the update-policy sections in
|
# to use secure GSS-TSIG updates, you may remove the update-policy sections in
|
||||||
# both examples above.
|
# both examples above.
|
||||||
|
|
||||||
# If you are running a capable version of BIND and you wish to support secure
|
|
||||||
# GSS-TSIG updates, you must make the following configuration changes:
|
|
||||||
|
|
||||||
# - Insert the following lines into the options {} section of your named.conf
|
|
||||||
# file:
|
|
||||||
tkey-gssapi-credential "DNS/${DNSDOMAIN}";
|
|
||||||
tkey-domain "${REALM}";
|
|
||||||
|
|
||||||
# - Modify BIND init scripts to pass the location of the generated keytab file.
|
|
||||||
# Fedora 8 & later provide a variable named KEYTAB_FILE in /etc/sysconfig/named
|
|
||||||
# for this purpose:
|
|
||||||
KEYTAB_FILE="${DNS_KEYTAB_ABS}"
|
|
||||||
# Note that the Fedora scripts translate KEYTAB_FILE behind the scenes into a
|
|
||||||
# variable named KRB5_KTNAME, which is ultimately passed to the BIND daemon. If
|
|
||||||
# your distribution does not provide a variable like KEYTAB_FILE to pass a
|
|
||||||
# keytab file to the BIND daemon, a workaround is to place the following line in
|
|
||||||
# BIND's sysconfig file or in the init script for BIND:
|
|
||||||
export KRB5_KTNAME="${DNS_KEYTAB_ABS}"
|
|
||||||
|
|
||||||
# - Set appropriate ownership and permissions on the ${DNS_KEYTAB} file. Note
|
|
||||||
# that most distributions have BIND configured to run under a non-root user
|
|
||||||
# account. For example, Fedora 9 runs BIND as the user "named" once the daemon
|
|
||||||
# relinquishes its rights. Therefore, the file ${DNS_KEYTAB} must be readable
|
|
||||||
# by the user that BIND run as. If BIND is running as a non-root user, the
|
|
||||||
# "${DNS_KEYTAB}" file must have its permissions altered to allow the daemon to
|
|
||||||
# read it. Under Fedora 9, execute the following commands:
|
|
||||||
chgrp named ${DNS_KEYTAB_ABS}
|
|
||||||
chmod g+r ${DNS_KEYTAB_ABS}
|
|
||||||
|
|
||||||
# - Ensure the BIND zone file(s) that will be dynamically updated are in a
|
|
||||||
# directory where the BIND daemon can write. When BIND performs dynamic
|
|
||||||
# updates, it not only needs to update the zone file itself but it must also
|
|
||||||
# create a journal (.jnl) file to track the dynamic updates as they occur.
|
|
||||||
# Under Fedora 9, the /var/named directory can not be written to by the "named"
|
|
||||||
# user. However, the directory /var/named/dynamic directory does provide write
|
|
||||||
# access. Therefore the zone files were placed under the /var/named/dynamic
|
|
||||||
# directory. The file directives in both example zone statements at the
|
|
||||||
# beginning of this file were changed by prepending the directory "dynamic/".
|
|
||||||
|
|
||||||
# - If SELinux is enabled, ensure that all files have the appropriate SELinux
|
|
||||||
# file contexts. The ${DNS_KEYTAB} file must be accessible by the BIND daemon
|
|
||||||
# and should have a SELinux type of named_conf_t. This can be set with the
|
|
||||||
# following command:
|
|
||||||
chcon -t named_conf_t ${DNS_KEYTAB_ABS}
|
|
||||||
|
46
source4/setup/named.txt
Normal file
46
source4/setup/named.txt
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Additional informations for DNS setup using BIND
|
||||||
|
|
||||||
|
# If you are running a capable version of BIND and you wish to support secure
|
||||||
|
# GSS-TSIG updates, you must make the following configuration changes:
|
||||||
|
|
||||||
|
# - Insert the following lines into the options {} section of your named.conf
|
||||||
|
# file:
|
||||||
|
tkey-gssapi-credential "DNS/${DNSDOMAIN}";
|
||||||
|
tkey-domain "${REALM}";
|
||||||
|
|
||||||
|
# - Modify BIND init scripts to pass the location of the generated keytab file.
|
||||||
|
# Fedora 8 & later provide a variable named KEYTAB_FILE in /etc/sysconfig/named
|
||||||
|
# for this purpose:
|
||||||
|
KEYTAB_FILE="${DNS_KEYTAB_ABS}"
|
||||||
|
# Note that the Fedora scripts translate KEYTAB_FILE behind the scenes into a
|
||||||
|
# variable named KRB5_KTNAME, which is ultimately passed to the BIND daemon. If
|
||||||
|
# your distribution does not provide a variable like KEYTAB_FILE to pass a
|
||||||
|
# keytab file to the BIND daemon, a workaround is to place the following line in
|
||||||
|
# BIND's sysconfig file or in the init script for BIND:
|
||||||
|
export KRB5_KTNAME="${DNS_KEYTAB_ABS}"
|
||||||
|
|
||||||
|
# - Set appropriate ownership and permissions on the ${DNS_KEYTAB} file. Note
|
||||||
|
# that most distributions have BIND configured to run under a non-root user
|
||||||
|
# account. For example, Fedora 9 runs BIND as the user "named" once the daemon
|
||||||
|
# relinquishes its rights. Therefore, the file ${DNS_KEYTAB} must be readable
|
||||||
|
# by the user that BIND run as. If BIND is running as a non-root user, the
|
||||||
|
# "${DNS_KEYTAB}" file must have its permissions altered to allow the daemon to
|
||||||
|
# read it. Under Fedora 9, execute the following commands:
|
||||||
|
chgrp named ${DNS_KEYTAB_ABS}
|
||||||
|
chmod g+r ${DNS_KEYTAB_ABS}
|
||||||
|
|
||||||
|
# - Ensure the BIND zone file(s) that will be dynamically updated are in a
|
||||||
|
# directory where the BIND daemon can write. When BIND performs dynamic
|
||||||
|
# updates, it not only needs to update the zone file itself but it must also
|
||||||
|
# create a journal (.jnl) file to track the dynamic updates as they occur.
|
||||||
|
# Under Fedora 9, the /var/named directory can not be written to by the "named"
|
||||||
|
# user. However, the directory /var/named/dynamic directory does provide write
|
||||||
|
# access. Therefore the zone files were placed under the /var/named/dynamic
|
||||||
|
# directory. The file directives in both example zone statements at the
|
||||||
|
# beginning of this file were changed by prepending the directory "dynamic/".
|
||||||
|
|
||||||
|
# - If SELinux is enabled, ensure that all files have the appropriate SELinux
|
||||||
|
# file contexts. The ${DNS_KEYTAB} file must be accessible by the BIND daemon
|
||||||
|
# and should have a SELinux type of named_conf_t. This can be set with the
|
||||||
|
# following command:
|
||||||
|
chcon -t named_conf_t ${DNS_KEYTAB_ABS}
|
@ -14,10 +14,12 @@ ${HOSTIP6_BASE_LINE}
|
|||||||
;
|
;
|
||||||
${HOSTIP6_HOST_LINE}
|
${HOSTIP6_HOST_LINE}
|
||||||
${HOSTNAME} IN A ${HOSTIP}
|
${HOSTNAME} IN A ${HOSTIP}
|
||||||
|
gc._msdcs IN CNAME ${HOSTNAME}
|
||||||
${HOSTGUID}._msdcs IN CNAME ${HOSTNAME}
|
${HOSTGUID}._msdcs IN CNAME ${HOSTNAME}
|
||||||
;
|
;
|
||||||
; global catalog servers
|
; global catalog servers
|
||||||
_gc._tcp IN SRV 0 100 3268 ${HOSTNAME}
|
_gc._tcp IN SRV 0 100 3268 ${HOSTNAME}
|
||||||
|
_gc._tcp.${DEFAULTSITE}._sites IN SRV 0 100 3268 ${HOSTNAME}
|
||||||
_ldap._tcp.gc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
_ldap._tcp.gc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
||||||
_ldap._tcp.${DEFAULTSITE}._sites.gc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
_ldap._tcp.${DEFAULTSITE}._sites.gc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
||||||
;
|
;
|
||||||
@ -25,12 +27,15 @@ _ldap._tcp.${DEFAULTSITE}._sites.gc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
|||||||
_ldap._tcp IN SRV 0 100 389 ${HOSTNAME}
|
_ldap._tcp IN SRV 0 100 389 ${HOSTNAME}
|
||||||
_ldap._tcp.dc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
_ldap._tcp.dc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
||||||
_ldap._tcp.pdc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
_ldap._tcp.pdc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
||||||
|
_ldap._tcp.${DOMAINGUID} IN SRV 0 100 389 ${HOSTNAME}
|
||||||
_ldap._tcp.${DOMAINGUID}.domains._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
_ldap._tcp.${DOMAINGUID}.domains._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
||||||
|
_ldap._tcp.${DEFAULTSITE}._sites IN SRV 0 100 389 ${HOSTNAME}
|
||||||
_ldap._tcp.${DEFAULTSITE}._sites.dc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
_ldap._tcp.${DEFAULTSITE}._sites.dc._msdcs IN SRV 0 100 389 ${HOSTNAME}
|
||||||
;
|
;
|
||||||
; krb5 servers
|
; krb5 servers
|
||||||
_kerberos._tcp IN SRV 0 100 88 ${HOSTNAME}
|
_kerberos._tcp IN SRV 0 100 88 ${HOSTNAME}
|
||||||
_kerberos._tcp.dc._msdcs IN SRV 0 100 88 ${HOSTNAME}
|
_kerberos._tcp.dc._msdcs IN SRV 0 100 88 ${HOSTNAME}
|
||||||
|
_kerberos._tcp.${DEFAULTSITE}._sites IN SRV 0 100 88 ${HOSTNAME}
|
||||||
_kerberos._tcp.${DEFAULTSITE}._sites.dc._msdcs IN SRV 0 100 88 ${HOSTNAME}
|
_kerberos._tcp.${DEFAULTSITE}._sites.dc._msdcs IN SRV 0 100 88 ${HOSTNAME}
|
||||||
_kerberos._udp IN SRV 0 100 88 ${HOSTNAME}
|
_kerberos._udp IN SRV 0 100 88 ${HOSTNAME}
|
||||||
; MIT kpasswd likes to lookup this name on password change
|
; MIT kpasswd likes to lookup this name on password change
|
||||||
|
@ -3,9 +3,15 @@
|
|||||||
#
|
#
|
||||||
## Samba4 OID allocation from Samba3's examples/LDAP/samba.schema
|
## Samba4 OID allocation from Samba3's examples/LDAP/samba.schema
|
||||||
## 1.3.6.1.4.1.7165.4.1.x - attributetypes
|
## 1.3.6.1.4.1.7165.4.1.x - attributetypes
|
||||||
|
|
||||||
## 1.3.6.1.4.1.7165.4.2.x - objectclasses
|
## 1.3.6.1.4.1.7165.4.2.x - objectclasses
|
||||||
|
|
||||||
## 1.3.6.1.4.1.7165.4.3.x - LDB/LDAP Controls
|
## 1.3.6.1.4.1.7165.4.3.x - LDB/LDAP Controls
|
||||||
|
### see dsdb/samdb/samdb.h
|
||||||
|
|
||||||
## 1.3.6.1.4.1.7165.4.4.x - LDB/LDAP Extended Operations
|
## 1.3.6.1.4.1.7165.4.4.x - LDB/LDAP Extended Operations
|
||||||
|
### see dsdb/samdb/samdb.h
|
||||||
|
|
||||||
## 1.3.6.1.4.1.7165.4.255.x - mapped OIDs due to conflicts between AD and standards-track
|
## 1.3.6.1.4.1.7165.4.255.x - mapped OIDs due to conflicts between AD and standards-track
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -134,6 +134,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req,
|
|||||||
io->ntcreatex.in.security_flags = CVAL(params, 52);
|
io->ntcreatex.in.security_flags = CVAL(params, 52);
|
||||||
io->ntcreatex.in.sec_desc = NULL;
|
io->ntcreatex.in.sec_desc = NULL;
|
||||||
io->ntcreatex.in.ea_list = NULL;
|
io->ntcreatex.in.ea_list = NULL;
|
||||||
|
io->ntcreatex.in.query_maximal_access = false;
|
||||||
|
|
||||||
req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname,
|
req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname,
|
||||||
params + 53,
|
params + 53,
|
||||||
|
@ -2192,6 +2192,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
|
|||||||
io->ntcreatex.in.security_flags = CVAL(req->in.vwv, 47);
|
io->ntcreatex.in.security_flags = CVAL(req->in.vwv, 47);
|
||||||
io->ntcreatex.in.ea_list = NULL;
|
io->ntcreatex.in.ea_list = NULL;
|
||||||
io->ntcreatex.in.sec_desc = NULL;
|
io->ntcreatex.in.sec_desc = NULL;
|
||||||
|
io->ntcreatex.in.query_maximal_access = false;
|
||||||
|
|
||||||
/* we use a couple of bits of the create options internally */
|
/* we use a couple of bits of the create options internally */
|
||||||
if (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) {
|
if (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) {
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "lib/cmdline/popt_common.h"
|
#include "lib/cmdline/popt_common.h"
|
||||||
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
|
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
|
||||||
|
#include "librpc/gen_ndr/ndr_drsblobs.h"
|
||||||
#include "libcli/cldap/cldap.h"
|
#include "libcli/cldap/cldap.h"
|
||||||
#include "libcli/ldap/ldap_client.h"
|
#include "libcli/ldap/ldap_client.h"
|
||||||
#include "torture/torture.h"
|
#include "torture/torture.h"
|
||||||
@ -104,7 +105,7 @@ static struct DsSyncTest *test_create_context(struct torture_context *tctx)
|
|||||||
our_bind_info28->supported_extensions = 0xFFFFFFFF;
|
our_bind_info28->supported_extensions = 0xFFFFFFFF;
|
||||||
our_bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
|
our_bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
|
||||||
our_bind_info28->site_guid = GUID_zero();
|
our_bind_info28->site_guid = GUID_zero();
|
||||||
our_bind_info28->u1 = 0;
|
our_bind_info28->pid = 0;
|
||||||
our_bind_info28->repl_epoch = 1;
|
our_bind_info28->repl_epoch = 1;
|
||||||
|
|
||||||
our_bind_info_ctr = &ctx->admin.drsuapi.our_bind_info_ctr;
|
our_bind_info_ctr = &ctx->admin.drsuapi.our_bind_info_ctr;
|
||||||
@ -153,7 +154,7 @@ static struct DsSyncTest *test_create_context(struct torture_context *tctx)
|
|||||||
our_bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
|
our_bind_info28->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
|
||||||
}
|
}
|
||||||
our_bind_info28->site_guid = GUID_zero();
|
our_bind_info28->site_guid = GUID_zero();
|
||||||
our_bind_info28->u1 = 508;
|
our_bind_info28->pid = 0;
|
||||||
our_bind_info28->repl_epoch = 0;
|
our_bind_info28->repl_epoch = 0;
|
||||||
|
|
||||||
our_bind_info_ctr = &ctx->new_dc.drsuapi.our_bind_info_ctr;
|
our_bind_info_ctr = &ctx->new_dc.drsuapi.our_bind_info_ctr;
|
||||||
@ -210,13 +211,25 @@ static bool _test_DsBind(struct torture_context *tctx,
|
|||||||
info24 = &b->req.out.bind_info->info.info24;
|
info24 = &b->req.out.bind_info->info.info24;
|
||||||
b->peer_bind_info28.supported_extensions= info24->supported_extensions;
|
b->peer_bind_info28.supported_extensions= info24->supported_extensions;
|
||||||
b->peer_bind_info28.site_guid = info24->site_guid;
|
b->peer_bind_info28.site_guid = info24->site_guid;
|
||||||
b->peer_bind_info28.u1 = info24->u1;
|
b->peer_bind_info28.pid = info24->pid;
|
||||||
b->peer_bind_info28.repl_epoch = 0;
|
b->peer_bind_info28.repl_epoch = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 48: {
|
||||||
|
struct drsuapi_DsBindInfo48 *info48;
|
||||||
|
info48 = &b->req.out.bind_info->info.info48;
|
||||||
|
b->peer_bind_info28.supported_extensions= info48->supported_extensions;
|
||||||
|
b->peer_bind_info28.site_guid = info48->site_guid;
|
||||||
|
b->peer_bind_info28.pid = info48->pid;
|
||||||
|
b->peer_bind_info28.repl_epoch = info48->repl_epoch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 28:
|
case 28:
|
||||||
b->peer_bind_info28 = b->req.out.bind_info->info.info28;
|
b->peer_bind_info28 = b->req.out.bind_info->info.info28;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
printf("DsBind - warning: unknown BindInfo length: %u\n",
|
||||||
|
b->req.out.bind_info->length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,6 +527,8 @@ static void test_analyse_objects(struct torture_context *tctx,
|
|||||||
DEBUGADD(0,("ATTR: %s enc.length=%lu plain.length=%lu\n",
|
DEBUGADD(0,("ATTR: %s enc.length=%lu plain.length=%lu\n",
|
||||||
name, (long)enc_data->length, (long)plain_data.length));
|
name, (long)enc_data->length, (long)plain_data.length));
|
||||||
if (plain_data.length) {
|
if (plain_data.length) {
|
||||||
|
enum ndr_err_code ndr_err;
|
||||||
|
struct supplementalCredentialsBlob scb;
|
||||||
dump_data(0, plain_data.data, plain_data.length);
|
dump_data(0, plain_data.data, plain_data.length);
|
||||||
if (save_values_dir) {
|
if (save_values_dir) {
|
||||||
char *fname;
|
char *fname;
|
||||||
@ -529,6 +544,13 @@ static void test_analyse_objects(struct torture_context *tctx,
|
|||||||
}
|
}
|
||||||
talloc_free(fname);
|
talloc_free(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ndr_err = ndr_pull_struct_blob_all(&plain_data, tctx,
|
||||||
|
lp_iconv_convenience(tctx->lp_ctx), &scb,
|
||||||
|
(ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
|
||||||
|
if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||||
|
NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dump_data(0, enc_data->data, enc_data->length);
|
dump_data(0, enc_data->data, enc_data->length);
|
||||||
}
|
}
|
||||||
|
@ -540,8 +540,9 @@ int main(int argc,char *argv[])
|
|||||||
const char *basedir = NULL;
|
const char *basedir = NULL;
|
||||||
const char *extra_module = NULL;
|
const char *extra_module = NULL;
|
||||||
static int list_tests = 0;
|
static int list_tests = 0;
|
||||||
|
int num_extra_users = 0;
|
||||||
enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
|
enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
|
||||||
OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS};
|
OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,OPT_EXTRA_USER};
|
||||||
|
|
||||||
struct poptOption long_options[] = {
|
struct poptOption long_options[] = {
|
||||||
POPT_AUTOHELP
|
POPT_AUTOHELP
|
||||||
@ -569,6 +570,8 @@ int main(int argc,char *argv[])
|
|||||||
"number of simultaneous async requests", NULL},
|
"number of simultaneous async requests", NULL},
|
||||||
{"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
|
{"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
|
||||||
"set maximum time for smbtorture to live", "seconds"},
|
"set maximum time for smbtorture to live", "seconds"},
|
||||||
|
{"extra-user", 0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
|
||||||
|
"extra user credentials", NULL},
|
||||||
POPT_COMMON_SAMBA
|
POPT_COMMON_SAMBA
|
||||||
POPT_COMMON_CONNECTION
|
POPT_COMMON_CONNECTION
|
||||||
POPT_COMMON_CREDENTIALS
|
POPT_COMMON_CREDENTIALS
|
||||||
@ -612,6 +615,15 @@ int main(int argc,char *argv[])
|
|||||||
case OPT_SMB_PORTS:
|
case OPT_SMB_PORTS:
|
||||||
lp_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
|
lp_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
|
||||||
break;
|
break;
|
||||||
|
case OPT_EXTRA_USER:
|
||||||
|
{
|
||||||
|
char *option = talloc_asprintf(NULL, "torture:extra_user%u",
|
||||||
|
++num_extra_users);
|
||||||
|
char *value = poptGetOptArg(pc);
|
||||||
|
lp_set_cmdline(cmdline_lp_ctx, option, value);
|
||||||
|
talloc_free(option);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user