The branch, master has been updated
       via  a79b446... s4:smb_server: add dfs smbtorture to selftests
       via  fc94c50... s4:smb_server: Implement GET_DFS_REFERRAL for domain 
referral requests
       via  90d7689... s4:smb_server: fix trailling whitespace in trans2.c
       via  9f01e7a... s4 torture: Add tests for dfs referrals handling in 
SMB/trans2 requests
       via  0e4e39c... s4 torture test: Adapt ndr-dfsblobs torture test to new 
idl
       via  970cbad... librpc/idl: fix errors and improve idl in dfsblobs
       via  6f26410... s4:librpc: fix the autoconf build
       via  9b9def0... s4:dynconfig: let the autoconf build compile again
      from  4108728... s3-spoolss: Use the spoolss_map_to_os2_driver to modify 
drivername.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit a79b446e11c56de5244ec9b9823c436122fe5ffe
Author: Matthieu Patou <[email protected]>
Date:   Tue May 11 21:22:24 2010 +0400

    s4:smb_server: add dfs smbtorture to selftests
    
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit fc94c50a9fe0ef344068feafa21d85adb149b6b3
Author: Matthieu Patou <[email protected]>
Date:   Sat May 1 22:27:31 2010 +0400

    s4:smb_server: Implement GET_DFS_REFERRAL for domain referral requests
    
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 90d768989cff597a5b241ee14ba04024a3bda45a
Author: Matthieu Patou <[email protected]>
Date:   Sat May 1 22:33:20 2010 +0400

    s4:smb_server: fix trailling whitespace in trans2.c
    
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 9f01e7af6b5f0ab8022baabf097af6be82f13877
Author: Matthieu Patou <[email protected]>
Date:   Mon May 10 01:39:27 2010 +0400

    s4 torture: Add tests for dfs referrals handling in SMB/trans2 requests
    
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 0e4e39c7f51a6fe95485710454b5ced1a6ef7a51
Author: Matthieu Patou <[email protected]>
Date:   Mon May 10 01:40:31 2010 +0400

    s4 torture test: Adapt ndr-dfsblobs torture test to new idl
    
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 970cbad79ab4b6cad73dd75daae4f896dde92f38
Author: Matthieu Patou <[email protected]>
Date:   Mon Apr 26 01:31:19 2010 +0400

    librpc/idl: fix errors and improve idl in dfsblobs
    
    Fix problems between strings and nstring
    Allow get_deferral parameters to be used by ndr_push/pull_blobs
    Handle correctly the 16 bytes padding
    
    Signed-off-by: Stefan Metzmacher <[email protected]>

commit 6f264106a4476eb138df568f66d0a7a0216fb9fa
Author: Stefan Metzmacher <[email protected]>
Date:   Tue May 18 14:49:39 2010 +0200

    s4:librpc: fix the autoconf build
    
    metze

commit 9b9def0d724da1b20ca175c84ec03242748e45be
Author: Stefan Metzmacher <[email protected]>
Date:   Tue May 18 13:50:33 2010 +0200

    s4:dynconfig: let the autoconf build compile again
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 librpc/idl/dfsblobs.idl         |   38 +-
 selftest/target/Samba4.pm       |    4 +-
 source4/dynconfig/config.mk     |    7 +-
 source4/librpc/config.mk        |    7 +-
 source4/selftest/tests.sh       |    6 +
 source4/smb_server/smb/trans2.c |  922 +++++++++++++++++++++++++++++++++++++--
 source4/torture/config.mk       |    9 +-
 source4/torture/dfs/common.c    |   71 +++
 source4/torture/dfs/domaindfs.c |  488 +++++++++++++++++++++
 source4/torture/ndr/dfsblob.c   |    4 +-
 source4/torture/torture.c       |    1 +
 source4/torture/wscript_build   |   11 +-
 12 files changed, 1522 insertions(+), 46 deletions(-)
 create mode 100644 source4/torture/dfs/common.c
 create mode 100644 source4/torture/dfs/domaindfs.c


Changeset truncated at 500 lines:

diff --git a/librpc/idl/dfsblobs.idl b/librpc/idl/dfsblobs.idl
index ffd3e6e..88147b6 100644
--- a/librpc/idl/dfsblobs.idl
+++ b/librpc/idl/dfsblobs.idl
@@ -54,16 +54,12 @@ interface dfsblobs
                [relative_short] nstring *DFS_alt_path;
                [relative_short] nstring *netw_address;
                /* As stated in MS DFSC 2.2.4.3.1 this array was guid but now 
MUST be 16 null bytes*/
-               uint8   service_site_guid[16];
        } dfs_normal_referral;
 
        typedef struct {
                [relative_short] nstring *special_name;
                uint16 nb_expanded_names;
-               [relative_short] [flag(STR_NOTERM|NDR_REMAINING)] string_array 
*expanded_names;
-               /*[relative_short] nstring_array expanded_names2;*/
-               /* As stated in MS DFSC 2.2.4.3.1 this array was guid but now 
MUST be 16 null bytes*/
-               uint8   service_site_guid[16];
+               [relative_short,subcontext(0),flag(STR_NOTERM|NDR_REMAINING)] 
string_array *expanded_names;
        } dfs_domain_referral;
 
        typedef [nodiscriminant] union {
@@ -72,12 +68,23 @@ interface dfsblobs
                [default];
        } dfs_referral;
 
+       typedef [nodiscriminant] union {
+               [case(16)] uint8 *value;
+               [default];
+       } dfs_padding;
+
        typedef [flag(NDR_NOALIGN)] struct {
-               uint16 size;
                DFS_SERVER_TYPE server_type;
                DFS_FLAGS_REFERRAL entry_flags;
                uint32 ttl;
                [switch_is(entry_flags & DFS_FLAG_REFERRAL_DOMAIN_RESP)] 
dfs_referral referrals;
+       } dfs_referral_v3_remaining;
+
+       typedef [flag(NDR_NOALIGN)] struct {
+               uint16 size;
+               dfs_referral_v3_remaining data;
+               /* this is either 0 or 16 bytes */
+               [switch_is(size - 18)] dfs_padding service_site_guid;
        } dfs_referral_v3;
 
        typedef struct {
@@ -85,7 +92,7 @@ interface dfsblobs
                DFS_SERVER_TYPE server_type;
                DFS_FLAGS_REFERRAL entry_flags;
                uint32 ttl;
-               dfs_normal_referral referrals;
+               dfs_normal_referral r1;
        } dfs_referral_v4;
 
        typedef [nodiscriminant] union {
@@ -104,13 +111,18 @@ interface dfsblobs
        typedef [public] struct {
                uint16  path_consumed;
                uint16  nb_referrals;
-               uint32  header_flags;
+               DFS_HEADER_FLAG header_flags;
                dfs_referral_type referral_entries[nb_referrals];
        } dfs_referral_resp;
 
-       [public] void dfs_GetDFSReferral(
-               [in]            uint16 max_referral_level,
-               [in]            nstring servername,
-               [out,ref]       dfs_referral_resp *resp
-               );
+       typedef [public] struct {
+               uint16 max_referral_level;
+               nstring servername;
+       } dfs_GetDFSReferral_in;
+
+       [public] void dfs_GetDFSReferral(
+               [in]            dfs_GetDFSReferral_in req,
+               [out,ref]       dfs_referral_resp *resp
+              );
+
 }
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 69add20..e82ccfd 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -732,12 +732,14 @@ sub provision($$$$$$$)
        push(@{$ctx->{directories}}, "$ctx->{tmpdir}");
        push(@{$ctx->{directories}}, "$ctx->{tmpdir}/test1");
        push(@{$ctx->{directories}}, "$ctx->{tmpdir}/test2");
-
+       my $msdfs = "no";
+       $msdfs = "yes" if ($server_role eq "domain controller");
        $ctx->{smb_conf_extra_options} = "
 
        max xmit = 32K
        server max protocol = SMB2
         $extra_smbconf_options
+       host msdfs = $msdfs
 
 [tmp]
        path = $ctx->{tmpdir}
diff --git a/source4/dynconfig/config.mk b/source4/dynconfig/config.mk
index 976ca71..c4738b8 100644
--- a/source4/dynconfig/config.mk
+++ b/source4/dynconfig/config.mk
@@ -22,4 +22,9 @@ $(dynconfigsrcdir)/dynconfig.o: 
CFLAGS+=-DCONFIGFILE=\"$(CONFIG4FILE)\" -DBINDIR
         -DWINBINDD_PRIVILEGED_SOCKET_DIR=\"$(winbindd_privileged_socket_dir)\" 
\
         -DWINBINDD_SOCKET_DIR=\"$(winbindd_socket_dir)\" \
         -DNTP_SIGND_SOCKET_DIR=\"$(ntp_signd_socket_dir)\" \
-        -DPYTHONDIR=\"$(pythondir)\"
+        -DPYTHONDIR=\"$(pythondir)\" \
+        -DCODEPAGEDIR=\"$(codepagedir)\" \
+        -DLIBDIR=\"$(libdir)\" \
+        -DSTATEDIR=\"$(localstatedir)\" \
+        -DCACHEDIR=\"$(cachedir)\" \
+        -DSMB_PASSWD_FILE=\"$(privatedir)/smbpasswd\"
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 5985e92..5fe944a 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -301,6 +301,11 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD
 
 NDR_NTLMSSP_OBJ_FILES = ../librpc/gen_ndr/ndr_ntlmssp.o 
../librpc/ndr/ndr_ntlmssp.o
 
+[SUBSYSTEM::NDR_NTPRINTING]
+PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD
+
+NDR_NTPRINTING_OBJ_FILES = ../librpc/gen_ndr/ndr_ntprinting.o 
../librpc/ndr/ndr_ntprinting.o
+
 $(librpcsrcdir)/idl-deps:
        $(PERL) $(librpcsrcdir)/idl-deps.pl $(wildcard 
$(librpcsrcdir)/idl/*.idl ../librpc/idl/*.idl) >$@
 
@@ -357,7 +362,7 @@ PUBLIC_DEPENDENCIES = \
        NDR_FRSRPC NDR_FRSAPI NDR_FRSTRANS \
        NDR_NFS4ACL NDR_NTP_SIGND \
        NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH \
-       NDR_NTLMSSP NDR_DFSBLOBS
+       NDR_NTLMSSP NDR_NTPRINTING NDR_DFSBLOBS
 
 NDR_TABLE_OBJ_FILES = ../librpc/ndr/ndr_table.o $(gen_ndrsrcdir)/tables.o
 
diff --git a/source4/selftest/tests.sh b/source4/selftest/tests.sh
index 47bfba2..769e169 100755
--- a/source4/selftest/tests.sh
+++ b/source4/selftest/tests.sh
@@ -223,7 +223,13 @@ for bindoptions in connect $VALIDATE ; do
    done
  done
 done
+# Tests for the DFS referral calls implementation
 
+dfsc=`$smb4torture --list | grep "^DFS-" | xargs`
+
+for t in $dfsc; do
+    plansmbtorturetestsuite "$t" dc $ADDARGS //\$SERVER/ipc$ 
-U"\$USERNAME"%"\$PASSWORD"
+done
 
 # Tests for the NET API
 
diff --git a/source4/smb_server/smb/trans2.c b/source4/smb_server/smb/trans2.c
index 36dc317..e7e8edc 100644
--- a/source4/smb_server/smb/trans2.c
+++ b/source4/smb_server/smb/trans2.c
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    transaction2 handling
    Copyright (C) Andrew Tridgell 2003
+   Copyright Matthieu Patou 2010 [email protected]
 
    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
@@ -21,10 +22,20 @@
 */
 
 #include "includes.h"
+#include "smbd/service_stream.h"
 #include "smb_server/smb_server.h"
 #include "ntvfs/ntvfs.h"
 #include "libcli/raw/libcliraw.h"
 #include "libcli/raw/raw_proto.h"
+#include "librpc/gen_ndr/dfsblobs.h"
+#include "librpc/gen_ndr/ndr_dfsblobs.h"
+#include "dsdb/samdb/samdb.h"
+#include "auth/session.h"
+#include "param/param.h"
+#include "lib/tsocket/tsocket.h"
+
+#define MAX_DFS_RESPONSE 56*1024 /* 56 Kb */
+#define DEFAULT_SITE_NAME "Default-First-Site-Name"
 
 #define TRANS2_CHECK_ASYNC_STATUS_SIMPLE do { \
        if (!NT_STATUS_IS_OK(req->ntvfs->async_states->status)) { \
@@ -53,7 +64,13 @@ struct trans_op {
        NTSTATUS (*send_fn)(struct trans_op *);
        void *op_info;
 };
-
+/* A DC set is a group of DC, they might have been grouped together
+   because they belong to the same site, or to site with same cost ...
+*/
+struct dc_set {
+       const char **names;
+       uint32_t count;
+};
 #define CHECK_MIN_BLOB_SIZE(blob, size) do { \
        if ((blob)->length < (size)) { \
                return NT_STATUS_INFO_LENGTH_MISMATCH; \
@@ -204,7 +221,7 @@ static NTSTATUS trans2_open_send(struct trans_op *op)
 
        smbsrv_push_fnum(trans->out.params.data, VWV(0), 
io->t2open.out.file.ntvfs);
        SSVAL(trans->out.params.data, VWV(1), io->t2open.out.attrib);
-       srv_push_dos_date3(req->smb_conn, trans->out.params.data, 
+       srv_push_dos_date3(req->smb_conn, trans->out.params.data,
                           VWV(2), io->t2open.out.write_time);
        SIVAL(trans->out.params.data, VWV(4), io->t2open.out.size);
        SSVAL(trans->out.params.data, VWV(6), io->t2open.out.access);
@@ -239,7 +256,7 @@ static NTSTATUS trans2_open(struct smbsrv_request *req, 
struct trans_op *op)
        io->t2open.in.open_mode    = SVAL(trans->in.params.data, VWV(1));
        io->t2open.in.search_attrs = SVAL(trans->in.params.data, VWV(2));
        io->t2open.in.file_attrs   = SVAL(trans->in.params.data, VWV(3));
-       io->t2open.in.write_time   = srv_pull_dos_date(req->smb_conn, 
+       io->t2open.in.write_time   = srv_pull_dos_date(req->smb_conn,
                                                    trans->in.params.data + 
VWV(4));
        io->t2open.in.open_func    = SVAL(trans->in.params.data, VWV(6));
        io->t2open.in.size         = IVAL(trans->in.params.data, VWV(7));
@@ -300,8 +317,8 @@ static NTSTATUS trans2_mkdir(struct smbsrv_request *req, 
struct trans_op *op)
                return NT_STATUS_FOOBAR;
        }
 
-       TRANS2_CHECK(ea_pull_list(&trans->in.data, io, 
-                                 &io->t2mkdir.in.num_eas, 
+       TRANS2_CHECK(ea_pull_list(&trans->in.data, io,
+                                 &io->t2mkdir.in.num_eas,
                                  &io->t2mkdir.in.eas));
 
        op->op_info = io;
@@ -362,7 +379,7 @@ static NTSTATUS trans2_push_fileinfo(struct 
smbsrv_connection *smb_conn,
                                         st->ea_list.out.eas);
                TRANS2_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, list_size));
 
-               ea_put_list(blob->data, 
+               ea_put_list(blob->data,
                            st->ea_list.out.num_eas, st->ea_list.out.eas);
                return NT_STATUS_OK;
 
@@ -371,7 +388,7 @@ static NTSTATUS trans2_push_fileinfo(struct 
smbsrv_connection *smb_conn,
                                                  st->all_eas.out.eas);
                TRANS2_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, list_size));
 
-               ea_put_list(blob->data, 
+               ea_put_list(blob->data,
                            st->all_eas.out.num_eas, st->all_eas.out.eas);
                return NT_STATUS_OK;
 
@@ -472,7 +489,7 @@ static NTSTATUS trans2_qpathinfo(struct smbsrv_request 
*req, struct trans_op *op
        }
 
        if (st->generic.level == RAW_FILEINFO_EA_LIST) {
-               TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req, 
+               TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,
                                               &st->ea_list.in.num_names,
                                               &st->ea_list.in.ea_names));
        }
@@ -513,7 +530,7 @@ static NTSTATUS trans2_qfileinfo(struct smbsrv_request 
*req, struct trans_op *op
        }
 
        if (st->generic.level == RAW_FILEINFO_EA_LIST) {
-               TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req, 
+               TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,
                                               &st->ea_list.in.num_names,
                                               &st->ea_list.in.ea_names));
        }
@@ -553,8 +570,8 @@ static NTSTATUS trans2_parse_sfileinfo(struct 
smbsrv_request *req,
                return NT_STATUS_OK;
 
        case RAW_SFILEINFO_EA_SET:
-               return ea_pull_list(blob, req, 
-                                   &st->ea_set.in.num_eas, 
+               return ea_pull_list(blob, req,
+                                   &st->ea_set.in.num_eas,
                                    &st->ea_set.in.eas);
 
        case SMB_SFILEINFO_BASIC_INFO:
@@ -698,7 +715,7 @@ struct find_state {
 };
 
 /*
-  fill a single entry in a trans2 find reply 
+  fill a single entry in a trans2 find reply
 */
 static NTSTATUS find_fill_info(struct find_state *state,
                               const union smb_search_data *file)
@@ -730,7 +747,7 @@ static NTSTATUS find_fill_info(struct find_state *state,
                SIVAL(data, 12, file->standard.size);
                SIVAL(data, 16, file->standard.alloc_size);
                SSVAL(data, 20, file->standard.attrib);
-               TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, 
file->standard.name.s, 
+               TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, 
file->standard.name.s,
                                                       ofs + 22, 
SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
                                                       STR_LEN8BIT | 
STR_TERMINATE | STR_LEN_NOTERM));
                break;
@@ -751,7 +768,7 @@ static NTSTATUS find_fill_info(struct find_state *state,
                SIVAL(data, 16, file->ea_size.alloc_size);
                SSVAL(data, 20, file->ea_size.attrib);
                SIVAL(data, 22, file->ea_size.ea_size);
-               TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, 
file->ea_size.name.s, 
+               TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, 
file->ea_size.name.s,
                                                       ofs + 26, 
SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
                                                       STR_LEN8BIT | 
STR_NOALIGN));
                TRANS2_CHECK(smbsrv_blob_fill_data(trans, &trans->out.data, 
trans->out.data.length + 1));
@@ -774,7 +791,7 @@ static NTSTATUS find_fill_info(struct find_state *state,
                SIVAL(data, 16, file->ea_list.alloc_size);
                SSVAL(data, 20, file->ea_list.attrib);
                ea_put_list(data+22, file->ea_list.eas.num_eas, 
file->ea_list.eas.eas);
-               TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, 
file->ea_list.name.s, 
+               TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, 
file->ea_list.name.s,
                                                       ofs + 22 + ea_size, 
SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
                                                       STR_LEN8BIT | 
STR_NOALIGN));
                TRANS2_CHECK(smbsrv_blob_fill_data(trans, &trans->out.data, 
trans->out.data.length + 1));
@@ -844,6 +861,857 @@ static NTSTATUS trans2_findfirst_send(struct trans_op *op)
 
 
 /*
+  fill a referral type structure
+ */
+static NTSTATUS fill_normal_dfs_referraltype(struct dfs_referral_type *ref,
+                                            uint16_t version,
+                                            const char *dfs_path,
+                                            const char *server_path, int 
isfirstoffset)
+{
+
+       switch (version) {
+       case 3:
+               ZERO_STRUCTP(ref);
+               ref->version = version;
+               ref->referral.v3.data.server_type = DFS_SERVER_NON_ROOT;
+               ref->referral.v3.size = 18;
+
+               ref->referral.v3.data.entry_flags = 0;
+               ref->referral.v3.data.ttl = 600; /* As w2k3 */
+               ref->referral.v3.data.referrals.r1.DFS_path = dfs_path;
+               ref->referral.v3.data.referrals.r1.DFS_alt_path = dfs_path;
+               ref->referral.v3.data.referrals.r1.netw_address = server_path;
+               return NT_STATUS_OK;
+       case 4:
+               ZERO_STRUCTP(ref);
+               ref->version = version;
+               ref->referral.v4.server_type = DFS_SERVER_NON_ROOT;
+               ref->referral.v4.size = 18;
+
+               if (isfirstoffset) {
+                       ref->referral.v4.entry_flags =  
DFS_HEADER_FLAG_TARGET_BCK;
+               }
+               ref->referral.v4.ttl = 600; /* As w2k3 */
+               ref->referral.v4.r1.DFS_path = dfs_path;
+               ref->referral.v4.r1.DFS_alt_path = dfs_path;
+               ref->referral.v4.r1.netw_address = server_path;
+
+               return NT_STATUS_OK;
+       }
+       return NT_STATUS_INVALID_LEVEL;
+}
+
+/*
+  fill a domain refererral
+ */
+static NTSTATUS fill_domain_dfs_referraltype(struct dfs_referral_type *ref,
+                                            uint16_t version,
+                                            const char *domain,
+                                            const char **names,
+                                            uint16_t numnames)
+{
+       switch (version) {
+       case 3:
+               ZERO_STRUCTP(ref);
+               ref->version = version;
+               ref->referral.v3.data.server_type = DFS_SERVER_NON_ROOT;
+               ref->referral.v3.size = 34;
+               ref->referral.v3.data.entry_flags = 
DFS_FLAG_REFERRAL_DOMAIN_RESP;
+               ref->referral.v3.data.ttl = 600; /* As w2k3 */
+               ref->referral.v3.data.referrals.r2.special_name = domain;
+               ref->referral.v3.data.referrals.r2.nb_expanded_names = numnames;
+               /* Put the final terminator */
+               if (names) {
+                       const char **names2 = talloc_array(ref, const char *, 
numnames+1);
+                       NT_STATUS_HAVE_NO_MEMORY(names2);
+                       int i;
+                       for (i = 0; i<numnames; i++) {
+                               names2[i] = talloc_asprintf(names2, "\\%s", 
names[i]);
+                               NT_STATUS_HAVE_NO_MEMORY(names2[i]);
+                       }
+                       names2[numnames] = 0;
+                       ref->referral.v3.data.referrals.r2.expanded_names = 
names2;
+               }
+               return NT_STATUS_OK;
+       }
+       return NT_STATUS_INVALID_LEVEL;
+}
+
+/*
+  get the DCs list within a site
+ */
+static NTSTATUS get_dcs_insite(TALLOC_CTX *ctx, struct ldb_context *ldb,
+                              struct ldb_dn *sitedn, struct dc_set *list,
+                              bool dofqdn)
+{
+       static const char *attrs[] = { "serverReference", NULL };
+       static const char *attrs2[] = { "dNSHostName", "sAMAccountName", NULL };
+       struct ldb_result *r;
+       unsigned int i;
+       int ret;
+       const char **dc_list;
+
+       ret = ldb_search(ldb, ctx, &r, sitedn, LDB_SCOPE_SUBTREE, attrs,
+                        "(&(objectClass=server)(serverReference=*))");
+       if (ret != LDB_SUCCESS) {
+               DEBUG(2,(__location__ ": Failed to get list of servers - %s\n",
+                        ldb_errstring(ldb)));
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       if (r->count == 0) {
+               /* none in this site */
+               talloc_free(r);
+               return NT_STATUS_OK;
+       }
+
+       /*
+        * need to search for all server object to know the size of the array.
+        * Search all the object of class server in this site
+        */
+       dc_list = talloc_array(r, const char *, r->count);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dc_list, r);
+
+       /* TODO put some random here in the order */
+       list->names = talloc_realloc(list, list->names, const char *, 
list->count + r->count);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(list->names, r);
+
+       for (i = 0; i<r->count; i++) {
+               struct ldb_dn  *dn;
+               struct ldb_result *r2;
+
+               dn = ldb_msg_find_attr_as_dn(ldb, ctx, r->msgs[i], 
"serverReference");
+               if (!dn) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+
+               ret = ldb_search(ldb, r, &r2, dn, LDB_SCOPE_BASE, attrs2, 
"(objectClass=computer)");
+               if (ret != LDB_SUCCESS) {
+                       DEBUG(2,(__location__ ": Search for computer on %s 
failed - %s\n",
+                                ldb_dn_get_linearized(dn), 
ldb_errstring(ldb)));
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+
+               if (dofqdn) {
+                       const char *dns = 
ldb_msg_find_attr_as_string(r2->msgs[0], "dNSHostName", NULL);
+                       if (dns == NULL) {
+                               DEBUG(2,(__location__ ": dNSHostName missing on 
%s\n",
+                                        ldb_dn_get_linearized(dn)));
+                               talloc_free(r);
+                               return NT_STATUS_INTERNAL_ERROR;
+                       }
+
+                       list->names[list->count] = talloc_strdup(list->names, 
dns);
+                       
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(list->names[list->count], r);
+               } else {
+                       char *tmp;
+                       const char *acct = 
ldb_msg_find_attr_as_string(r2->msgs[0], "sAMAccountName", NULL);
+                       if (acct == NULL) {
+                               DEBUG(2,(__location__ ": sAMAccountName missing 
on %s\n",
+                                        ldb_dn_get_linearized(dn)));
+                               talloc_free(r);
+                               return NT_STATUS_INTERNAL_ERROR;
+                       }
+
+                       tmp = talloc_strdup(list->names, acct);
+                       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(tmp, r);
+
+                       /* Netbios name is also the sAMAccountName for
+                          computer but without the final $ */
+                       tmp[strlen(tmp) - 1] = '\0';
+                       list->names[list->count] = tmp;
+               }
+               list->count++;
+               talloc_free(r2);
+       }
+
+       talloc_free(r);
+       return NT_STATUS_OK;
+}
+
+
+/*
+  get all DCs
+ */
+static NTSTATUS get_dcs(TALLOC_CTX *ctx, struct ldb_context *ldb,
+                       const char *searched_site, bool need_fqdn,
+                       struct dc_set ***pset_list, uint32_t flags)
+{
+       /*


-- 
Samba Shared Repository

Reply via email to