Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into manpage
authorJelmer Vernooij <jelmer@samba.org>
Sun, 27 Jul 2008 17:57:27 +0000 (19:57 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Sun, 27 Jul 2008 17:57:27 +0000 (19:57 +0200)
(This used to be commit 7e90cc197c4fb2884f368cd72f391d0d8016fb96)

37 files changed:
packaging/Fedora/samba4.spec
source4/auth/credentials/credentials_krb5.c
source4/auth/gensec/gensec_gssapi.c
source4/dsdb/common/flags.h
source4/dsdb/repl/drepl_out_helpers.c
source4/dsdb/repl/drepl_service.c
source4/dsdb/samdb/ldb_modules/partition.c
source4/dsdb/samdb/ldb_modules/password_hash.c
source4/dsdb/samdb/ldb_modules/rootdse.c
source4/dsdb/samdb/ldb_modules/schema_fsmo.c
source4/dsdb/samdb/samdb.h
source4/dsdb/schema/schema_init.c
source4/kdc/hdb-ldb.c
source4/lib/events/events_signal.c
source4/lib/ldb/tools/cmdline.c
source4/lib/util/byteorder.h
source4/libnet/libnet_become_dc.c
source4/libnet/libnet_unbecome_dc.c
source4/librpc/idl/dcerpc.idl
source4/librpc/idl/drsblobs.idl
source4/librpc/idl/drsuapi.idl
source4/librpc/rpc/dcerpc_util.c
source4/ntvfs/posix/pvfs_open.c
source4/ntvfs/posix/xattr_system.c
source4/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
source4/rpc_server/dcerpc_server.c
source4/rpc_server/drsuapi/dcesrv_drsuapi.c
source4/scripting/bin/mymachinepw [new file with mode: 0755]
source4/scripting/python/samba/provision.py
source4/setup/named.conf
source4/setup/named.txt [new file with mode: 0644]
source4/setup/provision.zone
source4/setup/schema_samba4.ldif
source4/smb_server/smb/nttrans.c
source4/smb_server/smb/reply.c
source4/torture/rpc/dssync.c
source4/torture/smbtorture.c

index 4e86050dcf8b899a94eaeb57f4962036a0411763..45d1429362c27d6cae56a6c4bee3534b780bddc1 100644 (file)
@@ -11,7 +11,6 @@
 
 Summary: The Samba4 CIFS and AD client and server suite
 Name: samba4
-Epoch: 0
 Version: 4.0.0
 Release: 0.%{main_release}.alpha%{alpha_version}%{?dist}
 License: GPLv3+, LGPLv3+, BSD
@@ -25,7 +24,7 @@ Source1: %{name}.log
 Source4: %{name}.sysconfig
 Source5: %{name}.init
 
-Requires(pre): %{name}-common = %{epoch}:%{version}-%{release}
+Requires(pre): %{name}-common = %{version}-%{release}
 Requires: pam >= 0:0.64
 Requires: logrotate >= 0:3.4
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -33,7 +32,7 @@ Requires(pre): /usr/sbin/groupadd
 Requires(post): /sbin/chkconfig, /sbin/service
 Requires(preun): /sbin/chkconfig, /sbin/service
 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: libtalloc-devel >= %{talloc_version}
 BuildRequires: libtdb-devel >= %{tdb_version}
@@ -48,8 +47,8 @@ by Windows 2000 and above.
 %package client
 Summary: Samba client programs
 Group: Applications/System
-Requires: %{name}-common = %{epoch}:%{version}-%{release}
-Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+Requires: %{name}-common = %{version}-%{release}
+Requires: %{name}-libs = %{version}-%{release}
 
 %description client
 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
 Summary: Samba libraries
 Group: Applications/System
-Requires: libtdb >= 0:%{tdb_version}
-Requires: libtalloc >= 0:%{talloc_version}
-Requires(post): /sbin/ldconfig
-Requires(postun): /sbin/ldconfig
 
 %description libs
 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
 Summary: Samba python libraries
 Group: Applications/System
-Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+Requires: %{name}-libs = %{version}-%{release}
 
 %description python
 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
 Summary: Developer tools for Samba libraries
 Group: Development/Libraries
-Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+Requires: %{name}-libs = %{version}-%{release}
 
 %description devel
 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
 Summary: Files used by both Samba servers and clients
 Group: Applications/System
-Requires: %{name}-libs = %{epoch}:%{version}-%{release}
-Requires(post): /sbin/chkconfig, /sbin/service, coreutils
+Requires: %{name}-libs = %{version}-%{release}
+Requires(post): /sbin/chkconfig, /sbin/service
 Requires(preun): /sbin/chkconfig, /sbin/service
 
 %description common
@@ -110,7 +105,7 @@ packages of Samba.
 %package winbind
 Summary: Samba winbind
 Group: Applications/System
-Requires: %{name} = %{epoch}:%{version}-%{release}
+Requires: %{name} = %{version}-%{release}
 
 %description winbind
 The samba-winbind package provides the winbind NSS library, and some
index a880486f0fc884679e97824c2b97638069b66192..c4c58398c3f750386c18da9ff8da176555e6d8ac 100644 (file)
@@ -360,6 +360,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
        struct gssapi_creds_container *gcc;
        struct ccache_container *ccache;
        gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
+       krb5_enctype *etypes = NULL;
 
        if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold && 
            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;
        }
 
+       /* 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 */
        maj_stat = gss_set_cred_option(&min_stat, &gcc->creds,
                                       GSS_KRB5_CRED_NO_CI_FLAGS_X,
index cc0d40469e529099113c12233fdc52f1cc04d1de..205d8a0f9b9ea2dac70c8c1098af4d40d5086e64 100644 (file)
@@ -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);
        OM_uint32 maj_stat, min_stat;
        gss_buffer_desc input_token, output_token;
-       int conf_state;
-       ssize_t sig_length = 0;
 
        input_token.length = length;
        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,
-                           0,
                            GSS_C_QOP_DEFAULT,
                            &input_token,
-                           &conf_state,
                            &output_token);
        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)));
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       if (output_token.length < input_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);
+       *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, output_token.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
                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
        OM_uint32 maj_stat, min_stat;
-       gss_buffer_desc input_token, output_token;
-       int conf_state;
+       gss_buffer_desc input_token;
+       gss_buffer_desc input_message;
        gss_qop_t qop_state;
-       DATA_BLOB in;
 
        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);
-       memcpy(in.data + sig->length, data, length);
+       input_token.length = sig->length;
+       input_token.value = sig->data;
 
-       input_token.length = in.length;
-       input_token.value = in.data;
-       
-       maj_stat = gss_unwrap(&min_stat, 
+       maj_stat = gss_verify_mic(&min_stat,
                              gensec_gssapi_state->gssapi_context, 
+                             &input_message,
                              &input_token,
-                             &output_token, 
-                             &conf_state,
                              &qop_state);
        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)));
                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;
 }
 
index 36111418e20c5ad5f2645ae0cf550ec27700e121..e8802fdf9c1b5d0d1588976cdccdb9ee238e9a7a 100644 (file)
 #define DS_BEHAVIOR_WIN2000            0
 #define DS_BEHAVIOR_WIN2003_INTERIM    1
 #define DS_BEHAVIOR_WIN2003            2
+#define DS_BEHAVIOR_WIN2008            3
index 281e5691e2616f023a3481a1b34a727dc488bbfb..345e3db1ab0561bee55788af8b134b1008e1e23d 100644 (file)
@@ -142,10 +142,19 @@ static void dreplsrv_out_drsuapi_bind_recv(struct rpc_request *req)
                        info24 = &st->bind_r.out.bind_info->info.info24;
                        st->drsuapi->remote_info28.supported_extensions = info24->supported_extensions;
                        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;
                        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:
                        st->drsuapi->remote_info28 = st->bind_r.out.bind_info->info.info28;
                        break;
index e485c50a473d5e94f0199adc37bbeceb4c492508..3611258ca586b995fdd3e2d1e74ababe74f2b9a1 100644 (file)
@@ -104,7 +104,7 @@ static WERROR dreplsrv_connect_samdb(struct dreplsrv_service *service, struct lo
        /* TODO: fill in site_guid */
        bind_info28->site_guid                  = GUID_zero();
        /* TODO: find out how this is really triggered! */
-       bind_info28->u1                         = 0;
+       bind_info28->pid                        = 0;
        bind_info28->repl_epoch                 = 0;
 
        return WERR_OK;
index 22826e4f3346325a7d55122cbb9d7ab992bc49d7..9285d6d0d862e6e2d73b05f5db85d412ff356fed 100644 (file)
@@ -699,6 +699,50 @@ static int partition_extended_replicated_objects(struct ldb_module *module, stru
        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 */
 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);
        }
 
+       /* 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
         * we need to send it to all partitions
index 3e442b634140c403720f6746df84c8612f351aa1..69783aefa8946b77b78fc5626787f213bf48b31a 100644 (file)
@@ -140,6 +140,11 @@ struct setup_password_fields_io {
                struct samr_Password *nt_history;
                uint32_t lm_history_len;
                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;
                NTTIME last_set;
                uint32_t kvno;
@@ -216,21 +221,12 @@ static int setup_lm_fields(struct setup_password_fields_io *io)
        return LDB_SUCCESS;
 }
 
-static int setup_primary_kerberos(struct setup_password_fields_io *io,
-                                 const struct supplementalCredentialsBlob *old_scb,
-                                 struct package_PrimaryKerberosBlob *pkb)
+static int setup_kerberos_keys(struct setup_password_fields_io *io)
 {
        krb5_error_code krb5_ret;
        Principal *salt_principal;
        krb5_salt salt;
        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
         * 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) {
                ldb_asprintf_errstring(io->ac->module->ldb,
-                                      "setup_primary_kerberos: "
+                                      "setup_kerberos_keys: "
                                       "generation of a salting principal failed: %s",
                                       smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
                return LDB_ERR_OPERATIONS_ERROR;
@@ -304,81 +300,72 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
        krb5_free_principal(io->smb_krb5_context->krb5_context, salt_principal);
        if (krb5_ret) {
                ldb_asprintf_errstring(io->ac->module->ldb,
-                                      "setup_primary_kerberos: "
+                                      "setup_kerberos_keys: "
                                       "generation of krb5_salt failed: %s",
                                       smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
                return LDB_ERR_OPERATIONS_ERROR;
        }
        /* create a talloc copy */
-       pkb3->salt.string = talloc_strndup(io->ac,
-                                         salt.saltvalue.data,
-                                         salt.saltvalue.length);
+       io->g.salt = talloc_strndup(io->ac,
+                                   salt.saltvalue.data,
+                                   salt.saltvalue.length);
        krb5_free_salt(io->smb_krb5_context->krb5_context, salt);
-       if (!pkb3->salt.string) {
+       if (!io->g.salt) {
                ldb_oom(io->ac->module->ldb);
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       salt.saltvalue.data     = discard_const(pkb3->salt.string);
-       salt.saltvalue.length   = strlen(pkb3->salt.string);
+       salt.saltvalue.data     = discard_const(io->g.salt);
+       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!
+        * create ENCTYPE_AES256_CTS_HMAC_SHA1_96 key out of
+        * the salt and the cleartext password
         */
-       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);
+       krb5_ret = krb5_string_to_key_salt(io->smb_krb5_context->krb5_context,
+                                          ENCTYPE_AES256_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 aes256-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;
        }
-       pkb3->unknown3  = talloc_zero_array(io->ac, uint64_t, pkb3->num_keys);
-       if (!pkb3->unknown3) {
+       io->g.aes_256 = 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_256.data) {
                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_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_AES256_CTS_HMAC_SHA1_96,
+                                          ENCTYPE_AES128_CTS_HMAC_SHA1_96,
                                           io->n.cleartext,
                                           salt,
                                           &key);
-       pkb3->keys[k].keytype   = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
-       pkb3->keys[k].value     = talloc(pkb3->keys, DATA_BLOB);
-       if (!pkb3->keys[k].value) {
-               krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
-               ldb_oom(io->ac->module->ldb);
+       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;
        }
-       *pkb3->keys[k].value    = data_blob_talloc(pkb3->keys[k].value,
-                                                  key.keyvalue.data,
-                                                  key.keyvalue.length);
+       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 (!pkb3->keys[k].value->data) {
+       if (!io->g.aes_128.data) {
                ldb_oom(io->ac->module->ldb);
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       k++;
-}
 
        /*
         * create ENCTYPE_DES_CBC_MD5 key out of
@@ -389,22 +376,21 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
                                           io->n.cleartext,
                                           salt,
                                           &key);
-       pkb3->keys[k].keytype   = ENCTYPE_DES_CBC_MD5;
-       pkb3->keys[k].value     = talloc(pkb3->keys, DATA_BLOB);
-       if (!pkb3->keys[k].value) {
-               krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
-               ldb_oom(io->ac->module->ldb);
+       if (krb5_ret) {
+               ldb_asprintf_errstring(io->ac->module->ldb,
+                                      "setup_kerberos_keys: "
+                                      "generation of a des-cbc-md5 key failed: %s",
+                                      smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       *pkb3->keys[k].value    = data_blob_talloc(pkb3->keys[k].value,
-                                                  key.keyvalue.data,
-                                                  key.keyvalue.length);
+       io->g.des_md5 = data_blob_talloc(io->ac,
+                                        key.keyvalue.data,
+                                        key.keyvalue.length);
        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);
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       k++;
 
        /*
         * 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,
                                           salt,
                                           &key);
-       pkb3->keys[k].keytype   = ENCTYPE_DES_CBC_CRC;
-       pkb3->keys[k].value     = talloc(pkb3->keys, DATA_BLOB);
-       if (!pkb3->keys[k].value) {
-               krb5_free_keyblock_contents(io->smb_krb5_context->krb5_context, &key);
-               ldb_oom(io->ac->module->ldb);
+       if (krb5_ret) {
+               ldb_asprintf_errstring(io->ac->module->ldb,
+                                      "setup_kerberos_keys: "
+                                      "generation of a des-cbc-crc key failed: %s",
+                                      smb_get_krb5_error_message(io->smb_krb5_context->krb5_context, krb5_ret, io->ac));
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       *pkb3->keys[k].value    = data_blob_talloc(pkb3->keys[k].value,
-                                                  key.keyvalue.data,
-                                                  key.keyvalue.length);
+       io->g.des_crc = data_blob_talloc(io->ac,
+                                        key.keyvalue.data,
+                                        key.keyvalue.length);
        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);
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       k++;
 
-       /* fix up key number */
-       pkb3->num_keys = k;
+       return LDB_SUCCESS;
+}
+
+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 */
        pkb3->num_old_keys      = 0;
        pkb3->old_keys          = NULL;
-       pkb3->unknown3_old      = NULL;
 
        /* if there're no old keys, then we're done */
        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++) {
-               if (old_scb->sub.packages[i].unknown1 != 0x00000001) {
-                       continue;
-               }
-
                if (strcmp("Primary:Kerberos", old_scb->sub.packages[i].name) != 0) {
                        continue;
                }
@@ -503,7 +516,124 @@ static int setup_primary_kerberos(struct setup_password_fields_io *io,
        /* fill in the old keys */
        pkb3->num_old_keys      = old_pkb3->num_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;
 }
@@ -845,30 +975,48 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
        struct supplementalCredentialsBlob scb;
        struct supplementalCredentialsBlob _old_scb;
        struct supplementalCredentialsBlob *old_scb = NULL;
-       /* Packages + (Kerberos, WDigest and maybe CLEARTEXT) */
-       uint32_t num_packages = 1 + 2;
-       struct supplementalCredentialsPackage packages[1+3];
-       struct supplementalCredentialsPackage *pp = &packages[0];
-       struct supplementalCredentialsPackage *pk = &packages[1];
-       struct supplementalCredentialsPackage *pd = &packages[2];
-       struct supplementalCredentialsPackage *pc = NULL;
+       /* Packages + (Kerberos-Newer-Keys, Kerberos, WDigest and CLEARTEXT) */
+       uint32_t num_names = 0;
+       const char *names[1+4];
+       uint32_t num_packages = 0;
+       struct supplementalCredentialsPackage packages[1+4];
+       /* Packages */
+       struct supplementalCredentialsPackage *pp = NULL;
        struct package_PackagesBlob pb;
        DATA_BLOB pb_blob;
        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;
        DATA_BLOB pkb_blob;
        char *pkb_hexstr;
+       /* Primary:WDigest */
+       const char **nd = NULL;
+       struct supplementalCredentialsPackage *pd = NULL;
        struct package_PrimaryWDigestBlob pdb;
        DATA_BLOB pdb_blob;
        char *pdb_hexstr;
+       /* Primary:CLEARTEXT */
+       const char **nc = NULL;
+       struct supplementalCredentialsPackage *pc = NULL;
        struct package_PrimaryCLEARTEXTBlob pcb;
        DATA_BLOB pcb_blob;
        char *pcb_hexstr;
        int ret;
        enum ndr_err_code ndr_err;
        uint8_t zero16[16];
+       bool do_newer_keys = false;
+       bool do_cleartext = false;
 
        ZERO_STRUCT(zero16);
+       ZERO_STRUCT(names);
 
        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 (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);
                if (!NDR_ERR_CODE_IS_SUCCESS(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;
                }
 
-               old_scb = &_old_scb;
+               if (_old_scb.sub.signature == SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
+                       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 &&
            (io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
-               pc = &packages[3];
-               num_packages++;
+               do_cleartext = true;
+       }
+
+       /*
+        * 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++];
        }
 
-       /* Kerberos, WDigest, CLEARTEXT and termination(counted by the Packages element) */
-       pb.names = talloc_zero_array(io->ac, const char *, 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
         */
-       pb.names[0] = "Kerberos";
+       *nk = "Kerberos";
 
        ret = setup_primary_kerberos(io, old_scb, &pkb);
        if (ret != LDB_SUCCESS) {
@@ -925,29 +1154,19 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
                                       nt_errstr(status));
                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);
        if (!pkb_hexstr) {
                ldb_oom(io->ac->module->ldb);
                return LDB_ERR_OPERATIONS_ERROR;
        }
        pk->name        = "Primary:Kerberos";
-       pk->unknown1    = 1;
+       pk->reserved    = 1;
        pk->data        = pkb_hexstr;
 
        /*
         * setup 'Primary:WDigest' element
         */
-       pb.names[1] = "WDigest";
+       *nd = "WDigest";
 
        ret = setup_primary_wdigest(io, old_scb, &pdb);
        if (ret != LDB_SUCCESS) {
@@ -972,14 +1191,14 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
                return LDB_ERR_OPERATIONS_ERROR;
        }
        pd->name        = "Primary:WDigest";
-       pd->unknown1    = 1;
+       pd->reserved    = 1;
        pd->data        = pdb_hexstr;
 
        /*
         * setup 'Primary:CLEARTEXT' element
         */
        if (pc) {
-               pb.names[2]     = "CLEARTEXT";
+               *nc             = "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;
                }
                pc->name        = "Primary:CLEARTEXT";
-               pc->unknown1    = 1;
+               pc->reserved    = 1;
                pc->data        = pcb_hexstr;
        }
 
        /*
         * setup 'Packages' element
         */
+       pb.names = names;
        ndr_err = ndr_push_struct_blob(&pb_blob, io->ac, 
                                       lp_iconv_convenience(ldb_get_opaque(io->ac->module->ldb, "loadparm")), 
                                       &pb,
@@ -1026,12 +1246,13 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
                return LDB_ERR_OPERATIONS_ERROR;
        }
        pp->name        = "Packages";
-       pp->unknown1    = 2;
+       pp->reserved    = 2;
        pp->data        = pb_hexstr;
 
        /*
         * setup 'supplementalCredentials' value
         */
+       ZERO_STRUCT(scb);
        scb.sub.num_packages    = num_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;
        }
 
-       if (io->n.cleartext && !io->n.nt_hash) {
+       if (io->n.cleartext) {
                struct samr_Password *hash;
 
                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;
 
                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);
        if (ret != 0) {
                return ret;
index 75f99a139d797b17cbcc57be97fd36f1fd440818..ebc90d4cf3c009761ae097057640dffa99fb7aec 100644 (file)
@@ -263,9 +263,10 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
        struct ldb_request *down_req;
        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 ||
            ( ! ldb_dn_is_null(req->op.search.base))) {
+               /* Otherwise, pass down to the rest of the stack */
                return ldb_next_request(module, req);
        }
 
@@ -391,9 +392,50 @@ static int rootdse_init(struct ldb_module *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 = {
        .name                   = "rootdse",
-       .init_context           = rootdse_init,
-       .search                 = rootdse_search,
-       .request                = rootdse_request
+       .init_context   = rootdse_init,
+       .search         = rootdse_search,
+       .request                = rootdse_request,
+       .modify         = rootdse_modify
 };
index a3972287232600541bb5e28e961124d9f355873f..2acc5c0af4a6d29114a7515994f8582affd72290 100644 (file)
@@ -148,8 +148,70 @@ static int schema_fsmo_add(struct ldb_module *module, struct ldb_request *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 = {
        .name           = "schema_fsmo",
        .init_context   = schema_fsmo_init,
-       .add            = schema_fsmo_add
+       .add            = schema_fsmo_add,
+       .extended       = schema_fsmo_extended
 };
index 75aa819ccdd5809fc6dbe00a879e79d35c8fefbe..3e92671fa04690ab1b202bcdbc268e2149902f58 100644 (file)
@@ -90,4 +90,10 @@ struct dsdb_pdc_fsmo {
        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__ */
index 71d952b944bbaa926fd4aaab9fccb3a89246cc8c..9b8959466d5d9c7e393c005c427d11ec6a9ea616 100644 (file)
@@ -267,19 +267,153 @@ 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)
+{
+       return dsdb_find_prefix_for_oid(schema->num_prefixes, schema->prefixes, in, out);
+}
+
+
+WERROR dsdb_map_int2oid(const struct dsdb_schema *schema, uint32_t in, TALLOC_CTX *mem_ctx, const char **out)
 {
        uint32_t i;
 
        for (i=0; i < schema->num_prefixes; i++) {
+               const char *val;
+               if (schema->prefixes[i].id != (in & 0xFFFF0000)) {
+                       continue;
+               }
+
+               val = talloc_asprintf(mem_ctx, "%s%u",
+                                     schema->prefixes[i].oid,
+                                     in & 0xFFFF);
+               W_ERROR_HAVE_NO_MEMORY(val);
+
+               *out = val;
+               return WERR_OK;
+       }
+
+       return WERR_DS_NO_MSDS_INTID;
+}
+
+/*
+ * this function is called from within a ldb transaction from the schema_fsmo module
+ */
+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;
+
+       /*
+        * this is the algorithm we use to create new mappings for now
+        *
+        * TODO: find what algorithm windows use
+        */
+       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(schema->prefixes[i].oid, in, schema->prefixes[i].oid_len) != 0) {
+               if (strncmp(prefixes[i].oid, in, prefixes[i].oid_len) != 0) {
                        continue;
                }
 
-               val_str = in + schema->prefixes[i].oid_len;
+               val_str = in + prefixes[i].oid_len;
                end_str = NULL;
                errno = 0;
 
@@ -305,56 +439,141 @@ WERROR dsdb_map_oid2int(const struct dsdb_schema *schema, const char *in, uint32
                        return WERR_INVALID_PARAM;
                }
 
-               *out = schema->prefixes[i].id | val;
+               *out = 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_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;
+       }
 
-       for (i=0; i < schema->num_prefixes; i++) {
-               const char *val;
-               if (schema->prefixes[i].id != (in & 0xFFFF0000)) {
-                       continue;
-               }
-
-               val = talloc_asprintf(mem_ctx, "%s%u",
-                                     schema->prefixes[i].oid,
-                                     in & 0xFFFF);
-               W_ERROR_HAVE_NO_MEMORY(val);
+       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;
+       }
 
-               *out = val;
-               return WERR_OK;
+       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);
        }
 
-       return WERR_DS_NO_MSDS_INTID;
+       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 = &el;
+       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;
 }
 
-/*
- * this function is called from within a ldb transaction from the schema_fsmo module
- */
-WERROR dsdb_create_prefix_mapping(struct ldb_context *ldb, struct dsdb_schema *schema, const char *full_oid)
+WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes)
 {
-       /*
-        * TODO:
-        *      - (maybe) read the old prefixMap attribute and parse it
-        *
-        *      - recheck the prefix doesn't exist (because the ldb
-        *        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;
+       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 { \
@@ -1534,6 +1753,11 @@ int dsdb_set_global_schema(struct ldb_context *ldb)
                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;
 }
 
@@ -1571,6 +1795,10 @@ void dsdb_make_schema_global(struct ldb_context *ldb)
                return;
        }
 
+       if (global_schema) {
+               talloc_unlink(talloc_autofree_context(), schema);
+       }
+
        talloc_steal(talloc_autofree_context(), schema);
        global_schema = schema;
 
index 70e578ee0d546db5b93e6219b9c9247a5f999f3d..8f8ce3074b86d2cbf1ce09710aefdbc29fa2b1df 100644 (file)
@@ -190,9 +190,11 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
        struct samr_Password *hash;
        const struct ldb_val *sc_val;
        struct supplementalCredentialsBlob scb;
-       struct supplementalCredentialsPackage *scp = NULL;
+       struct supplementalCredentialsPackage *scpk = NULL;
+       bool newer_keys = false;
        struct package_PrimaryKerberosBlob _pkb;
        struct package_PrimaryKerberosCtr3 *pkb3 = NULL;
+       struct package_PrimaryKerberosCtr4 *pkb4 = NULL;
        uint32_t i;
        uint32_t allocated_keys = 0;
 
@@ -221,35 +223,48 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
                        goto out;
                }
 
-               for (i=0; i < scb.sub.num_packages; i++) {
-                       if (scb.sub.packages[i].unknown1 != 0x00000001) {
-                               continue;
-                       }
-
-                       if (strcmp("Primary:Kerberos", scb.sub.packages[i].name) != 0) {
-                               continue;
-                       }
+               if (scb.sub.signature != SUPPLEMENTAL_CREDENTIALS_SIGNATURE) {
+                       NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
+                       ret = EINVAL;
+                       goto out;
+               }
 
-                       if (!scb.sub.packages[i].data || !scb.sub.packages[i].data[0]) {
-                               continue;
+               for (i=0; i < scb.sub.num_packages; i++) {
+                       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;
+                               }
+                               newer_keys = true;
+                               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
+                                */
                        }
-
-                       scp = &scb.sub.packages[i];
-                       break;
                }
        }
-       /* Primary:Kerberos element of supplementalCredentials */
-       if (scp) {
+       /*
+        * Primary:Kerberos-Newer-Keys or Primary:Kerberos element
+        * of supplementalCredentials
+        */
+       if (scpk) {
                DATA_BLOB blob;
 
-               blob = strhex_to_data_blob(scp->data);
+               blob = strhex_to_data_blob(scpk->data);
                if (!blob.data) {
                        ret = ENOMEM;
                        goto out;
                }
                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_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -259,16 +274,27 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
                        goto out;
                }
 
-               if (_pkb.version != 3) {
-                       krb5_set_error_string(context, "LDB_message2entry_keys: could not parse PrimaryKerberos not version 3");
-                       krb5_warnx(context, "LDB_message2entry_keys: could not parse PrimaryKerberos not version 3");
+               if (newer_keys && _pkb.version != 4) {
+                       krb5_set_error_string(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+                       krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
                        ret = EINVAL;
                        goto out;
                }
-               
-               pkb3 = &_pkb.ctr.ctr3;
 
-               allocated_keys += pkb3->num_keys;
+               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;
+               }
        }
 
        if (allocated_keys == 0) {
@@ -304,7 +330,70 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
                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++) {
                        bool use = true;
                        Key key;
@@ -325,6 +414,7 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
                        if (!use) continue;
 
                        key.mkvno = 0;
+                       key.salt = NULL;
 
                        if (pkb3->salt.string) {
                                DATA_BLOB salt;
index 80a14acc117eff19d8a30309be8059994ff7b342..652df53d4b760a690479554d8ee7bf698feb07bc 100644 (file)
@@ -46,15 +46,15 @@ struct sigcounter {
   the poor design of signals means that this table must be static global
 */
 static struct sig_state {
-       struct signal_event *sig_handlers[NUM_SIGNALS];
-       struct sigaction *oldact[NUM_SIGNALS];
-       struct sigcounter signal_count[NUM_SIGNALS];
+       struct signal_event *sig_handlers[NUM_SIGNALS+1];
+       struct sigaction *oldact[NUM_SIGNALS+1];
+       struct sigcounter signal_count[NUM_SIGNALS+1];
        struct sigcounter got_signal;
        int pipe_hack[2];
 #ifdef SA_SIGINFO
        /* with SA_SIGINFO we get quite a lot of info per signal */
-       siginfo_t *sig_info[NUM_SIGNALS];
-       struct sigcounter sig_blocked[NUM_SIGNALS];
+       siginfo_t *sig_info[NUM_SIGNALS+1];
+       struct sigcounter sig_blocked[NUM_SIGNALS+1];
 #endif
 } *sig_state;
 
index c9c77c4e474059a0ad6dba659852744121ef7017..765d8b9edf692c16d8316d6c7513fbbdc12389bf 100644 (file)
@@ -75,6 +75,7 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb,
 #if (_SAMBA_BUILD_ >= 4)
                POPT_COMMON_SAMBA
                POPT_COMMON_CREDENTIALS
+               POPT_COMMON_CONNECTION
                POPT_COMMON_VERSION
 #endif
                { NULL }
index 857bd1d50b6d523132dd911ac4b4ba75b18e2069..894beccabf941f7df9ac7d16b8820aedd4a03c52 100644 (file)
@@ -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));
 }
 #define HAVE_ASM_BYTEORDER 1
+#else
+#define HAVE_ASM_BYTEORDER 0
 #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 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
    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 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) */
 #define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
index 3fece1a9bab0e36f2bee746c7db5e04a7f767579..1ce067c32199c941ad3d99ba9ec393beb5699a8c 100644 (file)
@@ -1516,13 +1516,30 @@ static void becomeDC_drsuapi_connect_send(struct libnet_BecomeDC_state *s,
        drsuapi->s = s;
 
        if (!drsuapi->binding) {
-               if (lp_parm_bool(s->libnet->lp_ctx, NULL, "become_dc", "print", false)) {
-                       binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[krb5,print,seal]", s->source_dsa.dns_name);
-                       if (composite_nomem(binding_str, c)) return;
-               } else {
-                       binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[krb5,seal]", s->source_dsa.dns_name);
-                       if (composite_nomem(binding_str, c)) return;
+               char *krb5_str = "";
+               char *print_str = "";
+               /*
+                * Note: Replication only works with Windows 2000 when 'krb5' is
+                *       passed as auth_type here. If NTLMSSP is used, Windows
+                *       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);
                talloc_free(binding_str);
                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;
 #endif
        bind_info28->site_guid                  = s->dest_dsa.site_guid;
-       if (s->domain.behavior_version == 2) {
-               /* TODO: find out how this is really triggered! */
-               bind_info28->u1                         = 528;
-       } else {
-               bind_info28->u1                         = 516;
-       }
+       bind_info28->pid                        = 0;
        bind_info28->repl_epoch                 = 0;
 
        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;
                        drsuapi->remote_info28.supported_extensions     = info24->supported_extensions;
                        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;
                        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:
                        drsuapi->remote_info28 = drsuapi->bind_r.out.bind_info->info.info28;
                        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);
                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];
 
index cff919018a6e0dec6e1c6de47b2296bb45fa74ce..6a42fa2370cd47ce0a77ac2baad53712b7d5e220 100644 (file)
@@ -574,7 +574,7 @@ static void unbecomeDC_drsuapi_bind_send(struct libnet_UnbecomeDC_state *s)
        bind_info28                             = &s->drsuapi.local_info28;
        bind_info28->supported_extensions       = 0;
        bind_info28->site_guid                  = GUID_zero();
-       bind_info28->u1                         = 508;
+       bind_info28->pid                        = 0;
        bind_info28->repl_epoch                 = 0;
 
        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;
                        s->drsuapi.remote_info28.supported_extensions   = info24->supported_extensions;
                        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;
                        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:
                        s->drsuapi.remote_info28 = s->drsuapi.bind_r.out.bind_info->info.info28;
                        break;
index 57028ffcbf7da01ca4f53afd6f37ab0c8f57b551..e54bc2c29f0edb88cd4b0a252fd8f0a81d64ad87 100644 (file)
@@ -253,6 +253,7 @@ interface dcerpc
        const uint8 DCERPC_PFC_FLAG_FIRST               = 0x01; /* First 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_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_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 */
index f8cbdac8c59702bd482ebe9f2d1ba062bc4c3d0d..adfc01023721237013ec400e79cdeac4d8668742 100644 (file)
@@ -205,7 +205,7 @@ interface drsblobs {
        typedef struct {
                [value(2*strlen_m(name))] uint16 name_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];
                /* 
                 * the data field contains data as HEX strings
@@ -215,6 +215,9 @@ interface drsblobs {
                 *   as non termiated UTF16 strings with
                 *   a UTF16 NULL byte as separator
                 *
+                * 'Primary:Kerberos-Newer-Keys':
+                *    ...
+                *
                 * 'Primary:Kerberos':
                 *    ...
                 *
@@ -228,11 +231,16 @@ interface drsblobs {
                [charset(DOS)] uint8 data[data_len];
        } supplementalCredentialsPackage;
 
-       /* this are 0x30 (48) whitespaces (0x20) followed by 'P' (0x50) */
-       const string SUPPLEMENTAL_CREDENTIALS_PREFIX = "                                                P";
+       /* this are 0x30 (48) whitespaces (0x20) */
+       const string SUPPLEMENTAL_CREDENTIALS_PREFIX = "                                                ";
+
+       typedef [flag(NDR_PAHEX)] enum {
+               SUPPLEMENTAL_CREDENTIALS_SIGNATURE = 0x0050
+       } supplementalCredentialsSignature;
 
        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;
                supplementalCredentialsPackage packages[num_packages];
        } supplementalCredentialsSubBlob;
@@ -264,31 +272,58 @@ interface drsblobs {
        } package_PrimaryKerberosString;
 
        typedef struct {
+               [value(0)] uint16 reserved1;
+               [value(0)] uint16 reserved2;
+               [value(0)] uint32 reserved3;
                uint32 keytype;
                [value((value?value->length:0))] uint32 value_len;
                [relative,subcontext(0),subcontext_size(value_len),flag(NDR_REMAINING)] DATA_BLOB *value;
-               [value(0)] uint32 unknown1;
-               [value(0)] uint32 unknown2;
-       } package_PrimaryKerberosKey;
+       } package_PrimaryKerberosKey3;
 
        typedef struct {
                uint16 num_keys;
                uint16 num_old_keys;
                package_PrimaryKerberosString salt;
-               [value(0)] uint32 unknown1;
-               [value(0)] uint32 unknown2;
-               package_PrimaryKerberosKey keys[num_keys];
-               package_PrimaryKerberosKey old_keys[num_old_keys];
-               udlong unknown3[num_keys];
-               udlong unknown3_old[num_old_keys];
+               package_PrimaryKerberosKey3 keys[num_keys];
+               package_PrimaryKerberosKey3 old_keys[num_old_keys];
+               [value(0)] uint32 padding1;
+               [value(0)] uint32 padding2;
+               [value(0)] uint32 padding3;
+               [value(0)] uint32 padding4;
+               [value(0)] uint32 padding5;
        } 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 {
                [case(3)] package_PrimaryKerberosCtr3 ctr3;
+               [case(4)] package_PrimaryKerberosCtr4 ctr4;
        } package_PrimaryKerberosCtr;
 
        typedef [public] struct {
-               [value(3)] uint32 version;
+               uint16 version;
+               [value(0)] uint16 flags;
                [switch_is(version)] package_PrimaryKerberosCtr ctr;
        } package_PrimaryKerberosBlob;
 
index b9cff5d11d9fbec4a19c4252c8829d47befbc576..c19da4fa19aa852c8f44f314ae618b94112bed8d 100644 (file)
@@ -58,21 +58,36 @@ interface drsuapi
                DRSUAPI_SUPPORTED_EXTENSION_80000000                    = 0x80000000
        } drsuapi_SupportedExtensions;
 
+       typedef [bitmap32bit] bitmap {
+               DRSUAPI_SUPPORTED_EXTENSION_ADAM                        = 0x00000001,
+               DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2                    = 0x00000002
+       } drsuapi_SupportedExtensionsExt;
+
        /* this is used by w2k */
        typedef struct {
                drsuapi_SupportedExtensions supported_extensions;
                GUID site_guid;
-               uint32 u1;
+               uint32 pid;
        } drsuapi_DsBindInfo24;
 
        /* this is used by w2k3 */
        typedef struct {
                drsuapi_SupportedExtensions supported_extensions;
                GUID site_guid;
-               uint32 u1;
+               uint32 pid;
                uint32 repl_epoch;
        } 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 {
                [flag(NDR_REMAINING)] DATA_BLOB info;
        } drsuapi_DsBindInfoFallBack;
@@ -80,6 +95,7 @@ interface drsuapi
        typedef [nodiscriminant] union {
                [case(24)][subcontext(4)] drsuapi_DsBindInfo24 info24;
                [case(28)][subcontext(4)] drsuapi_DsBindInfo28 info28;
+               [case(48)][subcontext(4)] drsuapi_DsBindInfo48 info48;
                [default][subcontext(4)] drsuapi_DsBindInfoFallBack FallBack;
        } drsuapi_DsBindInfo;
 
@@ -1409,7 +1425,7 @@ interface drsuapi
                GUID bind_guid;
                NTTIME_1sec bind_time;
                [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;
 
        typedef struct {
index 71c6d5f2cc85d08e79ca65f972b47d1720d0876a..32646e85b0e62793789a682c27f81632acb0a42e 100644 (file)
@@ -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
+
+  The key is always truncated to 16 bytes 
 */
 _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;
 }
 
 
index 01a249ceb76f70a63f4b0a469d6c97360e1857c7..6114b2052c1cf2f95f84fd202cd3d63f8651e90c 100644 (file)
@@ -631,12 +631,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
        status = pvfs_access_check_create(pvfs, req, name, &access_mask);
        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 */
        status = pvfs_resolve_parent(pvfs, req, name, &parent);
        if (NT_STATUS_IS_OK(status)) {
@@ -707,6 +701,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
                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
           opendb locking */
        status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key);
index 7283d716b4bd34a834e278aee5c6650a67c731fb..9a89f2a338b70a72fadc2327de1e2889d34ba1c9 100644 (file)
@@ -74,7 +74,7 @@ again:
                                return NT_STATUS_NOT_FOUND;
 
                        } 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 */
                                errno = EPERM;
                                ret = -1;
index 87ed29b54eb63ff76b1b2deb0af08be09ea0d30d..d2ab407eb0d96d5ed80adbfd3ae1dc08267bdbc6 100644 (file)
@@ -153,7 +153,6 @@ sub ParseFunction($$$)
        $self->pidl("");
        $self->pidl("status = cli_do_rpc_ndr(cli,");
        $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$ufn,");
        $self->pidl("\t\t\t&r);");
index d8dafd61f61f9d7aad80624cc17d5a004717e9af..cb07f6e8cee519d1224ee10a6a33c811f2096001 100644 (file)
@@ -36,6 +36,8 @@
 #include "libcli/security/security.h"
 #include "param/param.h"
 
+#define SAMBA_ACCOC_GROUP 0x12345678
+
 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
+
+  The key is always truncated to 16 bytes 
 */
 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
                                  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;
        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);        
        }
 
@@ -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_recv_frag = 0x2000;
        /* 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) {
                /* 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);
index e0a222e7675be23856c24fa7c54bba80d47ae414..bbb78cb7787f227ec38b216072151e34ebe161e8 100644 (file)
@@ -45,7 +45,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
        struct ldb_result *ntds_res;
        struct ldb_dn *ntds_dn;
        static const char *ntds_attrs[] = { "ms-DS-ReplicationEpoch", NULL };
-       uint32_t u1;
+       uint32_t pid;
        uint32_t repl_epoch;
        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);
 
        /*
-        * 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
@@ -119,7 +122,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
                        info24 = &r->in.bind_info->info.info24;
                        b_state->remote_info28.supported_extensions     = info24->supported_extensions;
                        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;
                        break;
                }
@@ -171,8 +174,8 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
        b_state->local_info28.supported_extensions      |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
 #endif
        b_state->local_info28.site_guid                 = site_guid;
-       b_state->local_info28.u1                                = u1;
-       b_state->local_info28.repl_epoch                        = repl_epoch;
+       b_state->local_info28.pid                       = pid;
+       b_state->local_info28.repl_epoch                = repl_epoch;
 
        /*
         * allocate the return bind_info
diff --git a/source4/scripting/bin/mymachinepw b/source4/scripting/bin/mymachinepw
new file mode 100755 (executable)
index 0000000..49a4245
--- /dev/null
@@ -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)
index 6eb47c8595d3bf656c172eb432512fea7f407296..0119f40c7f3c7b5f9c859cbb1aaaaa355eb4314e 100644 (file)
@@ -244,6 +244,7 @@ def provision_paths_from_lp(lp, dnsdomain):
     paths.templates = os.path.join(paths.private_dir, "templates.ldb")
     paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone")
     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.winsdb = os.path.join(paths.private_dir, "wins.ldb")
     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"]
         # OpenLDAP handles subtree renames, so we don't want to do any of these things
         tdb_modules_list = None
+    elif ldap_backend is not None:
+        raise "LDAP Backend specified, but LDAP Backend Type not specified"
     elif serverrole == "domain controller":
         backend_modules = ["repl_meta_data"]
     else:
@@ -1043,6 +1046,7 @@ def provision(setup_dir, message, session_info,
         policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", 
                                    "{" + policyguid + "}")
         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, "User"), 0755)
         if not os.path.isdir(paths.netlogon):
@@ -1081,12 +1085,15 @@ def provision(setup_dir, message, session_info,
                              hostip6=hostip6, hostname=names.hostname,
                              dnspass=dnspass, realm=names.realm,
                              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,
+                              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,
                               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,
                              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,
-                      private_dir, keytab_name):
+                      private_dir):
     """Write out a file containing zone statements suitable for inclusion in a
     named.conf file (including GSS-TSIG configuration).
     
@@ -1392,8 +1399,28 @@ def create_named_conf(path, setup_path, realm, dnsdomain,
             "DNSDOMAIN": dnsdomain,
             "REALM": realm,
             "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_ABS": os.path.join(private_dir, keytab_name),
+            "PRIVATE_DIR": private_dir
         })
 
 def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm):
index 4f98bbd91488995793c3b48ede1bf9281f28f1e6..0b087069c773c8cef00b1a84c05889e9b06f79ab 100644 (file)
@@ -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
-# the BIND nameserver.
-#
+# For example with
+# include "${PRIVATE_DIR}/named.conf";
 
-# You should always include the actual forward zone configuration:
 zone "${DNSDOMAIN}." IN {
        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 {
                /*
                 * 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
 # subnet of 192.168.123.0/24:
+
+/*
 zone "123.168.192.in-addr.arpa" in {
        type master;
        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;
        };
 };
+*/
+
 # 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
 # to use secure GSS-TSIG updates, you may remove the update-policy sections in
 # 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}
diff --git a/source4/setup/named.txt b/source4/setup/named.txt
new file mode 100644 (file)
index 0000000..c1e6b3a
--- /dev/null
@@ -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}
index 28c1c2976219e5fc67dfefcd25883c7f90abe03d..17ae3bb47a0ca056c9546130cb01872d3f0c459c 100644 (file)
@@ -14,10 +14,12 @@ ${HOSTIP6_BASE_LINE}
 ;
 ${HOSTIP6_HOST_LINE}
 ${HOSTNAME}            IN A    ${HOSTIP}
-${HOSTGUID}._msdcs     IN CNAME ${HOSTNAME}
+gc._msdcs              IN CNAME        ${HOSTNAME}
+${HOSTGUID}._msdcs     IN CNAME        ${HOSTNAME}
 ;
 ; global catalog servers
 _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.${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.dc._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.${DEFAULTSITE}._sites               IN SRV 0 100 389 ${HOSTNAME}
 _ldap._tcp.${DEFAULTSITE}._sites.dc._msdcs     IN SRV 0 100 389 ${HOSTNAME}
 ;
 ; krb5 servers
 _kerberos._tcp         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._udp         IN SRV 0 100 88         ${HOSTNAME}
 ; MIT kpasswd likes to lookup this name on password change
index 21d17c5caa6ebbfb42a25582b93e9e715684693d..3e129e4f6b09c8465f5e377409d969c760ce6079 100644 (file)
@@ -3,9 +3,15 @@
 #
 ## 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.2.x - objectclasses
+
 ## 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
+### 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
 #
 #
index a959793dde93ac7639d50652229ccf92b9710463..4a06ea4b91e04869853207b444a2cfb2294d61b7 100644 (file)
@@ -134,6 +134,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req,
        io->ntcreatex.in.security_flags   = CVAL(params, 52);
        io->ntcreatex.in.sec_desc         = NULL;
        io->ntcreatex.in.ea_list          = NULL;
+       io->ntcreatex.in.query_maximal_access = false;
 
        req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, 
                        params + 53, 
index d7ed052ba0e48661ee85b6befbc21bbfcdd81c64..9c4ee993d20129d445ccec18ab45cd9b4d34e8c2 100644 (file)
@@ -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.ea_list          = 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 */
        if (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) {
index 053f78e99b9d67ea94550889ebf4e9ae6e23c2bc..2930a9b1f9dc4240ed1e2f75bb606165b880abdc 100644 (file)
@@ -23,6 +23,7 @@
 #include "includes.h"
 #include "lib/cmdline/popt_common.h"
 #include "librpc/gen_ndr/ndr_drsuapi_c.h"
+#include "librpc/gen_ndr/ndr_drsblobs.h"
 #include "libcli/cldap/cldap.h"
 #include "libcli/ldap/ldap_client.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   |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
        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_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->site_guid              = GUID_zero();
-       our_bind_info28->u1                     = 508;
+       our_bind_info28->pid                    = 0;
        our_bind_info28->repl_epoch             = 0;
 
        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;
                        b->peer_bind_info28.supported_extensions= info24->supported_extensions;
                        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;
                        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:
                        b->peer_bind_info28 = b->req.out.bind_info->info.info28;
                        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",
                                    name, (long)enc_data->length, (long)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);
                                if (save_values_dir) {
                                        char *fname;
@@ -529,6 +544,13 @@ static void test_analyse_objects(struct torture_context *tctx,
                                        }
                                        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 {
                                dump_data(0, enc_data->data, enc_data->length);
                        }
index 37d7d171caddb788287a64c12daefcca6d076f72..1329f03b04b19f78f598ef4777ae9ee66bbca1ea 100644 (file)
@@ -540,8 +540,9 @@ int main(int argc,char *argv[])
        const char *basedir = NULL;
        const char *extra_module = NULL;
        static int list_tests = 0;
+       int num_extra_users = 0;
        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[] = {
                POPT_AUTOHELP
@@ -569,6 +570,8 @@ int main(int argc,char *argv[])
                 "number of simultaneous async requests", NULL},
                {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0, 
                 "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_CONNECTION
                POPT_COMMON_CREDENTIALS
@@ -612,6 +615,15 @@ int main(int argc,char *argv[])
                case OPT_SMB_PORTS:
                        lp_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
                        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;
                }
        }