* changed the way strings are handled in pidl to a much more general
authorAndrew Tridgell <tridge@samba.org>
Fri, 21 Nov 2003 13:14:17 +0000 (13:14 +0000)
committerAndrew Tridgell <tridge@samba.org>
Fri, 21 Nov 2003 13:14:17 +0000 (13:14 +0000)
  interface. We now support an arbitrary set of flags to each parser,
  and these can be used to control the string types. I have provided
  some common IDL string types in librpc/idl/idl_types.h which needs to
  be included in every IDL file.

* added IDL for the endpoint mapper. Added a test suite that enumerates
  all endpoints on the server.
(This used to be commit d2665f36a75b482ff82733f72ffac938c2acf87a)

24 files changed:
source4/Makefile.in
source4/build/pidl/NOTES.txt
source4/build/pidl/header.pm
source4/build/pidl/idl.gram
source4/build/pidl/parser.pm
source4/build/pidl/util.pm
source4/librpc/idl/atsvc.idl
source4/librpc/idl/dfs.idl
source4/librpc/idl/echo.idl
source4/librpc/idl/epmapper.idl [new file with mode: 0644]
source4/librpc/idl/eventlog.idl
source4/librpc/idl/lsa.idl
source4/librpc/idl/misc.idl
source4/librpc/idl/samr.idl
source4/librpc/idl/spoolss.idl
source4/librpc/idl/srvsvc.idl
source4/librpc/idl/winreg.idl
source4/librpc/idl/wkssvc.idl
source4/librpc/ndr/libndr.h
source4/librpc/ndr/ndr.c
source4/librpc/ndr/ndr_basic.c
source4/torture/rpc/epmapper.c [new file with mode: 0644]
source4/torture/rpc/samr.c
source4/torture/torture.c

index 0d577d93e10c301a684a6f2ca32aad0b19b49e7c..6614e4ebec780320050ea8d2a32a74b397fa0dda 100644 (file)
@@ -200,14 +200,15 @@ LIBRAW_NDR_OBJ = librpc/ndr/ndr.o librpc/ndr/ndr_basic.o librpc/ndr/ndr_sec.o \
                librpc/gen_ndr/ndr_samr.o librpc/gen_ndr/ndr_spoolss.o \
                librpc/gen_ndr/ndr_wkssvc.o librpc/gen_ndr/ndr_srvsvc.o \
                librpc/gen_ndr/ndr_atsvc.o librpc/gen_ndr/ndr_eventlog.o \
-               librpc/gen_ndr/ndr_winreg.o
+               librpc/gen_ndr/ndr_epmapper.o librpc/gen_ndr/ndr_winreg.o
 
 LIBRAW_RPC_OBJ = librpc/rpc/dcerpc.o librpc/rpc/dcerpc_smb.o \
                librpc/gen_rpc/rpc_echo.o librpc/gen_rpc/rpc_lsa.o \
                librpc/gen_rpc/rpc_dfs.o librpc/gen_rpc/rpc_spoolss.o \
                librpc/gen_rpc/rpc_samr.o librpc/gen_rpc/rpc_wkssvc.o \
                librpc/gen_rpc/rpc_srvsvc.o librpc/gen_rpc/rpc_atsvc.o \
-               librpc/gen_rpc/rpc_eventlog.o librpc/gen_rpc/rpc_winreg.o
+               librpc/gen_rpc/rpc_eventlog.o librpc/gen_rpc/rpc_epmapper.o \
+               librpc/gen_rpc/rpc_winreg.o
 
 LIBRAW_OBJ = libcli/raw/rawfile.o libcli/raw/smb_signing.o  \
             libcli/raw/clisocket.o libcli/raw/clitransport.o \
@@ -444,8 +445,8 @@ SMBTORTURE_RAW_OBJ = torture/raw/qfsinfo.o torture/raw/qfileinfo.o torture/raw/s
 
 SMBTORTURE_RPC_OBJ = torture/rpc/lsa.o torture/rpc/echo.o torture/rpc/dfs.o \
                torture/rpc/spoolss.o torture/rpc/samr.o torture/rpc/wkssvc.o \
-               torture/rpc/srvsvc.o torture/rpc/atsvc.o \
-               torture/rpc/eventlog.o torture/rpc/winreg.o
+               torture/rpc/srvsvc.o torture/rpc/atsvc.o torture/rpc/eventlog.o \
+               torture/rpc/epmapper.o torture/rpc/winreg.o
 
 SMBTORTURE_OBJ1 = torture/torture.o torture/torture_util.o torture/nbio.o torture/scanner.o \
                torture/utable.o torture/denytest.o torture/mangle_test.o \
index 4f729ecb952e1974188b0b295e9850fd713faefa..6210281244937da9a99124fae4a9848e2a0f1d8a 100644 (file)
@@ -64,6 +64,17 @@ midl.exe would write the above array as the following C header:
                long s[1];
        } Struct1;
 
+pidl takes a different approach, and writes it like this:
+
+       typedef struct {
+               long abc;
+               long count;     
+               long foo;
+               long *s;
+       } Struct1;
+
+
+
 VARYING ARRAYS
 --------------
 
index ec8b8451ad58a4644867b6dbec1dd969e797b1f8..25f0fecd47fe130b60c1ee64b30b56187650114e 100644 (file)
@@ -49,7 +49,8 @@ sub HeaderElement($)
     $res .= tabs();
     HeaderType($element, $element->{TYPE}, "");
     $res .= " ";
-    if ($element->{POINTERS}) {
+    if ($element->{POINTERS} && 
+       $element->{TYPE} ne "string") {
            my($n) = $element->{POINTERS};
            for (my($i)=$n; $i > 0; $i--) {
                    $res .= "*";
@@ -125,11 +126,7 @@ sub HeaderType($$$)
                    HeaderUnion($data, $name);
                return;
        }
-       if ($data =~ "unistr" ||
-           $data =~ "ascstr") {
-               $res .= "const char";
-       } elsif ($data =~ "nstring" ||
-                $data =~ "lstring") {
+       if ($data =~ "string") {
                $res .= "const char *";
        } elsif (util::is_scalar_type($data)) {
                $res .= "$data";
index d90c2238b4f318fb8c6fd4fdea8fe734ea6c30a6..ac373a5260d2fe96e267d8087111269c4666c387 100644 (file)
@@ -120,7 +120,8 @@ property: 'unique'
          | 'noprint'
          | 'relative'    
          | 'nodiscriminant'
-         | 'subcontext'
+          | 'subcontext' '(' constant ')' {{ "$item[1]" => "$item{constant}" }}
+          | 'flag' '(' anytext ')' {{ "$item[1]" => "$item{anytext}" }}
          | 'byte_count_pointer' '(' expression ')' {{ "$item[1]" => "$item{expression}" }}
           | 'size_is' '(' expression ')' {{ "$item[1]" => "$item{expression}" }}
           | 'length_is' '(' expression ')' {{ "$item[1]" => "$item{expression}" }}
@@ -153,7 +154,7 @@ type :
 
 text: /[\w\s\..?-]*/
 
-text2: /[\w\s\*\>\/\..?-]*/
+text2: /[\|\w\s\*\>\/\..?-]*/
 
 anytext: text2 '(' <commit> anytext ')' anytext
         {{ "$item[1]($item[4])$item[6]" }}
index 2438ef902acbfd546c0ac97deb7455dac19d89a0..c57610e9ae9dc55372876ab8145744d6149482a1 100644 (file)
@@ -42,6 +42,10 @@ sub find_sibling($$)
        my($name) = shift;
        my($fn) = $e->{PARENT};
 
+       if ($name =~ /\*(.*)/) {
+               $name = $1;
+       }
+
        if ($fn->{TYPE} eq "FUNCTION") {
                for my $e2 (@{$fn->{DATA}}) {
                        if ($e2->{NAME} eq $name) {
@@ -74,17 +78,24 @@ sub find_size_var($$)
                return $size;
        }
 
+       my $prefix = "";
+
+       if ($size =~ /\*(.*)/) {
+               $size = $1;
+               $prefix = "*";
+       }
+
        if ($fn->{TYPE} ne "FUNCTION") {
-               return "r->$size";
+               return $prefix . "r->$size";
        }
 
        my $e2 = find_sibling($e, $size);
 
        if (util::has_property($e2, "in")) {
-               return "r->in.$size";
+               return $prefix . "r->in.$size";
        }
        if (util::has_property($e2, "out")) {
-               return "r->out.$size";
+               return $prefix . "r->out.$size";
        }
 
        die "invalid variable in $size for element $e->{NAME} in $fn->{NAME}\n";
@@ -103,6 +114,30 @@ sub fn_prefix($)
 }
 
 
+###################################################################
+# setup any special flags for an element or structure
+sub start_flags($)
+{
+       my $e = shift;
+       my $flags = util::has_property($e, "flag");
+       if (defined $flags) {
+               pidl "\t{ uint32 _flags_save_$e->{TYPE} = ndr->flags;\n";
+               pidl "\tndr->flags |= $flags;\n";
+       }
+}
+
+###################################################################
+# end any special flags for an element or structure
+sub end_flags($)
+{
+       my $e = shift;
+       my $flags = util::has_property($e, "flag");
+       if (defined $flags) {
+               pidl "\tndr->flags = _flags_save_$e->{TYPE};\n\t}\n";
+       }
+}
+
+
 #####################################################################
 # work out the correct alignment for a structure
 sub struct_alignment
@@ -287,6 +322,8 @@ sub ParseElementPushScalar($$$)
        my($ndr_flags) = shift;
        my $cprefix = util::c_push_prefix($e);
 
+       start_flags($e);
+
        if (util::has_property($e, "relative")) {
                pidl "\tNDR_CHECK(ndr_push_relative(ndr, NDR_SCALARS, $var_prefix$e->{NAME}, (ndr_push_const_fn_t) ndr_push_$e->{TYPE}));\n";
        } elsif (util::is_inline_array($e)) {
@@ -304,6 +341,8 @@ sub ParseElementPushScalar($$$)
        } else {
                pidl "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
        }
+
+       end_flags($e);
 }
 
 #####################################################################
@@ -351,8 +390,9 @@ sub ParseElementPullSwitch($$$$)
                pidl "\t}\n";
        }
 
-       if (util::has_property($e, "subcontext")) {
-               pidl "\tNDR_CHECK(ndr_pull_subcontext_union_fn(ndr, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE}));\n";
+       my $sub_size = util::has_property($e, "subcontext");
+       if (defined $sub_size) {
+               pidl "\tNDR_CHECK(ndr_pull_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE}));\n";
        } else {
                pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n";
        }
@@ -378,8 +418,9 @@ sub ParseElementPushSwitch($$$$)
                pidl "\tNDR_CHECK(ndr_push_$e2->{TYPE}(ndr, $switch_var));\n";
        }
 
-       if (util::has_property($e, "subcontext")) {
-               pidl "\tNDR_CHECK(ndr_push_subcontext_union_fn(ndr, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_push_union_fn_t) ndr_pull_$e->{TYPE}));\n";
+       my $sub_size = util::has_property($e, "subcontext");
+       if (defined $sub_size) {
+               pidl "\tNDR_CHECK(ndr_push_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_push_union_fn_t) ndr_pull_$e->{TYPE}));\n";
        } else {
                pidl "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n";
        }
@@ -407,6 +448,9 @@ sub ParseElementPullScalar($$$)
        my($var_prefix) = shift;
        my($ndr_flags) = shift;
        my $cprefix = util::c_pull_prefix($e);
+       my $sub_size = util::has_property($e, "subcontext");
+
+       start_flags($e);
 
        if (util::has_property($e, "relative")) {
                pidl "\tNDR_CHECK(ndr_pull_relative(ndr, (const void **)&$var_prefix$e->{NAME}, sizeof(*$var_prefix$e->{NAME}), (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE}));\n";
@@ -425,17 +469,19 @@ sub ParseElementPullScalar($$$)
                # no scalar component
        } elsif (my $switch = util::has_property($e, "switch_is")) {
                ParseElementPullSwitch($e, $var_prefix, $ndr_flags, $switch);
-       } elsif (util::has_property($e, "subcontext")) {
+       } elsif (defined $sub_size) {
                if (util::is_builtin_type($e->{TYPE})) {
-                       pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n";
+                       pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n";
                } else {
-                       pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n";
+                       pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n";
                }
        } elsif (util::is_builtin_type($e->{TYPE})) {
                pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
        } else {
                pidl "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
        }
+
+       end_flags($e);
 }
 
 #####################################################################
@@ -451,6 +497,8 @@ sub ParseElementPushBuffer($$$)
                return;
        }
 
+       start_flags($e);
+
        if (util::need_wire_pointer($e)) {
                pidl "\tif ($var_prefix$e->{NAME}) {\n";
        }
@@ -478,6 +526,8 @@ sub ParseElementPushBuffer($$$)
        if (util::need_wire_pointer($e)) {
                pidl "\t}\n";
        }       
+
+       end_flags($e);
 }
 
 #####################################################################
@@ -514,6 +564,7 @@ sub ParseElementPullBuffer($$$)
        my($var_prefix) = shift;
        my($ndr_flags) = shift;
        my $cprefix = util::c_pull_prefix($e);
+       my $sub_size = util::has_property($e, "subcontext");
 
        if (util::is_pure_scalar($e)) {
                return;
@@ -523,6 +574,8 @@ sub ParseElementPullBuffer($$$)
                return;
        }
 
+       start_flags($e);
+
        if (util::need_wire_pointer($e)) {
                pidl "\tif ($var_prefix$e->{NAME}) {\n";
        }
@@ -537,11 +590,13 @@ sub ParseElementPullBuffer($$$)
                } else {
                        ParseElementPullSwitch($e, $var_prefix, "NDR_BUFFERS", $switch);
                }
-       } elsif (util::has_property($e, "subcontext")) {
-               if (util::is_builtin_type($e->{TYPE})) {
-                       pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n";
-               } else {
-                       pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n";
+       } elsif (defined $sub_size) {
+               if ($e->{POINTERS}) {
+                       if (util::is_builtin_type($e->{TYPE})) {
+                               pidl "\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n";
+                       } else {
+                               pidl "\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n";
+                       }
                }
        } elsif (util::is_builtin_type($e->{TYPE})) {
                pidl "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
@@ -554,6 +609,8 @@ sub ParseElementPullBuffer($$$)
        if (util::need_wire_pointer($e)) {
                pidl "\t}\n";
        }       
+
+       end_flags($e);
 }
 
 #####################################################################
@@ -562,11 +619,13 @@ sub ParseStructPush($)
 {
        my($struct) = shift;
        my $conform_e;
-
+       
        if (! defined $struct->{ELEMENTS}) {
                return;
        }
 
+       start_flags($struct);
+
        # see if the structure contains a conformant array. If it
        # does, then it must be the last element of the structure, and
        # we need to push the conformant length early, as it fits on
@@ -600,6 +659,8 @@ sub ParseStructPush($)
        }
 
        pidl "done:\n";
+
+       end_flags($struct);
 }
 
 #####################################################################
@@ -630,6 +691,8 @@ sub ParseStructPull($)
                return;
        }
 
+       start_flags($struct);
+
        # see if the structure contains a conformant array. If it
        # does, then it must be the last element of the structure, and
        # we need to pull the conformant length early, as it fits on
@@ -674,6 +737,8 @@ sub ParseStructPull($)
        }
 
        pidl "done:\n";
+
+       end_flags($struct);
 }
 
 
@@ -683,8 +748,10 @@ sub ParseUnionPush($)
 {
        my $e = shift;
        my $have_default = 0;
-       pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
 
+       start_flags($e);
+
+       pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
        pidl "\tNDR_CHECK(ndr_push_struct_start(ndr));\n";
 
 #      my $align = union_alignment($e);
@@ -729,6 +796,7 @@ sub ParseUnionPush($)
        }
        pidl "\t}\n";
        pidl "done:\n";
+       end_flags($e);
 }
 
 #####################################################################
@@ -764,6 +832,8 @@ sub ParseUnionPull($)
        my $e = shift;
        my $have_default = 0;
 
+       start_flags($e);
+
        pidl "\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
 
        pidl "\tNDR_CHECK(ndr_pull_struct_start(ndr));\n";
@@ -814,6 +884,7 @@ sub ParseUnionPull($)
        }
        pidl "\t}\n";
        pidl "done:\n";
+       end_flags($e);
 }
 
 #####################################################################
index 566253699df8641505c3540c30aa3951f98511dc..2f94d8001212fb151f203ee15672e8550d28b5f3 100644 (file)
@@ -149,7 +149,7 @@ sub has_property($$)
        my($p) = shift;
 
        if (!defined $e->{PROPERTIES}) {
-               return;
+               return undef;
        }
 
        my($props) = $e->{PROPERTIES};
@@ -168,7 +168,7 @@ sub has_property($$)
                }
        }
 
-    return undef;
+       return undef;
 }
 
 
@@ -222,8 +222,6 @@ sub is_builtin_type($)
     my($type) = shift;
 
     return 1, if (is_scalar_type($type));
-    return 1, if ($type =~ "unistr.*");
-    return 1, if ($type =~ "ascstr.*");
 
     return 0;
 }
@@ -304,6 +302,11 @@ sub need_alloc($)
 sub c_push_prefix($)
 {
        my $e = shift;
+
+       if ($e->{TYPE} =~ "string") {
+               return "";
+       }
+
        if (is_scalar_type($e->{TYPE}) &&
            $e->{POINTERS}) {
                return "*";
@@ -327,10 +330,7 @@ sub c_pull_prefix($)
                return "&";
        }
 
-       if ($e->{TYPE} =~ "unistr.*" ||
-           $e->{TYPE} =~ "nstring.*" ||
-           $e->{TYPE} =~ "ascstr.*" ||
-           $e->{TYPE} =~ "lstring.*") {
+       if ($e->{TYPE} =~ "string") {
                return "&";
        }
 
index 81394c747bc0fa0a90dbf6e034dfd088ef720f34..39add81b09a6568de87ee56a216239c6eab7bccb 100644 (file)
@@ -2,6 +2,8 @@
   atsvc interface definition
 */
 
+#include "idl_types.h"
+
 [ uuid(1ff70682-0a51-30e8-076d-740be8cee98b),
   version(1.0),
   pointer_default(unique)
index 8e8488e3671113b1be78e9996012cbaf65e77d2b..fd9e164ffa2aa8bb2bcc7453949fd95aea54d656 100644 (file)
@@ -2,6 +2,8 @@
   dfs interface definition
 */
 
+#include "idl_types.h"
+
 [ uuid(4fc742e0-4a10-11cf-8273-00aa004ae673),
   version(3.0),
   pointer_default(unique)
index 38650e990de1767c7ce079d00d420bfb0e981276..e6d93e52c425afe3e2ae58222f9bbe3612d87415 100644 (file)
@@ -1,3 +1,6 @@
+#include "idl_types.h"
+
+
 [
 uuid(60a15ec5-4de8-11d7-a637-005056a20182),
 version(1.0)
diff --git a/source4/librpc/idl/epmapper.idl b/source4/librpc/idl/epmapper.idl
new file mode 100644 (file)
index 0000000..c58ceb1
--- /dev/null
@@ -0,0 +1,134 @@
+#include "idl_types.h"
+
+/*
+  endpoint mapper interface
+*/
+
+[
+ uuid(e1af8308-5d1f-11c9-91a4-08002b14a0fa), 
+ version(3.0), 
+ pointer_default(unique)
+]
+interface epmapper
+{
+
+       typedef struct {
+               GUID uuid;
+               uint16 version;
+       } epm_prot_uuid;
+
+       typedef [nodiscriminant] union {
+               [case(13)] epm_prot_uuid uuid;
+               [default]  ;
+       } epm_protocol_info;
+
+       typedef struct {
+               uint8  protocol;
+               [switch_is(protocol)] epm_protocol_info info;
+       } epm_lhs;
+
+       typedef struct {
+               uint16 unknown;
+       } epm_rhs;
+
+       typedef struct {
+               [subcontext(2)] epm_lhs lhs;
+               [subcontext(2)] epm_rhs rhs;
+       } epm_floor;
+
+       typedef [flag(NDR_NOALIGN)] struct {
+               uint16 num_floors;
+               epm_floor floors[num_floors];
+       } epm_towers;
+
+       typedef struct {
+               uint32  tower_length;
+               [subcontext(4)] epm_towers towers;
+       } twr_t;
+
+       typedef struct {
+               GUID        object;
+               twr_t       *tower;
+               ascstr2     annotation;
+       } epm_entry_t;
+
+       typedef struct {
+               GUID                uuid;
+               uint16              vers_major;
+               uint16              vers_minor;
+       } rpc_if_id_t;
+    
+       /**********************/
+       /* Function 0x0       */
+       void epm_Insert(
+               [in]    uint32          num_ents,
+               [in,size_is(num_ents)]  epm_entry_t         entries[],
+               [in]    uint32    replace,
+               [out]   uint32    *status
+               );
+    
+       /**********************/
+       /* Function 0x1       */
+       void epm_Delete(
+               [in]     uint32          num_ents,
+               [in, size_is(num_ents)]  epm_entry_t entries[],
+               [out]    uint32          *status
+               );
+    
+       /**********************/
+       /* Function 0x02      */
+       void epm_Lookup(
+               [in]            uint32          inquiry_type,
+               [in]            GUID            *object,
+               [in]            rpc_if_id_t     *interface_id,
+               [in]            uint32          vers_option,
+               [in, out, ref]  policy_handle   *entry_handle,
+               [in]            uint32          max_ents,
+               [out]           uint32          num_ents,
+               [out, length_is(num_ents), size_is(max_ents)]  epm_entry_t entries[],
+               [out]           uint32          status
+               );
+
+
+       /**********************/
+       /* Function 0x03      */
+
+       typedef struct {
+               twr_t *twr;
+       } twr_p_t;
+
+       void epm_Map(
+               [in]            GUID            *object,
+               [in]            twr_t           *map_tower,
+               [in, out]       policy_handle   *entry_handle,
+               [in]            uint32          max_towers,
+               [out]           uint32          *num_towers,
+               [out, length_is(*num_towers), size_is(max_towers)]  twr_p_t towers[],
+               [out]           uint32          *status
+               );
+    
+
+       /**********************/
+       /* Function 0x04      */
+       void epm_LookupHandleFree(
+               [in, out]       policy_handle *entry_handle,
+               [out]           uint32        *status
+               );
+    
+       /**********************/
+       /* Function 0x05      */
+       void epm_InqObject(
+               [out]           GUID        *epm_object,
+               [out]           uint32      *status
+               );
+    
+
+       /**********************/
+       /* Function 0x05      */
+       void epm_MgmtDelete(
+               [in]            uint32   object_speced,
+               [in]            GUID     *object,
+               [in]            twr_t    *tower,
+               [out]           uint32   *status
+               );
+}
index a8eba4ae16e22f05d9ac1c52b77d1681d949d573..ee5bd8bba814e64c0e34415951a69d998df4578b 100644 (file)
@@ -1,3 +1,5 @@
+#include "idl_types.h"
+
 /*
   eventlog interface definition
 */
index 6aedd33b97fa4c84097105b5de81f368a8d7acfb..7b2de5bd8f48b82752f3e934c9a7d1aa2f6e03ed 100644 (file)
@@ -1,3 +1,5 @@
+#include "idl_types.h"
+
 /*
   lsa interface definition
 */
@@ -54,7 +56,7 @@
 
        typedef struct {
                uint32 size;
-               [subcontext] security_descriptor *sd;
+               [subcontext(4)] security_descriptor *sd;
        } sec_desc_buf;
 
        NTSTATUS lsa_QuerySecObj (
index 031ca89821adfca9a502cd85396f09bc4e47014c..04e03fc8147c0b2d846fbb23072f1f74ed92240e 100644 (file)
@@ -1,3 +1,5 @@
+#include "idl_types.h"
+
 /*
   miscellaneous IDL structures
 */
index 29ba402503e8f5e0932b8bc211fa16220923fd2e..bb0e85b7dee5426f30e02b0ccca6f41efb79cfd4 100644 (file)
@@ -1,6 +1,7 @@
+#include "idl_types.h"
+
 /*
   samr interface definition
-
 */
 
 /*
@@ -44,7 +45,7 @@
 
        typedef struct {
                uint32 sd_size;
-               [subcontext] security_descriptor *sd;
+               [subcontext(4)] security_descriptor *sd;
        } samr_SdBuf;
 
        NTSTATUS samr_QuerySecurity (
        /* Function    0x2b     */
        NTSTATUS samr_TEST_PRIVATE_FUNCTIONS_USER();
 
+
        /************************/
        /* Function    0x2c     */
-       NTSTATUS samr_GET_USRDOM_PWINFO();
+
+/*
+const ULONG DOMAIN_PASSWORD_COMPLEX = 0x00000001;
+const ULONG DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002;
+const ULONG DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004;
+const ULONG DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010;
+const ULONG DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020;
+*/
+       typedef struct {
+               uint16 min_pwd_len;
+               uint32 passwd_properties;
+       } samr_PwInfo;
+
+       NTSTATUS samr_GetUserPwInfo(
+               [in,ref]    policy_handle *handle,
+               [out]       samr_PwInfo info
+               );
 
        /************************/
        /* Function    0x2d     */
index 586536b69c13eabad23280abfe8c0d3b67ce39e8..a9d653458b2319ba7d009ac22ce7b1e0547d1e28 100644 (file)
@@ -1,3 +1,5 @@
+#include "idl_types.h"
+
 /*
   spoolss interface definitions
 */
                [in,ref]     policy_handle *handle,
                [in]         uint32 level,
                [in]         DATA_BLOB *buffer,
-               [out,subcontext,switch_is(level)] spoolss_PrinterInfo *info,
+               [out,subcontext(4),switch_is(level)] spoolss_PrinterInfo *info,
                [in,out,ref] uint32 *buf_size
                );
 
index 530b19d6cf380005244619243a08bcc8949516da..ac421d8626c3ecbf22a661f896f40b34f774cefa 100644 (file)
@@ -1,3 +1,5 @@
+#include "idl_types.h"
+
 /*
   srvsvc interface definitions
 */
                unistr *path;
                uint32 *password;
                uint32 unknown;
-               [subcontext] security_descriptor *sd;
+               [subcontext(4)] security_descriptor *sd;
        } srvsvc_NetShare502;
 
        typedef struct {
index 68b13f82458f55def05153e89610f84a335ab447..84250a61a5e580335919ee6f750725cd6385e05b 100644 (file)
@@ -1,3 +1,5 @@
+#include "idl_types.h"
+
 /*
   winreg interface definition
 */
index 2a1fb83f79be4322b997d76f619ea8d3b835fd6f..31e37d475977370a136898d30ca3ea0de48d4b8b 100644 (file)
@@ -1,3 +1,5 @@
+#include "idl_types.h"
+
 /*
   wkssvc interface definitions
 */
index 7876d3cc1cdf7b337296e08482f0a108578a487d..5c771ff2d225358eca57d6f5c83e6955325e5813 100644 (file)
@@ -91,8 +91,15 @@ struct ndr_print {
        void *private;
 };
 
-#define LIBNDR_FLAG_BIGENDIAN 1
+#define LIBNDR_FLAG_BIGENDIAN  (1<<0)
+#define LIBNDR_FLAG_NOALIGN    (1<<1)
 
+#define LIBNDR_FLAG_STR_ASCII    (1<<2)
+#define LIBNDR_FLAG_STR_LEN4     (1<<3)
+#define LIBNDR_FLAG_STR_SIZE4    (1<<4)
+#define LIBNDR_FLAG_STR_NOTERM   (1<<5)
+#define LIBNDR_FLAG_STR_NULLTERM (1<<6)
+#define LIBNDR_STRING_FLAGS      (0x7C)
 
 /* useful macro for debugging */
 #define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p)
@@ -110,7 +117,9 @@ enum ndr_err_code {
        NDR_ERR_OFFSET,
        NDR_ERR_RELATIVE,
        NDR_ERR_CHARCNV,
-       NDR_ERR_LENGTH
+       NDR_ERR_LENGTH,
+       NDR_ERR_SUBCONTEXT,
+       NDR_ERR_STRING
 };
 
 /*
@@ -133,7 +142,9 @@ enum ndr_err_code {
 } while(0)
 
 #define NDR_PULL_ALIGN(ndr, n) do { \
-       ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
+       if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \
+               ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
+       } \
        if (ndr->offset >= ndr->data_size) { \
                return NT_STATUS_BUFFER_TOO_SMALL; \
        } \
@@ -142,8 +153,10 @@ enum ndr_err_code {
 #define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n)))
 
 #define NDR_PUSH_ALIGN(ndr, n) do { \
-       uint32 _pad = (ndr->offset & (n-1)); \
-       while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \
+       if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \
+               uint32 _pad = (ndr->offset & (n-1)); \
+               while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \
+       } \
 } while(0)
 
 
@@ -201,4 +214,5 @@ typedef void (*ndr_print_union_fn_t)(struct ndr_print *, const char *, uint32, v
 #include "librpc/gen_ndr/ndr_srvsvc.h"
 #include "librpc/gen_ndr/ndr_atsvc.h"
 #include "librpc/gen_ndr/ndr_eventlog.h"
+#include "librpc/gen_ndr/ndr_epmapper.h"
 #include "librpc/gen_ndr/ndr_winreg.h"
index 2f0754d78fdb3b6c91e0bc32518efd4c7e8c411f..dcd0066083e885ae8cc9dd7bc5a0636b9266f2eb 100644 (file)
@@ -61,6 +61,7 @@ NTSTATUS ndr_pull_subcontext(struct ndr_pull *ndr, struct ndr_pull *ndr2, uint32
        ndr2->data += ndr2->offset;
        ndr2->offset = 0;
        ndr2->data_size = size;
+       ndr2->flags = ndr->flags;
        return NT_STATUS_OK;
 }
 
@@ -396,57 +397,98 @@ NTSTATUS ndr_push_error(struct ndr_push *ndr, enum ndr_err_code err, const char
 }
 
 
+/*
+  handle subcontext buffers, which in midl land are user-marshalled, but
+  we use magic in pidl to make them easier to cope with
+*/
+static NTSTATUS ndr_pull_subcontext_header(struct ndr_pull *ndr, 
+                                          size_t sub_size,
+                                          struct ndr_pull *ndr2)
+{
+       switch (sub_size) {
+       case 0: {
+               uint32 size = ndr->data_size - ndr->offset;
+               if (size == 0) return NT_STATUS_OK;
+               NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size));
+               break;
+       }
+
+       case 2: {
+               uint16 size;
+               NDR_CHECK(ndr_pull_uint16(ndr, &size));
+               if (size == 0) return NT_STATUS_OK;
+               NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size));
+               break;
+       }
+
+       case 4: {
+               uint32 size;
+               NDR_CHECK(ndr_pull_uint32(ndr, &size));
+               if (size == 0) return NT_STATUS_OK;
+               NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, size));
+               break;
+       }
+       default:
+               return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext size %d", 
+                                     sub_size);
+       }
+       return NT_STATUS_OK;
+}
+
 /*
   handle subcontext buffers, which in midl land are user-marshalled, but
   we use magic in pidl to make them easier to cope with
 */
 NTSTATUS ndr_pull_subcontext_fn(struct ndr_pull *ndr, 
+                               size_t sub_size,
                                void *base,
                                NTSTATUS (*fn)(struct ndr_pull *, void *))
 {
-       uint32 size;
        struct ndr_pull ndr2;
 
-       NDR_CHECK(ndr_pull_uint32(ndr, &size));
-       NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, size));
+       NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2));
        NDR_CHECK(fn(&ndr2, base));
-       NDR_CHECK(ndr_pull_advance(ndr, size));
+       if (sub_size) {
+               NDR_CHECK(ndr_pull_advance(ndr, ndr2.data_size));
+       } else {
+               NDR_CHECK(ndr_pull_advance(ndr, ndr2.offset));
+       }
        return NT_STATUS_OK;
 }
 
 
 NTSTATUS ndr_pull_subcontext_flags_fn(struct ndr_pull *ndr, 
+                                     size_t sub_size,
                                      void *base,
                                      NTSTATUS (*fn)(struct ndr_pull *, int , void *))
 {
-       uint32 size;
        struct ndr_pull ndr2;
 
-       NDR_CHECK(ndr_pull_uint32(ndr, &size));
-       if (size == 0) {
-               return NT_STATUS_OK;
-       }
-       NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, size));
+       NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2));
        NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, base));
-       NDR_CHECK(ndr_pull_advance(ndr, size));
+       if (sub_size) {
+               NDR_CHECK(ndr_pull_advance(ndr, ndr2.data_size));
+       } else {
+               NDR_CHECK(ndr_pull_advance(ndr, ndr2.offset));
+       }
        return NT_STATUS_OK;
 }
 
 NTSTATUS ndr_pull_subcontext_union_fn(struct ndr_pull *ndr, 
+                                     size_t sub_size,
                                      uint32 level,
                                      void *base,
                                      NTSTATUS (*fn)(struct ndr_pull *, int , uint32 , void *))
 {
-       uint32 size;
        struct ndr_pull ndr2;
 
-       NDR_CHECK(ndr_pull_uint32(ndr, &size));
-       if (size == 0) {
-               return NT_STATUS_OK;
-       }
-       NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, size));
+       NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2));
        NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, level, base));
-       NDR_CHECK(ndr_pull_advance(ndr, size));
+       if (sub_size) {
+               NDR_CHECK(ndr_pull_advance(ndr, ndr2.data_size));
+       } else {
+               NDR_CHECK(ndr_pull_advance(ndr, ndr2.offset));
+       }
        return NT_STATUS_OK;
 }
 
index 49cff11480d6b744a5565c5061ecddf08784d9d6..56c0ab231ecc8845665455cd33bebf7c2ac1a860 100644 (file)
@@ -314,119 +314,219 @@ NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p)
                   which means we can handle the case where a MS programmer
                   forgot to mark a pointer as unique */
                ndr->ptr_count++;
-               ptr = 0xaabbcc00 + ndr->ptr_count;
+               ptr = ndr->ptr_count;
        }
        return ndr_push_uint32(ndr, ptr);
 }
 
-/*
-  push a comformant, variable ucs2 string onto the wire from a C string
-*/
-NTSTATUS ndr_push_unistr(struct ndr_push *ndr, const char *s)
-{
-       char *ws;
-       ssize_t len;
-       len = push_ucs2_talloc(ndr->mem_ctx, (smb_ucs2_t **)&ws, s);
-       if (len == -1) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-       NDR_CHECK(ndr_push_uint32(ndr, len/2));
-       NDR_CHECK(ndr_push_uint32(ndr, 0));
-       NDR_CHECK(ndr_push_uint32(ndr, len/2));
-       NDR_CHECK(ndr_push_bytes(ndr, ws, len));
-       return NT_STATUS_OK;
-}
 
 /*
-  push a comformant, variable ascii string onto the wire from a C string
-  TODO: need to look at what charset this should be in
+  pull a general string from the wire
 */
-NTSTATUS ndr_push_ascstr(struct ndr_push *ndr, const char *s)
+NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
 {
-       ssize_t len = s?strlen(s):0;
-       NDR_CHECK(ndr_push_uint32(ndr, len));
-       NDR_CHECK(ndr_push_uint32(ndr, 0));
-       NDR_CHECK(ndr_push_uint32(ndr, len?len+1:0));
-       if (s) {
-               NDR_CHECK(ndr_push_bytes(ndr, s, len));
+       char *as=NULL;
+       uint32 len1, ofs, len2;
+       int ret;
+
+       if (!(ndr_flags & NDR_SCALARS)) {
+               return NT_STATUS_OK;
        }
-       return NT_STATUS_OK;
-}
 
-/*
-  push a comformant, variable ucs2 string onto the wire from a C string
-  don't send the null
-*/
-NTSTATUS ndr_push_unistr_noterm(struct ndr_push *ndr, const char *s)
-{
-       char *ws;
-       ssize_t len;
-       len = push_ucs2_talloc(ndr->mem_ctx, (smb_ucs2_t **)&ws, s);
-       if (len == -1) {
-               return NT_STATUS_INVALID_PARAMETER;
+       switch (ndr->flags & LIBNDR_STRING_FLAGS) {
+       case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
+       case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
+               NDR_CHECK(ndr_pull_uint32(ndr, &len1));
+               NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
+               NDR_CHECK(ndr_pull_uint32(ndr, &len2));
+               if (len2 > len1) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               if (len2 == 0) {
+                       *s = talloc_strdup(ndr->mem_ctx, "");
+                       break;
+               }
+               NDR_PULL_NEED_BYTES(ndr, len2*2);
+               ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, 
+                                           ndr->data+ndr->offset, 
+                                           len2*2,
+                                           (const void **)&as);
+               if (ret == -1) {
+                       return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               NDR_CHECK(ndr_pull_advance(ndr, len2*2));
+               *s = as;
+               break;
+
+       case LIBNDR_FLAG_STR_SIZE4:
+               NDR_CHECK(ndr_pull_uint32(ndr, &len1));
+               NDR_PULL_NEED_BYTES(ndr, len1*2);
+               if (len1 == 0) {
+                       *s = talloc_strdup(ndr->mem_ctx, "");
+                       break;
+               }
+               ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, 
+                                           ndr->data+ndr->offset, 
+                                           len1*2,
+                                           (const void **)&as);
+               if (ret == -1) {
+                       return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               NDR_CHECK(ndr_pull_advance(ndr, len1*2));
+               *s = as;
+               break;
+
+       case LIBNDR_FLAG_STR_NULLTERM:
+               ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, 
+                                           ndr->data+ndr->offset, 
+                                           ndr->data_size - ndr->offset,
+                                           (const void **)s);
+               if (ret == -1) {
+                       return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               NDR_CHECK(ndr_pull_advance(ndr, ret));
+               break;
+
+       case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
+               NDR_CHECK(ndr_pull_uint32(ndr, &len1));
+               NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
+               NDR_CHECK(ndr_pull_uint32(ndr, &len2));
+               if (len2 > len1) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               NDR_ALLOC_N(ndr, as, (len2+1));
+               NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
+               as[len2] = 0;
+               (*s) = as;
+               break;
+
+       case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
+               NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
+               NDR_CHECK(ndr_pull_uint32(ndr, &len2));
+               NDR_ALLOC_N(ndr, as, (len2+1));
+               NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
+               as[len2] = 0;
+               (*s) = as;
+               break;
+
+       default:
+               return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
+                                     ndr->flags & LIBNDR_STRING_FLAGS);
        }
-       NDR_CHECK(ndr_push_uint32(ndr, len/2 - 1));
-       NDR_CHECK(ndr_push_uint32(ndr, 0));
-       NDR_CHECK(ndr_push_uint32(ndr, len/2 - 1));
-       NDR_CHECK(ndr_push_bytes(ndr, ws, len - 2));
+
        return NT_STATUS_OK;
 }
 
+
 /*
-  pull a comformant, variable ucs2 string from the wire into a C string
+  push a general string onto the wire
 */
-NTSTATUS ndr_pull_unistr(struct ndr_pull *ndr, const char **s)
+NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
 {
-       char *ws, *as=NULL;
-       uint32 len1, ofs, len2;
+       ssize_t s_len, c_len;
+       int ret;
 
-       NDR_CHECK(ndr_pull_uint32(ndr, &len1));
-       NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
-       NDR_CHECK(ndr_pull_uint32(ndr, &len2));
-       if (len2 > len1) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-       NDR_ALLOC_N(ndr, ws, (len1+1)*2);
-       NDR_CHECK(ndr_pull_bytes(ndr, ws, len2*2));
-       SSVAL(ws, len1*2, 0);
-       SSVAL(ws, len2*2, 0);
-       pull_ucs2_talloc(ndr->mem_ctx, &as, (const smb_ucs2_t *)ws);
-       if (!as) {
-               return NT_STATUS_INVALID_PARAMETER;
+       if (!(ndr_flags & NDR_SCALARS)) {
+               return NT_STATUS_OK;
        }
-       *s = as;
-       return NT_STATUS_OK;
-}
+       
+       s_len = s?strlen(s):0;
+       c_len = s?strlen_m(s):0;
 
-/*
-  pull a comformant, variable ascii string from the wire into a C string
-  TODO: check what charset this is in
-*/
-NTSTATUS ndr_pull_ascstr(struct ndr_pull *ndr, const char **s)
-{
-       uint32 len1, ofs, len2;
-       char *as;
+       switch (ndr->flags & LIBNDR_STRING_FLAGS) {
+       case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
+               NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
+               NDR_CHECK(ndr_push_uint32(ndr, 0));
+               NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
+               NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
+               ret = convert_string(CH_UNIX, CH_UCS2, 
+                                    s, s_len+1,
+                                    ndr->data+ndr->offset, c_len*2 + 2);
+               if (ret == -1) {
+                       return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               ndr->offset += c_len*2 + 2;
+               break;
+
+       case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
+               NDR_CHECK(ndr_push_uint32(ndr, c_len));
+               NDR_CHECK(ndr_push_uint32(ndr, 0));
+               NDR_CHECK(ndr_push_uint32(ndr, c_len));
+               NDR_PUSH_NEED_BYTES(ndr, c_len*2);
+               ret = convert_string(CH_UNIX, CH_UCS2, 
+                                    s, s_len,
+                                    ndr->data+ndr->offset, c_len*2);
+               if (ret == -1) {
+                       return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               ndr->offset += c_len*2;
+               break;
+
+       case LIBNDR_FLAG_STR_SIZE4:
+               NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
+               NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
+               ret = convert_string(CH_UNIX, CH_UCS2, 
+                                    s, s_len + 1,
+                                    ndr->data+ndr->offset, c_len*2 + 2);
+               if (ret == -1) {
+                       return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               ndr->offset += c_len*2 + 2;
+               break;
+
+       case LIBNDR_FLAG_STR_NULLTERM:
+               NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
+               ret = convert_string(CH_UNIX, CH_UCS2, 
+                                    s, s_len+1,
+                                    ndr->data+ndr->offset, c_len*2 + 2);
+               if (ret == -1) {
+                       return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               ndr->offset += c_len*2 + 2;
+               break;
+               
+       case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
+               NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
+               NDR_CHECK(ndr_push_uint32(ndr, 0));
+               NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
+               NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
+               ret = convert_string(CH_UNIX, CH_DOS, 
+                                    s, s_len + 1,
+                                    ndr->data+ndr->offset, c_len + 1);
+               if (ret == -1) {
+                       return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               ndr->offset += c_len + 1;
+               break;
+
+       case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
+               NDR_CHECK(ndr_push_uint32(ndr, 0));
+               NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
+               NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
+               ret = convert_string(CH_UNIX, CH_DOS, 
+                                    s, s_len + 1,
+                                    ndr->data+ndr->offset, c_len + 1);
+               if (ret == -1) {
+                       return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
+                                             "Bad character conversion");
+               }
+               ndr->offset += c_len + 1;
+               break;
 
-       NDR_CHECK(ndr_pull_uint32(ndr, &len1));
-       NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
-       NDR_CHECK(ndr_pull_uint32(ndr, &len2));
-       if (len2 > len1) {
-               return NT_STATUS_INVALID_PARAMETER;
+       default:
+               return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
+                                     ndr->flags & LIBNDR_STRING_FLAGS);
        }
-       NDR_ALLOC_N(ndr, as, (len1+1));
-       NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
-       as[len2] = 0;
-       as[len1] = 0;
-       (*s) = as;
-       return NT_STATUS_OK;
-}
 
-/*
-  pull a comformant, variable ucs2 string from the wire into a C string
-*/
-NTSTATUS ndr_pull_unistr_noterm(struct ndr_pull *ndr, const char **s)
-{
-       return ndr_pull_unistr(ndr, s);
+       return NT_STATUS_OK;
 }
 
 /*
@@ -523,7 +623,7 @@ void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
        }
 }
 
-void ndr_print_unistr(struct ndr_print *ndr, const char *name, const char *s)
+void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
 {
        if (s) {
                ndr->print(ndr, "%-25s: '%s'", name, s);
@@ -532,16 +632,6 @@ void ndr_print_unistr(struct ndr_print *ndr, const char *name, const char *s)
        }
 }
 
-void ndr_print_unistr_noterm(struct ndr_print *ndr, const char *name, const char *s)
-{
-       ndr_print_unistr(ndr, name, s);
-}
-
-void ndr_print_ascstr(struct ndr_print *ndr, const char *name, const char *s)
-{
-       ndr_print_unistr(ndr, name, s);
-}
-
 void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
 {
        ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr->mem_ctx, &t));
@@ -603,122 +693,6 @@ void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *
                   guid->info[14], guid->info[15]);
 }
 
-
-/*
-  pull a null terminated UCS2 string
-*/
-NTSTATUS ndr_pull_nstring(struct ndr_pull *ndr, int ndr_flags, const char **s)
-{
-       int ret;
-
-       if (!(ndr_flags & NDR_SCALARS)) {
-               return NT_STATUS_OK;
-       }
-
-       ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, 
-                                   ndr->data+ndr->offset, 
-                                   ndr->data_size - ndr->offset,
-                                   (const void **)s);
-       if (ret == -1) {
-               return ndr_pull_error(ndr, NDR_ERR_CHARCNV, "Bad character conversion");
-       }
-       ndr->offset += ret;
-       return NT_STATUS_OK;
-}
-
-/*
-  pull a length prefixed UCS2 string
-*/
-NTSTATUS ndr_pull_lstring(struct ndr_pull *ndr, int ndr_flags, const char **s)
-{
-       int ret;
-       uint32 size;
-
-       if (!(ndr_flags & NDR_SCALARS)) {
-               return NT_STATUS_OK;
-       }
-
-       NDR_CHECK(ndr_pull_uint32(ndr, &size));
-       if (size == 0) {
-               *s = NULL;
-               return NT_STATUS_OK;
-       }
-
-       NDR_PULL_NEED_BYTES(ndr, size*2);
-
-       ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, 
-                                   ndr->data+ndr->offset, 
-                                   size*2,
-                                   (const void **)s);
-       if (ret == -1) {
-               return ndr_pull_error(ndr, NDR_ERR_CHARCNV, "Bad character conversion");
-       }
-       ndr->offset += size*2;
-       return NT_STATUS_OK;
-}
-
-/*
-  push a spoolss style "relative string"
-*/
-NTSTATUS ndr_push_nstring(struct ndr_push *ndr, int ndr_flags, const char **s)
-{
-       uint32 len;
-       int ret;
-
-       if (!(ndr_flags & NDR_SCALARS)) {
-               return NT_STATUS_OK;
-       }
-
-       len = 2*(strlen_m(*s)+1);
-       NDR_PUSH_NEED_BYTES(ndr, len);
-       ret = push_ucs2(NULL, ndr->data + ndr->offset, *s, len, STR_TERMINATE);
-       if (ret == -1) {
-               return ndr_push_error(ndr, NDR_ERR_CHARCNV, "Bad string conversion");
-       }
-       ndr->offset += len;
-       return NT_STATUS_OK;
-}
-
-/*
-  push a length prefixed ucs2 string
-*/
-NTSTATUS ndr_push_lstring(struct ndr_push *ndr, int ndr_flags, const char **s)
-{
-       uint32 len;
-       int ret;
-
-       if (!(ndr_flags & NDR_SCALARS)) {
-               return NT_STATUS_OK;
-       }
-
-       if (! *s) {
-               NDR_CHECK(ndr_push_uint32(ndr, 0));
-               return NT_STATUS_OK;
-       }
-
-       len = (strlen_m(*s)+1);
-
-       NDR_CHECK(ndr_push_uint32(ndr, len));
-       NDR_PUSH_NEED_BYTES(ndr, len*2);
-
-       ret = push_ucs2(NULL, ndr->data + ndr->offset, *s, len*2, STR_TERMINATE);
-       if (ret == -1) {
-               return ndr_push_error(ndr, NDR_ERR_CHARCNV, "Bad string conversion");
-       }
-       ndr->offset += len*2;
-       return NT_STATUS_OK;
-}
-
-void ndr_print_nstring(struct ndr_print *ndr, const char *name, const char **s)
-{
-       ndr_print_unistr(ndr, name, *s);
-}
-
-void ndr_print_lstring(struct ndr_print *ndr, const char *name, const char **s)
-{
-       ndr_print_unistr(ndr, name, *s);
-}
-
 void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
 {
        ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, r.length);
diff --git a/source4/torture/rpc/epmapper.c b/source4/torture/rpc/epmapper.c
new file mode 100644 (file)
index 0000000..0e4e5e0
--- /dev/null
@@ -0,0 +1,87 @@
+/* 
+   Unix SMB/CIFS implementation.
+   test suite for epmapper rpc operations
+
+   Copyright (C) Andrew Tridgell 2003
+   
+   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 2 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+static BOOL test_Lookup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+{
+       NTSTATUS status;
+       struct epm_Lookup r;
+       struct GUID uuid;
+       struct rpc_if_id_t iface;
+       struct policy_handle handle;
+
+       ZERO_STRUCT(uuid);
+       ZERO_STRUCT(iface);
+       ZERO_STRUCT(handle);
+
+       r.in.inquiry_type = 0;
+       r.in.object = &uuid;
+       r.in.interface_id = &iface;
+       r.in.vers_option = 0;
+       r.in.entry_handle = &handle;
+       r.out.entry_handle = &handle;
+       r.in.max_ents = 1;
+
+       do {
+               status = dcerpc_epm_Lookup(p, mem_ctx, &r);
+               if (NT_STATUS_IS_OK(status) && r.out.status == 0) {
+                       printf("Found '%s'\n", r.out.entries[0].annotation);
+               }
+       } while (NT_STATUS_IS_OK(status) && r.out.status == 0);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Lookup failed - %s\n", nt_errstr(status));
+               return False;
+       }
+
+
+       return True;
+}
+
+BOOL torture_rpc_epmapper(int dummy)
+{
+        NTSTATUS status;
+        struct dcerpc_pipe *p;
+       TALLOC_CTX *mem_ctx;
+       BOOL ret = True;
+
+       mem_ctx = talloc_init("torture_rpc_epmapper");
+
+       status = torture_rpc_connection(&p, 
+                                       DCERPC_EPMAPPER_NAME,
+                                       DCERPC_EPMAPPER_UUID,
+                                       DCERPC_EPMAPPER_VERSION);
+       if (!NT_STATUS_IS_OK(status)) {
+               return False;
+       }
+       
+       p->flags |= DCERPC_DEBUG_PRINT_BOTH;
+
+       if (!test_Lookup(p, mem_ctx)) {
+               ret = False;
+       }
+
+        torture_rpc_close(p);
+
+       return ret;
+}
index 047da518b3440370f27f303f7a3b5dccb02027ff..d825ddb02c8fec5a39d8fb594e019fcc1217b2a4 100644 (file)
@@ -202,6 +202,26 @@ static BOOL test_SetUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        return ret;
 }
 
+static BOOL test_GetUserPwInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+                              struct policy_handle *handle)
+{
+       NTSTATUS status;
+       struct samr_GetUserPwInfo r;
+       BOOL ret = True;
+
+       printf("Testing GetUserPwInfo\n");
+
+       r.in.handle = handle;
+
+       status = dcerpc_samr_GetUserPwInfo(p, mem_ctx, &r);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("GetUserPwInfo failed - %s\n", nt_errstr(status));
+               ret = False;
+       }
+
+       return ret;
+}
+
 
 static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
                          struct policy_handle *handle)
@@ -220,6 +240,10 @@ static BOOL test_user_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                ret = False;
        }       
 
+       if (!test_GetUserPwInfo(p, mem_ctx, handle)) {
+               ret = False;
+       }
+
        return ret;
 }
 
@@ -434,6 +458,10 @@ static BOOL test_OpenUser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                ret = False;
        }
 
+       if (!test_GetUserPwInfo(p, mem_ctx, &acct_handle)) {
+               ret = False;
+       }
+
        if (!test_Close(p, mem_ctx, &acct_handle)) {
                ret = False;
        }
index 25602e3a839af7f616f02d1524fc1b5ef516da1a..105abcf9ebf7d9cba7029b8cb2c6f2ede18d8c30 100644 (file)
@@ -3996,6 +3996,7 @@ static struct {
         {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
         {"RPC-ATSVC", torture_rpc_atsvc, 0},
         {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
+        {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
         {"RPC-WINREG", torture_rpc_winreg, 0},
        {NULL, NULL, 0}};