Merge commit 'master/master'
authorAndrew Tridgell <tridge@samba.org>
Fri, 3 Oct 2008 19:23:00 +0000 (12:23 -0700)
committerAndrew Tridgell <tridge@samba.org>
Fri, 3 Oct 2008 19:23:00 +0000 (12:23 -0700)
40 files changed:
README.Coding
lib/talloc/talloc_guide.txt
libcli/netlogon.c
libcli/netlogon.h
prog_guide4.txt
source3/configure.in
source3/lib/debug.c
source3/libaddns/dnsrecord.c
source3/libads/cldap.c
source3/librpc/gen_ndr/nbt.h
source3/librpc/gen_ndr/ndr_nbt.c
source3/librpc/idl/nbt.idl
source3/libsmb/clidgram.c
source3/libsmb/dsgetdcname.c
source3/modules/vfs_smb_traffic_analyzer.c
source3/printing/print_cups.c
source3/smbd/conn.c
source3/smbd/reply.c
source3/utils/net_dns.c
source3/web/statuspage.c
source3/winbindd/winbindd_util.c
source4/cldap_server/netlogon.c
source4/dsdb/samdb/ldb_modules/extended_dn.c
source4/dsdb/samdb/ldb_modules/kludge_acl.c
source4/dsdb/samdb/ldb_modules/linked_attributes.c
source4/dsdb/samdb/ldb_modules/partition.c
source4/dsdb/samdb/ldb_modules/rootdse.c
source4/lib/ldb/common/ldb_dn.c
source4/lib/registry/patchfile.c
source4/libnet/libnet_become_dc.c
source4/libnet/libnet_site.c
source4/libnet/libnet_unbecome_dc.c
source4/librpc/idl/drsuapi.idl
source4/nbt_server/dgram/netlogon.c
source4/nbt_server/irpc.c
source4/setup/provision_basedn_modify.ldif
source4/torture/ldap/cldap.c
source4/torture/nbt/dgram.c
source4/torture/rpc/dssync.c
testprogs/blackbox/test_ldb.sh

index 8063ae8691a78996e372bb068abe17a3bce0f51e..c1b6641a5aebf7de4d5e85d28cfd10403599e53c 100644 (file)
@@ -1,6 +1,7 @@
-##
-## Coding conventions in the Samba 3 tree
-##
+Coding conventions in the Samba tree
+------------------------------------
+
+.. contents::
 
 ===========
 Quick Start
@@ -14,15 +15,13 @@ style should never outweigh coding itself and so the the guidelines
 described here are hopefully easy enough to follow as they are very
 common and supported by tools and editors.
 
-The basic style, also mentioned in the SAMBA_4_0/prog_guide.txt is the
-Linux kernel coding style (See Documentation/CodingStyle in the kernel
-source tree).  The closely matches what most Samba developers use already
-anyways.
+The basic style, also mentioned in prog_guide4.txt, is the Linux kernel coding 
+style (See Documentation/CodingStyle in the kernel source tree). This closely 
+matches what most Samba developers use already anyways.
 
 But to save you the trouble of reading the Linux kernel style guide, here
 are the highlights.
 
-
 * Maximum Line Width is 80 Characters
   The reason is not for people with low-res screens but rather sticking
   to 80 columns prevents you from easily nesting more than one level of
@@ -59,14 +58,14 @@ Vi
 --
 (Thanks to SATOH Fumiyasu <fumiyas@osstech.jp> for these hints):
 
-For the basic vi editor including with all variants of *nix, add the 
+For the basic vi editor including with all variants of \*nix, add the 
 following to $HOME/.exrc:
 
   set tabstop=8
   set shiftwidth=8
 
 For Vim, the following settings in $HOME/.vimrc will also deal with 
-displaying trailing whitespace:
+displaying trailing whitespace::
 
   if has("syntax") && (&t_Co > 2 || has("gui_running"))
        syntax on
@@ -91,7 +90,7 @@ FAQ & Statement Reference
 Comments
 --------
 
-Comments should always use the standard C syntax.  I.e. /* ... */.  C++ 
+Comments should always use the standard C syntax.  C++ 
 style comments are not currently allowed.
 
 
@@ -145,7 +144,7 @@ The exception to the ending rule is when the closing brace is followed by
 another language keyword such as else or the closing while in a do..while 
 loop.
 
-Good examples:
+Good examples::
 
        if (x == 1) {
                printf("good\n");
@@ -162,7 +161,7 @@ Good examples:
                printf("also good\n");
        } while (1);
 
-Bad examples:
+Bad examples::
 
        while (1)
        {
@@ -177,29 +176,29 @@ evil, they can greatly enhance readability and reduce memory leaks when used
 as the single exit point from a function.  But in no Samba world what so ever 
 is a goto outside of a function or block of code a good idea.
 
-Good Examples:
-
-int function foo(int y)
-{
-       int *z = NULL;
-       int ret = 0;
+Good Examples::
 
-       if ( y < 10 ) {
-               z = malloc(sizeof(int)*y);
-               if (!z) {
-                       ret = 1;
-                       goto done;
+       int function foo(int y)
+       {
+               int *z = NULL;
+               int ret = 0;
+
+               if ( y < 10 ) {
+                       z = malloc(sizeof(int)*y);
+                       if (!z) {
+                               ret = 1;
+                               goto done;
+                       }
                }
-       }
 
-       print("Allocated %d elements.\n", y);
+               print("Allocated %d elements.\n", y);
 
- done: 
-       if (z)
-               free(z);
       done: 
+               if (z)
+                       free(z);
 
-       return ret;
-}
+               return ret;
+       }
 
 
 Checking Pointer Values
@@ -207,13 +206,13 @@ Checking Pointer Values
 
 When invoking functions that return pointer values, either of the following 
 are acceptable.  Use you best judgement and choose the more readable option.
-Remember that many other people will review it.
+Remember that many other people will review it.::
 
        if ((x = malloc(sizeof(short)*10)) == NULL ) {
                fprintf(stderr, "Unable to alloc memory!\n");
        }
 
-or
+or::
 
        x = malloc(sizeof(short)*10);
        if (!x) {
index 18663b370d9dc4d8b9aaeae28ef40655cd4d97c4..3201fe6f0f01f511e38c8ac58204a42458598278 100644 (file)
@@ -1,5 +1,7 @@
 Using talloc in Samba4
-----------------------
+======================
+
+.. contents::
 
 Andrew Tridgell
 September 2004
@@ -18,7 +20,7 @@ get used to it.
 Perhaps the biggest change from Samba3 is that there is no distinction
 between a "talloc context" and a "talloc pointer". Any pointer
 returned from talloc() is itself a valid talloc context. This means
-you can do this:
+you can do this::
 
   struct foo *X = talloc(mem_ctx, struct foo);
   X->name = talloc_strdup(X, "foo");
@@ -271,7 +273,7 @@ equivalent to:
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 void *talloc_named_const(const void *context, size_t size, const char *name);
 
-This is equivalent to:
+This is equivalent to::
 
    ptr = talloc_size(context, size);
    talloc_set_name_const(ptr, name);
@@ -288,7 +290,7 @@ talloc_set_name() for details.
 void *talloc_init(const char *fmt, ...);
 
 This function creates a zero length named talloc context as a top
-level context. It is equivalent to:
+level context. It is equivalent to::
 
   talloc_named(NULL, 0, fmt, ...);
 
@@ -309,7 +311,7 @@ The talloc_realloc() macro changes the size of a talloc
 pointer. The "count" argument is the number of elements of type "type"
 that you want the resulting pointer to hold. 
 
-talloc_realloc() has the following equivalences:
+talloc_realloc() has the following equivalences::
 
   talloc_realloc(context, NULL, type, 1) ==> talloc(context, type);
   talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N);
@@ -490,7 +492,7 @@ This disables tracking of the NULL memory context.
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 (type *)talloc_zero(const void *ctx, type);
 
-The talloc_zero() macro is equivalent to:
+The talloc_zero() macro is equivalent to::
 
   ptr = talloc(ctx, type);
   if (ptr) memset(ptr, 0, sizeof(type));
@@ -505,7 +507,7 @@ The talloc_zero_size() function is useful when you don't have a known type
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 void *talloc_memdup(const void *ctx, const void *p, size_t size);
 
-The talloc_memdup() function is equivalent to:
+The talloc_memdup() function is equivalent to::
 
   ptr = talloc_size(ctx, size);
   if (ptr) memcpy(ptr, p, size);
@@ -514,13 +516,14 @@ The talloc_memdup() function is equivalent to:
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 char *talloc_strdup(const void *ctx, const char *p);
 
-The talloc_strdup() function is equivalent to:
+The talloc_strdup() function is equivalent to::
 
   ptr = talloc_size(ctx, strlen(p)+1);
   if (ptr) memcpy(ptr, p, strlen(p)+1);
 
 This functions sets the name of the new pointer to the passed
-string. This is equivalent to:
+string. This is equivalent to::
+
    talloc_set_name_const(ptr, ptr)
 
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@@ -540,7 +543,8 @@ The talloc_append_string() function appends the given formatted
 string to the given string.
 
 This function sets the name of the new pointer to the new
-string. This is equivalent to:
+string. This is equivalent to::
+
    talloc_set_name_const(ptr, ptr)
 
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@@ -550,7 +554,8 @@ The talloc_vasprintf() function is the talloc equivalent of the C
 library function vasprintf()
 
 This functions sets the name of the new pointer to the new
-string. This is equivalent to:
+string. This is equivalent to::
+
    talloc_set_name_const(ptr, ptr)
 
 
@@ -561,7 +566,8 @@ The talloc_asprintf() function is the talloc equivalent of the C
 library function asprintf()
 
 This functions sets the name of the new pointer to the new
-string. This is equivalent to:
+string. This is equivalent to::
+
    talloc_set_name_const(ptr, ptr)
 
 
@@ -574,7 +580,8 @@ Use this varient when the string in the current talloc buffer may
 have been truncated in length.
 
 This functions sets the name of the new pointer to the new
-string. This is equivalent to:
+string. This is equivalent to::
+
    talloc_set_name_const(ptr, ptr)
 
 
@@ -587,14 +594,15 @@ Use this varient when the string in the current talloc buffer has
 not been changed.
 
 This functions sets the name of the new pointer to the new
-string. This is equivalent to:
+string. This is equivalent to::
+
    talloc_set_name_const(ptr, ptr)
 
 
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 ((type *)talloc_array(const void *ctx, type, uint_t count);
 
-The talloc_array() macro is equivalent to:
+The talloc_array() macro is equivalent to::
 
   (type *)talloc_size(ctx, sizeof(type) * count);
 
@@ -648,7 +656,7 @@ then the pointer is returned. It it doesn't then NULL is returned.
 
 This macro allows you to do type checking on talloc pointers. It is
 particularly useful for void* private pointers. It is equivalent to
-this:
+this::
 
    (type *)talloc_check_name(ptr, #type)
 
@@ -660,7 +668,8 @@ This macro allows you to force the name of a pointer to be a
 particular type. This can be used in conjunction with
 talloc_get_type() to do type checking on void* pointers.
 
-It is equivalent to this:
+It is equivalent to this::
+
    talloc_set_name_const(ptr, #type)
 
 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
index 36d9e5fdcd955eb2c87f2c3005fbf8616c85885f..acfce61ccaf5851cd972fa52cc3d5a426e27202b 100644 (file)
@@ -37,17 +37,17 @@ NTSTATUS push_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
        if (response->ntver == NETLOGON_NT_VERSION_1) {
                ndr_err = ndr_push_struct_blob(data, mem_ctx,
                                               iconv_convenience,
-                                              &response->nt4,
+                                              &response->data.nt4,
                                               (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_NT40);
        } else if (response->ntver & NETLOGON_NT_VERSION_5EX) {
                ndr_err = ndr_push_struct_blob(data, mem_ctx,
                                               iconv_convenience,
-                                              &response->nt5_ex,
+                                              &response->data.nt5_ex,
                                               (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags);
        } else if (response->ntver & NETLOGON_NT_VERSION_5) {
                ndr_err = ndr_push_struct_blob(data, mem_ctx,
                                               iconv_convenience,
-                                              &response->nt5,
+                                              &response->data.nt5,
                                               (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE);
        } else {
                DEBUG(0, ("Asked to push unknown netlogon response type 0x%02x\n", response->ntver));
@@ -86,11 +86,12 @@ NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
        if (ntver == NETLOGON_NT_VERSION_1) {
                ndr_err = ndr_pull_struct_blob_all(data, mem_ctx,
                                                   iconv_convenience,
-                                                  &response->nt4,
+                                                  &response->data.nt4,
                                                   (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_NT40);
                response->ntver = NETLOGON_NT_VERSION_1;
                if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) {
-                       NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_NT40, &response->nt4);
+                       NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_NT40,
+                                       &response->data.nt4);
                }
 
        } else if (ntver & NETLOGON_NT_VERSION_5EX) {
@@ -99,7 +100,9 @@ NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
                if (!ndr) {
                        return NT_STATUS_NO_MEMORY;
                }
-               ndr_err = ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(ndr, NDR_SCALARS|NDR_BUFFERS, &response->nt5_ex, ntver);
+               ndr_err = ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX_with_flags(
+                       ndr, NDR_SCALARS|NDR_BUFFERS, &response->data.nt5_ex,
+                       ntver);
                if (ndr->offset < ndr->data_size) {
                        ndr_err = ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES,
                                                 "not all bytes consumed ofs[%u] size[%u]",
@@ -107,17 +110,19 @@ NTSTATUS pull_netlogon_samlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
                }
                response->ntver = NETLOGON_NT_VERSION_5EX;
                if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) {
-                       NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_EX, &response->nt5_ex);
+                       NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_EX,
+                                       &response->data.nt5_ex);
                }
 
        } else if (ntver & NETLOGON_NT_VERSION_5) {
                ndr_err = ndr_pull_struct_blob_all(data, mem_ctx,
                                                   iconv_convenience,
-                                                  &response->nt5,
+                                                  &response->data.nt5,
                                                   (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE);
                response->ntver = NETLOGON_NT_VERSION_5;
                if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && DEBUGLEVEL >= 10) {
-                       NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE, &response->nt5);
+                       NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE,
+                                       &response->data.nt5);
                }
        } else {
                DEBUG(2,("failed to parse netlogon response of type 0x%02x - unknown response type\n",
@@ -144,34 +149,34 @@ void map_netlogon_samlogon_response(struct netlogon_samlogon_response *response)
                break;
        case NETLOGON_NT_VERSION_5:
                ZERO_STRUCT(response_5_ex);
-               response_5_ex.command = response->nt5.command;
-               response_5_ex.pdc_name = response->nt5.pdc_name;
-               response_5_ex.user_name = response->nt5.user_name;
-               response_5_ex.domain = response->nt5.domain_name;
-               response_5_ex.domain_uuid = response->nt5.domain_uuid;
-               response_5_ex.forest = response->nt5.forest;
-               response_5_ex.dns_domain = response->nt5.dns_domain;
-               response_5_ex.pdc_dns_name = response->nt5.pdc_dns_name;
-               response_5_ex.sockaddr.pdc_ip = response->nt5.pdc_ip;
-               response_5_ex.server_type = response->nt5.server_type;
-               response_5_ex.nt_version = response->nt5.nt_version;
-               response_5_ex.lmnt_token = response->nt5.lmnt_token;
-               response_5_ex.lm20_token = response->nt5.lm20_token;
+               response_5_ex.command = response->data.nt5.command;
+               response_5_ex.pdc_name = response->data.nt5.pdc_name;
+               response_5_ex.user_name = response->data.nt5.user_name;
+               response_5_ex.domain = response->data.nt5.domain_name;
+               response_5_ex.domain_uuid = response->data.nt5.domain_uuid;
+               response_5_ex.forest = response->data.nt5.forest;
+               response_5_ex.dns_domain = response->data.nt5.dns_domain;
+               response_5_ex.pdc_dns_name = response->data.nt5.pdc_dns_name;
+               response_5_ex.sockaddr.pdc_ip = response->data.nt5.pdc_ip;
+               response_5_ex.server_type = response->data.nt5.server_type;
+               response_5_ex.nt_version = response->data.nt5.nt_version;
+               response_5_ex.lmnt_token = response->data.nt5.lmnt_token;
+               response_5_ex.lm20_token = response->data.nt5.lm20_token;
                response->ntver = NETLOGON_NT_VERSION_5EX;
-               response->nt5_ex = response_5_ex;
+               response->data.nt5_ex = response_5_ex;
                break;
 
        case NETLOGON_NT_VERSION_1:
                ZERO_STRUCT(response_5_ex);
-               response_5_ex.command = response->nt4.command;
-               response_5_ex.pdc_name = response->nt4.server;
-               response_5_ex.user_name = response->nt4.user_name;
-               response_5_ex.domain = response->nt4.domain;
-               response_5_ex.nt_version = response->nt4.nt_version;
-               response_5_ex.lmnt_token = response->nt4.lmnt_token;
-               response_5_ex.lm20_token = response->nt4.lm20_token;
+               response_5_ex.command = response->data.nt4.command;
+               response_5_ex.pdc_name = response->data.nt4.server;
+               response_5_ex.user_name = response->data.nt4.user_name;
+               response_5_ex.domain = response->data.nt4.domain;
+               response_5_ex.nt_version = response->data.nt4.nt_version;
+               response_5_ex.lmnt_token = response->data.nt4.lmnt_token;
+               response_5_ex.lm20_token = response->data.nt4.lm20_token;
                response->ntver = NETLOGON_NT_VERSION_5EX;
-               response->nt5_ex = response_5_ex;
+               response->data.nt5_ex = response_5_ex;
                break;
        }
        return;
@@ -185,7 +190,9 @@ NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
        enum ndr_err_code ndr_err;
        switch (response->response_type) {
        case NETLOGON_GET_PDC:
-               ndr_err = ndr_push_struct_blob(data, mem_ctx, iconv_convenience, &response->get_pdc,
+               ndr_err = ndr_push_struct_blob(data, mem_ctx,
+                                              iconv_convenience,
+                                              &response->data.get_pdc,
                                               (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_response_from_pdc);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                        status = ndr_map_error2ntstatus(ndr_err);
@@ -199,7 +206,9 @@ NTSTATUS push_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
                status = NT_STATUS_OK;
                break;
        case NETLOGON_SAMLOGON:
-               status = push_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon);
+               status = push_netlogon_samlogon_response(
+                       data, mem_ctx, iconv_convenience,
+                       &response->data.samlogon);
                break;
        }
        return status;
@@ -221,7 +230,9 @@ NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
 
        switch (command) {
        case NETLOGON_RESPONSE_FROM_PDC:
-               ndr_err = ndr_pull_struct_blob_all(data, mem_ctx, iconv_convenience, &response->get_pdc,
+               ndr_err = ndr_pull_struct_blob_all(data, mem_ctx,
+                                                  iconv_convenience,
+                                                  &response->data.get_pdc,
                                                   (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_response_from_pdc);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                        status = ndr_map_error2ntstatus(ndr_err);
@@ -241,7 +252,9 @@ NTSTATUS pull_nbt_netlogon_response(DATA_BLOB *data, TALLOC_CTX *mem_ctx,
        case LOGON_SAM_LOGON_RESPONSE_EX:
        case LOGON_SAM_LOGON_PAUSE_RESPONSE_EX:
        case LOGON_SAM_LOGON_USER_UNKNOWN_EX:
-               status = pull_netlogon_samlogon_response(data, mem_ctx, iconv_convenience, &response->samlogon);
+               status = pull_netlogon_samlogon_response(
+                       data, mem_ctx, iconv_convenience,
+                       &response->data.samlogon);
                response->response_type = NETLOGON_SAMLOGON;
                break;
 
index 8bd9d0d90a7b5e770ea7b1ce79af5f477422e69b..6ca3de3366ea35ddc1d950577957981b8fa49aa8 100644 (file)
@@ -36,7 +36,7 @@ struct netlogon_samlogon_response
                struct NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4;
                struct NETLOGON_SAM_LOGON_RESPONSE nt5;
                struct NETLOGON_SAM_LOGON_RESPONSE_EX nt5_ex;
-       };
+       } data;
 
 };
 
@@ -46,7 +46,7 @@ struct nbt_netlogon_response
        union {
                struct nbt_netlogon_response_from_pdc get_pdc;
                struct netlogon_samlogon_response samlogon;
-       };
+       } data;
 };
 
 #include "../libcli/netlogon_proto.h"
index 2f5be5f7915582977ad0bbed19a21c0aad04ea00..8d6ff56964cd40807f3a440cab83a240352a86ea 100644 (file)
@@ -5,7 +5,9 @@ FROM A FEW PEOPLE. DON'T TAKE THIS AS THE FINAL VERSION YET.
 
 
 Samba4 Programming Guide
-------------------------
+========================
+
+.. contents::
 
 The internals of Samba4 are quite different from previous versions of
 Samba, so even if you are an experienced Samba developer please take
@@ -144,8 +146,7 @@ data is a bug waiting to happen.
 Static data is evil as it has the following consequences:
 - it makes code much less likely to be thread-safe
 - it makes code much less likely to be recursion-safe
-- it leads to subtle side effects when the same code is called from
-  multiple places
+- it leads to subtle side effects when the same code is called from multiple places
 - doesn't play well with shared libraries or plugins
 
 Static data is particularly evil in library code (such as our internal
@@ -273,9 +274,9 @@ generating the right offsets.
 The same rule applies to strings. In many places in the SMB and MSRPC
 protocols complex strings are used on the wire, with complex rules
 about padding, format, alighment, termination etc. None of that
-information is useful to a high level calling routine or to a backend
-- its all just so much wire fluff. So, in Samba4 these strings are
-just "char *" and are always in our internal multi-byte format (which
+information is useful to a high level calling routine or to a backend - its 
+all just so much wire fluff. So, in Samba4 these strings are
+just "char \*" and are always in our internal multi-byte format (which
 is usually UTF8). It is up to the parse functions to worry about
 translating the format and getting the padding right.
 
@@ -580,13 +581,17 @@ DCERPC Handles
 The various handles that are used in the RPC servers should be created and 
 fetch using the dcesrv_handle_* functions.
 
-Use dcesrv_handle_new(struct dcesrv_connection *, uint8 handle_type) to obtain 
+Use dcesrv_handle_new(struct dcesrv_connection \*, uint8 handle_type) to obtain 
 a new handle of the specified type. Handle types are unique within each 
 pipe.
 
-The handle can later be fetched again using
-struct dcesrv_handle *dcesrv_handle_fetch(struct dcesrv_connection *dce_conn, struct policy_handle *p, uint8 handle_type)
-and destroyed by dcesrv_handle_destroy(struct dcesrv_handle *).
+The handle can later be fetched again using::
+
+       struct dcesrv_handle *dcesrv_handle_fetch(struct dcesrv_connection *dce_conn, struct policy_handle *p, uint8 handle_type)
+
+and destroyed by::
+
+       dcesrv_handle_destroy(struct dcesrv_handle *).
 
 User data should be stored in the 'data' member of the dcesrv_handle struct.
 
@@ -765,12 +770,10 @@ BUGS:
   no 137 resolution not possible
   should not fallback to anon when pass supplied
   should check pass-thu cap bit, and skip lots of tests
-  possibly allow the test suite to say "allow oversized replies" for
-     trans2 and other calls
+  possibly allow the test suite to say "allow oversized replies" for trans2 and other calls
   handle servers that don't have the setattre call in torture
   add max file coponent length test and max path len test
-  check for alloc failure in all core reply.c and trans2.c code where
-    allocation size depends on client parameter
+  check for alloc failure in all core reply.c and trans2.c code where allocation size depends on client parameter
 
 case-insenstive idea:
   all filenames on disk lowercase
index f04ddbeaa5cedd668326be78f727b47fe414e7c4..545a5653de917ac330b84aba705971a330611ef3 100644 (file)
@@ -128,7 +128,7 @@ fi
 if test "x$debug" = "xyes" ; then
        CFLAGS="${CFLAGS} -g"
 else
-       CFLAGS="-O"
+       CFLAGS="${CFLAGS} -O"
 fi
 
 m4_include(../lib/socket_wrapper/config.m4)
index d835ea7c176e5a824b387a587f21ba94991bf6e5..d91b55dd23b70c150b4ee26c0b98dae7eddee830 100644 (file)
@@ -578,7 +578,9 @@ void setup_logging(const char *pname, bool interactive)
        stdout_logging = False;
        if (dbf) {
                x_fflush(dbf);
-               (void) x_fclose(dbf);
+                if (dbf != x_stdout) {
+                        (void) x_fclose(dbf);
+                }
        }
 
        dbf = NULL;
index 500cbd6681a41ad2c1cd4211daabe6c3d744acef..559c2644d44a1ef3d5fb37b4797184d80e446cd0 100644 (file)
@@ -378,10 +378,10 @@ DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
        if (!ERR_DNS_IS_OK(err)) return err;
 
        /*
-        * The zone must be used at all
+        * Use the same prereq as WinXP -- No CNAME records for this host.
         */
 
-       err = dns_create_rrec(req, domainname, QTYPE_ANY, DNS_CLASS_ANY,
+       err = dns_create_rrec(req, hostname, QTYPE_CNAME, DNS_CLASS_NONE,
                              0, 0, NULL, &rec);
        if (!ERR_DNS_IS_OK(err)) goto error;
 
index edabbed0e93bdda6ab91620dcc9379fa8a87fa95..c37220c9030a6669e427a9a54bb6eb9bac10cc05 100644 (file)
@@ -283,7 +283,7 @@ bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx,
                return false;
        }
 
-       *reply5 = reply->nt5_ex;
+       *reply5 = reply->data.nt5_ex;
 
        return true;
 }
index 264b00b84fe44d5255eaae05131420b792c2de42..4b872d7936e82dbb46913423bda15f0e38980087 100644 (file)
@@ -391,7 +391,7 @@ struct nbt_dgram_packet {
 }/* [public,flag(LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_BIGENDIAN|LIBNDR_PRINT_ARRAY_HEX)] */;
 
 struct nbt_sockaddr {
-       uint32_t sa_family;
+       uint32_t sockaddr_family;
        const char * pdc_ip;/* [flag(LIBNDR_FLAG_BIGENDIAN)] */
        DATA_BLOB remaining;/* [flag(LIBNDR_FLAG_REMAINING)] */
 }/* [gensize,public] */;
index 84cfabda574a3a58e456081dda4c6f5a3edaa44d..c02b539da52708f310af440c33d581b82de5f25c 100644 (file)
@@ -1531,7 +1531,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_nbt_sockaddr(struct ndr_push *ndr, int ndr_f
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_push_align(ndr, 4));
-               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sa_family));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sockaddr_family));
                {
                        uint32_t _flags_save_ipv4address = ndr->flags;
                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
@@ -1554,7 +1554,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_nbt_sockaddr(struct ndr_pull *ndr, int ndr_f
 {
        if (ndr_flags & NDR_SCALARS) {
                NDR_CHECK(ndr_pull_align(ndr, 4));
-               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sa_family));
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sockaddr_family));
                {
                        uint32_t _flags_save_ipv4address = ndr->flags;
                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
@@ -1577,7 +1577,7 @@ _PUBLIC_ void ndr_print_nbt_sockaddr(struct ndr_print *ndr, const char *name, co
 {
        ndr_print_struct(ndr, name, "nbt_sockaddr");
        ndr->depth++;
-       ndr_print_uint32(ndr, "sa_family", r->sa_family);
+       ndr_print_uint32(ndr, "sockaddr_family", r->sockaddr_family);
        ndr_print_ipv4address(ndr, "pdc_ip", r->pdc_ip);
        ndr_print_DATA_BLOB(ndr, "remaining", r->remaining);
        ndr->depth--;
index 82571d96e67ad09cc8bb4efe2376c96796fa72bf..f3590fcf2bc8f79d8457ece5b1def40661c3372a 100644 (file)
@@ -339,7 +339,7 @@ interface nbt
         */
 
        typedef [public,gensize] struct {
-               uint32                  sa_family;
+               uint32                  sockaddr_family;
                [flag(NDR_BIG_ENDIAN)]  ipv4address pdc_ip;
                [flag(NDR_REMAINING)]   DATA_BLOB remaining;
        } nbt_sockaddr;
index e8799bce4794602c41520a3cc8a4801fcb6ebb66..611ae0870c4f2bf6e8eb3a683dea3f8e87d1b364 100644 (file)
@@ -279,8 +279,8 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx,
        /* do we still need this ? */
        *nt_version = r.ntver;
 
-       returned_domain = r.nt5_ex.domain;
-       returned_dc = r.nt5_ex.pdc_name;
+       returned_domain = r.data.nt5_ex.domain;
+       returned_dc = r.data.nt5_ex.pdc_name;
 
        if (!strequal(returned_domain, domain_name)) {
                DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
index 89769d8a760f1783eb488b39397f9b8b1e396ee7..18010aaa1ce74b567588a2af5c370829b6d07e30 100644 (file)
@@ -200,7 +200,7 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx,
 
        /* FIXME */
        r->sockaddr_size = 0x10; /* the w32 winsock addr size */
-       r->sockaddr.sa_family = 2; /* AF_INET */
+       r->sockaddr.sockaddr_family = 2; /* AF_INET */
        r->sockaddr.pdc_ip = talloc_strdup(mem_ctx, addr);
 
        ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, r,
@@ -272,12 +272,12 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response *
                case 3:
                case 18:
                case 19:
-                       return r->nt5.server_type;
+                       return r->data.nt5.server_type;
                case 4:
                case 5:
                case 6:
                case 7:
-                       return r->nt5_ex.server_type;
+                       return r->data.nt5_ex.server_type;
                case 8:
                case 9:
                case 10:
@@ -286,7 +286,7 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response *
                case 13:
                case 14:
                case 15:
-                       return r->nt5_ex.server_type;
+                       return r->data.nt5_ex.server_type;
                case 20:
                case 21:
                case 22:
@@ -296,11 +296,11 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response *
                case 26:
                case 27:
                case 28:
-                       return r->nt5_ex.server_type;
+                       return r->data.nt5_ex.server_type;
                case 29:
                case 30:
                case 31:
-                       return r->nt5_ex.server_type;
+                       return r->data.nt5_ex.server_type;
                default:
                        return 0;
        }
@@ -913,10 +913,10 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
        }
 
        status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
-                                              &r->nt5_ex, info);
+                                              &r->data.nt5_ex, info);
        if (NT_STATUS_IS_OK(status)) {
                return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
-                                        nt_version, &r->nt5_ex);
+                                        nt_version, &r->data.nt5_ex);
        }
 
        return status;
@@ -1035,7 +1035,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
                        logon1.domain = talloc_strdup_upper(mem_ctx, domain_name);
                        NT_STATUS_HAVE_NO_MEMORY(logon1.domain);
 
-                       r->nt4 = logon1;
+                       r->data.nt4 = logon1;
                        r->ntver = nt_version;
 
                        namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list);
@@ -1049,10 +1049,10 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
  make_reply:
 
        status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss,
-                                              &r->nt5_ex, info);
+                                              &r->data.nt5_ex, info);
        if (NT_STATUS_IS_OK(status) && store_cache) {
                return store_cldap_reply(mem_ctx, flags, &dclist[i].ss,
-                                        nt_version, &r->nt5_ex);
+                                        nt_version, &r->data.nt5_ex);
        }
 
        return status;
index 9e4cf816385d3bdb99d55d618c31d2c5dbe46516..ff617684957d7726c00eee2cb67e729f9e885fbe 100644 (file)
@@ -3,6 +3,7 @@
  * on the net.
  *
  * Copyright (C) Holger Hetterich, 2008
+ * Copyright (C) Jeremy Allison, 2008
  *
  * 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
 #include "includes.h"
 
 /* abstraction for the send_over_network function */
-#define UNIX_DOMAIN_SOCKET 1
-#define INTERNET_SOCKET 0
 
+enum sock_type {INTERNET_SOCKET = 0, UNIX_DOMAIN_SOCKET};
 
-/* Prototypes */
-
-extern userdom_struct current_user_info;
+#define LOCAL_PATHNAME "/var/tmp/stadsocket"
 
 static int vfs_smb_traffic_analyzer_debug_level = DBGC_VFS;
 
-NTSTATUS vfs_smb_traffic_analyzer_init(void);
-
-static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle,
-               files_struct *fsp, const void *data, size_t n);
-
-static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle,
-               files_struct *fsp, void *data, size_t n);
-
-static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle,
-               files_struct *fsp, const void *data, size_t n,
-               SMB_OFF_T offset);
-
-static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle,
-               files_struct *fsp, void *data, size_t n, SMB_OFF_T offset);
-
-
-/* VFS operations we use */
-
-static vfs_op_tuple smb_traffic_analyzer_tuples[] = {
-
-       {SMB_VFS_OP(smb_traffic_analyzer_read), SMB_VFS_OP_READ,
-        SMB_VFS_LAYER_LOGGER},
-       {SMB_VFS_OP(smb_traffic_analyzer_pread), SMB_VFS_OP_PREAD,
-        SMB_VFS_LAYER_LOGGER},
-       {SMB_VFS_OP(smb_traffic_analyzer_write), SMB_VFS_OP_WRITE,
-        SMB_VFS_LAYER_LOGGER},
-       {SMB_VFS_OP(smb_traffic_analyzer_pwrite), SMB_VFS_OP_PWRITE,
-        SMB_VFS_LAYER_LOGGER},
-               {SMB_VFS_OP(NULL),SMB_VFS_OP_NOOP,SMB_VFS_LAYER_NOOP}
-
-       };
-
-
-/* Module initialization */
-
-NTSTATUS vfs_smb_traffic_analyzer_init(void)
-{
-       NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, \
-               "smb_traffic_analyzer", smb_traffic_analyzer_tuples);
-
-       if (!NT_STATUS_IS_OK(ret))
-               return ret;
-
-       vfs_smb_traffic_analyzer_debug_level =
-               debug_add_class("smb_traffic_analyzer");
-
-       if (vfs_smb_traffic_analyzer_debug_level == -1) {
-               vfs_smb_traffic_analyzer_debug_level = DBGC_VFS;
-               DEBUG(1, ("smb_traffic_analyzer: Couldn't register custom"
-                        "debugging class!\n"));
-       } else {
-               DEBUG(3, ("smb_traffic_analyzer: Debug class number of"
-                       "'smb_traffic_analyzer': %d\n", \
-                       vfs_smb_traffic_analyzer_debug_level));
-       }
-
-       return ret;
-}
-
-/* create the timestamp in sqlite compatible format */
-static void get_timestamp( char *String )
-{
-       struct timeval tv;
-       struct timezone tz;
-       struct tm *tm;
-       int seconds;
-
-       gettimeofday(&tv, &tz);
-       tm=localtime(&tv.tv_sec);
-       seconds=(float) (tv.tv_usec / 1000);
-
-       fstr_sprintf(String,"%04d-%02d-%02d %02d:%02d:%02d.%03d", \
-                       tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, \
-                       tm->tm_hour, tm->tm_min, tm->tm_sec, (int)seconds);
-
-}
-
-static int smb_traffic_analyzer_connMode( vfs_handle_struct *handle)
+static enum sock_type smb_traffic_analyzer_connMode(vfs_handle_struct *handle)
 {
        connection_struct *conn = handle->conn;
         const char *Mode;
@@ -119,53 +40,40 @@ static int smb_traffic_analyzer_connMode( vfs_handle_struct *handle)
        } else {
                return INTERNET_SOCKET;
        }
-
 }
 
-/* Send data over a internet socket */
-static void smb_traffic_analyzer_send_data_inet_socket( char *String,
-                       vfs_handle_struct *handle, const char *file_name,
-                       bool Write)
+/* Connect to an internet socket */
+
+static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle,
+                                       const char *name, uint16_t port)
 {
        /* Create a streaming Socket */
-       const char *Hostname;
        int sockfd = -1;
-        uint16_t port;
        struct addrinfo hints;
        struct addrinfo *ailist = NULL;
        struct addrinfo *res = NULL;
-       char Sender[200];
-       char TimeStamp[200];
-       connection_struct *conn = handle->conn;
        int ret;
 
-       /* get port number, target system from the config parameters */
-       Hostname=lp_parm_const_string(SNUM(conn), "smb_traffic_analyzer", 
-                               "host", "localhost");
-
        ZERO_STRUCT(hints);
        /* By default make sure it supports TCP. */
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_ADDRCONFIG;
 
-       ret = getaddrinfo(Hostname,
+       ret = getaddrinfo(name,
                        NULL,
                        &hints,
                        &ailist);
 
         if (ret) {
-               DEBUG(3,("smb_traffic_analyzer_send_data_inet_socket: "
+               DEBUG(3,("smb_traffic_analyzer_connect_inet_socket: "
                        "getaddrinfo failed for name %s [%s]\n",
-                        Hostname,
+                        name,
                         gai_strerror(ret) ));
-               return;
+               return -1;
         }
 
-       port = atoi( lp_parm_const_string(SNUM(conn), 
-                               "smb_traffic_analyzer", "port", "9430"));
-
        DEBUG(3,("smb_traffic_analyzer: Internet socket mode. Hostname: %s,"
-               "Port: %i\n", Hostname, port));
+               "Port: %i\n", name, port));
 
        for (res = ailist; res; res = res->ai_next) {
                struct sockaddr_storage ss;
@@ -188,116 +96,201 @@ static void smb_traffic_analyzer_send_data_inet_socket( char *String,
        }
 
         if (sockfd == -1) {
-               DEBUG(1, ("smb_traffic_analyzer: unable to create socket, error is %s", 
+               DEBUG(1, ("smb_traffic_analyzer: unable to create "
+                       "socket, error is %s",
                        strerror(errno)));
-               return;
+               return -1;
        }
 
-       strlcpy(Sender, String, sizeof(Sender));
-       strlcat(Sender, ",\"", sizeof(Sender));
-       strlcat(Sender, get_current_username(), sizeof(Sender));
-       strlcat(Sender, "\",\"", sizeof(Sender));
-       strlcat(Sender, current_user_info.domain, sizeof(Sender));
-       strlcat(Sender, "\",\"", sizeof(Sender));
-        if (Write)
-               strlcat(Sender, "W", sizeof(Sender));
-       else
-               strlcat(Sender, "R", sizeof(Sender));
-       strlcat(Sender, "\",\"", sizeof(Sender));
-       strlcat(Sender, handle->conn->connectpath, sizeof(Sender));
-       strlcat(Sender, "\",\"", sizeof(Sender) - 1);
-       strlcat(Sender, file_name, sizeof(Sender) - 1);
-       strlcat(Sender, "\",\"", sizeof(Sender) - 1);
-        get_timestamp(TimeStamp);
-       strlcat(Sender, TimeStamp, sizeof(Sender) - 1);
-       strlcat(Sender, "\");", sizeof(Sender) - 1);
-        DEBUG(10, ("smb_traffic_analyzer: sending %s\n", Sender));
-        if ( send(sockfd, Sender, strlen(Sender), 0) == -1 ) {
-                DEBUG(1, ("smb_traffic_analyzer: error sending data to socket!\n"));
-               close(sockfd);
-                return ;
-        }
-
-        /* one operation, close the socket */
-        close(sockfd);
+       return sockfd;
 }
 
+/* Connect to a unix domain socket */
 
-
-/* Send data over a unix domain socket */
-static void smb_traffic_analyzer_send_data_unix_socket( char *String ,
-                       vfs_handle_struct *handle, const char *file_name, 
-                       bool Write)
+static int smb_traffic_analyzer_connect_unix_socket(vfs_handle_struct *handle,
+                                               const char *name)
 {
        /* Create the socket to stad */
        int len, sock;
        struct sockaddr_un remote;
-        char Sender[200];
-        char TimeStamp[200];
 
-       DEBUG(7, ("smb_traffic_analyzer: Unix domain socket mode. Using "
-                       "/var/tmp/stadsocket\n"));
+       DEBUG(7, ("smb_traffic_analyzer_connect_unix_socket: "
+                       "Unix domain socket mode. Using %s\n",
+                       name ));
 
        if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
-               DEBUG(1, ("smb_traffic_analyzer: Couldn create socket,"
+               DEBUG(1, ("smb_traffic_analyzer_connect_unix_socket: "
+                       "Couldn't create socket, "
                        "make sure stad is running!\n"));
        }
        remote.sun_family = AF_UNIX;
-       strlcpy(remote.sun_path, "/var/tmp/stadsocket", 
+       strlcpy(remote.sun_path, name,
                    sizeof(remote.sun_path));
        len=strlen(remote.sun_path) + sizeof(remote.sun_family);
        if (connect(sock, (struct sockaddr *)&remote, len) == -1 ) {
-               DEBUG(1, ("smb_traffic_analyzer: Could not connect to"
+               DEBUG(1, ("smb_traffic_analyzer_connect_unix_socket: "
+                       "Could not connect to "
                        "socket, make sure\nstad is running!\n"));
                close(sock);
+               return -1;
+       }
+       return sock;
+}
+
+/* Private data allowing shared connection sockets. */
+
+struct refcounted_sock {
+       struct refcounted_sock *next, *prev;
+       char *name;
+       uint16_t port;
+       int sock;
+       unsigned int ref_count;
+};
+
+/* Send data over a socket */
+
+static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
+                                       ssize_t result,
+                                       const char *file_name,
+                                       bool Write)
+{
+       struct refcounted_sock *rf_sock = NULL;
+       struct timeval tv;
+       struct tm *tm = NULL;
+       int seconds;
+       char *str = NULL;
+       size_t len;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, rf_sock, struct refcounted_sock, return);
+
+       if (rf_sock == NULL || rf_sock->sock == -1) {
+               DEBUG(1, ("smb_traffic_analyzer_send_data: socket is "
+                       "closed\n"));
                return;
        }
-       strlcpy(Sender, String, sizeof(Sender));
-       strlcat(Sender, ",\"", sizeof(Sender));
-       strlcat(Sender, get_current_username(), sizeof(Sender));
-       strlcat(Sender,"\",\"",sizeof(Sender));
-       strlcat(Sender, current_user_info.domain, sizeof(Sender));
-       strlcat(Sender, "\",\"", sizeof(Sender));
-       if (Write)
-               strlcat(Sender, "W", sizeof(Sender));
-       else
-               strlcat(Sender, "R", sizeof(Sender));
-       strlcat(Sender, "\",\"", sizeof(Sender));
-       strlcat(Sender, handle->conn->connectpath, sizeof(Sender));
-       strlcat(Sender, "\",\"", sizeof(Sender));
-       strlcat(Sender, file_name, sizeof(Sender));
-       strlcat(Sender, "\",\"", sizeof(Sender));
-       get_timestamp(TimeStamp);
-       strlcat(Sender, TimeStamp, sizeof(Sender));
-       strlcat(Sender, "\");", sizeof(Sender));
-
-       DEBUG(10, ("smb_traffic_analyzer: sending %s\n", Sender));
-       if ( send(sock, Sender, strlen(Sender), 0) == -1 ) {
-               DEBUG(1, ("smb_traffic_analyzer: error sending data to"
-                       "socket!\n"));
-               close(sock);
+
+       GetTimeOfDay(&tv);
+       tm=localtime(&tv.tv_sec);
+       if (!tm) {
+               return;
+       }
+       seconds=(float) (tv.tv_usec / 1000);
+
+       str = talloc_asprintf(talloc_tos(),
+                       "V1,%u,\"%s\",\"%s\",\"%c\",\"%s\",\"%s\","
+                       "\"%04d-%02d-%02d %02d:%02d:%02d.%03d\"\n",
+                       (unsigned int)result,
+                       handle->conn->server_info->sanitized_username,
+                       pdb_get_domain(handle->conn->server_info->sam_account),
+                       Write ? 'W' : 'R',
+                       handle->conn->connectpath,
+                       file_name,
+                       tm->tm_year+1900,
+                       tm->tm_mon+1,
+                       tm->tm_mday,
+                       tm->tm_hour,
+                       tm->tm_min,
+                       tm->tm_sec,
+                       (int)seconds);
+
+       if (!str) {
                return;
        }
 
-       /* one operation, close the socket */
-       close(sock);
-       return;
+       len = strlen(str);
+
+       DEBUG(10, ("smb_traffic_analyzer_send_data_socket: sending %s\n",
+                       str));
+       if (write_data(rf_sock->sock, str, len) != len) {
+               DEBUG(1, ("smb_traffic_analyzer_send_data_socket: "
+                       "error sending data to socket!\n"));
+               return ;
+       }
 }
 
-static void smb_traffic_analyzer_send_data( char *Buffer , vfs_handle_struct \
-                       *handle, char *file_name, bool Write, files_struct *fsp)
-{
+static struct refcounted_sock *sock_list;
 
-        if (smb_traffic_analyzer_connMode(handle) == UNIX_DOMAIN_SOCKET) {
-                smb_traffic_analyzer_send_data_unix_socket(Buffer, handle, \
-                                                       fsp->fsp_name, Write);
-        } else {
-                smb_traffic_analyzer_send_data_inet_socket(Buffer, handle, \
-                                                       fsp->fsp_name, Write);
-        }
+static void smb_traffic_analyzer_free_data(void **pptr)
+{
+       struct refcounted_sock *rf_sock = *(struct refcounted_sock **)pptr;
+       if (rf_sock == NULL) {
+               return;
+       }
+       rf_sock->ref_count--;
+       if (rf_sock->ref_count != 0) {
+               return;
+       }
+       if (rf_sock->sock != -1) {
+               close(rf_sock->sock);
+       }
+       DLIST_REMOVE(sock_list, rf_sock);
+       TALLOC_FREE(rf_sock);
 }
 
+static int smb_traffic_analyzer_connect(struct vfs_handle_struct *handle,
+                         const char *service,
+                         const char *user)
+{
+       connection_struct *conn = handle->conn;
+       enum sock_type st = smb_traffic_analyzer_connMode(handle);
+       struct refcounted_sock *rf_sock = NULL;
+       const char *name = (st == UNIX_DOMAIN_SOCKET) ? LOCAL_PATHNAME :
+                               lp_parm_const_string(SNUM(conn),
+                                       "smb_traffic_analyzer",
+                               "host", "localhost");
+       uint16_t port = (st == UNIX_DOMAIN_SOCKET) ? 0 :
+                               atoi( lp_parm_const_string(SNUM(conn),
+                               "smb_traffic_analyzer", "port", "9430"));
+
+       /* Are we already connected ? */
+       for (rf_sock = sock_list; rf_sock; rf_sock = rf_sock->next) {
+               if (port == rf_sock->port &&
+                               (strcmp(name, rf_sock->name) == 0)) {
+                       break;
+               }
+       }
 
+       /* If we're connected already, just increase the
+        * reference count. */
+       if (rf_sock) {
+               rf_sock->ref_count++;
+       } else {
+               /* New connection. */
+               rf_sock = TALLOC_ZERO_P(NULL, struct refcounted_sock);
+               if (rf_sock == NULL) {
+                       errno = ENOMEM;
+                       return -1;
+               }
+               rf_sock->name = talloc_strdup(rf_sock, name);
+               if (rf_sock->name == NULL) {
+                       TALLOC_FREE(rf_sock);
+                       errno = ENOMEM;
+                       return -1;
+               }
+               rf_sock->port = port;
+               rf_sock->ref_count = 1;
+
+               if (st == UNIX_DOMAIN_SOCKET) {
+                       rf_sock->sock = smb_traffic_analyzer_connect_unix_socket(handle,
+                                                       name);
+               } else {
+
+                       rf_sock->sock = smb_traffic_analyzer_connect_inet_socket(handle,
+                                                       name,
+                                                       port);
+               }
+               if (rf_sock->sock == -1) {
+                       TALLOC_FREE(rf_sock);
+                       return -1;
+               }
+               DLIST_ADD(sock_list, rf_sock);
+       }
+
+       /* Store the private data. */
+       SMB_VFS_HANDLE_SET_DATA(handle, rf_sock, smb_traffic_analyzer_free_data,
+                               struct refcounted_sock, return -1);
+       return SMB_VFS_NEXT_CONNECT(handle, service, user);
+}
 
 /* VFS Functions: write, read, pread, pwrite for now */
 
@@ -305,14 +298,14 @@ static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \
                                files_struct *fsp, void *data, size_t n)
 {
        ssize_t result;
-        fstring Buffer;
 
        result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
-       DEBUG(10, ("smb_traffic_analyzer: READ: %s\n", fsp->fsp_name ));
+       DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp->fsp_name ));
 
-       fstr_sprintf(Buffer, "%u", (uint) result);
-
-       smb_traffic_analyzer_send_data(Buffer, handle, fsp->fsp_name, false, fsp);
+       smb_traffic_analyzer_send_data(handle,
+                       result,
+                       fsp->fsp_name,
+                       false);
        return result;
 }
 
@@ -321,14 +314,15 @@ static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, \
                files_struct *fsp, void *data, size_t n, SMB_OFF_T offset)
 {
        ssize_t result;
-        fstring Buffer;
 
        result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
 
-       DEBUG(10, ("smb_traffic_analyzerREAD: %s\n", fsp->fsp_name ));
+       DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", fsp->fsp_name ));
 
-       fstr_sprintf(Buffer,"%u", (uint) result);
-       smb_traffic_analyzer_send_data(Buffer, handle, fsp->fsp_name, false, fsp);
+       smb_traffic_analyzer_send_data(handle,
+                       result,
+                       fsp->fsp_name,
+                       false);
 
        return result;
 }
@@ -337,15 +331,15 @@ static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, \
                        files_struct *fsp, const void *data, size_t n)
 {
        ssize_t result;
-        fstring Buffer;
 
        result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
 
-       DEBUG(10, ("smb_traffic_analyzer: WRITE: %s\n", fsp->fsp_name ));
+       DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", fsp->fsp_name ));
 
-       fstr_sprintf(Buffer, "%u", (uint) result);
-       smb_traffic_analyzer_send_data(Buffer, handle, fsp->fsp_name, \
-                                                               true, fsp );
+       smb_traffic_analyzer_send_data(handle,
+                       result,
+                       fsp->fsp_name,
+                       true);
        return result;
 }
 
@@ -353,13 +347,58 @@ static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, \
             files_struct *fsp, const void *data, size_t n, SMB_OFF_T offset)
 {
        ssize_t result;
-        fstring Buffer;
 
        result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
 
-       DEBUG(10, ("smb_traffic_analyzer: PWRITE: %s\n", fsp->fsp_name ));
+       DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp->fsp_name ));
 
-       fstr_sprintf(Buffer, "%u", (uint) result);
-       smb_traffic_analyzer_send_data(Buffer, handle, fsp->fsp_name, true, fsp);
+       smb_traffic_analyzer_send_data(handle,
+                       result,
+                       fsp->fsp_name,
+                       true);
        return result;
 }
+
+/* VFS operations we use */
+
+static vfs_op_tuple smb_traffic_analyzer_tuples[] = {
+
+        {SMB_VFS_OP(smb_traffic_analyzer_connect), SMB_VFS_OP_CONNECT,
+         SMB_VFS_LAYER_LOGGER},
+       {SMB_VFS_OP(smb_traffic_analyzer_read), SMB_VFS_OP_READ,
+        SMB_VFS_LAYER_LOGGER},
+       {SMB_VFS_OP(smb_traffic_analyzer_pread), SMB_VFS_OP_PREAD,
+        SMB_VFS_LAYER_LOGGER},
+       {SMB_VFS_OP(smb_traffic_analyzer_write), SMB_VFS_OP_WRITE,
+        SMB_VFS_LAYER_LOGGER},
+       {SMB_VFS_OP(smb_traffic_analyzer_pwrite), SMB_VFS_OP_PWRITE,
+        SMB_VFS_LAYER_LOGGER},
+               {SMB_VFS_OP(NULL),SMB_VFS_OP_NOOP,SMB_VFS_LAYER_NOOP}
+};
+
+/* Module initialization */
+
+NTSTATUS vfs_smb_traffic_analyzer_init(void)
+{
+       NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, \
+               "smb_traffic_analyzer", smb_traffic_analyzer_tuples);
+
+       if (!NT_STATUS_IS_OK(ret)) {
+               return ret;
+       }
+
+       vfs_smb_traffic_analyzer_debug_level =
+               debug_add_class("smb_traffic_analyzer");
+
+       if (vfs_smb_traffic_analyzer_debug_level == -1) {
+               vfs_smb_traffic_analyzer_debug_level = DBGC_VFS;
+               DEBUG(1, ("smb_traffic_analyzer_init: Couldn't register custom"
+                        "debugging class!\n"));
+       } else {
+               DEBUG(3, ("smb_traffic_analyzer_init: Debug class number of"
+                       "'smb_traffic_analyzer': %d\n", \
+                       vfs_smb_traffic_analyzer_debug_level));
+       }
+
+       return ret;
+}
index f9568f0a540bd00650ca0b30ffead7589791ac23..b9bed7a138c7d1eebd8a5313dd59b06b009fe0ea 100644 (file)
@@ -2,21 +2,26 @@
  * Support code for the Common UNIX Printing System ("CUPS")
  *
  * Copyright 1999-2003 by Michael R Sweet.
+ * Copyright 2008 Jeremy Allison.
  *
  * 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/>.
  */
 
+/*
+ * JRA. Converted to utf8 pull/push.
+ */
+
 #include "includes.h"
 #include "printing.h"
 
@@ -51,24 +56,23 @@ cups_passwd_cb(const char *prompt)  /* I - Prompt */
        return (NULL);
 }
 
-static http_t *cups_connect(void)
+static http_t *cups_connect(TALLOC_CTX *frame)
 {
-       http_t *http;
-       char *server, *p;
+       http_t *http = NULL;
+       char *server = NULL, *p = NULL;
        int port;
        int timeout = lp_cups_connection_timeout();
-
-       gotalarm = 0;
-
-       if (timeout) {
-                CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
-                alarm(timeout);
-        }
+       size_t size;
 
        if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) {
-               server = smb_xstrdup(lp_cups_server());
+               if (!push_utf8_talloc(frame, &server, lp_cups_server(), &size)) {
+                       return NULL;
+               }
        } else {
-               server = smb_xstrdup(cupsServer());
+               server = talloc_strdup(frame,cupsServer());
+       }
+       if (!server) {
+               return NULL;
        }
 
        p = strchr(server, ':');
@@ -82,6 +86,13 @@ static http_t *cups_connect(void)
        DEBUG(10, ("connecting to cups server %s:%d\n",
                   server, port));
 
+       gotalarm = 0;
+
+       if (timeout) {
+                CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+                alarm(timeout);
+        }
+
        http = httpConnect(server, port);
 
        CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
@@ -92,12 +103,12 @@ static http_t *cups_connect(void)
                         server, port, strerror(errno)));
        }
 
-       SAFE_FREE(server);
        return http;
 }
 
 bool cups_cache_reload(void)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
@@ -109,8 +120,9 @@ bool cups_cache_reload(void)
                        {
                          "printer-name",
                          "printer-info"
-                       };       
+                       };
        bool ret = False;
+       size_t size;
 
        DEBUG(5, ("reloading cups printcap cache\n"));
 
@@ -124,7 +136,7 @@ bool cups_cache_reload(void)
        * Try to connect to the server...
        */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -145,7 +157,7 @@ bool cups_cache_reload(void)
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                     "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                      "attributes-natural-language", NULL, language->language);
@@ -185,12 +197,24 @@ bool cups_cache_reload(void)
 
                while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
                        if (strcmp(attr->name, "printer-name") == 0 &&
-                           attr->value_tag == IPP_TAG_NAME)
-                               name = attr->values[0].string.text;
+                           attr->value_tag == IPP_TAG_NAME) {
+                               if (!pull_utf8_talloc(frame,
+                                               &name,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
+                       }
 
                        if (strcmp(attr->name, "printer-info") == 0 &&
-                           attr->value_tag == IPP_TAG_TEXT)
-                               info = attr->values[0].string.text;
+                           attr->value_tag == IPP_TAG_TEXT) {
+                               if (!pull_utf8_talloc(frame,
+                                               &info,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
+                       }
 
                        attr = attr->next;
                }
@@ -225,7 +249,7 @@ bool cups_cache_reload(void)
        request->request.op.request_id   = 1;
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                     "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                      "attributes-natural-language", NULL, language->language);
@@ -265,12 +289,24 @@ bool cups_cache_reload(void)
 
                while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
                        if (strcmp(attr->name, "printer-name") == 0 &&
-                           attr->value_tag == IPP_TAG_NAME)
-                               name = attr->values[0].string.text;
+                           attr->value_tag == IPP_TAG_NAME) {
+                               if (!pull_utf8_talloc(frame,
+                                               &name,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
+                       }
 
                        if (strcmp(attr->name, "printer-info") == 0 &&
-                           attr->value_tag == IPP_TAG_TEXT)
-                               info = attr->values[0].string.text;
+                           attr->value_tag == IPP_TAG_TEXT) {
+                               if (!pull_utf8_talloc(frame,
+                                               &info,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
+                       }
 
                        attr = attr->next;
                }
@@ -299,6 +335,7 @@ bool cups_cache_reload(void)
        if (http)
                httpClose(http);
 
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -309,13 +346,15 @@ bool cups_cache_reload(void)
 
 static int cups_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        int             ret = 1;                /* Return value */
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
        cups_lang_t     *language = NULL;       /* Default language */
+       char *user = NULL;
        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
+       size_t size;
 
        DEBUG(5,("cups_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
 
@@ -329,7 +368,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru
        * Try to connect to the server...
        */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -351,7 +390,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                    "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
@@ -360,8 +399,12 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
 
+       if (!push_utf8_talloc(frame, &user, pjob->user, &size)) {
+               goto out;
+       }
+
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                    NULL, pjob->user);
+                    NULL, user);
 
        /*
        * Do the request and get back a response...
@@ -389,6 +432,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru
        if (http)
                httpClose(http);
 
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -399,13 +443,15 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru
 
 static int cups_job_pause(int snum, struct printjob *pjob)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        int             ret = 1;                /* Return value */
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
        cups_lang_t     *language = NULL;       /* Default language */
+       char *user = NULL;
        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
+       size_t size;
 
        DEBUG(5,("cups_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
 
@@ -419,7 +465,7 @@ static int cups_job_pause(int snum, struct printjob *pjob)
        * Try to connect to the server...
        */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -441,7 +487,7 @@ static int cups_job_pause(int snum, struct printjob *pjob)
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                    "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
@@ -450,8 +496,11 @@ static int cups_job_pause(int snum, struct printjob *pjob)
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
 
+       if (!push_utf8_talloc(frame, &user, pjob->user, &size)) {
+               goto out;
+       }
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                    NULL, pjob->user);
+                    NULL, user);
 
        /*
        * Do the request and get back a response...
@@ -479,6 +528,7 @@ static int cups_job_pause(int snum, struct printjob *pjob)
        if (http)
                httpClose(http);
 
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -489,13 +539,15 @@ static int cups_job_pause(int snum, struct printjob *pjob)
 
 static int cups_job_resume(int snum, struct printjob *pjob)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        int             ret = 1;                /* Return value */
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
        cups_lang_t     *language = NULL;       /* Default language */
+       char *user = NULL;
        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
+       size_t size;
 
        DEBUG(5,("cups_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
 
@@ -509,7 +561,7 @@ static int cups_job_resume(int snum, struct printjob *pjob)
        * Try to connect to the server...
        */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -531,7 +583,7 @@ static int cups_job_resume(int snum, struct printjob *pjob)
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                    "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
@@ -540,8 +592,11 @@ static int cups_job_resume(int snum, struct printjob *pjob)
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
 
+       if (!push_utf8_talloc(frame, &user, pjob->user, &size)) {
+               goto out;
+       }
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                    NULL, pjob->user);
+                    NULL, user);
 
        /*
        * Do the request and get back a response...
@@ -569,6 +624,7 @@ static int cups_job_resume(int snum, struct printjob *pjob)
        if (http)
                httpClose(http);
 
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -579,6 +635,7 @@ static int cups_job_resume(int snum, struct printjob *pjob)
 
 static int cups_job_submit(int snum, struct printjob *pjob)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        int             ret = 1;                /* Return value */
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
@@ -589,6 +646,12 @@ static int cups_job_submit(int snum, struct printjob *pjob)
        char *new_jobname = NULL;
        int             num_options = 0;
        cups_option_t   *options = NULL;
+       char *printername = NULL;
+       char *user = NULL;
+       char *jobname = NULL;
+       char *cupsoptions = NULL;
+       char *filename = NULL;
+       size_t size;
        char addr[INET6_ADDRSTRLEN];
 
        DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
@@ -603,7 +666,7 @@ static int cups_job_submit(int snum, struct printjob *pjob)
        * Try to connect to the server...
        */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -626,19 +689,25 @@ static int cups_job_submit(int snum, struct printjob *pjob)
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                    "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
 
+       if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
+               goto out;
+       }
        slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
-                PRINTERNAME(snum));
+                printername);
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
                     "printer-uri", NULL, uri);
 
+       if (!push_utf8_talloc(frame, &user, pjob->user, &size)) {
+               goto out;
+       }
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                    NULL, pjob->user);
+                    NULL, user);
 
        clientname = client_name(get_client_fd());
        if (strcmp(clientname, "UNKNOWN") == 0) {
@@ -649,31 +718,43 @@ static int cups_job_submit(int snum, struct printjob *pjob)
                     "job-originating-host-name", NULL,
                      clientname);
 
-       if (asprintf(&new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX,
-                       (unsigned int)pjob->smbjob, pjob->jobname) < 0) {
+       if (!push_utf8_talloc(frame, &jobname, pjob->jobname, &size)) {
+               goto out;
+       }
+       new_jobname = talloc_asprintf(frame,
+                       "%s%.8u %s", PRINT_SPOOL_PREFIX,
+                       (unsigned int)pjob->smbjob,
+                       jobname);
+       if (new_jobname == NULL) {
                goto out;
        }
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
                     new_jobname);
 
-       /* 
-        * add any options defined in smb.conf 
+       /*
+        * add any options defined in smb.conf
         */
 
+       if (!push_utf8_talloc(frame, &cupsoptions, lp_cups_options(snum), &size)) {
+               goto out;
+       }
        num_options = 0;
        options     = NULL;
-       num_options = cupsParseOptions(lp_cups_options(snum), num_options, &options);
+       num_options = cupsParseOptions(cupsoptions, num_options, &options);
 
        if ( num_options )
-               cupsEncodeOptions(request, num_options, options); 
+               cupsEncodeOptions(request, num_options, options);
 
        /*
        * Do the request and get back a response...
        */
 
-       slprintf(uri, sizeof(uri) - 1, "/printers/%s", PRINTERNAME(snum));
+       slprintf(uri, sizeof(uri) - 1, "/printers/%s", printername);
 
+       if (!push_utf8_talloc(frame, &filename, pjob->filename, &size)) {
+               goto out;
+       }
        if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
                if (response->request.status.status_code >= IPP_OK_CONFLICT) {
                        DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
@@ -700,7 +781,7 @@ static int cups_job_submit(int snum, struct printjob *pjob)
        if (http)
                httpClose(http);
 
-       SAFE_FREE(new_jobname);
+       TALLOC_FREE(frame);
 
        return ret;
 }
@@ -712,10 +793,11 @@ static int cups_job_submit(int snum, struct printjob *pjob)
 static int cups_queue_get(const char *sharename,
                enum printing_types printing_type,
                char *lpq_command,
-               print_queue_struct **q, 
+               print_queue_struct **q,
                print_status_struct *status)
 {
-       fstring         printername;
+       TALLOC_CTX *frame = talloc_stackframe();
+       char *printername = NULL;
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
@@ -726,13 +808,14 @@ static int cups_queue_get(const char *sharename,
                        qalloc = 0;             /* Number of queue entries allocated */
        print_queue_struct *queue = NULL,       /* Queue entries */
                        *temp;          /* Temporary pointer for queue */
-       const char      *user_name,     /* job-originating-user-name attribute */
-                       *job_name;      /* job-name attribute */
+       char            *user_name = NULL,      /* job-originating-user-name attribute */
+                       *job_name = NULL;       /* job-name attribute */
        int             job_id;         /* job-id attribute */
        int             job_k_octets;   /* job-k-octets attribute */
        time_t          job_time;       /* time-at-creation attribute */
        ipp_jstate_t    job_status;     /* job-status attribute */
        int             job_priority;   /* job-priority attribute */
+       size_t size;
        static const char *jattrs[] =   /* Requested job attributes */
                        {
                          "job-id",
@@ -751,15 +834,16 @@ static int cups_queue_get(const char *sharename,
 
        *q = NULL;
 
-       /* HACK ALERT!!!  The problem with support the 'printer name' 
-          option is that we key the tdb off the sharename.  So we will 
-          overload the lpq_command string to pass in the printername 
-          (which is basically what we do for non-cups printers ... using 
+       /* HACK ALERT!!!  The problem with support the 'printer name'
+          option is that we key the tdb off the sharename.  So we will
+          overload the lpq_command string to pass in the printername
+          (which is basically what we do for non-cups printers ... using
           the lpq_command to get the queue listing). */
 
-       fstrcpy( printername, lpq_command );
-
-       DEBUG(5,("cups_queue_get(%s, %p, %p)\n", printername, q, status));
+       if (!push_utf8_talloc(frame, &printername, lpq_command, &size)) {
+               goto out;
+       }
+       DEBUG(5,("cups_queue_get(%s, %p, %p)\n", lpq_command, q, status));
 
        /*
         * Make sure we don't ask for passwords...
@@ -771,7 +855,7 @@ static int cups_queue_get(const char *sharename,
        * Try to connect to the server...
        */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -799,7 +883,7 @@ static int cups_queue_get(const char *sharename,
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                     "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                      "attributes-natural-language", NULL, language->language);
@@ -904,12 +988,24 @@ static int cups_queue_get(const char *sharename,
                                job_time = attr->values[0].integer;
 
                        if (strcmp(attr->name, "job-name") == 0 &&
-                           attr->value_tag == IPP_TAG_NAME)
-                               job_name = attr->values[0].string.text;
+                           attr->value_tag == IPP_TAG_NAME) {
+                               if (!pull_utf8_talloc(frame,
+                                               &job_name,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
+                       }
 
                        if (strcmp(attr->name, "job-originating-user-name") == 0 &&
-                           attr->value_tag == IPP_TAG_NAME)
-                               user_name = attr->values[0].string.text;
+                           attr->value_tag == IPP_TAG_NAME) {
+                               if (!pull_utf8_talloc(frame,
+                                               &user_name,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
+                       }
 
                        attr = attr->next;
                }
@@ -933,8 +1029,8 @@ static int cups_queue_get(const char *sharename,
                                 LPQ_PRINTING;
                temp->priority = job_priority;
                temp->time     = job_time;
-               strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
-               strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);
+               strlcpy(temp->fs_user, user_name, sizeof(temp->fs_user));
+               strlcpy(temp->fs_file, job_name, sizeof(temp->fs_file));
 
                qcount ++;
 
@@ -961,7 +1057,7 @@ static int cups_queue_get(const char *sharename,
        request->request.op.request_id   = 1;
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                     "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                      "attributes-natural-language", NULL, language->language);
@@ -1004,8 +1100,15 @@ static int cups_queue_get(const char *sharename,
        }
 
         if ((attr = ippFindAttribute(response, "printer-state-message",
-                                    IPP_TAG_TEXT)) != NULL)
-               fstrcpy(status->message, attr->values[0].string.text);
+                                    IPP_TAG_TEXT)) != NULL) {
+               char *msg = NULL;
+               if (!pull_utf8_talloc(frame, &msg,
+                               attr->values[0].string.text,
+                               &size)) {
+                       goto out;
+               }
+               fstrcpy(status->message, msg);
+       }
 
        /*
         * Return the job queue...
@@ -1023,6 +1126,7 @@ static int cups_queue_get(const char *sharename,
        if (http)
                httpClose(http);
 
+       TALLOC_FREE(frame);
        return qcount;
 }
 
@@ -1033,13 +1137,16 @@ static int cups_queue_get(const char *sharename,
 
 static int cups_queue_pause(int snum)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        int             ret = 1;                /* Return value */
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
        cups_lang_t     *language = NULL;       /* Default language */
+       char *printername = NULL;
+       char *username = NULL;
        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
+       size_t size;
 
        DEBUG(5,("cups_queue_pause(%d)\n", snum));
 
@@ -1053,7 +1160,7 @@ static int cups_queue_pause(int snum)
         * Try to connect to the server...
         */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -1075,18 +1182,24 @@ static int cups_queue_pause(int snum)
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                    "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
 
+       if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
+               goto out;
+       }
        slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
-                PRINTERNAME(snum));
+                printername);
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
 
+       if (!push_utf8_talloc(frame, &username, current_user_info.unix_name, &size)) {
+               goto out;
+       }
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                    NULL, current_user_info.unix_name);
+                    NULL, username);
 
        /*
        * Do the request and get back a response...
@@ -1114,6 +1227,7 @@ static int cups_queue_pause(int snum)
        if (http)
                httpClose(http);
 
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -1124,13 +1238,16 @@ static int cups_queue_pause(int snum)
 
 static int cups_queue_resume(int snum)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        int             ret = 1;                /* Return value */
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
        cups_lang_t     *language = NULL;       /* Default language */
+       char *printername = NULL;
+       char *username = NULL;
        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
+       size_t size;
 
        DEBUG(5,("cups_queue_resume(%d)\n", snum));
 
@@ -1144,7 +1261,7 @@ static int cups_queue_resume(int snum)
        * Try to connect to the server...
        */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -1166,18 +1283,24 @@ static int cups_queue_resume(int snum)
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                    "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                     "attributes-natural-language", NULL, language->language);
 
+       if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
+               goto out;
+       }
        slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
-                PRINTERNAME(snum));
+                printername);
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
 
+       if (!push_utf8_talloc(frame, &username, current_user_info.unix_name, &size)) {
+               goto out;
+       }
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
-                    NULL, current_user_info.unix_name);
+                    NULL, username);
 
        /*
        * Do the request and get back a response...
@@ -1205,6 +1328,7 @@ static int cups_queue_resume(int snum)
        if (http)
                httpClose(http);
 
+       TALLOC_FREE(frame);
        return ret;
 }
 
@@ -1226,15 +1350,16 @@ struct printif  cups_printif =
 
 bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        http_t          *http = NULL;           /* HTTP connection to server */
        ipp_t           *request = NULL,        /* IPP Request */
                        *response = NULL;       /* IPP Response */
        ipp_attribute_t *attr;          /* Current attribute */
        cups_lang_t     *language = NULL;       /* Default language */
-       char            *name,          /* printer-name attribute */
-                       *info,          /* printer-info attribute */
-                       *location;      /* printer-location attribute */
        char            uri[HTTP_MAX_URI];
+       char *server = NULL;
+       char *sharename = NULL;
+       char *name = NULL;
        static const char *requested[] =/* Requested attributes */
                        {
                          "printer-name",
@@ -1242,6 +1367,7 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
                          "printer-location"
                        };
        bool ret = False;
+       size_t size;
 
        DEBUG(5, ("pulling %s location\n", printer->sharename));
 
@@ -1255,7 +1381,7 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
         * Try to connect to the server...
         */
 
-       if ((http = cups_connect()) == NULL) {
+       if ((http = cups_connect(frame)) == NULL) {
                goto out;
        }
 
@@ -1267,13 +1393,26 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
        language = cupsLangDefault();
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                     "attributes-charset", NULL, cupsLangEncoding(language));
+                     "attributes-charset", NULL, "utf-8");
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
                      "attributes-natural-language", NULL, language->language);
 
+       if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) {
+               if (!push_utf8_talloc(frame, &server, lp_cups_server(), &size)) {
+                       goto out;
+               }
+       } else {
+               server = talloc_strdup(frame,cupsServer());
+       }
+       if (server) {
+               goto out;
+       }
+       if (!push_utf8_talloc(frame, &sharename, printer->sharename, &size)) {
+               goto out;
+       }
        slprintf(uri, sizeof(uri) - 1, "ipp://%s/printers/%s",
-                lp_cups_server(), printer->sharename);
+                server, sharename);
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
                      "printer-uri", NULL, uri);
@@ -1308,43 +1447,64 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
                 * Pull the needed attributes from this printer...
                 */
 
-               name       = NULL;
-               info       = NULL;
-               location   = NULL;
-
                while ( attr && (attr->group_tag == IPP_TAG_PRINTER) ) {
+                       if (strcmp(attr->name, "printer-name") == 0 &&
+                           attr->value_tag == IPP_TAG_NAME) {
+                               if (!pull_utf8_talloc(frame,
+                                               &name,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
+                       }
+
                        /* Grab the comment if we don't have one */
                        if ( (strcmp(attr->name, "printer-info") == 0)
                             && (attr->value_tag == IPP_TAG_TEXT)
-                            && !strlen(printer->comment) ) 
+                            && !strlen(printer->comment) )
                        {
+                               char *comment = NULL;
+                               if (!pull_utf8_talloc(frame,
+                                               &comment,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
                                DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n",
-                                        attr->values[0].string.text));                         
+                                        comment));
                                strlcpy(printer->comment,
-                                               attr->values[0].string.text,
-                                               sizeof(printer->comment));
+                                       comment,
+                                       sizeof(printer->comment));
                        }
 
-                       /* Grab the location if we don't have one */ 
+                       /* Grab the location if we don't have one */
                        if ( (strcmp(attr->name, "printer-location") == 0)
-                            && (attr->value_tag == IPP_TAG_TEXT) 
+                            && (attr->value_tag == IPP_TAG_TEXT)
                             && !strlen(printer->location) )
                        {
+                               char *location = NULL;
+                               if (!pull_utf8_talloc(frame,
+                                               &location,
+                                               attr->values[0].string.text,
+                                               &size)) {
+                                       goto out;
+                               }
                                DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n",
-                                        attr->values[0].string.text));                         
-                               fstrcpy(printer->location,attr->values[0].string.text);
+                                        location));
+                               strlcpy(printer->location,
+                                       location,
+                                       sizeof(printer->location));
                        }
 
                        attr = attr->next;
                }
 
                /*
-                * See if we have everything needed...
+                * We have everything needed...
                 */
 
-               if (name == NULL)
+               if (name != NULL)
                        break;
-
        }
 
        ret = True;
@@ -1359,6 +1519,7 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer)
        if (http)
                httpClose(http);
 
+       TALLOC_FREE(frame);
        return ret;
 }
 
index b9433bb96580385a7312efe1e2afec17dc2941de..7f34d2b8e2b3e9d1971c2bd9cb9a9e5057b1c32c 100644 (file)
@@ -252,8 +252,8 @@ void conn_free_internal(connection_struct *conn)
        /* Free vfs_connection_struct */
        handle = conn->vfs_handles;
        while(handle) {
-               DLIST_REMOVE(conn->vfs_handles, handle);
                thandle = handle->next;
+               DLIST_REMOVE(conn->vfs_handles, handle);
                if (handle->free_data)
                        handle->free_data(&handle->data);
                handle = thandle;
index 6933533672e1e180693236ecae3243c19c3c975e..8bfa28faeaee8f990c1cfb0618c65c71b57c87aa 100644 (file)
@@ -5583,10 +5583,10 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
                        fsp->fsp_name,newname));
 
-               rename_open_files(conn, lck, newname);
-
                notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname);
 
+               rename_open_files(conn, lck, newname);
+
                /*
                 * A rename acts as a new file create w.r.t. allowing an initial delete
                 * on close, probably because in Windows there is a new handle to the
index 14d45e2b0fcf4b9a6596fa55cf7ce065a88f3e39..46f38d42f66012d61d24e23c90c22da3f2c35989 100644 (file)
@@ -150,9 +150,10 @@ int get_my_ip_address( struct sockaddr_storage **pp_ss )
        struct sockaddr_storage *list = NULL;
        int count = 0;
 
-       /* find the first non-loopback address from our list of interfaces */
+       /* Honor the configured list of interfaces to register */
 
-       n = get_interfaces(nics, MAX_INTERFACES);
+       load_interfaces();
+       n = iface_count();
 
        if (n <= 0) {
                return -1;
@@ -163,19 +164,17 @@ int get_my_ip_address( struct sockaddr_storage **pp_ss )
        }
 
        for ( i=0; i<n; i++ ) {
-               if (is_loopback_addr(&nics[i].ip)) {
+               const struct sockaddr_storage *nic_sa_storage = NULL;
+
+               if ((nic_sa_storage = iface_n_sockaddr_storage(i)) == NULL)
+                       continue;
+
+               /* Don't register loopback addresses */
+               if (is_loopback_addr(nic_sa_storage)) {
                        continue;
                }
-#if defined(HAVE_IPV6)
-               if ((nics[i].ip.ss_family == AF_INET6)) {
-                       memcpy(&list[count++], &nics[i].ip,
-                              sizeof(struct sockaddr_storage));
-               } else
-#endif
-               if (nics[i].ip.ss_family == AF_INET) {
-                       memcpy(&list[count++], &nics[i].ip,
-                              sizeof(struct sockaddr_storage));
-               }
+
+               memcpy(&list[count++], nic_sa_storage, sizeof(struct sockaddr_storage));
        }
        *pp_ss = list;
 
index ce24c7cddd480dd71f10c128834ded9264bd3d66..e684a075c25228762bdccf994dfdebdca84a32b1 100644 (file)
@@ -43,9 +43,10 @@ static void initPid2Machine (void)
 {
        /* show machine name rather PID on table "Open Files"? */
        if (PID_or_Machine) {
-               PIDMAP *p;
+               PIDMAP *p, *next;
 
-               for (p = pidmap; p != NULL; ) {
+               for (p = pidmap; p != NULL; p = next) {
+                       next = p->next;
                        DLIST_REMOVE(pidmap, p);
                        SAFE_FREE(p->machine);
                        SAFE_FREE(p);
index b8cb27c797420fe691ef3d4a38b87511ccc53ffd..fdfc8ed9d13dd3d076efa461d270da73d150b8ff 100644 (file)
@@ -1075,13 +1075,12 @@ void free_getent_state(struct getent_state *state)
        temp = state;
 
        while(temp != NULL) {
-               struct getent_state *next;
+               struct getent_state *next = temp->next;
 
                /* Free sam entries then list entry */
 
                SAFE_FREE(state->sam_entries);
                DLIST_REMOVE(state, state);
-               next = temp->next;
 
                SAFE_FREE(temp);
                temp = next;
index b31e89b7a5cfcb9f8fd672b32f5e23ca9a529539..1cb0d50d02befef0bc44d8d16d4ec5d941890c72 100644 (file)
@@ -331,68 +331,68 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
 
                /* could check if the user exists */
                if (user_known) {
-                       netlogon->nt5_ex.command      = LOGON_SAM_LOGON_RESPONSE_EX;
+                       netlogon->data.nt5_ex.command      = LOGON_SAM_LOGON_RESPONSE_EX;
                } else {
-                       netlogon->nt5_ex.command      = LOGON_SAM_LOGON_USER_UNKNOWN_EX;
+                       netlogon->data.nt5_ex.command      = LOGON_SAM_LOGON_USER_UNKNOWN_EX;
                }
-               netlogon->nt5_ex.server_type  = server_type;
-               netlogon->nt5_ex.domain_uuid  = domain_uuid;
-               netlogon->nt5_ex.forest       = realm;
-               netlogon->nt5_ex.dns_domain   = dns_domain;
-               netlogon->nt5_ex.pdc_dns_name = pdc_dns_name;
-               netlogon->nt5_ex.domain       = flatname;
-               netlogon->nt5_ex.pdc_name     = lp_netbios_name(lp_ctx);
-               netlogon->nt5_ex.user_name    = user;
-               netlogon->nt5_ex.server_site  = server_site;
-               netlogon->nt5_ex.client_site  = client_site;
+               netlogon->data.nt5_ex.server_type  = server_type;
+               netlogon->data.nt5_ex.domain_uuid  = domain_uuid;
+               netlogon->data.nt5_ex.forest       = realm;
+               netlogon->data.nt5_ex.dns_domain   = dns_domain;
+               netlogon->data.nt5_ex.pdc_dns_name = pdc_dns_name;
+               netlogon->data.nt5_ex.domain       = flatname;
+               netlogon->data.nt5_ex.pdc_name     = lp_netbios_name(lp_ctx);
+               netlogon->data.nt5_ex.user_name    = user;
+               netlogon->data.nt5_ex.server_site  = server_site;
+               netlogon->data.nt5_ex.client_site  = client_site;
 
                if (version & NETLOGON_NT_VERSION_5EX_WITH_IP) {
                        /* Clearly this needs to be fixed up for IPv6 */
                        extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP;
-                       netlogon->nt5_ex.sockaddr.sa_family    = 2;
-                       netlogon->nt5_ex.sockaddr.pdc_ip       = pdc_ip;
-                       netlogon->nt5_ex.sockaddr.remaining = data_blob_talloc_zero(mem_ctx, 8);
+                       netlogon->data.nt5_ex.sockaddr.sa_family    = 2;
+                       netlogon->data.nt5_ex.sockaddr.pdc_ip       = pdc_ip;
+                       netlogon->data.nt5_ex.sockaddr.remaining = data_blob_talloc_zero(mem_ctx, 8);
                }
-               netlogon->nt5_ex.nt_version   = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5EX|extra_flags;
-               netlogon->nt5_ex.lmnt_token   = 0xFFFF;
-               netlogon->nt5_ex.lm20_token   = 0xFFFF;
+               netlogon->data.nt5_ex.nt_version   = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5EX|extra_flags;
+               netlogon->data.nt5_ex.lmnt_token   = 0xFFFF;
+               netlogon->data.nt5_ex.lm20_token   = 0xFFFF;
 
        } else if (version & NETLOGON_NT_VERSION_5) {
                netlogon->ntver = NETLOGON_NT_VERSION_5;
 
                /* could check if the user exists */
                if (user_known) {
-                       netlogon->nt5.command      = LOGON_SAM_LOGON_RESPONSE;
+                       netlogon->data.nt5.command      = LOGON_SAM_LOGON_RESPONSE;
                } else {
-                       netlogon->nt5.command      = LOGON_SAM_LOGON_USER_UNKNOWN;
+                       netlogon->data.nt5.command      = LOGON_SAM_LOGON_USER_UNKNOWN;
                }
-               netlogon->nt5.pdc_name     = pdc_name;
-               netlogon->nt5.user_name    = user;
-               netlogon->nt5.domain_name  = flatname;
-               netlogon->nt5.domain_uuid  = domain_uuid;
-               netlogon->nt5.forest       = realm;
-               netlogon->nt5.dns_domain   = dns_domain;
-               netlogon->nt5.pdc_dns_name = pdc_dns_name;
-               netlogon->nt5.pdc_ip       = pdc_ip;
-               netlogon->nt5.server_type  = server_type;
-               netlogon->nt5.nt_version   = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5;
-               netlogon->nt5.lmnt_token   = 0xFFFF;
-               netlogon->nt5.lm20_token   = 0xFFFF;
+               netlogon->data.nt5.pdc_name     = pdc_name;
+               netlogon->data.nt5.user_name    = user;
+               netlogon->data.nt5.domain_name  = flatname;
+               netlogon->data.nt5.domain_uuid  = domain_uuid;
+               netlogon->data.nt5.forest       = realm;
+               netlogon->data.nt5.dns_domain   = dns_domain;
+               netlogon->data.nt5.pdc_dns_name = pdc_dns_name;
+               netlogon->data.nt5.pdc_ip       = pdc_ip;
+               netlogon->data.nt5.server_type  = server_type;
+               netlogon->data.nt5.nt_version   = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5;
+               netlogon->data.nt5.lmnt_token   = 0xFFFF;
+               netlogon->data.nt5.lm20_token   = 0xFFFF;
 
        } else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ {
                netlogon->ntver = NETLOGON_NT_VERSION_1;
                /* could check if the user exists */
                if (user_known) {
-                       netlogon->nt4.command      = LOGON_SAM_LOGON_RESPONSE;
+                       netlogon->data.nt4.command      = LOGON_SAM_LOGON_RESPONSE;
                } else {
-                       netlogon->nt4.command      = LOGON_SAM_LOGON_USER_UNKNOWN;
+                       netlogon->data.nt4.command      = LOGON_SAM_LOGON_USER_UNKNOWN;
                }
-               netlogon->nt4.server      = pdc_name;
-               netlogon->nt4.user_name   = user;
-               netlogon->nt4.domain      = flatname;
-               netlogon->nt4.nt_version  = NETLOGON_NT_VERSION_1;
-               netlogon->nt4.lmnt_token  = 0xFFFF;
-               netlogon->nt4.lm20_token  = 0xFFFF;
+               netlogon->data.nt4.server      = pdc_name;
+               netlogon->data.nt4.user_name   = user;
+               netlogon->data.nt4.domain      = flatname;
+               netlogon->data.nt4.nt_version  = NETLOGON_NT_VERSION_1;
+               netlogon->data.nt4.lmnt_token  = 0xFFFF;
+               netlogon->data.nt4.lm20_token  = 0xFFFF;
        }
 
        return NT_STATUS_OK;
index e40190e86f8ccccbe49ee80e20e99bedf48e4da6..88a8887056ed6c48e7aae3b48c7c3242df929412 100644 (file)
@@ -202,10 +202,14 @@ struct extended_context {
 
        struct ldb_module *module;
        struct ldb_request *req;
-
+       struct ldb_control *control;
+       struct ldb_dn *basedn;
+       char *wellknown_object;
+       bool inject;
        bool remove_guid;
        bool remove_sid;
        int extended_type;
+       const char * const *cast_attrs;
 };
 
 static int extended_callback(struct ldb_request *req, struct ldb_reply *ares)
@@ -226,13 +230,15 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares)
 
        switch (ares->type) {
        case LDB_REPLY_ENTRY:
-               /* for each record returned post-process to add any derived
-                  attributes that have been asked for */
-               ret = inject_extended_dn(ares->message, ac->module->ldb,
-                                        ac->extended_type, ac->remove_guid,
-                                        ac->remove_sid);
-               if (ret != LDB_SUCCESS) {
-                       return ldb_module_done(ac->req, NULL, NULL, ret);
+               if (ac->inject) {
+                       /* for each record returned post-process to add any derived
+                          attributes that have been asked for */
+                       ret = inject_extended_dn(ares->message, ac->module->ldb,
+                                                ac->extended_type, ac->remove_guid,
+                                                ac->remove_sid);
+                       if (ret != LDB_SUCCESS) {
+                               return ldb_module_done(ac->req, NULL, NULL, ret);
+                       }
                }
 
                return ldb_module_send_entry(ac->req, ares->message);
@@ -248,6 +254,118 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares)
        return LDB_SUCCESS;
 }
 
+static int extended_base_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+       struct extended_context *ac;
+       struct ldb_request *down_req;
+       struct ldb_control **saved_controls;
+       struct ldb_message_element *el;
+       int ret;
+       size_t i;
+       size_t wkn_len = 0;
+       char *valstr = NULL;
+       const char *found = NULL;
+
+       ac = talloc_get_type(req->context, struct extended_context);
+
+       if (!ares) {
+               return ldb_module_done(ac->req, NULL, NULL,
+                                       LDB_ERR_OPERATIONS_ERROR);
+       }
+       if (ares->error != LDB_SUCCESS) {
+               return ldb_module_done(ac->req, ares->controls,
+                                       ares->response, ares->error);
+       }
+
+       switch (ares->type) {
+       case LDB_REPLY_ENTRY:
+               if (!ac->wellknown_object) {
+                       ac->basedn = ares->message->dn;
+                       break;
+               }
+
+               wkn_len = strlen(ac->wellknown_object);
+
+               el = ldb_msg_find_element(ares->message, "wellKnownObjects");
+               if (!el) {
+                       ac->basedn = NULL;
+                       break;
+               }
+
+               for (i=0; i < el->num_values; i++) {
+                       valstr = talloc_strndup(ac,
+                                               (const char *)el->values[i].data,
+                                               el->values[i].length);
+                       if (!valstr) {
+                               ldb_oom(ac->module->ldb);
+                               return ldb_module_done(ac->req, NULL, NULL,
+                                                      LDB_ERR_OPERATIONS_ERROR);
+                       }
+
+                       if (strncasecmp(valstr, ac->wellknown_object, wkn_len) != 0) {
+                               talloc_free(valstr);
+                               continue;
+                       }
+
+                       found = &valstr[wkn_len];
+                       break;
+               }
+
+               if (!found) {
+                       break;
+               }
+
+               ac->basedn = ldb_dn_new(ac, ac->module->ldb, found);
+               talloc_free(valstr);
+               if (!ac->basedn) {
+                       ldb_oom(ac->module->ldb);
+                       return ldb_module_done(ac->req, NULL, NULL,
+                                              LDB_ERR_OPERATIONS_ERROR);
+               }
+
+               break;
+
+       case LDB_REPLY_REFERRAL:
+               break;
+
+       case LDB_REPLY_DONE:
+
+               if (!ac->basedn) {
+                       const char *str = talloc_asprintf(req, "Base-DN '%s' not found",
+                                                         ldb_dn_get_linearized(ac->req->op.search.base));
+                       ldb_set_errstring(ac->module->ldb, str);
+                       return ldb_module_done(ac->req, NULL, NULL,
+                                              LDB_ERR_NO_SUCH_OBJECT);
+               }
+
+               ret = ldb_build_search_req_ex(&down_req,
+                                               ac->module->ldb, ac,
+                                               ac->basedn,
+                                               ac->req->op.search.scope,
+                                               ac->req->op.search.tree,
+                                               ac->cast_attrs,
+                                               ac->req->controls,
+                                               ac, extended_callback,
+                                               ac->req);
+               if (ret != LDB_SUCCESS) {
+                       return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
+               }
+
+               if (ac->control) {
+                       /* save it locally and remove it from the list */
+                       /* we do not need to replace them later as we
+                        * are keeping the original req intact */
+                       if (!save_controls(ac->control, down_req, &saved_controls)) {
+                               return ldb_module_done(ac->req, NULL, NULL,
+                                                       LDB_ERR_OPERATIONS_ERROR);
+                       }
+               }
+
+               /* perform the search */
+               return ldb_next_request(ac->module, down_req);
+       }
+       return LDB_SUCCESS;
+}
 
 static int extended_search(struct ldb_module *module, struct ldb_request *req)
 {
@@ -256,25 +374,181 @@ static int extended_search(struct ldb_module *module, struct ldb_request *req)
        struct ldb_control **saved_controls;
        struct extended_context *ac;
        struct ldb_request *down_req;
-       const char * const *cast_attrs = NULL;
        char **new_attrs;
        int ret;
+       struct ldb_dn *base_dn = NULL;
+       enum ldb_scope base_dn_scope = LDB_SCOPE_BASE;
+       const char *base_dn_filter = NULL;
+       const char * const *base_dn_attrs = NULL;
+       char *wellknown_object = NULL;
+       static const char *dnattr[] = {
+               "distinguishedName",
+               NULL
+       };
+       static const char *wkattr[] = {
+               "wellKnownObjects",
+               NULL
+       };
+
+       if (ldb_dn_is_special(req->op.search.base)) {
+               char *dn;
+
+               dn = ldb_dn_alloc_linearized(req, req->op.search.base);
+               if (!dn) {
+                       ldb_oom(module->ldb);
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+
+               if (strncasecmp(dn, "<SID=", 5) == 0) {
+                       char *str;
+                       char *valstr;
+                       char *p;
+
+                       p = strchr(dn, '=');
+                       if (!p) {
+                               return LDB_ERR_INVALID_DN_SYNTAX;
+                       }
+
+                       p[0] = '\0';
+                       p++;
+
+                       str = p;
+
+                       p = strchr(str, '>');
+                       if (!p) {
+                               return LDB_ERR_INVALID_DN_SYNTAX;
+                       }
+                       p[0] = '\0';
+
+                       if (strncasecmp(str, "S-", 2) == 0) {
+                               valstr = str;
+                       } else {
+                               DATA_BLOB binary;
+                               binary = strhex_to_data_blob(str);
+                               if (!binary.data) {
+                                       ldb_oom(module->ldb);
+                                       return LDB_ERR_OPERATIONS_ERROR;
+                               }
+                               valstr = ldb_binary_encode(req, binary);
+                               data_blob_free(&binary);
+                               if (!valstr) {
+                                       ldb_oom(module->ldb);
+                                       return LDB_ERR_OPERATIONS_ERROR;
+                               }
+                       }
+
+                       /* TODO: do a search over all partitions */
+                       base_dn = ldb_get_default_basedn(module->ldb);
+                       base_dn_filter = talloc_asprintf(req, "(objectSid=%s)", valstr);
+                       if (!base_dn_filter) {
+                               ldb_oom(module->ldb);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       base_dn_scope = LDB_SCOPE_SUBTREE;
+                       base_dn_attrs = dnattr;
+               } else if (strncasecmp(dn, "<GUID=", 6) == 0) {
+                       char *str;
+                       char *valstr;
+                       char *p;
+
+                       p = strchr(dn, '=');
+                       if (!p) {
+                               return LDB_ERR_INVALID_DN_SYNTAX;
+                       }
+
+                       p[0] = '\0';
+                       p++;
+
+                       str = p;
+
+                       p = strchr(str, '>');
+                       if (!p) {
+                               return LDB_ERR_INVALID_DN_SYNTAX;
+                       }
+                       p[0] = '\0';
+
+                       if (strchr(str, '-')) {
+                               valstr = str;
+                       } else {
+                               DATA_BLOB binary;
+                               binary = strhex_to_data_blob(str);
+                               if (!binary.data) {
+                                       ldb_oom(module->ldb);
+                                       return LDB_ERR_OPERATIONS_ERROR;
+                               }
+                               valstr = ldb_binary_encode(req, binary);
+                               data_blob_free(&binary);
+                               if (!valstr) {
+                                       ldb_oom(module->ldb);
+                                       return LDB_ERR_OPERATIONS_ERROR;
+                               }
+                       }
+
+                       /* TODO: do a search over all partitions */
+                       base_dn = ldb_get_default_basedn(module->ldb);
+                       base_dn_filter = talloc_asprintf(req, "(objectGUID=%s)", valstr);
+                       if (!base_dn_filter) {
+                               ldb_oom(module->ldb);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       base_dn_scope = LDB_SCOPE_SUBTREE;
+                       base_dn_attrs = dnattr;
+               } else if (strncasecmp(dn, "<WKGUID=", 8) == 0) {
+                       char *tail_str;
+                       char *p;
+
+                       p = strchr(dn, ',');
+                       if (!p) {
+                               return LDB_ERR_INVALID_DN_SYNTAX;
+                       }
+
+                       p[0] = '\0';
+                       p++;
+
+                       wellknown_object = talloc_asprintf(req, "B:32:%s:", &dn[8]);
+                       if (!wellknown_object) {
+                               ldb_oom(module->ldb);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+
+                       tail_str = p;
+                       p = strchr(tail_str, '>');
+                       if (!p) {
+                               return LDB_ERR_INVALID_DN_SYNTAX;
+                       }
+                       p[0] = '\0';
+
+                       base_dn = ldb_dn_new(req, module->ldb, tail_str);
+                       if (!base_dn) {
+                               ldb_oom(module->ldb);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       base_dn_filter = talloc_strdup(req, "(objectClass=*)");
+                       if (!base_dn_filter) {
+                               ldb_oom(module->ldb);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+                       base_dn_scope = LDB_SCOPE_BASE;
+                       base_dn_attrs = wkattr;
+               }
+               talloc_free(dn);
+       }
 
        /* check if there's an extended dn control */
        control = ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID);
-       if (control == NULL) {
+       if (control == NULL && base_dn_filter == NULL) {
                /* not found go on */
                return ldb_next_request(module, req);
        }
 
-       if (control->data) {
+       if (control && control->data) {
                extended_ctrl = talloc_get_type(control->data, struct ldb_extended_dn_control);
                if (!extended_ctrl) {
                        return LDB_ERR_PROTOCOL_ERROR;
                }
        }
 
-       ac = talloc(req, struct extended_context);
+       ac = talloc_zero(req, struct extended_context);
        if (ac == NULL) {
                ldb_oom(module->ldb);
                return LDB_ERR_OPERATIONS_ERROR;
@@ -282,49 +556,75 @@ static int extended_search(struct ldb_module *module, struct ldb_request *req)
 
        ac->module = module;
        ac->req = req;
+       ac->control = control;
+       ac->basedn = NULL;
+       ac->wellknown_object = wellknown_object;
+       ac->inject = false;
        ac->remove_guid = false;
        ac->remove_sid = false;
-       if (extended_ctrl) {
-               ac->extended_type = extended_ctrl->type;
-       } else {
-               ac->extended_type = 0;
-       }
 
-       /* check if attrs only is specified, in that case check wether we need to modify them */
-       if (req->op.search.attrs) {
-               if (! is_attr_in_list(req->op.search.attrs, "objectGUID")) {
-                       ac->remove_guid = true;
-               }
-               if (! is_attr_in_list(req->op.search.attrs, "objectSID")) {
-                       ac->remove_sid = true;
+       if (control) {
+               ac->inject = true;
+               if (extended_ctrl) {
+                       ac->extended_type = extended_ctrl->type;
+               } else {
+                       ac->extended_type = 0;
                }
-               if (ac->remove_guid || ac->remove_sid) {
-                       new_attrs = copy_attrs(ac, req->op.search.attrs);
-                       if (new_attrs == NULL) {
-                               ldb_oom(module->ldb);
-                               return LDB_ERR_OPERATIONS_ERROR;
+
+               /* check if attrs only is specified, in that case check wether we need to modify them */
+               if (req->op.search.attrs) {
+                       if (! is_attr_in_list(req->op.search.attrs, "objectGUID")) {
+                               ac->remove_guid = true;
                        }
-                       
-                       if (ac->remove_guid) {
-                               if (!add_attrs(ac, &new_attrs, "objectGUID"))
-                                       return LDB_ERR_OPERATIONS_ERROR;
+                       if (! is_attr_in_list(req->op.search.attrs, "objectSID")) {
+                               ac->remove_sid = true;
                        }
-                       if (ac->remove_sid) {
-                               if (!add_attrs(ac, &new_attrs, "objectSID"))
+                       if (ac->remove_guid || ac->remove_sid) {
+                               new_attrs = copy_attrs(ac, req->op.search.attrs);
+                               if (new_attrs == NULL) {
+                                       ldb_oom(module->ldb);
                                        return LDB_ERR_OPERATIONS_ERROR;
+                               }
+
+                               if (ac->remove_guid) {
+                                       if (!add_attrs(ac, &new_attrs, "objectGUID"))
+                                               return LDB_ERR_OPERATIONS_ERROR;
+                               }
+                               if (ac->remove_sid) {
+                                       if (!add_attrs(ac, &new_attrs, "objectSID"))
+                                               return LDB_ERR_OPERATIONS_ERROR;
+                               }
+                               ac->cast_attrs = (const char * const *)new_attrs;
+                       } else {
+                               ac->cast_attrs = req->op.search.attrs;
                        }
-                       cast_attrs = (const char * const *)new_attrs;
-               } else {
-                       cast_attrs = req->op.search.attrs;
                }
        }
 
+       if (base_dn) {
+               ret = ldb_build_search_req(&down_req,
+                                          module->ldb, ac,
+                                          base_dn,
+                                          base_dn_scope,
+                                          base_dn_filter,
+                                          base_dn_attrs,
+                                          NULL,
+                                          ac, extended_base_callback,
+                                          req);
+               if (ret != LDB_SUCCESS) {
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+
+               /* perform the search */
+               return ldb_next_request(module, down_req);
+       }
+
        ret = ldb_build_search_req_ex(&down_req,
                                        module->ldb, ac,
                                        req->op.search.base,
                                        req->op.search.scope,
                                        req->op.search.tree,
-                                       cast_attrs,
+                                       ac->cast_attrs,
                                        req->controls,
                                        ac, extended_callback,
                                        req);
@@ -332,11 +632,13 @@ static int extended_search(struct ldb_module *module, struct ldb_request *req)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       /* save it locally and remove it from the list */
-       /* we do not need to replace them later as we
-        * are keeping the original req intact */
-       if (!save_controls(control, down_req, &saved_controls)) {
-               return LDB_ERR_OPERATIONS_ERROR;
+       if (ac->control) {
+               /* save it locally and remove it from the list */
+               /* we do not need to replace them later as we
+                * are keeping the original req intact */
+               if (!save_controls(control, down_req, &saved_controls)) {
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
        }
 
        /* perform the search */
index 24527c36c95641aa9556744cb5b62f013b563c63..6e6da5581d628488fc2b5d44f607f3abf91b778b 100644 (file)
@@ -321,6 +321,8 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
        struct kludge_private_data *data;
        const char * const *attrs;
        int ret, i;
+       struct ldb_control *sd_control;
+       struct ldb_control **sd_saved_controls;
 
        ac = talloc(req, struct kludge_acl_context);
        if (ac == NULL) {
@@ -382,6 +384,17 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
+       /* check if there's an SD_FLAGS control */
+       sd_control = ldb_request_get_control(down_req, LDB_CONTROL_SD_FLAGS_OID);
+       if (sd_control) {
+               /* save it locally and remove it from the list */
+               /* we do not need to replace them later as we
+                * are keeping the original req intact */
+               if (!save_controls(sd_control, down_req, &sd_saved_controls)) {
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+       }
+
        /* perform the search */
        return ldb_next_request(module, down_req);
 }
@@ -462,6 +475,13 @@ static int kludge_acl_init(struct ldb_module *module)
        }
        data->password_attrs[i] = NULL;
 
+       ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID);
+       if (ret != LDB_SUCCESS) {
+               ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+                       "partition: Unable to register control with rootdse!\n");
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
 done:
        talloc_free(mem_ctx);
        return ldb_next_init(module);
index 3b389afffbb853a33f4c71a0f8389069eb0f72e0..14fd107d81d504f347f39bfde334121fb317ffee 100644 (file)
@@ -217,6 +217,17 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request *
                
                /* Even link IDs are for the originating attribute */
                target_attr = dsdb_attribute_by_linkID(ac->schema, schema_attr->linkID + 1);
+               if (!target_attr) {
+                       /*
+                        * windows 2003 has a broken schema where
+                        * the definition of msDS-IsDomainFor
+                        * is missing (which is supposed to be
+                        * the backlink of the msDS-HasDomainNCs
+                        * attribute
+                        */
+                       continue;
+               }
+
                attr_name = target_attr->lDAPDisplayName;
                attr_val = ldb_dn_get_linearized(ac->req->op.add.message->dn);
 
@@ -301,6 +312,16 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are
                        }
 
                        target_attr = dsdb_attribute_by_linkID(ac->schema, schema_attr->linkID + 1);
+                       if (!target_attr) {
+                               /*
+                                * windows 2003 has a broken schema where
+                                * the definition of msDS-IsDomainFor
+                                * is missing (which is supposed to be
+                                * the backlink of the msDS-HasDomainNCs
+                                * attribute
+                                */
+                               continue;
+                       }
                        attr_name = target_attr->lDAPDisplayName;
 
                        /* make sure we manage each value */
@@ -399,9 +420,14 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
                /* Now find the target attribute */
                target_attr = dsdb_attribute_by_linkID(ac->schema, schema_attr->linkID + 1);
                if (!target_attr) {
-                       ldb_asprintf_errstring(module->ldb, 
-                                              "attribute %s does not have valid link target", el->name);
-                       return LDB_ERR_OBJECT_CLASS_VIOLATION;                  
+                       /*
+                        * windows 2003 has a broken schema where
+                        * the definition of msDS-IsDomainFor
+                        * is missing (which is supposed to be
+                        * the backlink of the msDS-HasDomainNCs
+                        * attribute
+                        */
+                       continue;
                }
 
                attr_name = target_attr->lDAPDisplayName;
@@ -654,9 +680,15 @@ static int la_op_search_callback(struct ldb_request *req,
                        if ((schema_attr->linkID & 1) == 0) {
                                /* Odd is for the target. */
                                target_attr = dsdb_attribute_by_linkID(ac->schema, schema_attr->linkID + 1);
+                               if (!target_attr) {
+                                       continue;
+                               }
                                attr_name = target_attr->lDAPDisplayName;
                        } else {
                                target_attr = dsdb_attribute_by_linkID(ac->schema, schema_attr->linkID - 1);
+                               if (!target_attr) {
+                                       continue;
+                               }
                                attr_name = target_attr->lDAPDisplayName;
                        }
                        for (j = 0; j < el->num_values; j++) {
index 1274061e775549666f13c9dbd6f2f6060f60d5a9..8e4483a78e375c81a9db5bffba4118bd48320f04 100644 (file)
@@ -472,6 +472,14 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
+       /*
+        * for now pass down the LDB_CONTROL_SEARCH_OPTIONS_OID control
+        * down as uncritical to make windows 2008 dcpromo happy.
+        */
+       if (search_control) {
+               search_control->critical = 0;
+       }
+
        /* TODO:
           Generate referrals (look for a partition under this DN) if we don't have the above control specified
        */
@@ -1186,6 +1194,20 @@ static int partition_init(struct ldb_module *module)
                }
        }
 
+       ret = ldb_mod_register_control(module, LDB_CONTROL_DOMAIN_SCOPE_OID);
+       if (ret != LDB_SUCCESS) {
+               ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+                       "partition: Unable to register control with rootdse!\n");
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ret = ldb_mod_register_control(module, LDB_CONTROL_SEARCH_OPTIONS_OID);
+       if (ret != LDB_SUCCESS) {
+               ldb_debug(module->ldb, LDB_DEBUG_ERROR,
+                       "partition: Unable to register control with rootdse!\n");
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
        talloc_free(mem_ctx);
        return ldb_next_init(module);
 }
index 0d14a54464c686e481593c0c1b8b79c14b2575bb..b38e182cf7897ca4bbc8557e987ef57efa4c43fa 100644 (file)
@@ -318,7 +318,7 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
                                        LDB_SCOPE_BASE,
                                        NULL,
                                        req->op.search.attrs,
-                                       req->controls,
+                                       NULL,/* for now skip the controls from the client */
                                        ac, rootdse_callback,
                                        req);
        if (ret != LDB_SUCCESS) {
index c0d36cfbf3e0c48239b123a8920fbd4d065cc068..e36aea4e697fd8b2dddf5bdfdcaad64d18aa7c2a 100644 (file)
@@ -91,7 +91,7 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const
                         * exploded_dn control is used */
                        dn->special = true;
                        /* FIXME: add a GUID string to ldb_dn structure */
-               } else if (strdn->length >= 8 && strncasecmp((const char *)strdn->data, "<SID=", 8) == 0) {
+               } else if (strdn->length >= 5 && strncasecmp((const char *)strdn->data, "<SID=", 5) == 0) {
                        /* this is special DN returned when the
                         * exploded_dn control is used */
                        dn->special = true;
@@ -150,7 +150,7 @@ struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char
                 * exploded_dn control is used */
                dn->special = true;
                /* FIXME: add a GUID string to ldb_dn structure */
-       } else if (strncasecmp(strdn, "<SID=", 8) == 0) {
+       } else if (strncasecmp(strdn, "<SID=", 5) == 0) {
                /* this is special DN returned when the
                 * exploded_dn control is used */
                dn->special = true;
index d49d46250d3d7b5d70da6afe9069be84cdc1dc59..a6f947ee78966ad0f57b62e61f2ab751ca1f2b99 100644 (file)
@@ -69,7 +69,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
                old_num_values = 0;
        }
 
-       /* Subkeys that were deleted */
+       /* Subkeys that were changed or deleted */
        for (i = 0; i < old_num_subkeys; i++) {
                error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i,
                                                     &keyname1, NULL, NULL);
@@ -81,24 +81,23 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
 
                if (newkey != NULL) {
                        error2 = reg_open_key(mem_ctx, newkey, keyname1, &t2);
-
-                       if (W_ERROR_IS_OK(error2))
-                               continue;
                } else {
                        error2 = WERR_BADFILE;
                        t2 = NULL;
                }
 
-               if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) {
+               if (!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_BADFILE)) {
                        DEBUG(0, ("Error occured while getting subkey by name: %s\n",
                                win_errstr(error2)));
                        talloc_free(mem_ctx);
                        return error2;
                }
 
-               /* newkey didn't have such a subkey, add del diff */
+               /* if "error2" is going to be "WERR_BADFILE", then newkey */
+               /* didn't have such a subkey and therefore add a del diff */
                tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1);
-               callbacks->del_key(callback_data, tmppath);
+               if (!W_ERROR_IS_OK(error2))
+                       callbacks->del_key(callback_data, tmppath);
 
                /* perform here also the recursive invocation */
                error1 = reg_open_key(mem_ctx, oldkey, keyname1, &t1);
@@ -385,14 +384,13 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name)
 static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name)
 {
        struct registry_context *ctx = (struct registry_context *)_ctx;
-       WERROR error;
 
-       error = reg_key_del_abs(ctx, key_name);
+       /* We can't proof here for success, because a common superkey could */
+       /* have been deleted before the subkey's (diff order). This removed */
+       /* therefore all childs recursively and the "WERR_BADFILE" result is */
+       /* expected. */
 
-       if(!W_ERROR_IS_OK(error)) {
-               DEBUG(0, ("Unable to delete key '%s'\n", key_name));
-               return error;
-       }
+       reg_key_del_abs(ctx, key_name);
 
        return WERR_OK;
 }
@@ -454,8 +452,7 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name)
        struct registry_context *ctx = (struct registry_context *)_ctx;
        struct registry_key *key;
        WERROR error;
-       int i;
-       uint32_t num_values;
+       const char* value_name;
 
        error = reg_open_key_abs(ctx, ctx, key_name, &key);
 
@@ -465,14 +462,15 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name)
        }
 
        W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, NULL,
-                              NULL, &num_values, NULL, NULL, NULL, NULL));
+                              NULL, NULL, NULL, NULL, NULL, NULL));
 
-       for (i = 0; i < num_values; i++) {
-               const char *name;
-               W_ERROR_NOT_OK_RETURN(reg_key_get_value_by_index(ctx, key, i,
-                                                                &name,
-                                                                NULL, NULL));
-               W_ERROR_NOT_OK_RETURN(reg_del_value(key, name));
+       while (W_ERROR_IS_OK(reg_key_get_value_by_index(
+                       ctx, key, 0, &value_name, NULL, NULL))) {
+               error = reg_del_value(key, value_name);
+               if (!W_ERROR_IS_OK(error)) {
+                       DEBUG(0, ("Error deleting value '%s'\n", value_name));
+                       return error;
+               }
        }
 
        return WERR_OK;
index b9071d5eb1dbbae8f16c2bf2570cefb598503800..4cbebbf6d0af1a69f45170eb36c514b903485263 100644 (file)
@@ -770,7 +770,7 @@ static void becomeDC_recv_cldap(struct cldap_request *req)
        c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
        if (!composite_is_ok(c)) return;
 
-       s->cldap.netlogon = s->cldap.io.out.netlogon.nt5_ex;
+       s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;
 
        s->domain.dns_name              = s->cldap.netlogon.dns_domain;
        s->domain.netbios_name          = s->cldap.netlogon.domain;
index 5647a93b8d283a75d08a96268af9175283338239..4a32ab92ed58b4a1e6559ecfac473f254e29eac1 100644 (file)
@@ -58,7 +58,8 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li
 
        cldap = cldap_socket_init(tmp_ctx, lctx->event_ctx, lp_iconv_convenience(lctx->lp_ctx));
        status = cldap_netlogon(cldap, tmp_ctx, &search);
-       if (!NT_STATUS_IS_OK(status) || !search.out.netlogon.nt5_ex.client_site) {
+       if (!NT_STATUS_IS_OK(status)
+           || !search.out.netlogon.data.nt5_ex.client_site) {
                /*
                  If cldap_netlogon() returns in error,
                  default to using Default-First-Site-Name.
@@ -72,7 +73,7 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li
                }
        } else {
                site_name_str = talloc_asprintf(tmp_ctx, "%s",
-                                       search.out.netlogon.nt5_ex.client_site);
+                                       search.out.netlogon.data.nt5_ex.client_site);
                if (!site_name_str) {
                        r->out.error_string = NULL;
                        talloc_free(tmp_ctx);
index 4eeaf1b80c306b0b062e739791d3739f8c254da2..2ee3c641b2bb7afb01ede8e3b7e6e2a38edb767b 100644 (file)
@@ -289,7 +289,7 @@ static void unbecomeDC_recv_cldap(struct cldap_request *req)
        c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
        if (!composite_is_ok(c)) return;
 
-       s->cldap.netlogon = s->cldap.io.out.netlogon.nt5_ex;
+       s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;
 
        s->domain.dns_name              = s->cldap.netlogon.dns_domain;
        s->domain.netbios_name          = s->cldap.netlogon.domain;
@@ -641,7 +641,7 @@ static void unbecomeDC_drsuapi_remove_ds_server_send(struct libnet_UnbecomeDC_st
        r->in.level             = 1;
        r->in.req.req1.server_dn= s->dest_dsa.server_dn_str;
        r->in.req.req1.domain_dn= s->domain.dn_str;
-       r->in.req.req1.unknown  = 0x00000001;
+       r->in.req.req1.commit   = true;
 
        req = dcerpc_drsuapi_DsRemoveDSServer_send(s->drsuapi.pipe, s, r);
        composite_continue_rpc(c, req, unbecomeDC_drsuapi_remove_ds_server_recv, s);
@@ -666,11 +666,6 @@ static void unbecomeDC_drsuapi_remove_ds_server_recv(struct rpc_request *req)
                composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
                return;
        }
-               
-       if (!W_ERROR_IS_OK(r->out.res.res1.status)) {
-               composite_error(c, werror_to_ntstatus(r->out.res.res1.status));
-               return;
-       }
 
        composite_done(c);
 }
index 0a5a081dd7fad9b016e837b9f2247d2cca68a474..76858b2d5c7abc1b0930ac982caabc3fb8b875af 100644 (file)
@@ -970,7 +970,7 @@ interface drsuapi
        typedef struct {
                [charset(UTF16),string] uint16 *server_dn;
                [charset(UTF16),string] uint16 *domain_dn;
-               uint32 unknown; /* 0x000000001 */
+               boolean32 commit;
        } drsuapi_DsRemoveDSServerRequest1;
 
        typedef [switch_type(int32)] union {
@@ -978,7 +978,7 @@ interface drsuapi
        } drsuapi_DsRemoveDSServerRequest;
 
        typedef struct {
-               WERROR status;
+               boolean32 last_dc_in_domain;
        } drsuapi_DsRemoveDSServerResult1;
 
        typedef [switch_type(int32)] union {
index 5e95270b7d2f8f01960b552055748fd308dd454f..1bc3e2b62fd63f7b260ec1549111719f95ec6cc2 100644 (file)
@@ -77,7 +77,7 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
        /* setup a GETDC reply */
        ZERO_STRUCT(netlogon_response);
        netlogon_response.response_type = NETLOGON_GET_PDC;
-       pdc = &netlogon_response.get_pdc;
+       pdc = &netlogon_response.data.get_pdc;
 
        pdc->command = NETLOGON_RESPONSE_FROM_PDC;
        pdc->pdc_name         = lp_netbios_name(iface->nbtsrv->task->lp_ctx);
@@ -132,7 +132,7 @@ static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot,
 
        status = fill_netlogon_samlogon_response(samctx, packet, NULL, name->name, sid, NULL, 
                                                 netlogon->req.logon.user_name, netlogon->req.logon.acct_control, src->addr, 
-                                                netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.samlogon);
+                                                netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.data.samlogon);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(2,("NBT netlogon query failed domain=%s sid=%s version=%d - %s\n",
                         name->name, dom_sid_string(packet, sid), netlogon->req.logon.nt_version, nt_errstr(status)));
index 8f1f74afcf2bfe1d391c077fb78d8ac7e60b7eb7..fc61372ead8377b7be865f286fe75e0b3c267d52 100644 (file)
@@ -79,16 +79,17 @@ static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot,
 
        /* We asked for version 1 only */
        if (netlogon.response_type == NETLOGON_SAMLOGON
-           && netlogon.samlogon.ntver != NETLOGON_NT_VERSION_1) {
+           && netlogon.data.samlogon.ntver != NETLOGON_NT_VERSION_1) {
                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
                goto done;
        }
 
-       p = netlogon.samlogon.nt4.server;
+       p = netlogon.data.samlogon.data.nt4.server;
 
        DEBUG(10, ("NTLOGON_SAM_LOGON_REPLY: server: %s, user: %s, "
-                  "domain: %s\n", p, netlogon.samlogon.nt4.user_name,
-                  netlogon.samlogon.nt4.domain));
+                  "domain: %s\n", p,
+                  netlogon.data.samlogon.data.nt4.user_name,
+                  netlogon.data.samlogon.data.nt4.domain));
 
        if (*p == '\\') p += 1;
        if (*p == '\\') p += 1;
index 63332e937b2a72b3930c53506014951047c686fa..a7b501e8a8741b4ed20e1b4dd760a0f8590c1fd5 100644 (file)
@@ -77,4 +77,12 @@ subRefs: ${SCHEMADN}
 replace: gPLink
 gPLink: [LDAP://CN={${POLICYGUID}},CN=Policies,CN=System,${DOMAINDN};0]
 -
+replace: wellKnownObjects
+wellKnownObjects: B:32:22b70c67d56e4efb91e9300fca3dc1aa:CN=ForeignSecurityPrincipals,${DOMAINDN}
+wellKnownObjects: B:32:2fbac1870ade11d297c400c04fd8d5cd:CN=Infrastructure,${DOMAINDN}
+wellKnownObjects: B:32:ab1d30f3768811d1aded00c04fd8d5cd:CN=System,${DOMAINDN}
+wellKnownObjects: B:32:a361b2ffffd211d1aa4b00c04fd7d83a:OU=Domain Controllers,${DOMAINDN}
+wellKnownObjects: B:32:aa312825768811d1aded00c04fd8d5cd:CN=Computers,${DOMAINDN}
+wellKnownObjects: B:32:a9d1ca15768811d1aded00c04fd8d5cd:CN=Users,${DOMAINDN}
+-
 ${DOMAINGUID_MOD}
index 3730193c86fb22034eba4a6113d56944aba4f8e8..23b0554c4f65ecc7eb0688083baeaea8171355ae 100644 (file)
@@ -64,7 +64,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        n1 = search.out.netlogon;
 
        search.in.user         = "Administrator";
-       search.in.realm        = n1.nt5_ex.dns_domain;
+       search.in.realm        = n1.data.nt5_ex.dns_domain;
        search.in.host         = "__cldap_torture__";
 
        printf("Scanning for netlogon levels\n");
@@ -93,8 +93,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        search.in.user = NULL;
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
 
        printf("Trying with User=Administrator\n");
 
@@ -102,8 +102,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user);
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
 
        search.in.version = NETLOGON_NT_VERSION_5;
        status = cldap_netlogon(cldap, tctx, &search);
@@ -114,8 +114,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        search.in.user = NULL;
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE);
 
        printf("Trying with User=Administrator\n");
 
@@ -123,18 +123,18 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user);
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN);
 
        search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
 
        printf("Trying with a GUID\n");
        search.in.realm       = NULL;
-       search.in.domain_guid = GUID_string(tctx, &n1.nt5_ex.domain_uuid);
+       search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
-       CHECK_STRING(GUID_string(tctx, &search.out.netlogon.nt5_ex.domain_uuid), search.in.domain_guid);
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
+       CHECK_STRING(GUID_string(tctx, &search.out.netlogon.data.nt5_ex.domain_uuid), search.in.domain_guid);
 
        printf("Trying with a incorrect GUID\n");
        guid = GUID_random();
@@ -145,53 +145,53 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
 
        printf("Trying with a AAC\n");
        search.in.acct_control = ACB_WSTRUST|ACB_SVRTRUST;
-       search.in.realm = n1.nt5_ex.dns_domain;
+       search.in.realm = n1.data.nt5_ex.dns_domain;
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
 
        printf("Trying with a zero AAC\n");
        search.in.acct_control = 0x0;
-       search.in.realm = n1.nt5_ex.dns_domain;
+       search.in.realm = n1.data.nt5_ex.dns_domain;
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
 
        printf("Trying with a zero AAC and user=Administrator\n");
        search.in.acct_control = 0x0;
        search.in.user = "Administrator";
-       search.in.realm = n1.nt5_ex.dns_domain;
+       search.in.realm = n1.data.nt5_ex.dns_domain;
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "Administrator");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "Administrator");
 
        printf("Trying with a bad AAC\n");
        search.in.user = NULL;
        search.in.acct_control = 0xFF00FF00;
-       search.in.realm = n1.nt5_ex.dns_domain;
+       search.in.realm = n1.data.nt5_ex.dns_domain;
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
 
        printf("Trying with a user only\n");
        search = empty_search;
        search.in.user = "Administrator";
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
 
        printf("Trying with just a bad username\n");
        search.in.user = "___no_such_user___";
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, search.in.user);
-       CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
 
        printf("Trying with just a bad domain\n");
        search = empty_search;
@@ -200,29 +200,29 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
        CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
 
        printf("Trying with a incorrect domain and correct guid\n");
-       search.in.domain_guid = GUID_string(tctx, &n1.nt5_ex.domain_uuid);
+       search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
 
        printf("Trying with a incorrect domain and incorrect guid\n");
        search.in.domain_guid = GUID_string(tctx, &guid);
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
-       CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
 
        printf("Trying with a incorrect GUID and correct domain\n");
        search.in.domain_guid = GUID_string(tctx, &guid);
-       search.in.realm = n1.nt5_ex.dns_domain;
+       search.in.realm = n1.data.nt5_ex.dns_domain;
        status = cldap_netlogon(cldap, tctx, &search);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_STRING(search.out.netlogon.nt5_ex.dns_domain, n1.nt5_ex.dns_domain);
-       CHECK_STRING(search.out.netlogon.nt5_ex.user_name, "");
-       CHECK_VAL(search.out.netlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
+       CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
+       CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
 
        return true;
 }
@@ -255,9 +255,9 @@ static bool test_cldap_netlogon_flags(struct torture_context *tctx,
 
        n1 = search.out.netlogon;
        if (n1.ntver == NETLOGON_NT_VERSION_5)
-               server_type = n1.nt5.server_type;
+               server_type = n1.data.nt5.server_type;
        else if (n1.ntver == NETLOGON_NT_VERSION_5EX)
-               server_type = n1.nt5_ex.server_type;    
+               server_type = n1.data.nt5_ex.server_type;       
 
        printf("The word is: %i\n", server_type);
        if (server_type & NBT_SERVER_PDC)
@@ -366,9 +366,9 @@ static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx,
 
        n1 = search.out.netlogon;
        if (n1.ntver == NETLOGON_NT_VERSION_5)
-               server_type = n1.nt5.server_type;
+               server_type = n1.data.nt5.server_type;
        else if (n1.ntver == NETLOGON_NT_VERSION_5EX)
-               server_type = n1.nt5_ex.server_type;
+               server_type = n1.data.nt5_ex.server_type;
 
        if (server_type & NBT_SERVER_DS_DNS_FOREST) {
                struct cldap_search search2;
index eac2b1fe30951169663a50f66ba1edefb6848408..5d26d65e0c0f25b1d296fca42af38cab6b92acfd 100644 (file)
@@ -148,7 +148,7 @@ static bool nbt_test_netlogon(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert(tctx, response->response_type == NETLOGON_GET_PDC, "Got incorrect type of netlogon response");
-       torture_assert(tctx, response->get_pdc.command == NETLOGON_RESPONSE_FROM_PDC, "Got incorrect netlogon response command");
+       torture_assert(tctx, response->data.get_pdc.command == NETLOGON_RESPONSE_FROM_PDC, "Got incorrect netlogon response command");
 
        return true;
 }
@@ -243,10 +243,10 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
-       map_netlogon_samlogon_response(&response->samlogon);
+       map_netlogon_samlogon_response(&response->data.samlogon);
 
-       torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX, "Got incorrect netlogon response command");
-       torture_assert_int_equal(tctx, response->samlogon.nt5_ex.nt_version, NETLOGON_NT_VERSION_5EX_WITH_IP|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_1, "Got incorrect netlogon response command");
+       torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX, "Got incorrect netlogon response command");
+       torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.nt_version, NETLOGON_NT_VERSION_5EX_WITH_IP|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_1, "Got incorrect netlogon response command");
 
        /* setup (another) temporary mailslot listener for replies */
        dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
@@ -282,11 +282,11 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
-       map_netlogon_samlogon_response(&response->samlogon);
+       map_netlogon_samlogon_response(&response->data.samlogon);
 
-       torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
+       torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
 
-       torture_assert_str_equal(tctx, response->samlogon.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
+       torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
 
        join_ctx = torture_join_domain(tctx, TEST_NAME, 
                                       ACB_WSTRUST, &machine_credentials);
@@ -333,9 +333,9 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
-       map_netlogon_samlogon_response(&response->samlogon);
+       map_netlogon_samlogon_response(&response->data.samlogon);
 
-       torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
+       torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
 
        /* setup (another) temporary mailslot listener for replies */
        dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
@@ -374,9 +374,9 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
-       map_netlogon_samlogon_response(&response->samlogon);
+       map_netlogon_samlogon_response(&response->data.samlogon);
 
-       torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
+       torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
 
        dgmslot->private = NULL;
 
@@ -413,9 +413,9 @@ static bool nbt_test_netlogon2(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
-       map_netlogon_samlogon_response(&response->samlogon);
+       map_netlogon_samlogon_response(&response->data.samlogon);
 
-       torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
+       torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN, "Got incorrect netlogon response command");
 
        torture_leave_domain(tctx, join_ctx);
        return true;
@@ -522,11 +522,11 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
-       map_netlogon_samlogon_response(&response->samlogon);
+       map_netlogon_samlogon_response(&response->data.samlogon);
 
-       torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
+       torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
 
-       torture_assert_str_equal(tctx, response->samlogon.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
+       torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
 
 
        /* setup a temporary mailslot listener for replies */
@@ -566,11 +566,11 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
-       map_netlogon_samlogon_response(&response->samlogon);
+       map_netlogon_samlogon_response(&response->data.samlogon);
 
-       torture_assert_int_equal(tctx, response->samlogon.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
+       torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");
 
-       torture_assert_str_equal(tctx, response->samlogon.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
+       torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");
 
 
        /* setup (another) temporary mailslot listener for replies */
@@ -606,7 +606,7 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
-       torture_assert_int_equal(tctx, response->get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");
+       torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");
 
        torture_leave_domain(tctx, join_ctx);
 
@@ -643,7 +643,7 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
        torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");
 
        torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
-       torture_assert_int_equal(tctx, response->get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");
+       torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");
 
 
        return true;
index df16c860cbf6dc2bf744150eed322218a3099cfc..41bb168619138e8d2289247969f670f11c15f1aa 100644 (file)
@@ -310,14 +310,14 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
                ctx->site_name = talloc_asprintf(ctx, "%s", "Default-First-Site-Name");
                printf("cldap_netlogon() returned %s. Defaulting to Site-Name: %s\n", errstr, ctx->site_name);          
        } else {
-               ctx->site_name = talloc_steal(ctx, search.out.netlogon.nt5_ex.client_site);
+               ctx->site_name = talloc_steal(ctx, search.out.netlogon.data.nt5_ex.client_site);
                printf("cldap_netlogon() returned Client Site-Name: %s.\n",ctx->site_name);
-               printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.nt5_ex.server_site);
+               printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.data.nt5_ex.server_site);
        }
 
        if (!ctx->domain_dn) {
                struct ldb_context *ldb = ldb_init(ctx, tctx->ev);
-               struct ldb_dn *dn = samdb_dns_domain_to_dn(ldb, ctx, search.out.netlogon.nt5_ex.dns_domain);
+               struct ldb_dn *dn = samdb_dns_domain_to_dn(ldb, ctx, search.out.netlogon.data.nt5_ex.dns_domain);
                ctx->domain_dn = ldb_dn_alloc_linearized(ctx, dn);
                talloc_free(dn);
                talloc_free(ldb);
index 8e1af99719178cf7bf2c32ddc2a9a5d557fd82a6..7a657d2e8d369f4ea4a9a530742dcb5368d27cf4 100755 (executable)
@@ -117,5 +117,67 @@ echo "Search Options Control Query test returned 0 items"
 failed=`expr $failed + 1`
 fi
 
+function wellkown_object_test() {
+       local guid=$1
+       local object=$2
+       local basedns
+       local dn
+       local r
+       local c
+       local n
+       local failed=0
+
+       basedns="<WKGUID=${guid},${BASEDN}> <wkGuId=${guid},${BASEDN}>"
+       for dn in ${basedns}; do
+               echo "Test ${dn} => ${object}"
+               r=`bin/ldbsearch $options $CONFIGURATION -H $p://$SERVER '(objectClass=*)' -b "${dn}" | grep 'dn: '`
+               n=`echo "${r}" | grep 'dn: ' | wc -l`
+               c=`echo "${r}" | grep "${object}" | wc -l`
+
+               if [ $n -lt 1 ]; then
+                       echo "Object not found by WKGUID"
+                       failed=`expr $failed + 1`
+                       continue
+               fi
+               if [ $c -lt 1 ]; then
+                       echo "Wrong object found by WKGUID: [${r}]"
+                       failed=`expr $failed + 1`
+                       continue
+               fi
+       done
+
+       return $failed
+}
+
+wellkown_object_test 22B70C67D56E4EFB91E9300FCA3DC1AA ForeignSecurityPrincipals
+st=$?
+if [ x"$st" != x"0" ]; then
+       failed=`expr $failed + $st`
+fi
+wellkown_object_test 2FBAC1870ADE11D297C400C04FD8D5CD Infrastructure
+st=$?
+if [ x"$st" != x"0" ]; then
+       failed=`expr $failed + $st`
+fi
+wellkown_object_test AB1D30F3768811D1ADED00C04FD8D5CD System
+st=$?
+if [ x"$st" != x"0" ]; then
+       failed=`expr $failed + $st`
+fi
+wellkown_object_test A361B2FFFFD211D1AA4B00C04FD7D83A Domain Controllers
+st=$?
+if [ x"$st" != x"0" ]; then
+       failed=`expr $failed + $st`
+fi
+wellkown_object_test AA312825768811D1ADED00C04FD8D5CD Computers
+st=$?
+if [ x"$st" != x"0" ]; then
+       failed=`expr $failed + $st`
+fi
+wellkown_object_test A9D1CA15768811D1ADED00C04FD8D5CD Users
+st=$?
+if [ x"$st" != x"0" ]; then
+       failed=`expr $failed + $st`
+fi
 
 exit $failed