summaryrefslogtreecommitdiffstats
path: root/source/librpc
diff options
context:
space:
mode:
authorCVS Import User <samba-bugs@samba.org>2004-04-04 11:51:10 +0000
committerCVS Import User <samba-bugs@samba.org>2004-04-04 11:51:10 +0000
commite3d2dbdff6711b0bc768fb6b08f41240f21d5fba (patch)
tree159ef54b59b18e9b950f5c6af105915214244912 /source/librpc
parent139b1658ca30692835c1a7203c7cd003e587ac12 (diff)
downloadsamba-e3d2dbdff6711b0bc768fb6b08f41240f21d5fba.tar.gz
samba-e3d2dbdff6711b0bc768fb6b08f41240f21d5fba.tar.xz
samba-e3d2dbdff6711b0bc768fb6b08f41240f21d5fba.zip
r6: merge in the samba4 HEAD branch from cvs
to checkout try: svn co svn+ssh://svn.samba.org/home/svn/samba/branches/SAMBA_4_0 metze
Diffstat (limited to 'source/librpc')
-rw-r--r--source/librpc/.cvsignore2
-rw-r--r--source/librpc/config.m436
-rw-r--r--source/librpc/idl/.cvsignore2
-rw-r--r--source/librpc/idl/atsvc.idl67
-rw-r--r--source/librpc/idl/browser.idl10
-rw-r--r--source/librpc/idl/dcerpc.idl189
-rw-r--r--source/librpc/idl/dcom.idl43
-rw-r--r--source/librpc/idl/dfs.idl174
-rw-r--r--source/librpc/idl/echo.idl90
-rw-r--r--source/librpc/idl/epmapper.idl168
-rw-r--r--source/librpc/idl/eventlog.idl48
-rw-r--r--source/librpc/idl/idl_types.h72
-rw-r--r--source/librpc/idl/keysvc.idl15
-rw-r--r--source/librpc/idl/lsa.idl500
-rw-r--r--source/librpc/idl/mgmt.idl74
-rw-r--r--source/librpc/idl/misc.idl79
-rw-r--r--source/librpc/idl/netlogon.idl796
-rw-r--r--source/librpc/idl/ntsvcs.idl15
-rw-r--r--source/librpc/idl/protected_storage.idl15
-rw-r--r--source/librpc/idl/samr.idl894
-rw-r--r--source/librpc/idl/scerpc.idl16
-rw-r--r--source/librpc/idl/spoolss.idl843
-rw-r--r--source/librpc/idl/srvsvc.idl1241
-rw-r--r--source/librpc/idl/trkwks.idl15
-rw-r--r--source/librpc/idl/w32time.idl16
-rw-r--r--source/librpc/idl/winreg.idl299
-rw-r--r--source/librpc/idl/wkssvc.idl249
-rw-r--r--source/librpc/idl/wzcsvc.idl15
-rw-r--r--source/librpc/ndr/libndr.h246
-rw-r--r--source/librpc/ndr/ndr.c766
-rw-r--r--source/librpc/ndr/ndr_basic.c868
-rw-r--r--source/librpc/ndr/ndr_sec.c185
-rw-r--r--source/librpc/ndr/ndr_sec.h56
-rw-r--r--source/librpc/ndr/ndr_spoolss_buf.c93
-rw-r--r--source/librpc/rpc/dcerpc.c860
-rw-r--r--source/librpc/rpc/dcerpc.h117
-rw-r--r--source/librpc/rpc/dcerpc_auth.c43
-rw-r--r--source/librpc/rpc/dcerpc_lsa.c79
-rw-r--r--source/librpc/rpc/dcerpc_ntlm.c197
-rw-r--r--source/librpc/rpc/dcerpc_schannel.c266
-rw-r--r--source/librpc/rpc/dcerpc_smb.c391
-rw-r--r--source/librpc/rpc/dcerpc_tcp.c206
-rw-r--r--source/librpc/rpc/dcerpc_util.c668
43 files changed, 11024 insertions, 0 deletions
diff --git a/source/librpc/.cvsignore b/source/librpc/.cvsignore
new file mode 100644
index 00000000000..ca42d5444c1
--- /dev/null
+++ b/source/librpc/.cvsignore
@@ -0,0 +1,2 @@
+gen_ndr
+gen_rpc
diff --git a/source/librpc/config.m4 b/source/librpc/config.m4
new file mode 100644
index 00000000000..a4e5fa27fac
--- /dev/null
+++ b/source/librpc/config.m4
@@ -0,0 +1,36 @@
+dnl # LIBRPC subsystem
+
+SMB_SUBSYSTEM(LIBNDR_RAW,[],
+ [librpc/ndr/ndr.o librpc/ndr/ndr_basic.o librpc/ndr/ndr_sec.o \
+ librpc/ndr/ndr_spoolss_buf.o \
+ librpc/gen_ndr/tables.o librpc/gen_ndr/ndr_dcerpc.o \
+ librpc/gen_ndr/ndr_echo.o librpc/gen_ndr/ndr_misc.o \
+ librpc/gen_ndr/ndr_lsa.o librpc/gen_ndr/ndr_dfs.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_epmapper.o librpc/gen_ndr/ndr_winreg.o \
+ librpc/gen_ndr/ndr_mgmt.o librpc/gen_ndr/ndr_protected_storage.o \
+ librpc/gen_ndr/ndr_dcom.o librpc/gen_ndr/ndr_wzcsvc.o \
+ librpc/gen_ndr/ndr_browser.o librpc/gen_ndr/ndr_w32time.o \
+ librpc/gen_ndr/ndr_scerpc.o librpc/gen_ndr/ndr_ntsvcs.o \
+ librpc/gen_ndr/ndr_netlogon.o librpc/gen_ndr/ndr_trkwks.o \
+ librpc/gen_ndr/ndr_keysvc.o],
+ librpc/gen_ndr/libndr_raw_public_proto.h)
+
+SMB_SUBSYSTEM(LIBRPC_RAW,[],
+ [librpc/rpc/dcerpc.o librpc/rpc/dcerpc_auth.o \
+ librpc/rpc/dcerpc_util.o \
+ librpc/rpc/dcerpc_schannel.o librpc/rpc/dcerpc_ntlm.o \
+ librpc/rpc/dcerpc_smb.o librpc/rpc/dcerpc_tcp.o],
+ librpc/rpc/librpc_raw_public_proto.h)
+
+SMB_SUBSYSTEM(LIBRPC_CLIENT,[],
+ [librpc/rpc/dcerpc_lsa.o],
+ librpc/rpc/librpc/client/public_proto.h)
+
+SMB_SUBSYSTEM(LIBRPC,[],
+ [\$(LIBNDR_RAW_OBJS) \$(LIBRPC_RAW_OBJS) \
+ \$(LIBRPC_CLIENT_OBJS)],
+ librpc/librpc_public_proto.h)
+
diff --git a/source/librpc/idl/.cvsignore b/source/librpc/idl/.cvsignore
new file mode 100644
index 00000000000..b8252381b81
--- /dev/null
+++ b/source/librpc/idl/.cvsignore
@@ -0,0 +1,2 @@
+*.pidl
+*.c
diff --git a/source/librpc/idl/atsvc.idl b/source/librpc/idl/atsvc.idl
new file mode 100644
index 00000000000..e221875f9fb
--- /dev/null
+++ b/source/librpc/idl/atsvc.idl
@@ -0,0 +1,67 @@
+/*
+ atsvc interface definition
+*/
+
+#include "idl_types.h"
+
+[ uuid(1ff70682-0a51-30e8-076d-740be8cee98b),
+ version(1.0),
+ pointer_default(unique)
+] interface atsvc
+{
+ typedef struct {
+ uint32 job_time;
+ uint32 days_of_month;
+ uint8 days_of_week;
+ uint8 flags;
+ unistr *command;
+ } atsvc_JobInfo;
+
+ /******************/
+ /* Function: 0x00 */
+ NTSTATUS atsvc_JobAdd(
+ [in] unistr *servername,
+ [in,ref] atsvc_JobInfo *job_info,
+ [out] uint32 job_id
+ );
+
+ /******************/
+ /* Function: 0x01 */
+ NTSTATUS atsvc_JobDel(
+ [in] unistr *servername,
+ [in] uint32 min_job_id,
+ [in] uint32 max_job_id
+ );
+
+ typedef struct {
+ uint32 job_id;
+ uint32 job_time;
+ uint32 days_of_month;
+ uint8 days_of_week;
+ uint8 flags;
+ unistr *command;
+ } atsvc_JobEnumInfo;
+
+ typedef struct {
+ uint32 entries_read;
+ [size_is(entries_read)] atsvc_JobEnumInfo *first_entry;
+ } atsvc_enum_ctr;
+
+ /******************/
+ /* Function: 0x02 */
+ NTSTATUS atsvc_JobEnum(
+ [in] unistr *servername,
+ [in,out,ref] atsvc_enum_ctr *ctr,
+ [in] uint32 preferred_max_len,
+ [out] uint32 total_entries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x03 */
+ [public] NTSTATUS atsvc_JobGetInfo(
+ [in] unistr *servername,
+ [in] uint32 job_id,
+ [out] atsvc_JobInfo *job_info
+ );
+}
diff --git a/source/librpc/idl/browser.idl b/source/librpc/idl/browser.idl
new file mode 100644
index 00000000000..e1441c7857c
--- /dev/null
+++ b/source/librpc/idl/browser.idl
@@ -0,0 +1,10 @@
+[
+ uuid(6bffd098-a112-3610-9833-012892020162),
+ version(0.0)
+]
+interface browser
+{
+ /******************/
+ /* Function 0x00 */
+ NTSTATUS browser_Unknown0();
+}
diff --git a/source/librpc/idl/dcerpc.idl b/source/librpc/idl/dcerpc.idl
new file mode 100644
index 00000000000..334ae8ce5db
--- /dev/null
+++ b/source/librpc/idl/dcerpc.idl
@@ -0,0 +1,189 @@
+#include "idl_types.h"
+
+/*
+ the base dcerpc packet definitions - not traditionally coded as IDL,
+ but given that pidl can handle it nicely it simplifies things a lot
+ to do it this way
+
+ see http://www.opengroup.org/onlinepubs/9629399/chap12.htm for packet
+ layouts
+*/
+[]
+interface dcerpc
+{
+ typedef [public] struct {
+ GUID uuid;
+ uint32 if_version;
+ } dcerpc_syntax_id;
+
+ typedef struct {
+ uint16 context_id;
+ uint8 num_transfer_syntaxes;
+ dcerpc_syntax_id abstract_syntax;
+ dcerpc_syntax_id transfer_syntaxes[num_transfer_syntaxes];
+ } dcerpc_ctx_list;
+
+ typedef struct {
+ uint16 max_xmit_frag;
+ uint16 max_recv_frag;
+ uint32 assoc_group_id;
+ uint8 num_contexts;
+ dcerpc_ctx_list ctx_list[num_contexts];
+ [flag(NDR_ALIGN8)] DATA_BLOB _pad;
+ [flag(NDR_REMAINING)] DATA_BLOB auth_info;
+ } dcerpc_bind;
+
+
+ const uint8 DCERPC_REQUEST_LENGTH = 24;
+ const uint8 DCERPC_MAX_SIGN_SIZE = 32;
+
+ typedef struct {
+ uint32 alloc_hint;
+ uint16 context_id;
+ uint16 opnum;
+ [flag(NDR_ALIGN8)] DATA_BLOB _pad;
+ [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier;
+ } dcerpc_request;
+
+ const int DCERPC_BIND_PROVIDER_REJECT = 2;
+ const int DCERPC_BIND_REASON_ASYNTAX = 1;
+
+ typedef struct {
+ uint16 result;
+ uint16 reason;
+ dcerpc_syntax_id syntax;
+ } dcerpc_ack_ctx;
+
+ typedef struct {
+ uint16 max_xmit_frag;
+ uint16 max_recv_frag;
+ uint32 assoc_group_id;
+ ascstr3 secondary_address;
+ [flag(NDR_ALIGN4)] DATA_BLOB _pad1;
+ uint8 num_results;
+ dcerpc_ack_ctx ctx_list[num_results];
+ [flag(NDR_REMAINING)] DATA_BLOB auth_info;
+ } dcerpc_bind_ack;
+
+ typedef struct {
+ uint16 reject_reason;
+ uint32 num_versions;
+ uint32 versions[num_versions];
+ } dcerpc_bind_nak;
+
+ const uint8 DCERPC_RESPONSE_LENGTH = 24;
+
+ typedef struct {
+ uint32 alloc_hint;
+ uint16 context_id;
+ uint8 cancel_count;
+ [flag(NDR_ALIGN8)] DATA_BLOB _pad;
+ [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier;
+ } dcerpc_response;
+
+
+ const int DCERPC_FAULT_OP_RNG_ERROR = 0x1c010002;
+ const int DCERPC_FAULT_NDR = 0x000006f7;
+ const int DCERPC_FAULT_CONTEXT_MISMATCH = 0x1c00001a;
+ const int DCERPC_FAULT_OTHER = 0x00000001;
+
+ /* we return this fault when we haven't yet run the test
+ to see what fault w2k3 returns in this case */
+ const int DCERPC_FAULT_TODO = 0x00000042;
+
+ typedef struct {
+ uint32 alloc_hint;
+ uint16 context_id;
+ uint8 cancel_count;
+ uint32 status;
+ } dcerpc_fault;
+
+
+ const uint8 DCERPC_AUTH_TYPE_NONE = 0;
+ const uint8 DCERPC_AUTH_TYPE_KRB5 = 1;
+ const uint8 DCERPC_AUTH_TYPE_NTLMSSP = 10;
+ const uint8 DCERPC_AUTH_TYPE_SCHANNEL = 68;
+
+ const uint8 DCERPC_AUTH_LEVEL_NONE = 1;
+ const uint8 DCERPC_AUTH_LEVEL_CONNECT = 2;
+ const uint8 DCERPC_AUTH_LEVEL_CALL = 3;
+ const uint8 DCERPC_AUTH_LEVEL_PACKET = 4;
+ const uint8 DCERPC_AUTH_LEVEL_INTEGRITY = 5;
+ const uint8 DCERPC_AUTH_LEVEL_PRIVACY = 6;
+
+ typedef [public] struct {
+ uint8 auth_type;
+ uint8 auth_level;
+ uint8 auth_pad_length;
+ uint8 auth_reserved;
+ uint32 auth_context_id;
+ [flag(NDR_REMAINING)] DATA_BLOB credentials;
+ } dcerpc_auth;
+
+ typedef [public] struct {
+ uint32 _pad;
+ [flag(NDR_REMAINING)] DATA_BLOB auth_info;
+ } dcerpc_auth3;
+
+ typedef enum {
+ DCERPC_PKT_REQUEST = 0,
+ DCERPC_PKT_PING = 1,
+ DCERPC_PKT_RESPONSE = 2,
+ DCERPC_PKT_FAULT = 3,
+ DCERPC_PKT_WORKING = 4,
+ DCERPC_PKT_NOCALL = 5,
+ DCERPC_PKT_REJECT = 6,
+ DCERPC_PKT_ACK = 7,
+ DCERPC_PKT_CL_CANCEL = 8,
+ DCERPC_PKT_FACK = 9,
+ DCERPC_PKT_CANCEL_ACK = 10,
+ DCERPC_PKT_BIND = 11,
+ DCERPC_PKT_BIND_ACK = 12,
+ DCERPC_PKT_BIND_NAK = 13,
+ DCERPC_PKT_ALTER = 14,
+ DCERPC_PKT_ALTER_ACK = 15,
+ DCERPC_PKT_AUTH3 = 16,
+ DCERPC_PKT_SHUTDOWN = 17,
+ DCERPC_PKT_CO_CANCEL = 18,
+ DCERPC_PKT_ORPHANED = 19
+ } dcerpc_pkt_type;
+
+ typedef [nodiscriminant] union {
+ [case(DCERPC_PKT_REQUEST)] dcerpc_request request;
+ [case(DCERPC_PKT_RESPONSE)] dcerpc_response response;
+ [case(DCERPC_PKT_BIND)] dcerpc_bind bind;
+ [case(DCERPC_PKT_BIND_ACK)] dcerpc_bind_ack bind_ack;
+ [case(DCERPC_PKT_ALTER)] dcerpc_bind alter;
+ [case(DCERPC_PKT_ALTER_ACK)] dcerpc_bind_ack alter_ack;
+ [case(DCERPC_PKT_FAULT)] dcerpc_fault fault;
+ [case(DCERPC_PKT_AUTH3)] dcerpc_auth3 auth;
+ [case(DCERPC_PKT_BIND_NAK)] dcerpc_bind_nak bind_nak;
+ } dcerpc_payload;
+
+
+ /* pfc_flags values */
+ const uint8 DCERPC_PFC_FLAG_FIRST = 0x01;
+ const uint8 DCERPC_PFC_FLAG_LAST = 0x02;
+ const uint8 DCERPC_PFC_FLAG_NOCALL = 0x20;
+
+ /* these offsets are needed by the signing code */
+ const uint8 DCERPC_DREP_OFFSET = 4;
+ const uint8 DCERPC_FRAG_LEN_OFFSET = 8;
+ const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
+
+ /* little-endian flag */
+ const uint8 DCERPC_DREP_LE = 0x10;
+
+ typedef [public] struct {
+ uint8 rpc_vers; /* RPC version */
+ uint8 rpc_vers_minor; /* Minor version */
+ uint8 ptype; /* Packet type */
+ uint8 pfc_flags; /* Fragmentation flags */
+ uint8 drep[4]; /* NDR data representation */
+ uint16 frag_length; /* Total length of fragment */
+ uint16 auth_length; /* authenticator length */
+ uint32 call_id; /* Call identifier */
+
+ [switch_is(ptype)] dcerpc_payload u;
+ } dcerpc_packet;
+}
diff --git a/source/librpc/idl/dcom.idl b/source/librpc/idl/dcom.idl
new file mode 100644
index 00000000000..fc432c6aa4b
--- /dev/null
+++ b/source/librpc/idl/dcom.idl
@@ -0,0 +1,43 @@
+/*
+ this is just a placeholder until we start to support DCOM calls
+*/
+
+[
+ uuid(99fcfec4-5260-101b-bbcb-00aa0021347a),
+ version(0.0)
+]
+interface IOXIDResolver
+{
+
+ /*****************/
+ /* Function 0x00 */
+ WERROR ResolveOxid();
+}
+
+
+[
+ uuid(4d9f4ab8-7d1c-11cf-861e-0020af6e7c57),
+ version(0.0)
+]
+interface IRemoteActivation
+{
+
+ /*****************/
+ /* Function 0x00 */
+ NTSTATUS RemoteActivation();
+}
+
+
+
+[
+ uuid(000001a0-0000-0000-c000-000000000046),
+ version(0.0)
+]
+interface ISystemActivator
+{
+
+ /*****************/
+ /* Function 0x00 */
+ NTSTATUS isa_Unknown0();
+
+}
diff --git a/source/librpc/idl/dfs.idl b/source/librpc/idl/dfs.idl
new file mode 100644
index 00000000000..16c19744746
--- /dev/null
+++ b/source/librpc/idl/dfs.idl
@@ -0,0 +1,174 @@
+/*
+ dfs interface definition
+*/
+
+#include "idl_types.h"
+
+[ uuid(4fc742e0-4a10-11cf-8273-00aa004ae673),
+ version(3.0),
+ pointer_default(unique)
+] interface netdfs
+{
+ /******************/
+ /* Function: 0x00 */
+ void dfs_Exist(
+ [out,ref] uint32 *exist_flag
+ );
+
+
+ /******************/
+ /* Function: 0x01 */
+ WERROR dfs_Add (
+ [in,ref] unistr *path,
+ [in,ref] unistr *server,
+ [in] unistr *share,
+ [in] unistr *comment,
+ [in] uint32 flags
+ );
+
+ /******************/
+ /* Function: 0x02 */
+ WERROR dfs_Remove (
+ [in,ref] unistr *path,
+ [in] unistr *server,
+ [in] unistr *share
+ );
+
+ /******************/
+ /* Function: 0x03 */
+ WERROR dfs_SetInfo ();
+
+ /******************/
+ /* Function: 0x04 */
+
+ typedef struct {
+ unistr *path;
+ } dfs_Info1;
+
+ typedef struct {
+ unistr *path;
+ unistr *comment;
+ uint32 state;
+ uint32 num_stores;
+ } dfs_Info2;
+
+ typedef struct {
+ uint32 state;
+ unistr *server;
+ unistr *share;
+ } dfs_StorageInfo;
+
+ typedef struct {
+ unistr *path;
+ unistr *comment;
+ uint32 state;
+ uint32 num_stores;
+ [size_is(num_stores)] dfs_StorageInfo *stores;
+ } dfs_Info3;
+
+ typedef struct {
+ unistr *path;
+ unistr *comment;
+ uint32 state;
+ uint32 timeout;
+ GUID guid;
+ uint32 num_stores;
+ [size_is(num_stores)] dfs_StorageInfo *stores;
+ } dfs_Info4;
+
+ typedef struct {
+ unistr *comment;
+ } dfs_Info100;
+
+ typedef struct {
+ uint32 state;
+ } dfs_Info101;
+
+ typedef struct {
+ uint32 timeout;
+ } dfs_Info102;
+
+ typedef struct {
+ unistr *dom_root;
+ } dfs_Info200;
+
+ typedef struct {
+ uint32 flags;
+ unistr *dom_root;
+ } dfs_Info300;
+
+ typedef union {
+ [case(1)] dfs_Info1 *info1;
+ [case(2)] dfs_Info2 *info2;
+ [case(3)] dfs_Info3 *info3;
+ [case(4)] dfs_Info4 *info4;
+ [case(100)] dfs_Info100 *info100;
+ [case(101)] dfs_Info101 *info101;
+ [case(102)] dfs_Info102 *info102;
+ [default] ;
+ } dfs_Info;
+
+ WERROR dfs_GetInfo (
+ [in,ref] unistr *path,
+ [in] unistr *server,
+ [in] unistr *share,
+ [in] uint32 level,
+ [out,switch_is(level)] dfs_Info info
+ );
+
+ /******************/
+ /* Function: 0x05 */
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] dfs_Info1 *s;
+ } dfs_EnumArray1;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] dfs_Info2 *s;
+ } dfs_EnumArray2;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] dfs_Info3 *s;
+ } dfs_EnumArray3;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] dfs_Info4 *s;
+ } dfs_EnumArray4;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] dfs_Info200 *s;
+ } dfs_EnumArray200;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] dfs_Info300 *s;
+ } dfs_EnumArray300;
+
+
+ typedef union {
+ [case(1)] dfs_EnumArray1 *info1;
+ [case(2)] dfs_EnumArray2 *info2;
+ [case(3)] dfs_EnumArray3 *info3;
+ [case(4)] dfs_EnumArray4 *info4;
+ [case(200)] dfs_EnumArray200 *info200;
+ [case(300)] dfs_EnumArray300 *info300;
+ } dfs_EnumInfo;
+
+ typedef struct {
+ uint32 level;
+ [switch_is(level)] dfs_EnumInfo e;
+ } dfs_EnumStruct;
+
+ WERROR dfs_Enum (
+ [in] uint32 level,
+ [in] uint32 bufsize,
+ [in,out] dfs_EnumStruct *info,
+ [in] uint32 *unknown,
+ [in,out] uint32 *total
+ );
+}
diff --git a/source/librpc/idl/echo.idl b/source/librpc/idl/echo.idl
new file mode 100644
index 00000000000..e62208ac98a
--- /dev/null
+++ b/source/librpc/idl/echo.idl
@@ -0,0 +1,90 @@
+#include "idl_types.h"
+
+
+[
+ uuid(60a15ec5-4de8-11d7-a637-005056a20182),
+ endpoints(rpcecho, TCP-0),
+ version(1.0)
+]
+interface rpcecho
+{
+ /* Add one to an integer */
+ void echo_AddOne(
+ [in,out,ref] uint32 *v
+ );
+ /* Echo an array of bytes back at the caller */
+ void echo_EchoData(
+ [in] uint32 len,
+ [in] [size_is(len)] uint8 in_data[],
+ [out] [size_is(len)] uint8 out_data[]
+ );
+ /* Sink data to the server */
+ void echo_SinkData(
+ [in] uint32 len,
+ [in,ref,size_is(len)] uint8 *data
+ );
+ /* Source data from server */
+ void echo_SourceData(
+ [in] uint32 len,
+ [out,ref,size_is(len)] uint8 *data
+ );
+
+
+ /* test strings */
+ void echo_TestCall (
+ [in] unistr *s1,
+ [out] unistr *s2
+ );
+
+
+ /* test some alignment issues */
+ typedef struct {
+ uint8 v;
+ } echo_info1;
+
+ typedef struct {
+ uint16 v;
+ } echo_info2;
+
+ typedef struct {
+ uint32 v;
+ } echo_info3;
+
+ typedef struct {
+ HYPER_T v;
+ } echo_info4;
+
+ typedef struct {
+ uint8 v1;
+ HYPER_T v2;
+ } echo_info5;
+
+ typedef struct {
+ uint8 v1;
+ echo_info1 info1;
+ } echo_info6;
+
+ typedef union {
+ [case(1)] echo_info1 info1;
+ } echo_XXX;
+
+ typedef struct {
+ uint8 v1;
+ echo_info4 info4;
+ } echo_info7;
+
+ typedef union {
+ [case(1)] echo_info1 info1;
+ [case(2)] echo_info2 info2;
+ [case(3)] echo_info3 info3;
+ [case(4)] echo_info4 info4;
+ [case(5)] echo_info5 info5;
+ [case(6)] echo_info6 info6;
+ [case(7)] echo_info7 info7;
+ } echo_Info;
+
+ NTSTATUS echo_TestCall2 (
+ [in] uint16 level,
+ [out,switch_is(level)] echo_Info *info
+ );
+}
diff --git a/source/librpc/idl/epmapper.idl b/source/librpc/idl/epmapper.idl
new file mode 100644
index 00000000000..5db65cd7cf0
--- /dev/null
+++ b/source/librpc/idl/epmapper.idl
@@ -0,0 +1,168 @@
+#include "idl_types.h"
+
+/*
+ endpoint mapper interface
+*/
+
+[
+ uuid(e1af8308-5d1f-11c9-91a4-08002b14a0fa),
+ version(3.0),
+ endpoints(epmapper, TCP-135),
+ pointer_default(unique)
+]
+interface epmapper
+{
+
+ /*
+ note that the following IDL won't work in MIDL, and in fact
+ that the full towers/floors representation of epm cannot be
+ represented in MIDL at all. I decided to represent it using
+ the extended IDL syntax in pidl to make it easier to work
+ with.
+ */
+
+ const int EPMAPPER_STATUS_NO_MORE_ENTRIES = 0x16c9a0d6;
+
+
+ /* this guid indicates NDR encoding in a protocol tower */
+ const string NDR_GUID = "8a885d04-1ceb-11c9-9fe8-08002b104860";
+ const string NDR_GUID_VERSION = 2;
+
+ const uint32 EPMAPPER_PORT = 135;
+
+ typedef struct {
+ GUID uuid;
+ uint16 version;
+ } epm_prot_uuid;
+
+ typedef enum {
+ EPM_PROTOCOL_TCP = 0x07,
+ EPM_PROTOCOL_IP = 0x09,
+ EPM_PROTOCOL_PIPE = 0x10,
+ EPM_PROTOCOL_NETBIOS = 0x11,
+ EPM_PROTOCOL_RPC_C = 0x0b,
+ EPM_PROTOCOL_UUID = 0x0d,
+ EPM_PROTOCOL_SMB = 0x0f,
+ EPM_PROTOCOL_HTTP = 0x1f
+ } epm_protocols;
+
+ typedef [nodiscriminant] union {
+ [case(13)] epm_prot_uuid uuid;
+ [default] [flag(NDR_REMAINING)] DATA_BLOB lhs_data;
+ } epm_protocol_info;
+
+ typedef struct {
+ uint8 protocol;
+ [switch_is(protocol)] epm_protocol_info info;
+ } epm_lhs;
+
+ typedef struct {
+ [flag(NDR_REMAINING)] DATA_BLOB rhs_data;
+ } epm_rhs;
+
+ typedef struct {
+ [subcontext(2)] epm_lhs lhs;
+ [subcontext(2)] epm_rhs rhs;
+ } epm_floor;
+
+ /* note that the NDR_NOALIGN flag is inherited by all nested
+ structures. All of the towers/floors stuff is
+ non-aligned. I wonder what sort of wicked substance these
+ guys were smoking?
+ */
+ typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN)] struct {
+ uint16 num_floors;
+ epm_floor floors[num_floors];
+ } epm_towers;
+
+ typedef struct {
+ [value(ndr_size_epm_towers(&r->towers))] uint32 tower_length;
+ [subcontext(4)] epm_towers towers;
+ } epm_twr_t;
+
+ typedef struct {
+ GUID object;
+ epm_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] error_status_t status
+ );
+
+ /**********************/
+ /* Function 0x1 */
+ void epm_Delete(
+ [in] uint32 num_ents,
+ [in, size_is(num_ents)] epm_entry_t entries[],
+ [out] error_status_t 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] error_status_t status
+ );
+
+
+ /**********************/
+ /* Function 0x03 */
+
+ typedef struct {
+ epm_twr_t *twr;
+ } epm_twr_p_t;
+
+ void epm_Map(
+ [in] GUID *object,
+ [in] epm_twr_t *map_tower,
+ [in,out,ref] policy_handle *entry_handle,
+ [in] uint32 max_towers,
+ [out] uint32 num_towers,
+ [out, length_is(num_towers), size_is(max_towers)] epm_twr_p_t towers[],
+ [out] error_status_t status
+ );
+
+
+ /**********************/
+ /* Function 0x04 */
+ void epm_LookupHandleFree(
+ [in,out,ref] policy_handle *entry_handle,
+ [out] error_status_t status
+ );
+
+ /**********************/
+ /* Function 0x05 */
+ void epm_InqObject(
+ [out] GUID *epm_object,
+ [out] error_status_t status
+ );
+
+
+ /**********************/
+ /* Function 0x05 */
+ void epm_MgmtDelete(
+ [in] uint32 object_speced,
+ [in] GUID *object,
+ [in] epm_twr_t *tower,
+ [out] error_status_t status
+ );
+}
diff --git a/source/librpc/idl/eventlog.idl b/source/librpc/idl/eventlog.idl
new file mode 100644
index 00000000000..ee5bd8bba81
--- /dev/null
+++ b/source/librpc/idl/eventlog.idl
@@ -0,0 +1,48 @@
+#include "idl_types.h"
+
+/*
+ eventlog interface definition
+*/
+[ uuid(82273fdc-e32a-18c3-3f78-827929dc23ea),
+ version(0.0),
+ pointer_default(unique)
+] interface eventlog
+{
+ typedef struct {
+ uint16 unknown0;
+ uint16 unknown1;
+ } eventlog_OpenUnknown0;
+
+ typedef struct {
+ [value(2*strlen_m(r->name))] uint16 name_len;
+ [value(r->name_len)] uint16 name_size;
+ unistr_noterm *name;
+ } eventlog_String;
+
+ /******************/
+ /* Function: 0x00 */
+ NTSTATUS eventlog_OpenEventLog(
+ [in] eventlog_OpenUnknown0 *unknown0,
+ [in] eventlog_String source,
+ [in] eventlog_String unknown1,
+ [in] uint32 unknown2,
+ [in] uint32 unknown3,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x01 */
+ NTSTATUS eventlog_GetNumRecords(
+ );
+
+ /******************/
+ /* Function: 0x02 */
+ NTSTATUS eventlog_ReadEventLog(
+ );
+
+ /******************/
+ /* Function: 0x03 */
+ NTSTATUS eventlog_CloseEventLog(
+ [in,out,ref] policy_handle *handle
+ );
+}
diff --git a/source/librpc/idl/idl_types.h b/source/librpc/idl/idl_types.h
new file mode 100644
index 00000000000..434dfb8c649
--- /dev/null
+++ b/source/librpc/idl/idl_types.h
@@ -0,0 +1,72 @@
+#define STR_ASCII LIBNDR_FLAG_STR_ASCII
+#define STR_LEN4 LIBNDR_FLAG_STR_LEN4
+#define STR_SIZE4 LIBNDR_FLAG_STR_SIZE4
+#define STR_SIZE2 LIBNDR_FLAG_STR_SIZE2
+#define STR_NOTERM LIBNDR_FLAG_STR_NOTERM
+#define STR_NULLTERM LIBNDR_FLAG_STR_NULLTERM
+
+/*
+ a UCS2 string prefixed with [size] [offset] [length], all 32 bits
+ not null terminated
+*/
+#define unistr_noterm [flag(STR_NOTERM|STR_SIZE4|STR_LEN4)] string
+
+/*
+ a UCS2 string prefixed with [size] [offset] [length], all 32 bits
+*/
+#define unistr [flag(STR_SIZE4|STR_LEN4)] string
+
+/*
+ a UCS2 string prefixed with [size], 32 bits
+*/
+#define lstring [flag(STR_SIZE4)] string
+
+/*
+ a null terminated UCS2 string
+*/
+#define nstring [flag(STR_NULLTERM)] string
+
+/*
+ an ascii string prefixed with [size] [offset] [length], all 32 bits
+ null terminated
+*/
+#define ascstr [flag(STR_ASCII|STR_SIZE4|STR_LEN4)] string
+
+/*
+ an ascii string prefixed with [offset] [length], both 32 bits
+ null terminated
+*/
+#define ascstr2 [flag(STR_ASCII|STR_LEN4)] string
+
+/*
+ an ascii string prefixed with [size], 16 bits
+ null terminated
+*/
+#define ascstr3 [flag(STR_ASCII|STR_SIZE2)] string
+
+
+#define NDR_NOALIGN LIBNDR_FLAG_NOALIGN
+#define NDR_REMAINING LIBNDR_FLAG_REMAINING
+#define NDR_ALIGN2 LIBNDR_FLAG_ALIGN2
+#define NDR_ALIGN4 LIBNDR_FLAG_ALIGN4
+#define NDR_ALIGN8 LIBNDR_FLAG_ALIGN8
+
+/* this flag is used to force a section of IDL as little endian. It is
+ needed for the epmapper IDL, which is defined as always being LE */
+#define NDR_LITTLE_ENDIAN LIBNDR_FLAG_LITTLE_ENDIAN
+
+
+/*
+ these are used by the epmapper and mgmt interfaces
+*/
+#define error_status_t uint32
+#define boolean32 uint32
+#define unsigned32 uint32
+
+/*
+ this is used to control formatting of uint8 arrays
+*/
+#define NDR_PAHEX LIBNDR_PRINT_ARRAY_HEX
+
+
+#define bool8 uint8
diff --git a/source/librpc/idl/keysvc.idl b/source/librpc/idl/keysvc.idl
new file mode 100644
index 00000000000..396e0fedaf9
--- /dev/null
+++ b/source/librpc/idl/keysvc.idl
@@ -0,0 +1,15 @@
+/*
+ cryptographic key services interface
+*/
+
+[
+ uuid(8d0ffe72-d252-11d0-bf8f-00c04fd9126b),
+ version(1.0)
+]
+interface keysvc
+{
+
+ /*****************/
+ /* Function 0x00 */
+ WERROR keysvc_Unknown0();
+}
diff --git a/source/librpc/idl/lsa.idl b/source/librpc/idl/lsa.idl
new file mode 100644
index 00000000000..d8c6389bb3e
--- /dev/null
+++ b/source/librpc/idl/lsa.idl
@@ -0,0 +1,500 @@
+#include "idl_types.h"
+
+/*
+ lsa interface definition
+*/
+
+[ uuid(12345778-1234-abcd-ef00-0123456789ab),
+ version(0.0),
+ endpoints(lsarpc,lsass),
+ pointer_default(unique)
+] interface lsarpc
+{
+ /******************/
+ /* Function: 0x00 */
+ NTSTATUS lsa_Close (
+ [in,out,ref] policy_handle *handle
+ );
+
+
+ /******************/
+ /* Function: 0x01 */
+ NTSTATUS lsa_Delete (
+ [in,ref] policy_handle *handle
+ );
+
+
+ /******************/
+ /* Function: 0x02 */
+
+ typedef struct {
+ [value(2*strlen_m(r->name))] uint16 name_len;
+ [value(r->name_len)] uint16 name_size;
+ unistr_noterm *name;
+ } lsa_Name;
+
+ typedef struct {
+ lsa_Name name;
+ uint32 luid_low;
+ uint32 luid_high;
+ } lsa_PrivEntry;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] lsa_PrivEntry *privs;
+ } lsa_PrivArray;
+
+ NTSTATUS lsa_EnumPrivs (
+ [in,ref] policy_handle *handle,
+ [in,out,ref] uint32 *resume_handle,
+ [in] uint32 max_count,
+ [out,ref] lsa_PrivArray *privs
+ );
+
+ /******************/
+ /* Function: 0x03 */
+
+ typedef [public] struct {
+ uint32 size;
+ [subcontext(4)] security_descriptor *sd;
+ } sec_desc_buf;
+
+ NTSTATUS lsa_QuerySecObj (
+ [in,ref] policy_handle *handle,
+ [in] uint32 sec_info,
+ [out] sec_desc_buf *sd
+ );
+
+
+ /******************/
+ /* Function: 0x04 */
+ NTSTATUS lsa_SetSecObj ();
+
+
+ /******************/
+ /* Function: 0x05 */
+ NTSTATUS lsa_ChangePassword ();
+
+
+ /******************/
+ /* Function: 0x06 */
+ typedef struct {
+ uint32 len; /* ignored */
+ uint16 impersonation_level;
+ uint8 context_mode;
+ uint8 effective_only;
+ } lsa_QosInfo;
+
+ typedef struct {
+ uint32 len; /* ignored */
+ uint8 *root_dir;
+ unistr *object_name;
+ uint32 attributes;
+ security_descriptor *sec_desc;
+ lsa_QosInfo *sec_qos;
+ } lsa_ObjectAttribute;
+
+ /* notice the screwup with the system_name - thats why MS created
+ OpenPolicy2 */
+ NTSTATUS lsa_OpenPolicy (
+ [in] uint16 *system_name,
+ [in,ref] lsa_ObjectAttribute *attr,
+ [in] uint32 desired_access,
+ [out,ref] policy_handle *handle
+ );
+
+
+
+ /******************/
+ /* Function: 0x07 */
+
+ typedef struct {
+ uint32 percent_full;
+ uint32 log_size;
+ NTTIME retention_time;
+ uint8 shutdown_in_progress;
+ NTTIME time_to_shutdown;
+ uint32 next_audit_record;
+ uint32 unknown;
+ } lsa_AuditLogInfo;
+
+ typedef struct {
+ uint32 auditing_mode;
+ [size_is(count)] uint32 *settings;
+ uint32 count;
+ } lsa_AuditEventsInfo;
+
+ typedef struct {
+ lsa_Name name;
+ dom_sid2 *sid;
+ } lsa_DomainInfo;
+
+ typedef struct {
+ lsa_Name name;
+ } lsa_PDAccountInfo;
+
+ typedef struct {
+ uint16 unknown; /* an midl padding bug? */
+ uint16 role;
+ } lsa_ServerRole;
+
+ typedef struct {
+ lsa_Name source;
+ lsa_Name account;
+ } lsa_ReplicaSourceInfo;
+
+ typedef struct {
+ uint32 paged_pool;
+ uint32 non_paged_pool;
+ uint32 min_wss;
+ uint32 max_wss;
+ uint32 pagefile;
+ HYPER_T unknown;
+ } lsa_DefaultQuotaInfo;
+
+ typedef struct {
+ HYPER_T modified_id;
+ NTTIME db_create_time;
+ } lsa_ModificationInfo;
+
+ typedef struct {
+ uint8 shutdown_on_full;
+ } lsa_AuditFullSetInfo;
+
+ typedef struct {
+ uint16 unknown; /* an midl padding bug? */
+ uint8 shutdown_on_full;
+ uint8 log_is_full;
+ } lsa_AuditFullQueryInfo;
+
+ typedef struct {
+ lsa_Name name;
+ lsa_Name dns_domain;
+ lsa_Name dns_forest;
+ GUID domain_guid;
+ dom_sid2 *sid;
+ } lsa_DnsDomainInfo;
+
+ typedef enum {
+ LSA_POLICY_INFO_AUDIT_LOG=1,
+ LSA_POLICY_INFO_AUDIT_EVENTS=2,
+ LSA_POLICY_INFO_DOMAIN=3,
+ LSA_POLICY_INFO_PD=4,
+ LSA_POLICY_INFO_ACCOUNT_DOMAIN=5,
+ LSA_POLICY_INFO_ROLE=6,
+ LSA_POLICY_INFO_REPLICA=7,
+ LSA_POLICY_INFO_QUOTA=8,
+ LSA_POLICY_INFO_DB=9,
+ LSA_POLICY_INFO_AUDIT_FULL_SET=10,
+ LSA_POLICY_INFO_AUDIT_FULL_QUERY=11,
+ LSA_POLICY_INFO_DNS=12
+ } lsaPolicyInfo;
+
+ typedef union {
+ [case(1)] lsa_AuditLogInfo audit_log;
+ [case(2)] lsa_AuditEventsInfo audit_events;
+ [case(3)] lsa_DomainInfo domain;
+ [case(4)] lsa_PDAccountInfo pd;
+ [case(5)] lsa_DomainInfo account_domain;
+ [case(6)] lsa_ServerRole role;
+ [case(7)] lsa_ReplicaSourceInfo replica;
+ [case(8)] lsa_DefaultQuotaInfo quota;
+ [case(9)] lsa_ModificationInfo db;
+ [case(10)] lsa_AuditFullSetInfo auditfullset;
+ [case(11)] lsa_AuditFullQueryInfo auditfullquery;
+ [case(12)] lsa_DnsDomainInfo dns;
+ } lsa_PolicyInformation;
+
+ NTSTATUS lsa_QueryInfoPolicy (
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [out,switch_is(level)] lsa_PolicyInformation *info
+ );
+
+ /******************/
+ /* Function: 0x08 */
+ NTSTATUS lsa_SetInfoPolicy ();
+
+ /******************/
+ /* Function: 0x09 */
+ NTSTATUS lsa_ClearAuditLog ();
+
+ /******************/
+ /* Function: 0x0a */
+ NTSTATUS lsa_CreateAccount (
+ [in,ref] policy_handle *handle,
+ [in,ref] dom_sid2 *sid,
+ [in] uint32 desired_access,
+ [out,ref] policy_handle *acct_handle
+ );
+
+ /******************/
+ /* Function: 0x0b */
+ typedef struct {
+ dom_sid2 *sid;
+ } lsa_SidPtr;
+
+ typedef [public] struct {
+ uint32 num_sids;
+ [size_is(num_sids)] lsa_SidPtr *sids;
+ } lsa_SidArray;
+
+ NTSTATUS lsa_EnumAccounts (
+ [in,ref] policy_handle *handle,
+ [in,out,ref] uint32 *resume_handle,
+ [in] uint32 num_entries,
+ [out,ref] lsa_SidArray *sids
+ );
+
+
+ /*************************************************/
+ /* Function: 0x0c */
+
+ typedef struct {
+ lsa_Name name;
+ dom_sid2 *sid;
+ } lsa_TrustInformation;
+
+ NTSTATUS lsa_CreateTrustedDomain(
+ [in,ref] policy_handle *handle,
+ [in,ref] lsa_TrustInformation *info,
+ [in] uint32 desired_access,
+ [out,ref] policy_handle *dom_handle
+ );
+
+
+ /******************/
+ /* Function: 0x0d */
+
+ typedef struct {
+ lsa_Name name;
+ dom_sid2 *sid;
+ } lsa_DomainInformation;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] lsa_DomainInformation *domains;
+ } lsa_DomainList;
+
+ NTSTATUS lsa_EnumTrustDom (
+ [in,ref] policy_handle *handle,
+ [in,out,ref] uint32 *resume_handle,
+ [in] uint32 num_entries,
+ [out,ref] lsa_DomainList *domains
+ );
+
+
+ /******************/
+ /* Function: 0x0e */
+
+ typedef struct {
+ uint16 sid_type;
+ uint32 rid;
+ uint32 sid_index;
+ } lsa_TranslatedSid;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] lsa_TranslatedSid *sids;
+ } lsa_TransSidArray;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] lsa_TrustInformation *domains;
+ uint32 max_count;
+ } lsa_RefDomainList;
+
+ NTSTATUS lsa_LookupNames (
+ [in,ref] policy_handle *handle,
+ [in] uint32 num_names,
+ [in,ref,size_is(num_names)] lsa_Name *names,
+ [out] lsa_RefDomainList *domains,
+ [in,out,ref] lsa_TransSidArray *sids,
+ [in] uint16 level,
+ [in,out,ref] uint32 *count
+ );
+
+
+ /******************/
+ /* Function: 0x0f */
+
+ typedef struct {
+ uint16 sid_type;
+ lsa_Name name;
+ uint32 sid_index;
+ } lsa_TranslatedName;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] lsa_TranslatedName *names;
+ } lsa_TransNameArray;
+
+ NTSTATUS lsa_LookupSids (
+ [in,ref] policy_handle *handle,
+ [in,ref] lsa_SidArray *sids,
+ [out] lsa_RefDomainList *domains,
+ [in,out,ref] lsa_TransNameArray *names,
+ [in] uint16 level,
+ [in,out,ref] uint32 *count
+ );
+
+
+ /* Function: 0x10 */
+ NTSTATUS lsa_CreateSecret(
+ [in,ref] policy_handle *handle,
+ [in] lsa_Name name,
+ [in] uint32 desired_access,
+ [out,ref] policy_handle *sec_handle
+ );
+
+
+ /*****************************************/
+ /* Function: 0x11 */
+ NTSTATUS lsa_OpenAccount (
+ [in,ref] policy_handle *handle,
+ [in,ref] dom_sid2 *sid,
+ [in] uint32 desired_access,
+ [out,ref] policy_handle *acct_handle
+ );
+
+
+ /****************************************/
+ /* Function: 0x12 */
+
+ typedef struct {
+ uint32 low;
+ uint32 high;
+ } lsa_LUID;
+
+ typedef struct {
+ lsa_LUID luid;
+ uint32 attribute;
+ } lsa_LUIDAttribute;
+
+ typedef struct {
+ uint32 count;
+ uint32 unknown;
+ [size_is(count)] lsa_LUIDAttribute set[*];
+ } lsa_PrivilegeSet;
+
+ NTSTATUS lsa_EnumPrivsAccount (
+ [in,ref] policy_handle *handle,
+ [out] lsa_PrivilegeSet *privs
+ );
+
+
+ /* Function: 0x13 */
+ NTSTATUS ADDPRIVS ();
+ /* Function: 0x14 */
+ NTSTATUS REMOVEPRIVS ();
+ /* Function: 0x15 */
+ NTSTATUS GETQUOTAS ();
+ /* Function: 0x16 */
+ NTSTATUS SETQUOTAS ();
+ /* Function: 0x17 */
+ NTSTATUS GETSYSTEMACCOUNT ();
+ /* Function: 0x18 */
+ NTSTATUS SETSYSTEMACCOUNT ();
+ /* Function: 0x19 */
+ NTSTATUS OPENTRUSTDOM ();
+ /* Function: 0x1a */
+ NTSTATUS QUERYTRUSTDOM ();
+ /* Function: 0x1b */
+ NTSTATUS SETINFOTRUSTDOM ();
+
+ /* Function: 0x1c */
+ NTSTATUS lsa_OpenSecret(
+ [in,ref] policy_handle *handle,
+ [in] lsa_Name name,
+ [in] uint32 desired_access,
+ [out,ref] policy_handle *sec_handle
+ );
+
+ /* Function: 0x1d */
+ NTSTATUS SETSECRET ();
+ /* Function: 0x1e */
+ NTSTATUS QUERYSECRET ();
+
+ /* Function: 0x1f */
+ NTSTATUS LOOKUPPRIVVALUE ();
+
+
+ /* Function: 0x20 */
+ NTSTATUS lsa_LookupPrivName (
+ [in,ref] policy_handle *handle,
+ [in,ref] lsa_LUID *luid,
+ [out] lsa_Name *name
+ );
+
+
+ /* Function: 0x21 */
+ NTSTATUS PRIV_GET_DISPNAME ();
+ /* Function: 0x22 */
+ NTSTATUS DELETEOBJECT ();
+ /* Function: 0x23 */
+ NTSTATUS ENUMACCTWITHRIGHT ();
+
+ /* Function: 0x24 */
+ typedef struct {
+ unistr *name;
+ } lsa_RightAttribute;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] lsa_Name *names;
+ } lsa_RightSet;
+
+ NTSTATUS lsa_EnumAccountRights (
+ [in,ref] policy_handle *handle,
+ [in,ref] dom_sid2 *sid,
+ [out,ref] lsa_RightSet *rights
+ );
+
+
+ /* Function: 0x25 */
+ NTSTATUS ADDACCTRIGHTS ();
+ /* Function: 0x26 */
+ NTSTATUS REMOVEACCTRIGHTS ();
+ /* Function: 0x27 */
+ NTSTATUS QUERYTRUSTDOMINFO ();
+ /* Function: 0x28 */
+ NTSTATUS SETTRUSTDOMINFO ();
+ /* Function: 0x29 */
+ NTSTATUS DELETETRUSTDOM ();
+ /* Function: 0x2a */
+ NTSTATUS STOREPRIVDATA ();
+ /* Function: 0x2b */
+ NTSTATUS RETRPRIVDATA ();
+
+
+ /**********************/
+ /* Function: 0x2c */
+ NTSTATUS lsa_OpenPolicy2 (
+ [in] unistr *system_name,
+ [in,ref] lsa_ObjectAttribute *attr,
+ [in] uint32 desired_access,
+ [out,ref] policy_handle *handle
+ );
+
+
+ /* Function: 0x2d */
+ NTSTATUS UNK_GET_CONNUSER ();
+ /* Function: 0x2e */
+ NTSTATUS QUERYINFO2 ();
+}
+
+
+[
+ uuid(3919286a-b10c-11d0-9ba8-00c04fd92ef5),
+ version(0.0),
+ endpoints(lsarpc,lsass),
+ pointer_default(unique)
+]
+interface lsads
+{
+
+ /*****************/
+ /* Function 0x00 */
+ void lsads_Unknown0();
+
+}
diff --git a/source/librpc/idl/mgmt.idl b/source/librpc/idl/mgmt.idl
new file mode 100644
index 00000000000..7e691d3c31b
--- /dev/null
+++ b/source/librpc/idl/mgmt.idl
@@ -0,0 +1,74 @@
+#include "idl_types.h"
+
+/*
+ dcerpc remote management interface
+*/
+
+
+[
+ uuid(afa8bd80-7d8a-11c9-bef4-08002b102989),
+ version(1)
+]
+interface mgmt
+{
+ typedef struct {
+ dcerpc_syntax_id *id;
+ } dcerpc_syntax_id_p;
+
+ typedef struct {
+ unsigned32 count;
+ [size_is(count)] dcerpc_syntax_id_p if_id[*];
+ } rpc_if_id_vector_t;
+
+
+ /***********************/
+ /* Function 0x00 */
+ WERROR mgmt_inq_if_ids (
+ [out] rpc_if_id_vector_t *if_id_vector
+ );
+
+
+
+ /***********************/
+ /* Function 0x01 */
+
+
+ /* these are the array indexes in the statistics array */
+ const int MGMT_STATS_CALLS_IN = 0;
+ const int MGMT_STATS_CALLS_OUT = 1;
+ const int MGMT_STATS_PKTS_IN = 2;
+ const int MGMT_STATS_PKTS_OUT = 3;
+ const int MGMT_STATS_ARRAY_MAX_SIZE = 4;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] uint32 statistics[*];
+ } mgmt_statistics;
+
+ WERROR mgmt_inq_stats (
+ [in] uint32 max_count,
+ [in] uint32 unknown,
+ [out] mgmt_statistics statistics
+ );
+
+
+ /***********************/
+ /* Function 0x02 */
+ boolean32 mgmt_is_server_listening (
+ [out] error_status_t status
+ );
+
+
+ /***********************/
+ /* Function 0x03 */
+ WERROR mgmt_stop_server_listening ();
+
+
+ /***********************/
+ /* Function 0x04 */
+ WERROR mgmt_inq_princ_name (
+ [in] uint32 authn_proto,
+ [in] uint32 princ_name_size,
+ [out] ascstr princ_name
+ );
+}
diff --git a/source/librpc/idl/misc.idl b/source/librpc/idl/misc.idl
new file mode 100644
index 00000000000..fca8fe876e2
--- /dev/null
+++ b/source/librpc/idl/misc.idl
@@ -0,0 +1,79 @@
+#include "idl_types.h"
+
+/*
+ miscellaneous IDL structures
+*/
+
+[]
+interface misc
+{
+
+ typedef [public,noprint] struct {
+ uint32 time_low;
+ uint16 time_mid;
+ uint16 time_hi_and_version;
+ uint8 clock_seq[2];
+ uint8 node[6];
+ } GUID;
+
+ /* a domain SID. Note that unlike Samba3 this contains a pointer,
+ so you can't copy them using assignment */
+ typedef [public,noprint] struct {
+ uint8 sid_rev_num; /**< SID revision number */
+ uint8 num_auths; /**< Number of sub-authorities */
+ uint8 id_auth[6]; /**< Identifier Authority */
+ uint32 sub_auths[num_auths];
+ } dom_sid;
+
+ typedef [public] struct {
+ uint8 type; /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */
+ uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */
+ [value(ndr_size_security_ace(r))] uint16 size;
+ uint32 access_mask;
+
+#if 0
+ /* the 'obj' part is present when type is XXXX_TYPE_XXXX_OBJECT */
+ struct {
+ uint32 flags;
+ GUID object_guid;
+ GUID inherit_guid;
+ } *obj;
+#endif
+
+ dom_sid trustee;
+ } security_ace;
+
+ typedef [public] struct {
+ uint16 revision;
+ [value(ndr_size_security_acl(r))] uint16 size;
+ uint32 num_aces;
+ security_ace aces[num_aces];
+ } security_acl;
+
+
+ typedef [public] struct {
+ uint8 revision;
+ uint16 type; /* SEC_DESC_xxxx flags */
+ [relative] dom_sid *owner_sid;
+ [relative] dom_sid *group_sid;
+ [relative] security_acl *sacl; /* system ACL */
+ [relative] security_acl *dacl; /* user (discretionary) ACL */
+ } security_descriptor;
+
+ typedef [public] struct {
+ uint32 handle_type;
+ GUID uuid;
+ } policy_handle;
+
+ /* a 4 byte aligned 64-bit integer */
+ typedef [public] struct {
+ uint32 low;
+ uint32 high;
+ } ULONG8;
+
+ /* this is also used in samr and netlogon */
+ typedef [public, flag(NDR_PAHEX)] struct {
+ uint16 units_per_week;
+ [size_is(1260), length_is(units_per_week/8)] uint8 *bitmap;
+ } samr_LogonHours;
+}
diff --git a/source/librpc/idl/netlogon.idl b/source/librpc/idl/netlogon.idl
new file mode 100644
index 00000000000..5b2d2aa1d34
--- /dev/null
+++ b/source/librpc/idl/netlogon.idl
@@ -0,0 +1,796 @@
+/*
+ netlogon interface
+ much of this was derived from the ethereal sources - thanks to everyone
+ who contributed!
+*/
+
+#include "idl_types.h"
+
+[
+ uuid(12345678-1234-abcd-ef00-01234567cffb),
+ version(1.0),
+ pointer_default(unique)
+]
+
+interface netlogon
+{
+
+ /*****************/
+ /* Function 0x00 */
+
+ typedef struct {
+ unistr *account_name;
+ uint32 priv;
+ uint32 auth_flags;
+ uint32 logon_count;
+ uint32 bad_pw_count;
+ time_t last_logon;
+ time_t last_logoff;
+ time_t logoff_time;
+ time_t kickoff_time;
+ uint32 password_age;
+ time_t pw_can_change;
+ time_t pw_must_change;
+ unistr *computer;
+ unistr *domain;
+ unistr *script_path;
+ uint32 unknown;
+ } netr_UasInfo;
+
+ WERROR netr_LogonUasLogon(
+ [in] unistr *server_name,
+ [in] unistr username,
+ [in] unistr workstation,
+ [out] netr_UasInfo *info
+ );
+
+
+ /*****************/
+ /* Function 0x01 */
+
+ typedef struct {
+ uint32 duration;
+ uint16 logon_count;
+ } netr_UasLogoffInfo;
+
+ WERROR netr_LogonUasLogoff(
+ [in] unistr *server_name,
+ [in] unistr username,
+ [in] unistr workstation,
+ [out] netr_UasLogoffInfo info
+ );
+
+
+ /*****************/
+ /* Function 0x02 */
+
+ typedef [flag(NDR_PAHEX)] struct {
+ uint8 data[8];
+ } netr_Credential;
+
+ typedef [flag(NDR_PAHEX)] struct {
+ uint8 session_key[8];
+ uint32 sequence;
+ netr_Credential seed;
+ netr_Credential client;
+ netr_Credential server;
+ } netr_CredentialState;
+
+ typedef struct {
+ [value(strlen_m(r->string)*2)] uint16 size;
+ [value(r->size)] uint16 length;
+ unistr_noterm *string;
+ } netr_String;
+
+ typedef struct {
+ netr_String domain_name;
+ uint32 parameter_control;
+ uint32 logon_id_low;
+ uint32 logon_id_high;
+ netr_String username;
+ netr_String workstation;
+ } netr_IdentityInfo;
+
+ typedef [flag(NDR_PAHEX)] struct {
+ uint8 data[16];
+ } netr_Password;
+
+ typedef struct {
+ netr_IdentityInfo identity_info;
+ netr_Password lmpassword;
+ netr_Password ntpassword;
+ } netr_PasswordInfo;
+
+ typedef [flag(NDR_PAHEX)] struct {
+ uint16 length;
+ [value(r->length)] uint16 size;
+ [size_is(size),length_is(length)] uint8 *data;
+ } netr_ChallengeResponse;
+
+ typedef [flag(NDR_PAHEX)] struct {
+ netr_IdentityInfo logon_info;
+ uint8 challenge[8];
+ netr_ChallengeResponse nt;
+ netr_ChallengeResponse lm;
+ } netr_NetworkInfo;
+
+ typedef union {
+ [case(1)] netr_PasswordInfo *interactive;
+ [case(2)] netr_NetworkInfo *network;
+ [case(3)] netr_PasswordInfo *service;
+ } netr_LogonLevel;
+
+ typedef struct {
+ netr_Credential cred;
+ time_t timestamp;
+ } netr_Authenticator;
+
+ typedef struct {
+ uint32 user_id;
+ uint32 attributes;
+ } netr_GroupMembership;
+
+ typedef [flag(NDR_PAHEX)] struct {
+ uint8 user_session_key[16];
+ } netr_UserSessionKey;
+
+ typedef struct {
+ NTTIME logon_time;
+ NTTIME logoff_time;
+ NTTIME kickoff_time;
+ NTTIME passwd_last_set;
+ NTTIME passwd_can_change;
+ NTTIME passwd_must_change;
+ netr_String account_name;
+ netr_String full_name;
+ netr_String logon_script;
+ netr_String profile_path;
+ netr_String home_dir;
+ netr_String home_drive;
+ uint16 logon_count;
+ uint16 bad_passwd_count;
+ uint32 userid;
+ uint32 primary_group;
+ uint32 group_count;
+ [size_is(group_count)] netr_GroupMembership *groupids;
+ uint32 user_flags;
+ netr_UserSessionKey key;
+ netr_String logon_server;
+ netr_String domain;
+ dom_sid2 *domain_sid;
+ uint32 expansionroom[10];
+ } netr_SamInfo;
+
+ typedef struct {
+ dom_sid2 *sid;
+ uint32 attribute;
+ } netr_SidAttr;
+
+ typedef struct {
+ NTTIME logon_time;
+ NTTIME logoff_time;
+ NTTIME kickoff_time;
+ NTTIME passwd_last_set;
+ NTTIME passwd_can_change;
+ NTTIME passwd_must_change;
+ netr_String account_name;
+ netr_String full_name;
+ netr_String logon_script;
+ netr_String profile_path;
+ netr_String home_dir;
+ netr_String home_drive;
+ uint16 logon_count;
+ uint16 bad_passwd_count;
+ uint32 userid;
+ uint32 primary_group;
+ uint32 group_count;
+ [size_is(group_count)] netr_GroupMembership *groupids;
+ uint32 user_flags;
+ netr_UserSessionKey key;
+ netr_String logon_server;
+ netr_String domain;
+ dom_sid2 *domain_sid;
+ uint32 expansionroom[10];
+ uint32 sidcount;
+ [size_is(sidcount)] netr_SidAttr *sids;
+ } netr_SamInfo2;
+
+ typedef struct {
+ uint32 pac_size;
+ [size_is(pac_size)] uint8 *pac;
+ netr_String logon_domain;
+ netr_String logon_server;
+ netr_String principal_name;
+ uint32 auth_size;
+ [size_is(auth_size)] uint8 *auth;
+ netr_UserSessionKey user_session_key;
+ uint32 expansionroom[10];
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ } netr_PacInfo;
+
+ typedef union {
+ [case(2)] netr_SamInfo *sam;
+ [case(3)] netr_SamInfo2 *sam2;
+ [case(4)] netr_PacInfo *pac;
+ [case(5)] netr_PacInfo *pac2;
+ } netr_Validation;
+
+ NTSTATUS netr_LogonSamLogon(
+ [in] unistr *server_name,
+ [in] unistr *workstation,
+ [in] netr_Authenticator *credential,
+ [in][out] netr_Authenticator *authenticator,
+ [in] uint16 logon_level,
+ [in] [switch_is(logon_level)] netr_LogonLevel logon,
+ [in] uint16 validation_level,
+ [out] [switch_is(validation_level)] netr_Validation validation,
+ [out] uint32 authoritative
+ );
+
+
+ /*****************/
+ /* Function 0x03 */
+
+ NTSTATUS netr_LogonSamLogoff(
+ [in] unistr *server_name,
+ [in] unistr *computer_name,
+ [in] netr_Authenticator *credential,
+ [in][out] netr_Authenticator *return_authenticator,
+ [in] uint16 logon_level,
+ [in] [switch_is(logon_level)] netr_LogonLevel logon
+ );
+
+
+
+ /*****************/
+ /* Function 0x04 */
+
+ NTSTATUS netr_ServerReqChallenge(
+ [in] unistr *server_name,
+ [in] unistr computer_name,
+ [in][out] netr_Credential credentials
+ );
+
+
+ /*****************/
+ /* Function 0x05 */
+
+ /* secure channel types */
+ const int SEC_CHAN_WKSTA = 2;
+ const int SEC_CHAN_DOMAIN = 4;
+ const int SEC_CHAN_BDC = 6;
+
+ NTSTATUS netr_ServerAuthenticate(
+ [in] unistr *server_name,
+ [in] unistr username,
+ [in] uint16 secure_channel_type,
+ [in] unistr computer_name,
+ [in,out] netr_Credential credentials
+ );
+
+
+ /*****************/
+ /* Function 0x06 */
+
+ NTSTATUS netr_ServerPasswordSet(
+ [in] unistr *server_name,
+ [in] unistr username,
+ [in] uint16 secure_channel_type,
+ [in] unistr computer_name,
+ [in] netr_Authenticator credential,
+ [in] netr_Password new_password,
+ [out] netr_Authenticator return_authenticator
+ );
+
+
+ /*****************/
+ /* Function 0x07 */
+
+ typedef struct {
+ unistr *username;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_DELETE_USER;
+
+ typedef struct {
+ bool8 SensitiveDataFlag;
+ uint32 DataLength;
+ [size_is(DataLength)] uint8 *SensitiveData;
+ } netr_USER_PRIVATE_INFO;
+
+ typedef struct {
+ netr_String account_name;
+ netr_String full_name;
+ uint32 rid;
+ uint32 primary_group;
+ netr_String home_dir;
+ netr_String home_drive;
+ netr_String logon_script;
+ netr_String description;
+ netr_String workstations;
+ NTTIME LastLogon;
+ NTTIME LastLogoff;
+ samr_LogonHours logon_hours;
+ uint16 bad_pw_count;
+ uint16 logon_count;
+ NTTIME PwLastSet;
+ NTTIME AccountExpires;
+ uint32 AccountControl;
+ netr_Password lmpw;
+ netr_Password ntpw;
+ bool8 NTPwPresent;
+ bool8 LMPwPresent;
+ bool8 PwExpired;
+ netr_String UserComment;
+ netr_String Parameters;
+ uint16 CountryCode;
+ uint16 CodePage;
+ netr_USER_PRIVATE_INFO user_private_info;
+ uint32 SecurityInformation;
+ sec_desc_buf sdbuf;
+ netr_String profile_path;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_USER;
+
+ typedef struct {
+ netr_String DomainName;
+ netr_String OEMInfo;
+ NTTIME forcedlogoff;
+ uint16 minpasswdlen;
+ uint16 passwdhistorylen;
+ ULONG8 pwd_must_change_time;
+ ULONG8 pwd_can_change_time;
+ ULONG8 sequence_num;
+ NTTIME domain_create_time;
+ uint32 SecurityInformation;
+ sec_desc_buf sdbuf;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_DOMAIN;
+
+ typedef struct {
+ netr_String groupname;
+ netr_GroupMembership group_membership;
+ netr_String comment;
+ uint32 SecurityInformation;
+ sec_desc_buf sdbuf;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_GROUP;
+
+ typedef struct {
+ netr_String OldName;
+ netr_String NewName;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_RENAME;
+
+ typedef struct {
+ [size_is(num_rids)] uint32 *rids;
+ [size_is(num_rids)] uint32 *attribs;
+ uint32 num_rids;
+ uint32 unknown1;
+ uint32 unknown2;
+ uint32 unknown3;
+ uint32 unknown4;
+ } netr_DELTA_GROUP_MEMBER;
+
+ typedef struct {
+ netr_String alias_name;
+ uint32 rid;
+ uint32 SecurityInformation;
+ sec_desc_buf sdbuf;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_ALIAS;
+
+ typedef struct {
+ lsa_SidArray sids;
+ uint32 unknown1;
+ uint32 unknown2;
+ uint32 unknown3;
+ uint32 unknown4;
+ } netr_DELTA_ALIAS_MEMBER;
+
+ typedef struct {
+ uint32 pagedpoollimit;
+ uint32 nonpagedpoollimit;
+ uint32 minimumworkingsetsize;
+ uint32 maximumworkingsetsize;
+ uint32 pagefilelimit;
+ NTTIME timelimit;
+ } netr_QUOTA_LIMITS;
+
+ typedef struct {
+ uint32 maxlogsize;
+ NTTIME auditretentionperiod;
+ bool8 auditingmode;
+ uint32 maxauditeventcount;
+ [size_is(maxauditeventcount+1)] uint32 *eventauditoptions;
+ netr_String primarydomainname;
+ dom_sid2 *sid;
+ netr_QUOTA_LIMITS quota_limits;
+ NTTIME db_modify_time;
+ NTTIME db_create_time;
+ uint32 SecurityInformation;
+ sec_desc_buf sdbuf;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_POLICY;
+
+ typedef struct {
+ netr_String DomainName;
+ uint32 num_controllers;
+ [size_is(num_controllers)] netr_String *controller_names;
+ uint32 SecurityInformation;
+ sec_desc_buf sdbuf;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_TRUSTED_DOMAINS;
+
+ typedef struct {
+ uint32 privilege_entries;
+ uint32 privilege_control;
+ [size_is(privilege_entries)] uint32 *privilege_attrib;
+ [size_is(privilege_entries)] netr_String *privilege_name;
+ netr_QUOTA_LIMITS quotalimits;
+ uint32 system_flags;
+ uint32 SecurityInformation;
+ sec_desc_buf sdbuf;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_ACCOUNTS;
+
+ typedef struct {
+ uint32 len;
+ uint32 maxlen;
+ [size_is(maxlen)][length_is(len)] uint8 *cipher_data;
+ } netr_CIPHER_VALUE;
+
+ typedef struct {
+ netr_CIPHER_VALUE current_cipher;
+ NTTIME current_cipher_set_time;
+ netr_CIPHER_VALUE old_cipher;
+ NTTIME old_cipher_set_time;
+ uint32 SecurityInformation;
+ sec_desc_buf sdbuf;
+ netr_String unknown1;
+ netr_String unknown2;
+ netr_String unknown3;
+ netr_String unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+ } netr_DELTA_SECRET;
+
+ typedef union {
+ [case(1)] netr_DELTA_DOMAIN *domain;
+ [case(2)] netr_DELTA_GROUP *group;
+ [case(4)] netr_DELTA_RENAME *rename_group;
+ [case(5)] netr_DELTA_USER *user;
+ [case(7)] netr_DELTA_RENAME *rename_user;
+ [case(8)] netr_DELTA_GROUP_MEMBER *group_member;
+ [case(9)] netr_DELTA_ALIAS *alias;
+ [case(11)] netr_DELTA_RENAME *rename_alias;
+ [case(12)] netr_DELTA_ALIAS_MEMBER *alias_member;
+ [case(13)] netr_DELTA_POLICY *policy;
+ [case(14)] netr_DELTA_TRUSTED_DOMAINS *trusted_domains;
+ [case(16)] netr_DELTA_ACCOUNTS *accounts;
+ [case(18)] netr_DELTA_SECRET *secret;
+ [case(20)] netr_DELTA_DELETE_USER *delete_group;
+ [case(21)] netr_DELTA_DELETE_USER *delete_user;
+ [case(22)] ULONG8 *modified_count;
+ } netr_DELTA_UNION;
+
+ typedef union {
+ [case(1)] uint32 rid;
+ [case(2)] uint32 rid;
+ [case(3)] uint32 rid;
+ [case(4)] uint32 rid;
+ [case(5)] uint32 rid;
+ [case(6)] uint32 rid;
+ [case(7)] uint32 rid;
+ [case(8)] uint32 rid;
+ [case(9)] uint32 rid;
+ [case(10)] uint32 rid;
+ [case(11)] uint32 rid;
+ [case(12)] uint32 rid;
+ [case(13)] dom_sid2 *sid;
+ [case(14)] dom_sid2 *sid;
+ [case(15)] dom_sid2 *sid;
+ [case(16)] dom_sid2 *sid;
+ [case(17)] dom_sid2 *sid;
+ [case(18)] unistr *Name;
+ [case(19)] unistr *Name;
+ [case(20)] uint32 rid;
+ [case(21)] uint32 rid;
+ } netr_DELTA_ID_UNION;
+
+ typedef struct {
+ uint16 delta_type;
+ [switch_is(delta_type)] netr_DELTA_ID_UNION delta_id_union;
+ [switch_is(delta_type)] netr_DELTA_UNION delta_union;
+ } netr_DELTA_ENUM;
+
+ typedef struct {
+ uint32 num_deltas;
+ [size_is(num_deltas)] netr_DELTA_ENUM *delta_enum;
+ } netr_DELTA_ENUM_ARRAY;
+
+
+ NTSTATUS netr_DatabaseDeltas(
+ [in] unistr logon_server,
+ [in] unistr computername,
+ [in] netr_Authenticator credential,
+ [in,out] netr_Authenticator return_authenticator,
+ [in] uint32 database_id,
+ [in,out] ULONG8 sequence_num,
+ [in] uint32 preferredmaximumlength,
+ [out] netr_DELTA_ENUM_ARRAY *delta_enum_array
+ );
+
+
+ /*****************/
+ /* Function 0x08 */
+
+ NTSTATUS netr_DatabaseSync(
+ [in] unistr logon_server,
+ [in] unistr computername,
+ [in] netr_Authenticator credential,
+ [in,out] netr_Authenticator return_authenticator,
+ [in] uint32 database_id,
+ [in,out] uint32 sync_context,
+ [in] uint32 preferredmaximumlength,
+ [out] netr_DELTA_ENUM_ARRAY *delta_enum_array
+ );
+
+
+ /*****************/
+ /* Function 0x09 */
+
+ /* w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this call */
+
+ typedef [flag(NDR_PAHEX)] struct {
+ uint8 computer_name[16];
+ uint32 timecreated;
+ uint32 serial_number;
+ } netr_UAS_INFO_0;
+
+ typedef struct {
+ [flag(NDR_REMAINING)] DATA_BLOB blob;
+ } netr_AccountBuffer;
+
+ NTSTATUS netr_AccountDeltas(
+ [in] unistr *logon_server,
+ [in] unistr computername,
+ [in] netr_Authenticator credential,
+ [in,out] netr_Authenticator return_authenticator,
+ [in] netr_UAS_INFO_0 uas,
+ [in] uint32 count,
+ [in] uint32 level,
+ [in] uint32 buffersize,
+ [out,subcontext(4)] netr_AccountBuffer buffer,
+ [out] uint32 count_returned,
+ [out] uint32 total_entries,
+ [out] netr_UAS_INFO_0 recordid
+ );
+
+
+ /*****************/
+ /* Function 0x0A */
+
+ NTSTATUS netr_AccountSync(
+ [in] unistr *logon_server,
+ [in] unistr computername,
+ [in] netr_Authenticator credential,
+ [in,out] netr_Authenticator return_authenticator,
+ [in] uint32 reference,
+ [in] uint32 level,
+ [in] uint32 buffersize,
+ [out,subcontext(4)] netr_AccountBuffer buffer,
+ [out] uint32 count_returned,
+ [out] uint32 total_entries,
+ [out] uint32 next_reference,
+ [in,out] netr_UAS_INFO_0 recordid
+ );
+
+
+ /*****************/
+ /* Function 0x0B */
+
+ NTSTATUS netr_GetDcName(
+ [in] unistr logon_server,
+ [in] unistr *domainname,
+ [out] unistr *dcname
+ );
+
+
+
+ /*****************/
+ /* Function 0x0C */
+
+ typedef struct {
+ uint32 flags;
+ uint32 pdc_connection_status;
+ } netr_NETLOGON_INFO_1;
+
+ typedef struct {
+ uint32 flags;
+ uint32 pdc_connection_status;
+ unistr trusted_dc_name;
+ uint32 tc_connection_status;
+ } netr_NETLOGON_INFO_2;
+
+ typedef struct {
+ uint32 flags;
+ uint32 logon_attempts;
+ uint32 unknown1;
+ uint32 unknown2;
+ uint32 unknown3;
+ uint32 unknown4;
+ uint32 unknown5;
+ } netr_NETLOGON_INFO_3;
+
+ typedef union {
+ [case(1)] netr_NETLOGON_INFO_1 *info1;
+ [case(2)] netr_NETLOGON_INFO_2 *info2;
+ [case(3)] netr_NETLOGON_INFO_3 *info3;
+ } netr_CONTROL_QUERY_INFORMATION;
+
+ /* function_code values */
+ const int NETLOGON_CONTROL_REDISCOVER = 5;
+ const int NETLOGON_CONTROL_TC_QUERY = 6;
+ const int NETLOGON_CONTROL_TRANSPORT_NOTIFY = 7;
+ const int NETLOGON_CONTROL_SET_DBFLAG = 65534;
+
+ WERROR netr_LogonControl(
+ [in] unistr *logon_server,
+ [in] uint32 function_code,
+ [in] uint32 level,
+ [out,switch_is(level)] netr_CONTROL_QUERY_INFORMATION info
+ );
+
+
+ /*****************/
+ /* Function 0x0D */
+
+ WERROR netr_GetAnyDCName(
+ [in] unistr *logon_server,
+ [in] unistr *domainname,
+ [out] unistr *dcname
+ );
+
+
+ /*****************/
+ /* Function 0x0E */
+
+ typedef union {
+ [case(NETLOGON_CONTROL_REDISCOVER)] unistr *domain;
+ [case(NETLOGON_CONTROL_TC_QUERY)] unistr *domain;
+ [case(NETLOGON_CONTROL_TRANSPORT_NOTIFY)] unistr *domain;
+ [case(NETLOGON_CONTROL_SET_DBFLAG)] uint32 debug_level;
+ } netr_CONTROL_DATA_INFORMATION;
+
+ WERROR netr_LogonControl2(
+ [in] unistr *logon_server,
+ [in] uint32 function_code,
+ [in] uint32 level,
+ [in][switch_is(function_code)] netr_CONTROL_DATA_INFORMATION data,
+ [out][switch_is(level)] netr_CONTROL_QUERY_INFORMATION query
+ );
+
+
+ /*****************/
+ /* Function 0x0F */
+
+ NTSTATUS netr_ServerAuthenticate2(
+ [in] unistr *server_name,
+ [in] unistr username,
+ [in] uint16 secure_channel_type,
+ [in] unistr computer_name,
+ [in,out] netr_Credential credentials,
+ [in,out,ref] uint32 *negotiate_flags
+ );
+
+
+ /*****************/
+ /* Function 0x10 */
+
+ NTSTATUS netr_DatabaseSync2(
+ [in] unistr logon_server,
+ [in] unistr computername,
+ [in] netr_Authenticator credential,
+ [in,out] netr_Authenticator return_authenticator,
+ [in] uint32 database_id,
+ [in] uint16 restart_state,
+ [in,out] uint32 sync_context,
+ [in] uint32 preferredmaximumlength,
+ [out] netr_DELTA_ENUM_ARRAY *delta_enum_array
+ );
+
+
+ /*****************/
+ /* Function 0x11 */
+
+ /* i'm not at all sure how this call works */
+
+ NTSTATUS netr_DatabaseRedo(
+ [in] unistr logon_server,
+ [in] unistr computername,
+ [in] netr_Authenticator credential,
+ [in,out] netr_Authenticator return_authenticator,
+ [in][size_is(change_log_entry_size)] uint8 *change_log_entry,
+ [in] uint32 change_log_entry_size,
+ [out] netr_DELTA_ENUM_ARRAY *delta_enum_array
+ );
+
+
+ /*****************/
+ /* Function 0x12 */
+
+ WERROR netr_LogonControl2Ex(
+ [in] unistr *logon_server,
+ [in] uint32 function_code,
+ [in] uint32 level,
+ [in][switch_is(function_code)] netr_CONTROL_DATA_INFORMATION data,
+ [out][switch_is(level)] netr_CONTROL_QUERY_INFORMATION query
+ );
+}
diff --git a/source/librpc/idl/ntsvcs.idl b/source/librpc/idl/ntsvcs.idl
new file mode 100644
index 00000000000..88d51a05bae
--- /dev/null
+++ b/source/librpc/idl/ntsvcs.idl
@@ -0,0 +1,15 @@
+/*
+ plug and play services?
+*/
+
+[
+ uuid(8d9f4e40-a03d-11ce-8f69-08003e30051b),
+ version(1.0)
+]
+interface ntsvcs
+{
+
+ /*****************/
+ /* Function 0x00 */
+ WERROR ntsvcs_Unknown0();
+}
diff --git a/source/librpc/idl/protected_storage.idl b/source/librpc/idl/protected_storage.idl
new file mode 100644
index 00000000000..aaf223bbb21
--- /dev/null
+++ b/source/librpc/idl/protected_storage.idl
@@ -0,0 +1,15 @@
+#include "idl_types.h"
+
+/*
+ protected_storage interface definitions
+*/
+
+[ uuid(e3514235-4b06-11d1-ab04-00c04fc2dcd2),
+ version(4.0),
+ pointer_default(unique)
+] interface protected_storage
+{
+ /*****************************/
+ /* Function 0x00 */
+ WERROR ps_XXX ();
+}
diff --git a/source/librpc/idl/samr.idl b/source/librpc/idl/samr.idl
new file mode 100644
index 00000000000..1226d1f7707
--- /dev/null
+++ b/source/librpc/idl/samr.idl
@@ -0,0 +1,894 @@
+#include "idl_types.h"
+
+/*
+ samr interface definition
+*/
+
+/*
+ Thanks to Todd Sabin for some information from his samr.idl in acltools
+*/
+
+[ uuid(12345778-1234-abcd-ef00-0123456789ac),
+ version(1.0),
+ pointer_default(unique)
+] interface samr
+{
+ /******************/
+ /* Function: 0x00 */
+ NTSTATUS samr_Connect (
+ /* notice the lack of [string] */
+ [in] uint16 *system_name,
+ [in] uint32 access_mask,
+ [out,ref] policy_handle *handle
+ );
+
+
+ /******************/
+ /* Function: 0x01 */
+ NTSTATUS samr_Close (
+ [in,out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x02 */
+
+ typedef struct {
+ [value(ndr_size_security_descriptor(r->sd))] uint32 sd_size;
+ [subcontext(4)] security_descriptor *sd;
+ } samr_SdBuf;
+
+ NTSTATUS samr_SetSecurity (
+ [in,ref] policy_handle *handle,
+ [in] uint32 sec_info,
+ [in,ref] samr_SdBuf *sdbuf
+ );
+
+ /******************/
+ /* Function: 0x03 */
+
+ NTSTATUS samr_QuerySecurity (
+ [in,ref] policy_handle *handle,
+ [in] uint32 sec_info,
+ [out] samr_SdBuf *sdbuf
+ );
+
+ /******************/
+ /* Function: 0x04 */
+ NTSTATUS samr_Shutdown ();
+
+ /******************/
+ /* Function: 0x05 */
+ typedef struct {
+ [value(2*strlen_m(r->name))] uint16 name_len;
+ [value(r->name_len)] uint16 name_size;
+ unistr_noterm *name;
+ } samr_Name;
+
+ NTSTATUS samr_LookupDomain (
+ [in,ref] policy_handle *handle,
+ [in,ref] samr_Name *domain,
+ [out] dom_sid2 *sid
+ );
+
+
+ /******************/
+ /* Function: 0x06 */
+
+ typedef struct {
+ uint32 idx;
+ samr_Name name;
+ } samr_SamEntry;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] samr_SamEntry *entries;
+ } samr_SamArray;
+
+ NTSTATUS samr_EnumDomains (
+ [in,ref] policy_handle *handle,
+ [in,out,ref] uint32 *resume_handle,
+ [in] uint32 buf_size,
+ [out] samr_SamArray *sam,
+ [out] uint32 num_entries
+ );
+
+
+ /************************/
+ /* Function 0x07 */
+ NTSTATUS samr_OpenDomain(
+ [in,ref] policy_handle *handle,
+ [in] uint32 access_mask,
+ [in,ref] dom_sid2 *sid,
+ [out,ref] policy_handle *domain_handle
+ );
+
+ /************************/
+ /* Function 0x08 */
+
+ typedef struct {
+ uint16 min_length_password;
+ uint16 password_history;
+ uint32 flag;
+ NTTIME expire;
+ NTTIME min_passwordage;
+ } samr_DomInfo1;
+
+ typedef struct {
+ ULONG8 force_logoff_time;
+ samr_Name unknown1;
+ samr_Name domain; /* domain name */
+ samr_Name primary; /* PDC name if this is a BDC */
+ HYPER_T sequence_num;
+ uint32 unknown2;
+ uint32 role;
+ uint32 unknown3;
+ uint32 num_users;
+ uint32 num_groups;
+ uint32 num_aliases;
+ } samr_DomInfo2;
+
+ typedef struct {
+ ULONG8 force_logoff_time;
+ } samr_DomInfo3;
+
+ typedef struct {
+ samr_Name unknown;
+ } samr_DomInfo4;
+
+ typedef struct {
+ samr_Name domain;
+ } samr_DomInfo5;
+
+ typedef struct {
+ samr_Name primary;
+ } samr_DomInfo6;
+
+ typedef struct {
+ uint32 role;
+ } samr_DomInfo7;
+
+ typedef struct {
+ HYPER_T sequence_num;
+ NTTIME last_xxx_time;
+ } samr_DomInfo8;
+
+ typedef struct {
+ uint32 unknown;
+ } samr_DomInfo9;
+
+ typedef struct {
+ ULONG8 force_logoff_time;
+ samr_Name unknown1;
+ samr_Name domain;
+ samr_Name primary;
+ HYPER_T sequence_num;
+ uint32 unknown2;
+ uint32 role;
+ uint32 unknown3;
+ uint32 num_users;
+ uint32 num_groups;
+ uint32 num_aliases;
+ HYPER_T lockout_duration;
+ HYPER_T lockout_window;
+ uint16 lockout_threshold;
+ } samr_DomInfo11;
+
+ typedef struct {
+ HYPER_T lockout_duration;
+ HYPER_T lockout_window;
+ uint16 lockout_threshold;
+ } samr_DomInfo12;
+
+ typedef struct {
+ HYPER_T sequence_num;
+ NTTIME last_xxx_time;
+ uint32 unknown1;
+ uint32 unknown2;
+ } samr_DomInfo13;
+
+ typedef union {
+ [case(1)] samr_DomInfo1 info1;
+ [case(2)] samr_DomInfo2 info2;
+ [case(3)] samr_DomInfo3 info3;
+ [case(4)] samr_DomInfo4 info4;
+ [case(5)] samr_DomInfo5 info5;
+ [case(6)] samr_DomInfo6 info6;
+ [case(7)] samr_DomInfo7 info7;
+ [case(8)] samr_DomInfo8 info8;
+ [case(9)] samr_DomInfo9 info9;
+ [case(11)] samr_DomInfo11 info11;
+ [case(12)] samr_DomInfo12 info12;
+ [case(13)] samr_DomInfo13 info13;
+ } samr_DomainInfo;
+
+ NTSTATUS samr_QueryDomainInfo(
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [out,switch_is(level)] samr_DomainInfo *info
+ );
+
+ /************************/
+ /* Function 0x09 */
+ NTSTATUS samr_SET_DOMAIN_INFO();
+
+ /************************/
+ /* Function 0x0a */
+ NTSTATUS samr_CREATE_DOM_GROUP();
+
+ /************************/
+ /* Function 0x0b */
+ NTSTATUS samr_EnumDomainGroups(
+ [in,ref] policy_handle *handle,
+ [in,out,ref] uint32 *resume_handle,
+ [in] uint32 max_size,
+ [out] samr_SamArray *sam,
+ [out] uint32 num_entries
+ );
+
+ /************************/
+ /* Function 0x0c */
+ NTSTATUS samr_CreateUser(
+ [in,ref] policy_handle *handle,
+ [in,ref] samr_Name *username,
+ [in] uint32 access_mask,
+ [out,ref] policy_handle *acct_handle,
+ [out,ref] uint32 *rid
+ );
+
+ /************************/
+ /* Function 0x0d */
+ NTSTATUS samr_EnumDomainUsers(
+ [in,ref] policy_handle *handle,
+ [in,out,ref] uint32 *resume_handle,
+ [in] uint32 acct_flags,
+ [in] uint32 max_size,
+ [out] samr_SamArray *sam,
+ [out] uint32 num_entries
+ );
+
+ /************************/
+ /* Function 0x0e */
+ NTSTATUS samr_CreateDomAlias(
+ [in,ref] policy_handle *handle,
+ [in,ref] samr_Name *aliasname,
+ [in] uint32 access_mask,
+ [out,ref] policy_handle *acct_handle,
+ [out,ref] uint32 *rid
+ );
+
+ /************************/
+ /* Function 0x0f */
+ NTSTATUS samr_EnumDomainAliases(
+ [in,ref] policy_handle *handle,
+ [in,out,ref] uint32 *resume_handle,
+ [in] uint32 max_size,
+ [out] samr_SamArray *sam,
+ [out] uint32 num_entries
+ );
+
+ /************************/
+ /* Function 0x10 */
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] uint32 *ids;
+ } samr_Ids;
+
+ NTSTATUS samr_GetAliasMembership(
+ [in,ref] policy_handle *handle,
+ [in,ref] lsa_SidArray *sids,
+ [out] samr_Ids *rids
+ );
+
+ /************************/
+ /* Function 0x11 */
+
+ NTSTATUS samr_LookupNames(
+ [in,ref] policy_handle *handle,
+ [in] uint32 num_names,
+ [in,ref,size_is(1000),length_is(num_names)] samr_Name *names,
+ [out] samr_Ids rids,
+ [out] samr_Ids types
+ );
+
+
+ /************************/
+ /* Function 0x12 */
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] samr_Name *names;
+ } samr_Names;
+
+ NTSTATUS samr_LookupRids(
+ [in,ref] policy_handle *handle,
+ [in] uint32 num_rids,
+ [in,ref,size_is(1000),length_is(num_rids)] uint32 *rids,
+ [out] samr_Names names,
+ [out] samr_Ids types
+ );
+
+ /************************/
+ /* Function 0x13 */
+ NTSTATUS samr_OpenGroup(
+ [in,ref] policy_handle *handle,
+ [in] uint32 access_mask,
+ [in] uint32 rid,
+ [out,ref] policy_handle *acct_handle
+ );
+
+
+ /************************/
+ /* Function 0x14 */
+
+ typedef struct {
+ samr_Name name;
+ uint32 unknown;
+ uint32 num_members;
+ samr_Name description;
+ } samr_GroupInfoAll;
+
+ typedef struct {
+ uint32 unknown;
+ } samr_GroupInfoX;
+
+ typedef struct {
+ samr_Name description;
+ } samr_GroupInfoDesciption;
+
+ typedef enum {
+ GroupInfoAll = 1,
+ GroupInfoName,
+ GroupInfoX,
+ GroupInfoDescription
+ } GroupInfo;
+
+ typedef union {
+ [case(GroupInfoAll)] samr_GroupInfoAll all;
+ [case(GroupInfoName)] samr_Name name;
+ [case(GroupInfoX)] samr_GroupInfoX unknown;
+ [case(GroupInfoDescription)] samr_Name description;
+ } samr_GroupInfo;
+
+ NTSTATUS samr_QueryGroupInfo(
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [out,switch_is(level)] samr_GroupInfo *info
+ );
+
+ /************************/
+ /* Function 0x15 */
+ NTSTATUS samr_SET_GROUPINFO();
+
+ /************************/
+ /* Function 0x16 */
+ NTSTATUS samr_ADD_GROUPMEM();
+
+ /************************/
+ /* Function 0x17 */
+ NTSTATUS samr_DELETE_DOM_GROUP();
+
+ /************************/
+ /* Function 0x18 */
+ NTSTATUS samr_DEL_GROUPMEM();
+
+ /************************/
+ /* Function 0x19 */
+ NTSTATUS samr_QUERY_GROUPMEM();
+
+ /************************/
+ /* Function 0x1a */
+ NTSTATUS samr_SET_MEMBER_ATTRIBUTES_OF_GROUP();
+
+
+ /************************/
+ /* Function 0x1b */
+ NTSTATUS samr_OpenAlias (
+ [in,ref] policy_handle *handle,
+ [in] uint32 access_mask,
+ [in] uint32 rid,
+ [out,ref] policy_handle *acct_handle
+ );
+
+
+ /************************/
+ /* Function 0x1c */
+
+ typedef struct {
+ samr_Name name;
+ uint32 num_members;
+ samr_Name description;
+ } samr_AliasInfoAll;
+
+ typedef union {
+ [case(1)] samr_AliasInfoAll all;
+ [case(2)] samr_Name name;
+ [case(3)] samr_Name description;
+ } samr_AliasInfo;
+
+ NTSTATUS samr_QueryAliasInfo(
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [out,switch_is(level)] samr_AliasInfo *info
+ );
+
+ /************************/
+ /* Function 0x1d */
+ NTSTATUS samr_SetAliasInfo(
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [in,switch_is(level)] samr_AliasInfo info
+ );
+
+ /************************/
+ /* Function 0x1e */
+ NTSTATUS samr_DeleteDomAlias(
+ [in,out,ref] policy_handle *handle
+ );
+
+ /************************/
+ /* Function 0x1f */
+ NTSTATUS samr_AddAliasMem(
+ [in,ref] policy_handle *handle,
+ [in,ref] dom_sid2 *sid
+ );
+
+ /************************/
+ /* Function 0x20 */
+ NTSTATUS samr_DelAliasMem(
+ [in,ref] policy_handle *handle,
+ [in,ref] dom_sid2 *sid
+ );
+
+ /************************/
+ /* Function 0x21 */
+ NTSTATUS samr_GetMembersInAlias(
+ [in,ref] policy_handle *handle,
+ [out,ref] lsa_SidArray *sids
+ );
+
+ /************************/
+ /* Function 0x22 */
+ NTSTATUS samr_OpenUser(
+ [in,ref] policy_handle *handle,
+ [in] uint32 access_mask,
+ [in] uint32 rid,
+ [out,ref] policy_handle *acct_handle
+ );
+
+ /************************/
+ /* Function 0x23 */
+ NTSTATUS samr_DeleteUser(
+ [in,out,ref] policy_handle *handle
+ );
+
+ /************************/
+ /* Function 0x24 */
+ typedef struct {
+ samr_Name username;
+ samr_Name full_name;
+ uint32 primary_gid;
+ samr_Name description;
+ samr_Name comment;
+ } samr_UserInfo1;
+
+ typedef struct {
+ samr_Name comment;
+ samr_Name unknown; /* settable, but doesn't stick. probably obsolete */
+ uint16 country_code;
+ uint16 code_page;
+ } samr_UserInfo2;
+
+ typedef struct {
+ samr_Name username;
+ samr_Name full_name;
+ uint32 Rid;
+ uint32 primary_gid;
+ samr_Name home_directory;
+ samr_Name home_drive;
+ samr_Name logon_script;
+ samr_Name profile;
+ samr_Name workstations;
+ NTTIME last_logon;
+ NTTIME last_logoff;
+ NTTIME last_pwd_change;
+ NTTIME allow_pwd_change;
+ NTTIME force_pwd_change;
+ samr_LogonHours logon_hours;
+ uint16 bad_pwd_count;
+ uint16 num_logons;
+ uint32 acct_flags;
+ } samr_UserInfo3;
+
+ typedef struct {
+ samr_LogonHours logon_hours;
+ } samr_UserInfo4;
+
+ typedef struct {
+ samr_Name username;
+ samr_Name full_name;
+ uint32 rid;
+ uint32 primary_gid;
+ samr_Name home_directory;
+ samr_Name home_drive;
+ samr_Name logon_script;
+ samr_Name profile;
+ samr_Name description;
+ samr_Name workstations;
+ NTTIME last_logon;
+ NTTIME last_logoff;
+ samr_LogonHours logon_hours;
+ uint16 bad_pwd_count;
+ uint16 num_logons;
+ NTTIME last_pwd_change;
+ NTTIME acct_expiry;
+ uint32 acct_flags;
+ } samr_UserInfo5;
+
+ typedef struct {
+ samr_Name username;
+ samr_Name full_name;
+ } samr_UserInfo6;
+
+ typedef struct {
+ samr_Name username;
+ } samr_UserInfo7;
+
+ typedef struct {
+ samr_Name full_name;
+ } samr_UserInfo8;
+
+ typedef struct {
+ uint32 primary_gid;
+ } samr_UserInfo9;
+
+ typedef struct {
+ samr_Name home_dir;
+ samr_Name home_drive;
+ } samr_UserInfo10;
+
+ typedef struct {
+ samr_Name logon_script;
+ } samr_UserInfo11;
+
+ typedef struct {
+ samr_Name profile;
+ } samr_UserInfo12;
+
+ typedef struct {
+ samr_Name description;
+ } samr_UserInfo13;
+
+ typedef struct {
+ samr_Name workstations;
+ } samr_UserInfo14;
+
+ typedef struct {
+ uint32 acct_flags;
+ } samr_UserInfo16;
+
+ typedef struct {
+ NTTIME acct_expiry;
+ } samr_UserInfo17;
+
+ typedef struct {
+ samr_Name callback;
+ } samr_UserInfo20;
+
+ typedef struct {
+ NTTIME last_logon;
+ NTTIME last_logoff;
+ NTTIME last_pwd_change;
+ NTTIME acct_expiry;
+ NTTIME allow_pwd_change;
+ NTTIME force_pwd_change;
+ samr_Name username;
+ samr_Name full_name;
+ samr_Name home_dir;
+ samr_Name home_drive;
+ samr_Name logon_script;
+ samr_Name profile;
+ samr_Name description;
+ samr_Name workstations;
+ samr_Name comment;
+ samr_Name callback;
+ samr_Name unknown1;
+ samr_Name unknown2;
+ samr_Name unknown3;
+ uint32 buf_count;
+ [size_is(buf_count)] uint8 *buffer;
+ uint32 rid;
+ uint32 primary_gid;
+ uint32 acct_flags;
+ uint32 fields_present;
+ samr_LogonHours logon_hours;
+ uint16 bad_pwd_count;
+ uint16 num_logons;
+ uint16 country_code;
+ uint16 code_page;
+ uint8 nt_pwd_set;
+ uint8 lm_pwd_set;
+ uint8 expired_flag;
+ uint8 unknown4;
+ } samr_UserInfo21;
+
+ typedef union {
+ [case(1)] samr_UserInfo1 info1;
+ [case(2)] samr_UserInfo2 info2;
+ [case(3)] samr_UserInfo3 info3;
+ [case(4)] samr_UserInfo4 info4;
+ [case(5)] samr_UserInfo5 info5;
+ [case(6)] samr_UserInfo6 info6;
+ [case(7)] samr_UserInfo7 info7;
+ [case(8)] samr_UserInfo8 info8;
+ [case(9)] samr_UserInfo9 info9;
+ [case(10)] samr_UserInfo10 info10;
+ [case(11)] samr_UserInfo11 info11;
+ [case(12)] samr_UserInfo12 info12;
+ [case(13)] samr_UserInfo13 info13;
+ [case(14)] samr_UserInfo14 info14;
+ [case(16)] samr_UserInfo16 info16;
+ [case(17)] samr_UserInfo17 info17;
+ [case(20)] samr_UserInfo20 info20;
+ [case(21)] samr_UserInfo21 info21;
+ } samr_UserInfo;
+
+ NTSTATUS samr_QueryUserInfo(
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [out,switch_is(level)] samr_UserInfo *info
+ );
+
+
+ /************************/
+ /* Function 0x25 */
+ NTSTATUS samr_SetUserInfo(
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [in,ref,switch_is(level)] samr_UserInfo *info
+ );
+
+ /************************/
+ /* Function 0x26 */
+ NTSTATUS samr_CHANGE_PASSWORD_USER();
+
+ /************************/
+ /* Function 0x27 */
+
+ typedef struct {
+ uint32 rid;
+ uint32 type;
+ } samr_RidType;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] samr_RidType *rid;
+ } samr_RidArray;
+
+ NTSTATUS samr_GetGroupsForUser(
+ [in,ref] policy_handle *handle,
+ [out] samr_RidArray *rids
+ );
+
+ /************************/
+ /* Function 0x28 */
+
+ typedef struct {
+ uint32 idx;
+ uint32 rid;
+ uint32 acct_flags;
+ samr_Name account_name;
+ samr_Name full_name;
+ samr_Name description;
+ } samr_DispEntryGeneral;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] samr_DispEntryGeneral *entries;
+ } samr_DispInfoGeneral;
+
+ typedef struct {
+ uint32 idx;
+ uint32 rid;
+ uint32 acct_flags;
+ samr_Name account_name;
+ samr_Name description;
+ } samr_DispEntryFull;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] samr_DispEntryFull *entries;
+ } samr_DispInfoFull;
+
+ typedef struct {
+ [value(strlen_m(r->name))] uint16 name_len;
+ [value(strlen_m(r->name))] uint16 name_size;
+ ascstr *name;
+ } samr_AsciiName;
+
+ typedef struct {
+ uint32 idx;
+ samr_AsciiName account_name;
+ } samr_DispEntryAscii;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] samr_DispEntryAscii *entries;
+ } samr_DispInfoAscii;
+
+ typedef union {
+ [case(1)] samr_DispInfoGeneral info1;/* users */
+ [case(2)] samr_DispInfoFull info2; /* trust accounts? */
+ [case(3)] samr_DispInfoFull info3; /* groups */
+ [case(4)] samr_DispInfoAscii info4; /* users */
+ [case(5)] samr_DispInfoAscii info5; /* groups */
+ } samr_DispInfo;
+
+ NTSTATUS samr_QueryDisplayInfo(
+ [in,ref] policy_handle *handle,
+ [in] uint16 level,
+ [in] uint32 start_idx,
+ [in] uint32 max_entries,
+ [in] uint32 buf_size,
+ [out] uint32 total_size,
+ [out] uint32 returned_size,
+ [out,switch_is(level)] samr_DispInfo info
+ );
+
+ /************************/
+ /* Function 0x29 */
+ NTSTATUS samr_GET_DISPLAY_ENUMERATION_INDEX();
+
+ /************************/
+ /* Function 0x2a */
+ NTSTATUS samr_TEST_PRIVATE_FUNCTIONS_DOMAIN();
+
+ /************************/
+ /* Function 0x2b */
+ NTSTATUS samr_TEST_PRIVATE_FUNCTIONS_USER();
+
+
+ /************************/
+ /* Function 0x2c */
+
+ /* password properties flags */
+ const uint32 DOMAIN_PASSWORD_COMPLEX = 0x00000001;
+ const uint32 DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002;
+ const uint32 DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004;
+ const uint32 DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010;
+ const uint32 DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020;
+
+ typedef struct {
+ uint16 min_pwd_len;
+ uint32 password_properties;
+ } samr_PwInfo;
+
+ NTSTATUS samr_GetUserPwInfo(
+ [in,ref] policy_handle *handle,
+ [out] samr_PwInfo info
+ );
+
+ /************************/
+ /* Function 0x2d */
+ NTSTATUS samr_REMOVE_MEMBER_FROM_FOREIGN_DOMAIN();
+
+ /************************/
+ /* Function 0x2e */
+ NTSTATUS samr_QUERY_INFORMATION_DOMAIN2();
+
+ /************************/
+ /* Function 0x2f */
+ NTSTATUS samr_QUERY_INFORMATION_USER2();
+
+ /************************/
+ /* Function 0x30 */
+ NTSTATUS samr_QUERY_DISPINFO2();
+
+ /************************/
+ /* Function 0x31 */
+ NTSTATUS samr_GET_DISPLAY_ENUMERATION_INDEX2();
+
+ /************************/
+ /* Function 0x32 */
+ NTSTATUS samr_CreateUser2(
+ /************************/
+ [in,ref] policy_handle *handle,
+ [in,ref] samr_Name *username,
+ [in] uint32 acct_flags,
+ [in] uint32 access_mask,
+ [out,ref] policy_handle *acct_handle,
+ [out,ref] uint32 *access_granted,
+ [out,ref] uint32 *rid
+ );
+
+
+ /************************/
+ /* Function 0x33 */
+ NTSTATUS samr_QUERY_DISPINFO3();
+
+ /************************/
+ /* Function 0x34 */
+ NTSTATUS samr_ADD_MULTIPLE_MEMBERS_TO_ALIAS();
+
+ /************************/
+ /* Function 0x35 */
+ NTSTATUS samr_REMOVE_MULTIPLE_MEMBERS_FROM_ALIAS();
+
+ /************************/
+ /* Function 0x36 */
+ NTSTATUS samr_OEM_CHANGE_PASSWORD_USER2();
+
+ /************************/
+ /* Function 0x37 */
+ NTSTATUS samr_UNICODE_CHANGE_PASSWORD_USER2();
+
+ /************************/
+ /* Function 0x38 */
+ NTSTATUS samr_GET_DOM_PWINFO();
+
+ /************************/
+ /* Function 0x39 */
+ NTSTATUS samr_Connect2(
+ [in] unistr *system_name,
+ [in] uint32 access_mask,
+ [out,ref] policy_handle *handle
+ );
+
+ /************************/
+ /* Function 0x3a */
+ NTSTATUS samr_SET_USERINFO2();
+
+ /************************/
+ /* Function 0x3b */
+ NTSTATUS samr_SET_BOOT_KEY_INFORMATION();
+
+ /************************/
+ /* Function 0x3c */
+ NTSTATUS samr_GET_BOOT_KEY_INFORMATION();
+
+ /************************/
+ /* Function 0x3d */
+ NTSTATUS samr_CONNECT3();
+
+ /************************/
+ /* Function 0x3e */
+ NTSTATUS samr_Connect4(
+ [in] unistr *system_name,
+ [in] uint32 unknown,
+ [in] uint32 access_mask,
+ [out,ref] policy_handle *handle
+ );
+
+ /************************/
+ /* Function 0x3f */
+ NTSTATUS samr_UNICODE_CHANGE_PASSWORD_USER3();
+
+ /************************/
+ /* Function 0x40 */
+ NTSTATUS samr_Connect5(
+ [in] unistr *system_name,
+ [in] uint32 access_mask,
+ [in] uint32 unknown0,
+ [in] uint32 unknown1,
+ [in] uint32 unknown2,
+ [in] uint32 unknown3,
+ [out] uint32 unknown4,
+ [out] uint32 unknown5,
+ [out] uint32 unknown6,
+ [out] uint32 unknown7,
+ [out,ref] policy_handle *handle
+ );
+
+ /************************/
+ /* Function 0x41 */
+ NTSTATUS samr_RID_TO_SID();
+
+ /************************/
+ /* Function 0x42 */
+ NTSTATUS samr_SET_DSRM_PASSWORD();
+
+ /************************/
+ /* Function 0x43 */
+ NTSTATUS samr_VALIDATE_PASSWORD();
+
+}
diff --git a/source/librpc/idl/scerpc.idl b/source/librpc/idl/scerpc.idl
new file mode 100644
index 00000000000..049de3b19b9
--- /dev/null
+++ b/source/librpc/idl/scerpc.idl
@@ -0,0 +1,16 @@
+/*
+ security configuration editor interface definitions
+*/
+
+[
+ uuid(93149ca2-973b-11d1-8c39-00c04fb984f9),
+ version(0.0)
+]
+interface scerpc
+{
+
+ /*****************/
+ /* Function 0x00 */
+ WERROR scerpc_Unknown0();
+}
+
diff --git a/source/librpc/idl/spoolss.idl b/source/librpc/idl/spoolss.idl
new file mode 100644
index 00000000000..f9cd7705834
--- /dev/null
+++ b/source/librpc/idl/spoolss.idl
@@ -0,0 +1,843 @@
+#include "idl_types.h"
+
+/*
+ spoolss interface definitions
+*/
+
+[ uuid(12345678-1234-abcd-ef00-0123456789ab),
+ version(1.0),
+ pointer_default(unique)
+] interface spoolss
+{
+ typedef struct {
+ nstring devicename;
+ uint16 specversion;
+ uint16 driverversion;
+ uint16 size;
+ uint16 driverextra;
+ uint32 fields;
+ uint16 orientation;
+ uint16 papersize;
+ uint16 paperlength;
+ uint16 paperwidth;
+ uint16 scale;
+ uint16 copies;
+ uint16 defaultsource;
+ uint16 printquality;
+ uint16 color;
+ uint16 duplex;
+ uint16 yresolution;
+ uint16 ttoption;
+ uint16 collate;
+ nstring formname;
+ uint16 logpixels;
+ uint32 bitsperpel;
+ uint32 pelswidth;
+ uint32 pelsheight;
+ uint32 displayflags;
+ uint32 displayfrequency;
+ uint32 icmmethod;
+ uint32 icmintent;
+ uint32 mediatype;
+ uint32 dithertype;
+ uint32 reserved1;
+ uint32 reserved2;
+ uint32 panningwidth;
+ uint32 panningheight;
+ uint8 private[driverextra];
+ } spoolss_DeviceMode;
+
+ typedef struct {
+ uint32 flags;
+ [relative] nstring *name;
+ [relative] nstring *description;
+ [relative] nstring *comment;
+ } spoolss_PrinterInfo1;
+
+ typedef struct {
+ uint32 flags;
+ [relative] nstring *name;
+ uint32 width;
+ uint32 length;
+ uint32 left;
+ uint32 top;
+ uint32 right;
+ uint32 bottom;
+ } spoolss_FormInfo1;
+
+ typedef struct {
+ [relative] nstring *servername;
+ [relative] nstring *printername;
+ [relative] nstring *sharename;
+ [relative] nstring *portname;
+ [relative] nstring *drivername;
+ [relative] nstring *comment;
+ [relative] nstring *location;
+ [relative] spoolss_DeviceMode *devmode;
+ [relative] nstring *sepfile;
+ [relative] nstring *printprocessor;
+ [relative] nstring *datatype;
+ [relative] nstring *parameters;
+ [relative] security_descriptor *secdesc;
+ uint32 attributes;
+ uint32 priority;
+ uint32 defaultpriority;
+ uint32 starttime;
+ uint32 untiltime;
+ uint32 status;
+ uint32 cjobs;
+ uint32 averageppm;
+ } spoolss_PrinterInfo2;
+
+ typedef struct {
+ uint32 flags;
+ security_descriptor secdesc;
+ } spoolss_PrinterInfo3;
+
+ typedef struct {
+ [relative] nstring *printername;
+ [relative] nstring *servername;
+ uint32 attributes;
+ } spoolss_PrinterInfo4;
+
+ typedef struct {
+ [relative] nstring *printername;
+ [relative] nstring *portname;
+ uint32 attributes;
+ uint32 device_not_selected_timeout;
+ uint32 transmission_retry_timeout;
+ } spoolss_PrinterInfo5;
+
+ typedef struct {
+ uint32 unknown;
+ } spoolss_PrinterInfo6;
+
+ typedef struct {
+ [relative] nstring *guid; /* text form of printer guid */
+ uint32 action;
+ } spoolss_PrinterInfo7;
+
+ typedef [nodiscriminant,public] union {
+ [case(1)] spoolss_PrinterInfo1 info1;
+ [case(2)] spoolss_PrinterInfo2 info2;
+ [case(3)] spoolss_PrinterInfo3 info3;
+ [case(4)] spoolss_PrinterInfo4 info4;
+ [case(5)] spoolss_PrinterInfo5 info5;
+ [case(6)] spoolss_PrinterInfo6 info6;
+ [case(7)] spoolss_PrinterInfo7 info7;
+ } spoolss_PrinterInfo;
+
+ /******************/
+ /* Function: 0x00 */
+ WERROR spoolss_EnumPrinters(
+ [in] uint32 flags,
+ [in] unistr *server,
+ [in] uint32 level,
+ [in,out] DATA_BLOB *buffer,
+ [in,out,ref] uint32 *buf_size,
+ [out] uint32 count
+ );
+
+ /******************/
+ /* Function: 0x01 */
+ WERROR spoolss_OpenPrinter(
+ [in] unistr *server,
+ [in] unistr *printer,
+ [in] DATA_BLOB *buffer,
+ [in] uint32 access_mask,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x02 */
+ WERROR spoolss_SetJob(
+ [in,ref] policy_handle *handle,
+ [in] uint32 job_id,
+ [in] uint32 level,
+ [in] uint32 command
+ );
+
+ /******************/
+ /* Function: 0x03 */
+ WERROR spoolss_GetJob(
+ [in,ref] policy_handle *handle,
+ [in] uint32 job_id,
+ [in] uint32 level,
+ [in] DATA_BLOB *buffer,
+ [out,subcontext(4),switch_is(level)] spoolss_JobInfo *info,
+ [in,out,ref] uint32 *buf_size
+ );
+
+ typedef struct {
+ uint16 year;
+ uint16 month;
+ uint16 day_of_week;
+ uint16 day;
+ uint16 hour;
+ uint16 minute;
+ uint16 second;
+ uint16 millisecond;
+ } spoolss_Time;
+
+ typedef struct {
+ uint32 job_id;
+ [relative] nstring printer_name;
+ [relative] nstring server_name;
+ [relative] nstring user_name;
+ [relative] nstring document_name;
+ [relative] nstring data_type;
+ [relative] nstring text_status;
+ uint32 status;
+ uint32 priority;
+ uint32 position;
+ uint32 total_pages;
+ uint32 pages_printed;
+ spoolss_Time time;
+ } spoolss_JobInfo1;
+
+ typedef [nodiscriminant,public] union {
+ [case(1)] spoolss_JobInfo1 info1;
+ } spoolss_JobInfo;
+
+ /******************/
+ /* Function: 0x04 */
+ WERROR spoolss_EnumJobs(
+ [in,ref] policy_handle *handle,
+ [in] uint32 firstjob,
+ [in] uint32 numjobs,
+ [in] uint32 level,
+ [in,out] DATA_BLOB *buffer,
+ [in,out,ref] uint32 *buf_size,
+ [out] uint32 count
+ );
+
+ /******************/
+ /* Function: 0x05 */
+ WERROR spoolss_AddPrinter(
+ /* This function is not implemented in Samba 3 as no
+ clients have been observed using it. */
+ );
+
+ /******************/
+ /* Function: 0x06 */
+ WERROR spoolss_DeletePrinter(
+ );
+
+ /******************/
+ /* Function: 0x07 */
+ WERROR spoolss_SetPrinter(
+ );
+
+ /******************/
+ /* Function: 0x08 */
+ WERROR spoolss_GetPrinter(
+ [in,ref] policy_handle *handle,
+ [in] uint32 level,
+ [in] DATA_BLOB *buffer,
+ [out,subcontext(4),switch_is(level)] spoolss_PrinterInfo *info,
+ [in,out,ref] uint32 *buf_size
+ );
+
+ /******************/
+ /* Function: 0x09 */
+ WERROR spoolss_AddPrinterDriver(
+ );
+
+ typedef struct {
+ [relative] nstring *driver_name;
+ } spoolss_DriverInfo1;
+
+ typedef struct {
+ uint32 version;
+ [relative] nstring *driver_name;
+ [relative] nstring *architecture;
+ [relative] nstring *driver_path;
+ [relative] nstring *data_file;
+ [relative] nstring *config_file;
+ } spoolss_DriverInfo2;
+
+ typedef struct {
+ uint32 version;
+ [relative] nstring *driver_name;
+ [relative] nstring *architecture;
+ [relative] nstring *driver_path;
+ [relative] nstring *data_file;
+ [relative] nstring *config_file;
+ [relative] nstring *help_file;
+ [relative] nstring *dependent_files; /* array */
+ [relative] nstring *monitor_name;
+ [relative] nstring *default_datatype;
+ } spoolss_DriverInfo3;
+
+ typedef [nodiscriminant,public] union {
+ [case(1)] spoolss_DriverInfo1 info1;
+ [case(2)] spoolss_DriverInfo2 info2;
+ [case(3)] spoolss_DriverInfo3 info3;
+ } spoolss_DriverInfo;
+
+ /******************/
+ /* Function: 0x0a */
+ WERROR spoolss_EnumPrinterDrivers(
+ [in] unistr *server,
+ [in] unistr *environment,
+ [in] uint32 level,
+ [in,out] DATA_BLOB *buffer,
+ [in,out,ref] uint32 *buf_size,
+ [out] uint32 count
+ );
+
+ /******************/
+ /* Function: 0x0b */
+ WERROR spoolss_GetPrinterDriver(
+ );
+
+ /******************/
+ /* Function: 0x0c */
+ WERROR spoolss_GetPrinterDriverDirectory(
+ );
+
+ /******************/
+ /* Function: 0x0d */
+ WERROR spoolss_DeletePrinterDriver(
+ [in,ref] policy_handle *handle,
+ [in] unistr *server,
+ [in] unistr architecture,
+ [in] unistr driver
+ );
+
+ /******************/
+ /* Function: 0x0e */
+ WERROR spoolss_AddPrintProcessor(
+ );
+
+ /******************/
+ /* Function: 0x0f */
+ WERROR spoolss_EnumPrintProcessors(
+ );
+
+ /******************/
+ /* Function: 0x10 */
+ WERROR spoolss_GetPrintProcessorDirectory(
+ );
+
+ /******************/
+ /* Function: 0x11 */
+ WERROR spoolss_StartDocPrinter(
+ );
+
+ /******************/
+ /* Function: 0x12 */
+ WERROR spoolss_StartPagePrinter(
+ [in,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x13 */
+ WERROR spoolss_WritePrinter(
+ );
+
+ /******************/
+ /* Function: 0x14 */
+ WERROR spoolss_EndPagePrinter(
+ [in,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x15 */
+ WERROR spoolss_AbortPrinter(
+ );
+
+ /******************/
+ /* Function: 0x16 */
+ WERROR spoolss_ReadPrinter(
+ );
+
+ /******************/
+ /* Function: 0x17 */
+ WERROR spoolss_EndDocPrinter(
+ );
+
+ /******************/
+ /* Function: 0x18 */
+ WERROR spoolss_AddJob(
+ );
+
+ /******************/
+ /* Function: 0x19 */
+ WERROR spoolss_ScheduleJob(
+ );
+
+ /******************/
+ /* Function: 0x1a */
+ WERROR spoolss_GetPrinterData(
+ [in,ref] policy_handle *handle,
+ [in] unistr value_name,
+ [out] uint32 type,
+ [out] DATA_BLOB buffer,
+ [in,out,ref] uint32 *buf_size
+ );
+
+ /******************/
+ /* Function: 0x1b */
+ WERROR spoolss_SetPrinterData(
+ [in,ref] policy_handle *handle,
+ [in] unistr value_name,
+ [in] uint32 type,
+ [in] DATA_BLOB buffer,
+ [in] uint32 real_len
+ );
+
+ /******************/
+ /* Function: 0x1c */
+ WERROR spoolss_WaitForPrinterChange(
+ );
+
+ /******************/
+ /* Function: 0x1d */
+ WERROR spoolss_ClosePrinter(
+ [in,out,ref] policy_handle *handle
+ );
+
+ typedef struct {
+ uint32 flags;
+ [relative] unistr *name;
+ uint32 width;
+ uint32 length;
+ uint32 left;
+ uint32 top;
+ uint32 right;
+ uint32 bottom;
+ } spoolss_AddFormInfo1;
+
+ typedef union {
+ [case(1)] spoolss_AddFormInfo1 *info1;
+ } spoolss_AddFormInfo;
+
+ /******************/
+ /* Function: 0x1e */
+ WERROR spoolss_AddForm(
+ [in,ref] policy_handle *handle,
+ [in] uint32 level,
+ [in,switch_is(level)] spoolss_AddFormInfo info
+ );
+
+ /******************/
+ /* Function: 0x1f */
+ WERROR spoolss_DeleteForm(
+ [in,ref] policy_handle *handle,
+ [in] unistr formname
+ );
+
+ /******************/
+ /* Function: 0x20 */
+ WERROR spoolss_GetForm(
+ [in,ref] policy_handle *handle,
+ [in] unistr formname,
+ [in] uint32 level,
+ [in] DATA_BLOB *buffer,
+ [out,subcontext(4),switch_is(level)] spoolss_FormInfo *info,
+ [in,out,ref] uint32 *buf_size
+ );
+
+ /******************/
+ /* Function: 0x21 */
+ WERROR spoolss_SetForm(
+ [in,ref] policy_handle *handle,
+ [in] unistr form_name,
+ [in] uint32 level,
+ [in,switch_is(level)] spoolss_AddFormInfo info
+ );
+
+ typedef [nodiscriminant,public] union {
+ [case(1)] spoolss_FormInfo1 info1;
+ } spoolss_FormInfo;
+
+ /******************/
+ /* Function: 0x22 */
+ WERROR spoolss_EnumForms(
+ [in,ref] policy_handle *handle,
+ [in] uint32 level,
+ [in,out] DATA_BLOB *buffer,
+ [in,out,ref] uint32 *buf_size,
+ [out] uint32 count
+ );
+
+ /******************/
+ /* Function: 0x23 */
+ WERROR spoolss_EnumPorts(
+ );
+
+ /******************/
+ /* Function: 0x24 */
+ WERROR spoolss_EnumMonitors(
+ );
+
+ /******************/
+ /* Function: 0x25 */
+ WERROR spoolss_AddPort(
+ );
+
+ /******************/
+ /* Function: 0x26 */
+ WERROR spoolss_ConfigurePort(
+ );
+
+ /******************/
+ /* Function: 0x27 */
+ WERROR spoolss_DeletePort(
+ );
+
+ /******************/
+ /* Function: 0x28 */
+ WERROR spoolss_CreatePrinterIC(
+ );
+
+ /******************/
+ /* Function: 0x29 */
+ WERROR spoolss_PlayGDIScriptOnPrinterIC(
+ );
+
+ /******************/
+ /* Function: 0x2a */
+ WERROR spoolss_DeletePrinterIC(
+ );
+
+ /******************/
+ /* Function: 0x2b */
+ WERROR spoolss_AddPrinterConnection(
+ );
+
+ /******************/
+ /* Function: 0x2c */
+ WERROR spoolss_DeletePrinterConnection(
+ );
+
+ /******************/
+ /* Function: 0x2d */
+ WERROR spoolss_PrinterMessageBox(
+ /* Marked as obsolete in MSDN. "Not necessary and has
+ no effect". */
+ );
+
+ /******************/
+ /* Function: 0x2e */
+ WERROR spoolss_AddMonitor(
+ );
+
+ /******************/
+ /* Function: 0x2f */
+ WERROR spoolss_DeleteMonitor(
+ );
+
+ /******************/
+ /* Function: 0x30 */
+ WERROR spoolss_DeletePrintProcessor(
+ );
+
+ /******************/
+ /* Function: 0x31 */
+ WERROR spoolss_AddPrintProvidor(
+ );
+
+ /******************/
+ /* Function: 0x32 */
+ WERROR spoolss_DeletePrintProvidor(
+ );
+
+ /******************/
+ /* Function: 0x33 */
+ WERROR spoolss_EnumPrintProcDataTypes(
+ );
+
+ /******************/
+ /* Function: 0x34 */
+ WERROR spoolss_ResetPrinter(
+ );
+
+ /******************/
+ /* Function: 0x35 */
+ WERROR spoolss_GetPrinterDriver2(
+ [in,ref] policy_handle *handle,
+ [in] unistr *architecture,
+ [in] uint32 level,
+ [in,out] DATA_BLOB *buffer,
+ [in,out,ref] uint32 *buf_size,
+ [in] uint32 client_major_version,
+ [in] uint32 client_minor_version,
+ [out] uint32 server_major_version,
+ [out] uint32 server_minor_version
+ );
+
+ /******************/
+ /* Function: 0x36 */
+ WERROR spoolss_FindFirstPrinterChangeNotification(
+ );
+
+ /******************/
+ /* Function: 0x37 */
+ WERROR spoolss_FindNextPrinterChangeNotification(
+ );
+
+ /******************/
+ /* Function: 0x38 */
+ WERROR spoolss_FindClosePrinterNotify(
+ );
+
+ /******************/
+ /* Function: 0x39 */
+ WERROR spoolss_RouterFindFirstPrinterChangeNotificationOld(
+ );
+
+ /******************/
+ /* Function: 0x3a */
+ WERROR spoolss_ReplyOpenPrinter(
+ );
+
+ /******************/
+ /* Function: 0x3b */
+ WERROR spoolss_RouterReplyPrinter(
+ );
+
+ /******************/
+ /* Function: 0x3c */
+ WERROR spoolss_ReplyClosePrinter(
+ );
+
+ /******************/
+ /* Function: 0x3d */
+ WERROR spoolss_AddPortEx(
+ );
+
+ /******************/
+ /* Function: 0x3e */
+ WERROR spoolss_RouterFindFirstPrinterChangeNotification(
+ );
+
+ /******************/
+ /* Function: 0x3f */
+ WERROR spoolss_SpoolerInit(
+ );
+
+ /******************/
+ /* Function: 0x40 */
+ WERROR spoolss_ResetPrinterEx(
+ );
+
+ /******************/
+ /* Function: 0x41 */
+ WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx(
+ );
+
+ /******************/
+ /* Function: 0x42 */
+ WERROR spoolss_RouterRefreshPrinterChangeNotification(
+ );
+
+ /******************/
+ /* Function: 0x43 */
+ WERROR spoolss_RemoteFindNextPrinterChangeNotifyEx(
+ );
+
+ /******************/
+ /* Function: 0x44 */
+ WERROR spoolss_44(
+ );
+
+ typedef struct {
+ uint32 foo;
+ } spoolss_Devmode;
+
+ typedef struct {
+ uint32 size;
+ spoolss_Devmode *devmode;
+ } spoolss_DevmodeContainer;
+
+ typedef struct {
+ uint32 size;
+ unistr *client;
+ unistr *user;
+ uint32 build;
+ uint32 major;
+ uint32 minor;
+ uint32 processor;
+ } spoolss_UserLevel1;
+
+ typedef union {
+ [case(1)] spoolss_UserLevel1 *level1;
+ } spoolss_UserLevel;
+
+ /******************/
+ /* Function: 0x45 */
+ WERROR spoolss_OpenPrinterEx(
+ [in] unistr *printername,
+ [in] unistr *datatype,
+ [in] spoolss_DevmodeContainer devmode_ctr,
+ [in] uint32 access_required,
+ [in] uint32 level,
+ [in,switch_is(level)] spoolss_UserLevel userlevel,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x46 */
+ WERROR spoolss_AddPrinterEx(
+ [in] unistr *server,
+ [in] uint32 level,
+ [in,switch_is(level)] spoolss_PrinterInfo *info,
+ [in] spoolss_DevmodeContainer devmode_ctr,
+ [in] security_descriptor *secdesc,
+ [in] uint32 ulevel,
+ [in,switch_is(ulevel)] spoolss_UserLevel userlevel
+ );
+
+ /******************/
+ /* Function: 0x47 */
+ WERROR spoolss_47(
+ );
+
+ /******************/
+ /* Function: 0x48 */
+ WERROR spoolss_EnumPrinterData(
+ [in,ref] policy_handle *handle,
+ [in] uint32 enum_index,
+ [in] uint32 value_offered,
+ [out] lstring value_name,
+ [out] uint32 value_needed,
+ [out] uint32 printerdata_type,
+ [out] DATA_BLOB data,
+ [in,out,ref] uint32 *data_size
+ );
+
+ /******************/
+ /* Function: 0x49 */
+ WERROR spoolss_DeletePrinterData(
+ [in,ref] policy_handle *handle,
+ [in] unistr value_name
+ );
+
+ /******************/
+ /* Function: 0x4a */
+ WERROR spoolss_4a(
+ );
+
+ /******************/
+ /* Function: 0x4b */
+ WERROR spoolss_4b(
+ );
+
+ /******************/
+ /* Function: 0x4c */
+ WERROR spoolss_4c(
+ );
+
+ /******************/
+ /* Function: 0x4d */
+ WERROR spoolss_SetPrinterDataEx(
+ [in,ref] policy_handle *handle,
+ [in] unistr key_name,
+ [in] unistr value_name,
+ [in] uint32 type,
+ [in] DATA_BLOB buffer,
+ [in,out,ref] uint32 *buf_size
+ );
+
+ /******************/
+ /* Function: 0x4e */
+ WERROR spoolss_GetPrinterDataEx(
+ [in,ref] policy_handle *handle,
+ [in] unistr key_name,
+ [in] unistr value_name,
+ [out] uint32 type,
+ [out] DATA_BLOB buffer,
+ [in,out,ref] uint32 *buf_size
+ );
+
+ /******************/
+ /* Function: 0x4f */
+ WERROR spoolss_EnumPrinterDataEx(
+ [in,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x50 */
+ WERROR spoolss_EnumPrinterKey(
+ );
+
+ /******************/
+ /* Function: 0x51 */
+ WERROR spoolss_DeletePrinterDataEx(
+ [in,ref] policy_handle *handle,
+ [in] unistr key_name,
+ [in] unistr value_name
+ );
+
+ /******************/
+ /* Function: 0x52 */
+ WERROR spoolss_DeletePrinterKey(
+ );
+
+ /******************/
+ /* Function: 0x53 */
+ WERROR spoolss_53(
+ );
+
+ /******************/
+ /* Function: 0x54 */
+ WERROR spoolss_DeletePrinterDriverEx(
+ );
+
+ /******************/
+ /* Function: 0x55 */
+ WERROR spoolss_55(
+ );
+
+ /******************/
+ /* Function: 0x56 */
+ WERROR spoolss_56(
+ );
+
+ /******************/
+ /* Function: 0x57 */
+ WERROR spoolss_57(
+ );
+
+ /******************/
+ /* Function: 0x58 */
+ WERROR spoolss_58(
+ );
+
+ /******************/
+ /* Function: 0x59 */
+ WERROR spoolss_AddPrinterDriverEx(
+ );
+
+ /******************/
+ /* Function: 0x5a */
+ WERROR spoolss_5a(
+ );
+
+ /******************/
+ /* Function: 0x5b */
+ WERROR spoolss_5b(
+ );
+
+ /******************/
+ /* Function: 0x5c */
+ WERROR spoolss_5c(
+ );
+
+ /******************/
+ /* Function: 0x5d */
+ WERROR spoolss_5d(
+ );
+
+ /******************/
+ /* Function: 0x5e */
+ WERROR spoolss_5e(
+ );
+
+ /******************/
+ /* Function: 0x5f */
+ WERROR spoolss_5f(
+ );
+}
diff --git a/source/librpc/idl/srvsvc.idl b/source/librpc/idl/srvsvc.idl
new file mode 100644
index 00000000000..4d737a6c0d7
--- /dev/null
+++ b/source/librpc/idl/srvsvc.idl
@@ -0,0 +1,1241 @@
+#include "idl_types.h"
+
+/*
+ srvsvc interface definitions
+*/
+
+[ uuid(4b324fc8-1670-01d3-1278-5a47bf6ee188),
+ version(3.0),
+ pointer_default(unique)
+] interface srvsvc
+{
+/**************************/
+/* srvsvc_NetCharDev */
+/**************************/
+ typedef struct {
+ unistr *device;
+ } srvsvc_NetCharDevInfo0;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetCharDevInfo0 *array;
+ } srvsvc_NetCharDevCtr0;
+
+ typedef struct {
+ unistr *device;
+ uint32 status;
+ unistr *user;
+ uint32 time;
+ } srvsvc_NetCharDevInfo1;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetCharDevInfo1 *array;
+ } srvsvc_NetCharDevCtr1;
+
+ typedef union {
+ [case(0)] srvsvc_NetCharDevInfo0 *info0;
+ [case(1)] srvsvc_NetCharDevInfo1 *info1;
+ [default] ;
+ } srvsvc_NetCharDevInfo;
+
+ typedef union {
+ [case(0)] srvsvc_NetCharDevCtr0 *ctr0;
+ [case(1)] srvsvc_NetCharDevCtr1 *ctr1;
+ [default] ;
+ } srvsvc_NetCharDevCtr;
+
+ /******************/
+ /* Function: 0x00 */
+ WERROR srvsvc_NetCharDevEnum(
+ [in] unistr *server_unc,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] srvsvc_NetCharDevCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x01 */
+ WERROR srvsvc_NetCharDevGetInfo(
+ [in] unistr *server_unc,
+ [in] unistr device_name,
+ [in] uint32 level,
+ [out,switch_is(level)] srvsvc_NetCharDevInfo info
+ );
+
+ /******************/
+ /* Function: 0x02 */
+ WERROR srvsvc_NetCharDevControl(
+ [in] unistr *server_unc,
+ [in] unistr device_name,
+ [in] uint32 opcode
+ );
+
+/**************************/
+/* srvsvc_NetCharDevQ */
+/**************************/
+ typedef struct {
+ unistr *device;
+ } srvsvc_NetCharDevQInfo0;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetCharDevQInfo0 *array;
+ } srvsvc_NetCharDevQCtr0;
+
+ typedef struct {
+ unistr *device;
+ uint32 priority;
+ unistr *devices;
+ uint32 users;
+ uint32 num_ahead;
+ } srvsvc_NetCharDevQInfo1;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetCharDevQInfo1 *array;
+ } srvsvc_NetCharDevQCtr1;
+
+ typedef union {
+ [case(0)] srvsvc_NetCharDevQInfo0 *info0;
+ [case(1)] srvsvc_NetCharDevQInfo1 *info1;
+ [default] ;
+ } srvsvc_NetCharDevQInfo;
+
+ typedef union {
+ [case(0)] srvsvc_NetCharDevQCtr0 *ctr0;
+ [case(1)] srvsvc_NetCharDevQCtr1 *ctr1;
+ [default] ;
+ } srvsvc_NetCharDevQCtr;
+
+ /******************/
+ /* Function: 0x03 */
+ WERROR srvsvc_NetCharDevQEnum(
+ [in] unistr *server_unc,
+ [in] unistr *user,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] srvsvc_NetCharDevQCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x04 */
+ WERROR srvsvc_NetCharDevQGetInfo(
+ [in] unistr *server_unc,
+ [in] unistr queue_name,
+ [in] unistr user,
+ [in] uint32 level,
+ [out,switch_is(level)] srvsvc_NetCharDevQInfo info
+ );
+
+ /******************/
+ /* Function: 0x05 */
+ WERROR srvsvc_NetCharDevQSetInfo(
+ [in] unistr *server_unc,
+ [in] unistr queue_name,
+ [in] uint32 level,
+ [in,switch_is(level)] srvsvc_NetCharDevQInfo info,
+ [in,out] uint32 *parm_error
+ );
+
+ /******************/
+ /* Function: 0x06 */
+ WERROR srvsvc_NetCharDevQPurge(
+ [in] unistr *server_unc,
+ [in] unistr queue_name
+ );
+
+ /******************/
+ /* Function: 0x07 */
+ WERROR srvsvc_NetCharDevQPurgeSelf(
+ [in] unistr *server_unc,
+ [in] unistr queue_name,
+ [in] unistr computer_name
+ );
+
+/**************************/
+/* srvsvc_NetConn */
+/**************************/
+ typedef struct {
+ uint32 conn_id;
+ } srvsvc_NetConnInfo0;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetConnInfo0 *array;
+ } srvsvc_NetConnCtr0;
+
+ typedef struct {
+ uint32 conn_id;
+ uint32 conn_type;
+ uint32 num_open;
+ uint32 num_users;
+ uint32 conn_time;
+ unistr *user;
+ unistr *client;
+ } srvsvc_NetConnInfo1;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetConnInfo1 *array;
+ } srvsvc_NetConnCtr1;
+
+ typedef union {
+ [case(0)] srvsvc_NetConnCtr0 *ctr0;
+ [case(1)] srvsvc_NetConnCtr1 *ctr1;
+ [default] ;
+ } srvsvc_NetConnCtr;
+
+ /******************/
+ /* Function: 0x08 */
+ WERROR srvsvc_NetConnEnum(
+ [in] unistr *server_unc,
+ [in] unistr *path,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] srvsvc_NetConnCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+/**************************/
+/* srvsvc_NetFile */
+/**************************/
+ typedef struct {
+ uint32 fid;
+ } srvsvc_NetFileInfo2;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetFileInfo2 *array;
+ } srvsvc_NetFileCtr2;
+
+ typedef struct {
+ uint32 fid;
+ uint32 permissions;
+ uint32 num_locks;
+ unistr *path;
+ unistr *user;
+ } srvsvc_NetFileInfo3;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetFileInfo3 *array;
+ } srvsvc_NetFileCtr3;
+
+ typedef union {
+ [case(2)] srvsvc_NetFileInfo2 *info2;
+ [case(3)] srvsvc_NetFileInfo3 *info3;
+ [default] ;
+ } srvsvc_NetFileInfo;
+
+ typedef union {
+ [case(2)] srvsvc_NetFileCtr2 *ctr2;
+ [case(3)] srvsvc_NetFileCtr3 *ctr3;
+ [default] ;
+ } srvsvc_NetFileCtr;
+
+ /******************/
+ /* Function: 0x09 */
+ WERROR srvsvc_NetFileEnum(
+ [in] unistr *server_unc,
+ [in] unistr *path,
+ [in] unistr *user,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] srvsvc_NetFileCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x0a */
+ WERROR srvsvc_NetFileGetInfo(
+ [in] unistr *server_unc,
+ [in] uint32 fid,
+ [in] uint32 level,
+ [out,switch_is(level)] srvsvc_NetFileInfo info
+ );
+
+ /******************/
+ /* Function: 0x0b */
+ WERROR srvsvc_NetFileClose(
+ [in] unistr *server_unc,
+ [in] uint32 fid
+ );
+
+/**************************/
+/* srvsvc_NetSess */
+/**************************/
+ typedef struct {
+ unistr *client;
+ } srvsvc_NetSessInfo0;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetSessInfo0 *array;
+ } srvsvc_NetSessCtr0;
+
+ typedef struct {
+ unistr *client;
+ unistr *user;
+ uint32 num_open;
+ uint32 time;
+ uint32 idle_time;
+ uint32 user_flags;
+ } srvsvc_NetSessInfo1;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetSessInfo1 *array;
+ } srvsvc_NetSessCtr1;
+
+ typedef struct {
+ unistr *client;
+ unistr *user;
+ uint32 num_open;
+ uint32 time;
+ uint32 idle_time;
+ uint32 user_flags;
+ unistr *client_type;
+ } srvsvc_NetSessInfo2;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetSessInfo2 *array;
+ } srvsvc_NetSessCtr2;
+
+ typedef struct {
+ unistr *client;
+ unistr *user;
+ uint32 time;
+ uint32 idle_time;
+ } srvsvc_NetSessInfo10;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetSessInfo10 *array;
+ } srvsvc_NetSessCtr10;
+
+ typedef struct {
+ unistr *client;
+ unistr *user;
+ uint32 num_open;
+ uint32 time;
+ uint32 idle_time;
+ uint32 user_flags;
+ unistr *client_type;
+ unistr *transport;
+ } srvsvc_NetSessInfo502;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetSessInfo502 *array;
+ } srvsvc_NetSessCtr502;
+
+ typedef union {
+ [case(0)] srvsvc_NetSessCtr0 *ctr0;
+ [case(1)] srvsvc_NetSessCtr1 *ctr1;
+ [case(2)] srvsvc_NetSessCtr2 *ctr2;
+ [case(10)] srvsvc_NetSessCtr10 *ctr10;
+ [case(502)] srvsvc_NetSessCtr502 *ctr502;
+ [default] ;
+ } srvsvc_NetSessCtr;
+
+ /******************/
+ /* Function: 0x0c */
+ WERROR srvsvc_NetSessEnum(
+ [in] unistr *server_unc,
+ [in] unistr *client,
+ [in] unistr *user,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] srvsvc_NetSessCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x0d */
+ WERROR srvsvc_NetSessDel(
+ [in] unistr *server_unc,
+ [in] unistr *client,
+ [in] unistr *user
+ );
+
+/**************************/
+/* srvsvc_NetShare */
+/**************************/
+ typedef struct {
+ unistr *name;
+ } srvsvc_NetShareInfo0;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetShareInfo0 *array;
+ } srvsvc_NetShareCtr0;
+
+ typedef struct {
+ unistr *name;
+ uint32 type;
+ unistr *comment;
+ } srvsvc_NetShareInfo1;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetShareInfo1 *array;
+ } srvsvc_NetShareCtr1;
+
+ typedef struct {
+ unistr *name;
+ uint32 type;
+ unistr *comment;
+ uint32 permissions;
+ uint32 max_users;
+ uint32 current_users;
+ unistr *path;
+ unistr *password;
+ } srvsvc_NetShareInfo2;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetShareInfo2 *array;
+ } srvsvc_NetShareCtr2;
+
+ typedef struct {
+ unistr *name;
+ uint32 type;
+ unistr *comment;
+ uint32 csc_policy;
+ } srvsvc_NetShareInfo501;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetShareInfo501 *array;
+ } srvsvc_NetShareCtr501;
+
+ typedef struct {
+ unistr *name;
+ uint32 type;
+ unistr *comment;
+ uint32 permissions;
+ uint32 max_users;
+ uint32 current_users;
+ unistr *path;
+ unistr *password;
+ uint32 unknown;
+ [subcontext(4)] security_descriptor *sd;
+ } srvsvc_NetShareInfo502;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetShareInfo502 *array;
+ } srvsvc_NetShareCtr502;
+
+ typedef union {
+ [case(0)] srvsvc_NetShareInfo0 *info0;
+ [case(1)] srvsvc_NetShareInfo1 *info1;
+ [case(2)] srvsvc_NetShareInfo2 *info2;
+ [case(501)] srvsvc_NetShareInfo501 *info501;
+ [case(502)] srvsvc_NetShareInfo502 *info502;
+ [default] ;
+ } srvsvc_NetShareInfo;
+
+ typedef union {
+ [case(0)] srvsvc_NetShareCtr0 *ctr0;
+ [case(1)] srvsvc_NetShareCtr1 *ctr1;
+ [case(2)] srvsvc_NetShareCtr2 *ctr2;
+ [case(501)] srvsvc_NetShareCtr501 *ctr501;
+ [case(502)] srvsvc_NetShareCtr502 *ctr502;
+ [default] ;
+ } srvsvc_NetShareCtr;
+
+ /******************/
+ /* Function: 0x0e */
+ WERROR srvsvc_NetShareAdd(
+ [in] unistr *server_unc,
+ [in] uint32 level,
+ [in,switch_is(level)] srvsvc_NetShareInfo info,
+ [in,out] uint32 *parm_error
+ );
+
+ /******************/
+ /* Function: 0x0f */
+ WERROR srvsvc_NetShareEnumAll (
+ [in] unistr *server_unc,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] srvsvc_NetShareCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x10 */
+ WERROR srvsvc_NetShareGetInfo(
+ [in] unistr *server_unc,
+ [in] unistr *share_name,
+ [in] uint32 level,
+ [out,switch_is(level)] srvsvc_NetShareInfo info
+ );
+
+ /******************/
+ /* Function: 0x11 */
+ WERROR srvsvc_NetShareSetInfo(
+ [in] unistr *server_unc,
+ [in] unistr *share_name,
+ [in] uint32 level,
+ [in,switch_is(level)] srvsvc_NetShareInfo info,
+ [in,out] uint32 *parm_error
+ );
+
+ /******************/
+ /* Function: 0x12 */
+ WERROR srvsvc_NetShareDel(
+ [in] unistr *server_unc,
+ [in] unistr *share_name,
+ [in] uint32 reserved
+ );
+
+ /******************/
+ /* Function: 0x13 */
+ WERROR srvsvc_NetShareDelSticky(
+ [in] unistr *server_unc,
+ [in] unistr *share_name,
+ [in] uint32 reserved
+ );
+
+ /******************/
+ /* Function: 0x14 */
+ WERROR srvsvc_NetShareCheck(
+ [in] unistr *server_unc,
+ [in] unistr *share_name,
+ [out] uint32 type
+ );
+
+/**************************/
+/* srvsvc_NetSrv */
+/**************************/
+ typedef struct {
+ uint32 platform_id;
+ unistr *server_unc;
+ } srvsvc_NetSrvInfo100;
+
+ typedef struct {
+ uint32 platform_id;
+ unistr *server_unc;
+ uint32 ver_major;
+ uint32 ver_minor;
+ uint32 type;
+ unistr *comment;
+ } srvsvc_NetSrvInfo101;
+
+ typedef struct {
+ uint32 platform_id;
+ unistr *server_unc;
+ uint32 ver_major;
+ uint32 ver_minor;
+ uint32 type;
+ unistr *comment;
+ uint32 users;
+ uint32 disc;
+ uint32 hidden;
+ uint32 announce;
+ uint32 anndelta;
+ uint32 licences;
+ unistr *userpath;
+ } srvsvc_NetSrvInfo102;
+
+ typedef struct {
+ uint32 ulist_mtime;
+ uint32 glist_mtime;
+ uint32 alist_mtime;
+ unistr *alerts;
+ uint32 security;
+ uint32 numadmin;
+ uint32 lanmask;
+ unistr *guestaccount;
+ uint32 chdevs;
+ uint32 chdevqs;
+ uint32 chdevjobs;
+ uint32 connections;
+ uint32 shares;
+ uint32 openfiles;
+ uint32 sessopen;
+ uint32 sesssvc;
+ uint32 sessreqs;
+ uint32 opensearch;
+ uint32 activelocks;
+ uint32 sizereqbufs;
+ uint32 numbigbufs;
+ uint32 numfiletasks;
+ uint32 alertsched;
+ uint32 eroralert;
+ uint32 logonalert;
+ uint32 accessalert;
+ uint32 diskalert;
+ uint32 netioalert;
+ uint32 maxaudits;
+ unistr *srvheuristics;
+ } srvsvc_NetSrvInfo402;
+
+ typedef struct {
+ uint32 ulist_mtime;
+ uint32 glist_mtime;
+ uint32 alist_mtime;
+ unistr *alerts;
+ uint32 security;
+ uint32 numadmin;
+ uint32 lanmask;
+ unistr *guestaccount;
+ uint32 chdevs;
+ uint32 chdevqs;
+ uint32 chdevjobs;
+ uint32 connections;
+ uint32 shares;
+ uint32 openfiles;
+ uint32 sessopen;
+ uint32 sesssvc;
+ uint32 sessreqs;
+ uint32 opensearch;
+ uint32 activelocks;
+ uint32 sizereqbufs;
+ uint32 numbigbufs;
+ uint32 numfiletasks;
+ uint32 alertsched;
+ uint32 eroralert;
+ uint32 logonalert;
+ uint32 accessalert;
+ uint32 diskalert;
+ uint32 netioalert;
+ uint32 maxaudits;
+ unistr *srvheuristics;
+ uint32 auditedevents;
+ uint32 auditprofile;
+ unistr *autopath;
+ } srvsvc_NetSrvInfo403;
+
+ typedef struct {
+ uint32 sessopen;
+ uint32 sesssvc;
+ uint32 opensearch;
+ uint32 sizereqbufs;
+ uint32 initworkitems;
+ uint32 maxworkitems;
+ uint32 rawworkitems;
+ uint32 irpstacksize;
+ uint32 maxrawbuflen;
+ uint32 sessusers;
+ uint32 sessconns;
+ uint32 maxpagedmemoryusage;
+ uint32 maxnonpagedmemoryusage;
+ uint32 enablesoftcompat;
+ uint32 enableforcedlogoff;
+ uint32 timesource;
+ uint32 acceptdownlevelapis;
+ uint32 lmannounce;
+ } srvsvc_NetSrvInfo502;
+
+ typedef struct{
+ uint32 sessopen;
+ uint32 sesssvc;
+ uint32 opensearch;
+ uint32 sizereqbufs;
+ uint32 initworkitems;
+ uint32 maxworkitems;
+ uint32 rawworkitems;
+ uint32 irpstacksize;
+ uint32 maxrawbuflen;
+ uint32 sessusers;
+ uint32 sessconns;
+ uint32 maxpagedmemoryusage;
+ uint32 maxnonpagedmemoryusage;
+ uint32 enablesoftcompat;
+ uint32 enableforcedlogoff;
+ uint32 timesource;
+ uint32 acceptdownlevelapis;
+ uint32 lmannounce;
+ unistr *domain;
+ uint32 maxcopyreadlen;
+ uint32 maxcopywritelen;
+ uint32 minkeepsearch;
+ uint32 maxkeepsearch;
+ uint32 minkeepcomplsearch;
+ uint32 maxkeepcomplsearch;
+ uint32 threadcountadd;
+ uint32 numlockthreads;
+ uint32 scavtimeout;
+ uint32 minrcvqueue;
+ uint32 minfreeworkitems;
+ uint32 xactmemsize;
+ uint32 threadpriority;
+ uint32 maxmpxct;
+ uint32 oplockbreakwait;
+ uint32 oplockbreakresponsewait;
+ uint32 enableoplocks;
+ uint32 enableoplockforceclose;
+ uint32 enablefcbopens;
+ uint32 enableraw;
+ uint32 enablesharednetdrives;
+ uint32 minfreeconnections;
+ uint32 maxfreeconnections;
+ } srvsvc_NetSrvInfo503;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo599;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1005;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1010;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1016;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1017;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1018;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1107;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1501;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1502;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1503;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1506;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1509;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1510;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1511;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1512;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1513;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1514;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1515;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1516;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1518;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1520;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1521;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1522;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1523;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1524;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1525;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1528;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1529;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1530;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1533;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1534;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1535;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1536;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1537;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1538;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1539;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1540;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1541;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1542;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1543;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1544;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1545;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1546;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1547;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1548;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1549;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1550;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1552;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1553;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1554;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1555;
+
+ typedef struct{
+ uint32 dummy;
+ } srvsvc_NetSrvInfo1556;
+
+
+ typedef union{
+ [case(100)] srvsvc_NetSrvInfo100 *info100;
+ [case(101)] srvsvc_NetSrvInfo101 *info101;
+ [case(102)] srvsvc_NetSrvInfo102 *info102;
+ [case(402)] srvsvc_NetSrvInfo402 *info402;
+ [case(403)] srvsvc_NetSrvInfo403 *info403;
+ [case(502)] srvsvc_NetSrvInfo502 *info502;
+ [case(503)] srvsvc_NetSrvInfo503 *info503;
+ [case(599)] srvsvc_NetSrvInfo599 *info599;
+ [case(1005)] srvsvc_NetSrvInfo1005 *info1005;
+ [case(1010)] srvsvc_NetSrvInfo1010 *info1010;
+ [case(1016)] srvsvc_NetSrvInfo1016 *info1016;
+ [case(1017)] srvsvc_NetSrvInfo1017 *info1017;
+ [case(1018)] srvsvc_NetSrvInfo1018 *info1018;
+ [case(1107)] srvsvc_NetSrvInfo1107 *info1107;
+ [case(1501)] srvsvc_NetSrvInfo1501 *info1501;
+ [case(1502)] srvsvc_NetSrvInfo1502 *info1502;
+ [case(1503)] srvsvc_NetSrvInfo1503 *info1503;
+ [case(1506)] srvsvc_NetSrvInfo1506 *info1506;
+ [case(1509)] srvsvc_NetSrvInfo1509 *info1509;
+ [case(1510)] srvsvc_NetSrvInfo1510 *info1510;
+ [case(1511)] srvsvc_NetSrvInfo1511 *info1511;
+ [case(1512)] srvsvc_NetSrvInfo1512 *info1512;
+ [case(1513)] srvsvc_NetSrvInfo1513 *info1513;
+ [case(1514)] srvsvc_NetSrvInfo1514 *info1514;
+ [case(1515)] srvsvc_NetSrvInfo1515 *info1515;
+ [case(1516)] srvsvc_NetSrvInfo1516 *info1516;
+ [case(1518)] srvsvc_NetSrvInfo1518 *info1518;
+ [case(1520)] srvsvc_NetSrvInfo1520 *info1520;
+ [case(1521)] srvsvc_NetSrvInfo1521 *info1521;
+ [case(1522)] srvsvc_NetSrvInfo1522 *info1522;
+ [case(1523)] srvsvc_NetSrvInfo1523 *info1523;
+ [case(1524)] srvsvc_NetSrvInfo1524 *info1524;
+ [case(1525)] srvsvc_NetSrvInfo1525 *info1525;
+ [case(1528)] srvsvc_NetSrvInfo1528 *info1528;
+ [case(1529)] srvsvc_NetSrvInfo1529 *info1529;
+ [case(1530)] srvsvc_NetSrvInfo1530 *info1530;
+ [case(1533)] srvsvc_NetSrvInfo1533 *info1533;
+ [case(1534)] srvsvc_NetSrvInfo1534 *info1534;
+ [case(1535)] srvsvc_NetSrvInfo1535 *info1535;
+ [case(1536)] srvsvc_NetSrvInfo1536 *info1536;
+ [case(1537)] srvsvc_NetSrvInfo1537 *info1537;
+ [case(1538)] srvsvc_NetSrvInfo1538 *info1538;
+ [case(1539)] srvsvc_NetSrvInfo1539 *info1539;
+ [case(1540)] srvsvc_NetSrvInfo1540 *info1540;
+ [case(1541)] srvsvc_NetSrvInfo1541 *info1541;
+ [case(1542)] srvsvc_NetSrvInfo1542 *info1542;
+ [case(1543)] srvsvc_NetSrvInfo1543 *info1543;
+ [case(1544)] srvsvc_NetSrvInfo1544 *info1544;
+ [case(1545)] srvsvc_NetSrvInfo1545 *info1545;
+ [case(1546)] srvsvc_NetSrvInfo1546 *info1546;
+ [case(1547)] srvsvc_NetSrvInfo1547 *info1547;
+ [case(1548)] srvsvc_NetSrvInfo1548 *info1548;
+ [case(1549)] srvsvc_NetSrvInfo1549 *info1549;
+ [case(1550)] srvsvc_NetSrvInfo1550 *info1550;
+ [case(1552)] srvsvc_NetSrvInfo1552 *info1552;
+ [case(1553)] srvsvc_NetSrvInfo1553 *info1553;
+ [case(1554)] srvsvc_NetSrvInfo1554 *info1554;
+ [case(1555)] srvsvc_NetSrvInfo1555 *info1555;
+ [case(1556)] srvsvc_NetSrvInfo1556 *info1556;
+ [default];
+ } srvsvc_NetSrvInfo;
+
+ /******************/
+ /* Function: 0x15 */
+ WERROR srvsvc_NetSrvGetInfo(
+ [in] unistr *server_unc,
+ [in] uint32 level,
+ [out,switch_is(level)] srvsvc_NetSrvInfo info
+ );
+
+ /******************/
+ /* Function: 0x16 */
+ WERROR srvsvc_NetSrvSetInfo(
+ [in] unistr *server_unc,
+ [in] uint32 level,
+ [in,switch_is(level)] srvsvc_NetSrvInfo info,
+ [in,out] uint32 *parm_error
+ );
+
+/**************************/
+/* srvsvc_NetDisk */
+/**************************/
+ typedef struct {
+ uint32 unknown;
+ lstring disk;
+ uint16 unknown2;
+ } srvsvc_NetDiskInfo0;
+
+ typedef struct {
+ uint32 unknown;
+ uint32 count;
+ [size_is(count)] srvsvc_NetDiskInfo0 array[];
+ } srvsvc_NetDiskCtr0;
+
+ typedef union {
+ [case(0)] srvsvc_NetDiskCtr0 *ctr0;
+ } srvsvc_NetDiskCtr;
+
+ /******************/
+ /* Function: 0x17 */
+ WERROR srvsvc_NetDiskEnum(
+ [in] unistr *server_unc,
+ [in] uint32 level,
+ [out] uint32 count,
+ [in,switch_is(level)] srvsvc_NetDiskCtr ctr,
+ [out] srvsvc_NetDiskCtr0 *ctr0,
+ [in] uint32 unknown,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x18 */
+ NTSTATUS srvsvc_NETRSERVERSTATISTICSGET(
+ );
+
+ /******************/
+ /* Function: 0x19 */
+ NTSTATUS srvsvc_NETRSERVERTRANSPORTADD(
+ );
+
+/**************************/
+/* srvsvc_NetTransport */
+/**************************/
+ typedef struct {
+ uint32 count;
+ uint8 addr[count];
+ } srvsvc_NetTransportAddress;
+
+ typedef struct {
+ uint32 vcs;
+ unistr *name;
+ srvsvc_NetTransportAddress *addr;
+ uint32 addr_len;
+ unistr *net_addr;
+ } srvsvc_NetTransportInfo0;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetTransportInfo0 *array;
+ } srvsvc_NetTransportCtr0;
+
+ typedef struct {
+ uint32 vcs;
+ unistr *name;
+ srvsvc_NetTransportAddress *addr;
+ uint32 addr_len;
+ unistr *net_addr;
+ unistr *domain;
+ } srvsvc_NetTransportInfo1;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetTransportInfo1 *array;
+ } srvsvc_NetTransportCtr1;
+
+ typedef struct {
+ uint32 dummy;
+ } srvsvc_NetTransportInfo2;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetTransportInfo2 *array;
+ } srvsvc_NetTransportCtr2;
+
+ typedef struct {
+ uint32 dummy;
+ } srvsvc_NetTransportInfo3;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] srvsvc_NetTransportInfo3 *array;
+ } srvsvc_NetTransportCtr3;
+
+ typedef union {
+ [case(0)] srvsvc_NetTransportInfo0 *info0;
+ [case(1)] srvsvc_NetTransportInfo1 *info1;
+ [case(2)] srvsvc_NetTransportInfo2 *info2;
+ [case(3)] srvsvc_NetTransportInfo3 *info3;
+ [default];
+ } srvsvc_NetTransportInfo;
+
+ typedef union {
+ [case(0)] srvsvc_NetTransportCtr0 *ctr0;
+ [case(1)] srvsvc_NetTransportCtr1 *ctr1;
+ [case(2)] srvsvc_NetTransportCtr2 *ctr2;
+ [case(3)] srvsvc_NetTransportCtr3 *ctr3;
+ [default];
+ } srvsvc_NetTransportCtr;
+
+ /******************/
+ /* Function: 0x1a */
+ WERROR srvsvc_NetTransportEnum(
+ [in] unistr *server_unc,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] srvsvc_NetTransportCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x1b */
+ NTSTATUS srvsvc_NETRSERVERTRANSPORTDEL(
+ );
+
+ /******************/
+ /* Function: 0x1c */
+ NTSTATUS srvsvc_NET_REMOTE_TOD(
+ );
+
+ /******************/
+ /* Function: 0x1d */
+ NTSTATUS srvsvc_NETRSERVERSETSERVICEBITS(
+ );
+
+ /******************/
+ /* Function: 0x1e */
+ NTSTATUS srvsvc_NETRPRPATHTYPE(
+ );
+
+ /******************/
+ /* Function: 0x1f */
+ NTSTATUS srvsvc_NETRPRPATHCANONICALIZE(
+ );
+
+ /******************/
+ /* Function: 0x20 */
+ NTSTATUS srvsvc_NETRPRPATHCOMPARE(
+ );
+
+ /******************/
+ /* Function: 0x21 */
+ NTSTATUS srvsvc_NET_NAME_VALIDATE(
+ );
+
+ /******************/
+ /* Function: 0x22 */
+ NTSTATUS srvsvc_NETRPRNAMECANONICALIZE(
+ );
+
+ /******************/
+ /* Function: 0x23 */
+ NTSTATUS srvsvc_NETRPRNAMECOMPARE(
+ );
+
+ /******************/
+ /* Function: 0x24 */
+ /* Note, there must be some way to return entries read vs
+ total entries ... */
+ WERROR srvsvc_NetShareEnum(
+ [in] unistr *server_unc,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] srvsvc_NetShareCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+ /******************/
+ /* Function: 0x25 */
+ NTSTATUS srvsvc_NETRSHAREDELSTART(
+ );
+
+ /******************/
+ /* Function: 0x26 */
+ NTSTATUS srvsvc_NETRSHAREDELCOMMIT(
+ );
+
+ /******************/
+ /* Function: 0x27 */
+ NTSTATUS srvsvc_NET_FILE_QUERY_SECDESC(
+ );
+
+ /******************/
+ /* Function: 0x28 */
+ NTSTATUS srvsvc_NET_FILE_SET_SECDESC(
+ );
+
+ /******************/
+ /* Function: 0x29 */
+ NTSTATUS srvsvc_NETRSERVERTRANSPORTADDEX(
+ );
+
+ /******************/
+ /* Function: 0x2a */
+ NTSTATUS srvsvc_NETRSERVERSETSERVICEBITSEX(
+ );
+
+ /******************/
+ /* Function: 0x2b */
+ NTSTATUS srvsvc_NETRDFSGETVERSION(
+ );
+
+ /******************/
+ /* Function: 0x2c */
+ NTSTATUS srvsvc_NETRDFSCREATELOCALPARTITION(
+ );
+
+ /******************/
+ /* Function: 0x2d */
+ NTSTATUS srvsvc_NETRDFSDELETELOCALPARTITION(
+ );
+
+ /******************/
+ /* Function: 0x2e */
+ NTSTATUS srvsvc_NETRDFSSETLOCALVOLUMESTATE(
+ );
+
+ /******************/
+ /* Function: 0x2f */
+ NTSTATUS srvsvc_NETRDFSSETSERVERINFO(
+ );
+
+ /******************/
+ /* Function: 0x30 */
+ NTSTATUS srvsvc_NETRDFSCREATEEXITPOINT(
+ );
+
+ /******************/
+ /* Function: 0x31 */
+ NTSTATUS srvsvc_NETRDFSDELETEEXITPOINT(
+ );
+
+ /******************/
+ /* Function: 0x32 */
+ NTSTATUS srvsvc_NETRDFSMODIFYPREFIX(
+ );
+
+ /******************/
+ /* Function: 0x33 */
+ NTSTATUS srvsvc_NETRDFSFIXLOCALVOLUME(
+ );
+
+ /******************/
+ /* Function: 0x34 */
+ NTSTATUS srvsvc_NETRDFSMANAGERREPORTSITEINFO(
+ );
+
+ /******************/
+ /* Function: 0x35 */
+ NTSTATUS srvsvc_NETRSERVERTRANSPORTDELEX(
+ );
+}
diff --git a/source/librpc/idl/trkwks.idl b/source/librpc/idl/trkwks.idl
new file mode 100644
index 00000000000..c91e1ea7884
--- /dev/null
+++ b/source/librpc/idl/trkwks.idl
@@ -0,0 +1,15 @@
+/*
+ distributed key tracking services
+*/
+
+[
+ uuid(300f3532-38cc-11d0-a3f0-0020af6b0add),
+ version(1.2)
+]
+interface trkwks
+{
+
+ /*****************/
+ /* Function 0x00 */
+ WERROR trkwks_Unknown0();
+}
diff --git a/source/librpc/idl/w32time.idl b/source/librpc/idl/w32time.idl
new file mode 100644
index 00000000000..ef411b126a6
--- /dev/null
+++ b/source/librpc/idl/w32time.idl
@@ -0,0 +1,16 @@
+/*
+ w32time interface definitions
+*/
+
+[
+ uuid(8fb6d884-2388-11d0-8c35-00c04fda2795),
+ endpoints(srvsvc,atsvc,browser,keysvc,wkssvc),
+ version(4.1)
+]
+interface w32time
+{
+
+ /*****************/
+ /* Function 0x00 */
+ WERROR w32time_Unknown0();
+}
diff --git a/source/librpc/idl/winreg.idl b/source/librpc/idl/winreg.idl
new file mode 100644
index 00000000000..54cba24760b
--- /dev/null
+++ b/source/librpc/idl/winreg.idl
@@ -0,0 +1,299 @@
+#include "idl_types.h"
+
+/*
+ winreg interface definition
+*/
+
+[ uuid(338cd001-2244-31f1-aaaa-900038001003),
+ version(1.0),
+ pointer_default(unique)
+] interface winreg
+{
+ typedef struct {
+ [value(strlen_m_term(r->name)*2)] uint16 name_len;
+ [value(r->name_len)] uint16 name_size;
+ unistr *name;
+ } winreg_String;
+
+ typedef struct {
+ uint16 unknown0;
+ uint16 unknown1;
+ } winreg_OpenUnknown;
+
+ /******************/
+ /* Function: 0x00 */
+ WERROR winreg_OpenHKCR(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x01 */
+ WERROR winreg_OpenHKCU(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x02 */
+ WERROR winreg_OpenHKLM(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x03 */
+ WERROR winreg_OpenHKPD(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x04 */
+ WERROR winreg_OpenHKU(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x05 */
+ WERROR winreg_CloseKey(
+ [in,out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x06 */
+ WERROR winreg_CreateKey(
+ );
+
+ /******************/
+ /* Function: 0x07 */
+ WERROR winreg_DeleteKey(
+ [in,ref] policy_handle *handle,
+ [in] winreg_String key
+ );
+
+ /******************/
+ /* Function: 0x08 */
+ WERROR winreg_DeleteValue(
+ [in,ref] policy_handle *handle,
+ [in] winreg_String value
+ );
+
+ typedef struct {
+ uint32 low;
+ uint32 high;
+ } winreg_Time;
+
+ typedef struct {
+ uint32 unknown;
+ winreg_String key_name;
+ } winreg_EnumKeyNameRequest;
+
+ typedef struct {
+ uint32 unknown1;
+ uint32 unknown2;
+ lstring name;
+ } winreg_EnumKeyNameResponse;
+
+ /******************/
+ /* Function: 0x09 */
+ WERROR winreg_EnumKey(
+ [in,ref] policy_handle *handle,
+ [in] uint32 enum_index,
+ [in,out] uint16 key_name_len,
+ [in,out] uint16 unknown,
+ [in] winreg_EnumKeyNameRequest *in_name,
+ [out] winreg_EnumKeyNameResponse *out_name,
+ [in,out] winreg_String *class,
+ [in,out] winreg_Time *last_changed_time
+ );
+
+ typedef struct {
+ uint32 max_len;
+ uint32 offset;
+ uint32 len;
+ uint16 buffer[len];
+ } winreg_Uint16buf;
+
+ typedef struct {
+ uint16 len;
+ uint16 max_len;
+ winreg_Uint16buf *buf;
+ } winreg_EnumValueName;
+
+ typedef struct {
+ uint32 max_len;
+ uint32 offset;
+ uint32 len;
+ uint8 buffer[len];
+ } winreg_Uint8buf;
+
+ /******************/
+ /* Function: 0x0a */
+ WERROR winreg_EnumValue(
+ [in,ref] policy_handle *handle,
+ [in] uint32 enum_index,
+ [in,out,ref] winreg_EnumValueName *name,
+ [in,out] uint32 *type,
+ [in,out] winreg_Uint8buf *value,
+ [in,out] uint32 *requested_len,
+ [in,out] uint32 *returned_len
+ );
+
+ /******************/
+ /* Function: 0x0b */
+ WERROR winreg_FlushKey(
+ [in,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x0c */
+ WERROR winreg_GetKeySecurity(
+ );
+
+ /******************/
+ /* Function: 0x0d */
+ WERROR winreg_LoadKey(
+ );
+
+ /******************/
+ /* Function: 0x0e */
+ WERROR winreg_NotifyChangeKeyValue(
+ );
+
+ /******************/
+ /* Function: 0x0f */
+ WERROR winreg_OpenKey(
+ [in,ref] policy_handle *handle,
+ [in] winreg_String keyname,
+ [in] uint32 unknown,
+ [in] uint32 access_mask,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x10 */
+ WERROR winreg_QueryInfoKey(
+ [in,ref] policy_handle *handle,
+ [in] winreg_String class,
+ [out] winreg_String class,
+ [out] uint32 num_subkeys,
+ [out] uint32 max_subkeylen,
+ [out] uint32 max_subkeysize,
+ [out] uint32 num_values,
+ [out] uint32 max_valnamelen,
+ [out] uint32 max_valbufsize,
+ [out] uint32 secdescsize,
+ [out] winreg_Time last_changed_time
+ );
+
+ /******************/
+ /* Function: 0x11 */
+ WERROR winreg_QueryValue(
+ );
+
+ /******************/
+ /* Function: 0x12 */
+ WERROR winreg_ReplaceKey(
+ );
+
+ /******************/
+ /* Function: 0x13 */
+ WERROR winreg_RestoreKey(
+ );
+
+ /******************/
+ /* Function: 0x14 */
+ WERROR winreg_SaveKey(
+ );
+
+ /******************/
+ /* Function: 0x15 */
+ WERROR winreg_SetKeySecurity(
+ );
+
+ /******************/
+ /* Function: 0x16 */
+ WERROR winreg_SetValue(
+ );
+
+ /******************/
+ /* Function: 0x17 */
+ WERROR winreg_UnLoadKey(
+ );
+
+ /******************/
+ /* Function: 0x18 */
+ WERROR winreg_InitiateSystemShutdown(
+ );
+
+ /******************/
+ /* Function: 0x19 */
+ WERROR winreg_AbortSystemShutdown(
+ );
+
+ /******************/
+ /* Function: 0x1a */
+ WERROR winreg_GetVersion(
+ [in,ref] policy_handle *handle,
+ [out] uint32 version
+ );
+
+ /******************/
+ /* Function: 0x1b */
+ WERROR winreg_OpenHKCC(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x1c */
+ WERROR winreg_OpenHKDD(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x1d */
+ WERROR winreg_QueryMultipleValues(
+ );
+
+ /******************/
+ /* Function: 0x1e */
+ WERROR winreg_InitiateSystemShutdownEx(
+ );
+
+ /******************/
+ /* Function: 0x1f */
+ WERROR winreg_SaveKeyEx(
+ );
+
+ /******************/
+ /* Function: 0x20 */
+ WERROR winreg_OpenHKPT(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x21 */
+ WERROR winreg_OpenHKPN(
+ [in] winreg_OpenUnknown *unknown,
+ [in] uint32 access_required,
+ [out,ref] policy_handle *handle
+ );
+
+ /******************/
+ /* Function: 0x21 */
+ WERROR winreg_QueryMultipleValues2(
+ );
+}
diff --git a/source/librpc/idl/wkssvc.idl b/source/librpc/idl/wkssvc.idl
new file mode 100644
index 00000000000..9a92d4e3e00
--- /dev/null
+++ b/source/librpc/idl/wkssvc.idl
@@ -0,0 +1,249 @@
+#include "idl_types.h"
+
+/*
+ wkssvc interface definitions
+*/
+
+[ uuid(6bffd098-a112-3610-9833-46c3f87e345a),
+ version(1.0),
+ pointer_default(unique)
+] interface wkssvc
+{
+
+#define BOOL uint32
+
+ /******************/
+ /* Function: 0x00 */
+
+ typedef struct {
+ uint32 platform_id;
+ unistr *server;
+ unistr *domain;
+ uint32 ver_major;
+ uint32 ver_minor;
+ } wkssvc_NetWkstaInfo100;
+
+ typedef struct {
+ uint32 platform_id;
+ unistr *server;
+ unistr *domain;
+ uint32 ver_major;
+ uint32 ver_minor;
+ unistr *lan_root;
+ } wkssvc_NetWkstaInfo101;
+
+ typedef struct {
+ uint32 platform_id;
+ unistr *server;
+ unistr *domain;
+ uint32 ver_major;
+ uint32 ver_minor;
+ unistr *lan_root;
+ uint32 logged_on_users;
+ } wkssvc_NetWkstaInfo102;
+
+ typedef struct {
+ uint32 char_wait;
+ uint32 collection_time;
+ uint32 maximum_collection_count;
+ uint32 keep_connection;
+ uint32 max_commands;
+ uint32 session_timeout;
+ uint32 size_char_buf;
+ uint32 max_threads;
+ uint32 lock_quota;
+ uint32 lock_increment;
+ uint32 lock_maximum;
+ uint32 pipe_increment;
+ uint32 pipe_maximum;
+ uint32 cache_file_timeout;
+ uint32 dormant_file_limit;
+ uint32 read_ahead_throughput;
+ uint32 num_mailslot_buffers;
+ uint32 num_srv_announce_buffers;
+ uint32 max_illegal_dgram_events;
+ uint32 dgram_event_reset_freq;
+ BOOL log_election_packets;
+ BOOL use_opportunistic_locking;
+ BOOL use_unlock_behind;
+ BOOL use_close_behind;
+ BOOL buf_named_pipes;
+ BOOL use_lock_read_unlock;
+ BOOL utilize_nt_caching;
+ BOOL use_raw_read;
+ BOOL use_raw_write;
+ BOOL use_write_raw_data;
+ BOOL use_encryption;
+ BOOL buf_files_deny_write;
+ BOOL buf_read_only_files;
+ BOOL force_core_create_mode;
+ BOOL use_512_byte_max_transfer;
+ } wkssvc_NetWkstaInfo502;
+
+ typedef union {
+ [case(100)] wkssvc_NetWkstaInfo100 *info100;
+ [case(101)] wkssvc_NetWkstaInfo101 *info101;
+ [case(102)] wkssvc_NetWkstaInfo102 *info102;
+ [case(502)] wkssvc_NetWkstaInfo502 *info502;
+ } wkssvc_NetWkstaInfo;
+
+ WERROR wkssvc_NetWkstaGetInfo(
+ [in] unistr *server_name,
+ [in] uint32 level,
+ [out,switch_is(level)] wkssvc_NetWkstaInfo info
+ );
+
+
+ /******************/
+ /* Function: 0x01 */
+ WERROR wkssvc_NetWkstaSetInfo(
+ [in] unistr *server_name,
+ [in] uint32 level,
+ [in,switch_is(level)] wkssvc_NetWkstaInfo info,
+ [in,out] uint32 *parm_error
+ );
+
+ /*****************************/
+ /* Function 0x02 */
+ WERROR WKSSVC_NETRWKSTAUSERENUM ();
+
+ /*****************************/
+ /* Function 0x03 */
+ WERROR WKSSVC_NETRWKSTAUSERGETINFO ();
+
+ /*****************************/
+ /* Function 0x04 */
+ WERROR WKSSVC_NETRWKSTAUSERSETINFO ();
+
+
+ /*****************************/
+ /* Function 0x05 */
+
+ typedef struct {
+ uint32 quality_of_service;
+ uint32 vc_count;
+ unistr *name;
+ unistr *address;
+ uint32 wan_link;
+ } wkssvc_NetWkstaTransportInfo0;
+
+ typedef struct {
+ uint32 count;
+ [size_is(count)] wkssvc_NetWkstaTransportInfo0 *array;
+ } wkssvc_NetWkstaTransportCtr0;
+
+ typedef union {
+ [case(0)] wkssvc_NetWkstaTransportCtr0 *ctr0;
+ [default] ;
+ } wkssvc_NetWkstaTransportCtr;
+
+ WERROR wkssvc_NetWkstaTransportEnum (
+ [in] unistr *server_name,
+ [in,out] uint32 level,
+ [in,out,switch_is(level)] wkssvc_NetWkstaTransportCtr ctr,
+ [in] uint32 max_buffer,
+ [out] uint32 totalentries,
+ [in,out] uint32 *resume_handle
+ );
+
+
+ /*****************************/
+ /* Function 0x06 */
+ WERROR WKSSVC_NETRWKSTATRANSPORTADD ();
+
+ /*****************************/
+ /* Function 0x07 */
+ WERROR WKSSVC_NETRWKSTATRANSPORTDEL ();
+
+ /*****************************/
+ /* Function 0x08 */
+ WERROR WKSSVC_NETRUSEADD ();
+
+ /*****************************/
+ /* Function 0x09 */
+ WERROR WKSSVC_NETRUSEGETINFO ();
+
+ /*****************************/
+ /* Function 0x0a */
+ WERROR WKSSVC_NETRUSEDEL ();
+
+ /*****************************/
+ /* Function 0x0b */
+ WERROR WKSSVC_NETRUSEENUM ();
+
+ /*****************************/
+ /* Function 0x0c */
+ WERROR WKSSVC_NETRMESSAGEBUFFERSEND ();
+
+ /*****************************/
+ /* Function 0x0d */
+ WERROR WKSSVC_NETRWORKSTATIONSTATISTICSGET ();
+
+ /*****************************/
+ /* Function 0x0e */
+ WERROR WKSSVC_NETRLOGONDOMAINNAMEADD ();
+
+ /*****************************/
+ /* Function 0x0f */
+ WERROR WKSSVC_NETRLOGONDOMAINNAMEDEL ();
+
+ /*****************************/
+ /* Function 0x10 */
+ WERROR WKSSVC_NETRJOINDOMAIN ();
+
+ /*****************************/
+ /* Function 0x11 */
+ WERROR WKSSVC_NETRUNJOINDOMAIN ();
+
+ /*****************************/
+ /* Function 0x12 */
+ WERROR WKSSVC_NETRRENAMEMACHINEINDOMAIN ();
+
+ /*****************************/
+ /* Function 0x13 */
+ WERROR WKSSVC_NETRVALIDATENAME ();
+
+ /*****************************/
+ /* Function 0x14 */
+ WERROR WKSSVC_NETRGETJOININFORMATION ();
+
+ /*****************************/
+ /* Function 0x15 */
+ WERROR WKSSVC_NETRGETJOINABLEOUS ();
+
+ /*****************************/
+ /* Function 0x16 */
+ WERROR WKSSVC_NETRJOINDOMAIN2 ();
+
+ /*****************************/
+ /* Function 0x17 */
+ WERROR WKSSVC_NETRUNJOINDOMAIN2 ();
+
+ /*****************************/
+ /* Function 0x18 */
+ WERROR WKSSVC_NETRRENAMEMACHINEINDOMAIN2 ();
+
+ /*****************************/
+ /* Function 0x19 */
+ WERROR WKSSVC_NETRVALIDATENAME2 ();
+
+ /*****************************/
+ /* Function 0x1a */
+ WERROR WKSSVC_NETRGETJOINABLEOUS2 ();
+
+ /*****************************/
+ /* Function 0x1b */
+ WERROR WKSSVC_NETRADDALTERNATECOMPUTERNAME ();
+
+ /*****************************/
+ /* Function 0x1c */
+ WERROR WKSSVC_NETRREMOVEALTERNATECOMPUTERNAME ();
+
+ /*****************************/
+ /* Function 0x1d */
+ WERROR WKSSVC_NETRSETPRIMARYCOMPUTERNAME ();
+
+ /*****************************/
+ /* Function 0x1e */
+ WERROR WKSSVC_NETRENUMERATECOMPUTERNAMES ();
+}
diff --git a/source/librpc/idl/wzcsvc.idl b/source/librpc/idl/wzcsvc.idl
new file mode 100644
index 00000000000..167496e3cc7
--- /dev/null
+++ b/source/librpc/idl/wzcsvc.idl
@@ -0,0 +1,15 @@
+/*
+ windows zero-configuration service
+*/
+
+[
+ uuid(378e52b0-c0a9-11cf-822d-00aa0051e40f),
+ version(1.0)
+]
+interface wzcsvc
+{
+
+ /*****************/
+ /* Function 0x00 */
+ WERROR wzcsvc_Unknown0();
+}
diff --git a/source/librpc/ndr/libndr.h b/source/librpc/ndr/libndr.h
new file mode 100644
index 00000000000..97f36b78d0c
--- /dev/null
+++ b/source/librpc/ndr/libndr.h
@@ -0,0 +1,246 @@
+/*
+ Unix SMB/CIFS implementation.
+ rpc interface definitions
+ 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.
+*/
+
+/*
+ this provides definitions for the libcli/rpc/ MSRPC library
+*/
+
+
+/* offset lists are used to allow a push/pull function to find the
+ start of an encapsulating structure */
+struct ndr_ofs_list {
+ uint32 offset;
+ struct ndr_ofs_list *next;
+};
+
+
+/* this is the base structure passed to routines that
+ parse MSRPC formatted data
+
+ note that in Samba4 we use separate routines and structures for
+ MSRPC marshalling and unmarshalling. Also note that these routines
+ are being kept deliberately very simple, and are not tied to a
+ particular transport
+*/
+struct ndr_pull {
+ uint32 flags; /* LIBNDR_FLAG_* */
+ char *data;
+ uint32 data_size;
+ uint32 offset;
+ TALLOC_CTX *mem_ctx;
+
+ /* this points at a list of offsets to the structures being processed.
+ The first element in the list is the current structure */
+ struct ndr_ofs_list *ofs_list;
+};
+
+struct ndr_pull_save {
+ uint32 data_size;
+ uint32 offset;
+ struct ndr_pull_save *next;
+};
+
+/* structure passed to functions that generate NDR formatted data */
+struct ndr_push {
+ uint32 flags; /* LIBNDR_FLAG_* */
+ char *data;
+ uint32 alloc_size;
+ uint32 offset;
+ TALLOC_CTX *mem_ctx;
+
+ /* this is used to ensure we generate unique reference IDs */
+ uint32 ptr_count;
+
+ /* this points at a list of offsets to the structures being processed.
+ The first element in the list is the current structure */
+ struct ndr_ofs_list *ofs_list;
+
+ /* this list is used by the [relative] code to find the offsets */
+ struct ndr_ofs_list *relative_list, *relative_list_end;
+};
+
+struct ndr_push_save {
+ uint32 offset;
+ struct ndr_push_save *next;
+};
+
+
+/* structure passed to functions that print IDL structures */
+struct ndr_print {
+ uint32 flags; /* LIBNDR_FLAG_* */
+ TALLOC_CTX *mem_ctx;
+ uint32 depth;
+ void (*print)(struct ndr_print *, const char *, ...);
+ void *private;
+};
+
+#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_FLAG_STR_SIZE2 (1<<7)
+#define LIBNDR_STRING_FLAGS (0xFC)
+
+#define LIBNDR_FLAG_REF_ALLOC (1<<10)
+#define LIBNDR_FLAG_REMAINING (1<<11)
+#define LIBNDR_FLAG_ALIGN2 (1<<12)
+#define LIBNDR_FLAG_ALIGN4 (1<<13)
+#define LIBNDR_FLAG_ALIGN8 (1<<14)
+
+#define LIBNDR_ALIGN_FLAGS (LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8)
+
+#define LIBNDR_PRINT_ARRAY_HEX (1<<15)
+#define LIBNDR_PRINT_SET_VALUES (1<<16)
+
+/* used to force a section of IDL to be little-endian */
+#define LIBNDR_FLAG_LITTLE_ENDIAN (1<<17)
+
+
+/* useful macro for debugging */
+#define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p)
+#define NDR_PRINT_UNION_DEBUG(type, level, p) ndr_print_union_debug((ndr_print_union_fn_t)ndr_print_ ##type, #p, level, p)
+#define NDR_PRINT_FUNCTION_DEBUG(type, flags, p) ndr_print_function_debug((ndr_print_function_t)ndr_print_ ##type, #type, flags, p)
+#define NDR_PRINT_BOTH_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_BOTH, p)
+#define NDR_PRINT_OUT_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_OUT, p)
+#define NDR_PRINT_IN_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_IN | NDR_SET_VALUES, p)
+
+
+enum ndr_err_code {
+ NDR_ERR_CONFORMANT_SIZE,
+ NDR_ERR_ARRAY_SIZE,
+ NDR_ERR_BAD_SWITCH,
+ NDR_ERR_OFFSET,
+ NDR_ERR_RELATIVE,
+ NDR_ERR_CHARCNV,
+ NDR_ERR_LENGTH,
+ NDR_ERR_SUBCONTEXT,
+ NDR_ERR_STRING,
+ NDR_ERR_VALIDATE,
+ NDR_ERR_BUFSIZE,
+ NDR_ERR_ALLOC
+};
+
+/*
+ flags passed to control parse flow
+*/
+#define NDR_SCALARS 1
+#define NDR_BUFFERS 2
+
+/*
+ flags passed to ndr_print_*()
+*/
+#define NDR_IN 1
+#define NDR_OUT 2
+#define NDR_BOTH 3
+#define NDR_SET_VALUES 4
+
+#define NDR_PULL_NEED_BYTES(ndr, n) do { \
+ if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \
+ return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull bytes %u", n); \
+ } \
+} while(0)
+
+#define NDR_ALIGN(ndr, n) ndr_align_size(ndr->offset, n)
+
+#define NDR_PULL_ALIGN(ndr, n) do { \
+ if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \
+ ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
+ } \
+ if (ndr->offset >= ndr->data_size) { \
+ return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull align %u", n); \
+ } \
+} while(0)
+
+#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n)))
+
+#define NDR_PUSH_ALIGN(ndr, n) do { \
+ if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \
+ uint32 _pad = ((ndr->offset + (n-1)) & ~(n-1)) - ndr->offset; \
+ while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \
+ } \
+} while(0)
+
+
+/* these are used to make the error checking on each element in libndr
+ less tedious, hopefully making the code more readable */
+#define NDR_CHECK(call) do { NTSTATUS _status; \
+ _status = call; \
+ if (!NT_STATUS_IS_OK(_status)) \
+ return _status; \
+ } while (0)
+
+
+#define NDR_ALLOC_SIZE(ndr, s, size) do { \
+ (s) = talloc(ndr->mem_ctx, size); \
+ if ((size) && !(s)) return ndr_pull_error(ndr, NDR_ERR_ALLOC, \
+ "Alloc %u failed\n", \
+ size); \
+ } while (0)
+
+#define NDR_ALLOC(ndr, s) NDR_ALLOC_SIZE(ndr, s, sizeof(*(s)))
+
+
+#define NDR_ALLOC_N_SIZE(ndr, s, n, elsize) do { \
+ if ((n) == 0) { \
+ (s) = NULL; \
+ } else { \
+ (s) = talloc(ndr->mem_ctx, (n) * elsize); \
+ if (!(s)) return ndr_pull_error(ndr, \
+ NDR_ERR_ALLOC, \
+ "Alloc %u * %u failed\n", \
+ n, elsize); \
+ } \
+ } while (0)
+
+#define NDR_ALLOC_N(ndr, s, n) NDR_ALLOC_N_SIZE(ndr, s, n, sizeof(*(s)))
+
+
+#define NDR_PUSH_ALLOC_SIZE(ndr, s, size) do { \
+ (s) = talloc(ndr->mem_ctx, size); \
+ if ((size) && !(s)) return ndr_push_error(ndr, NDR_ERR_ALLOC, \
+ "push alloc %u failed\n",\
+ size); \
+ } while (0)
+
+#define NDR_PUSH_ALLOC(ndr, s) NDR_PUSH_ALLOC_SIZE(ndr, s, sizeof(*(s)))
+
+
+/* these are used when generic fn pointers are needed for ndr push/pull fns */
+typedef NTSTATUS (*ndr_push_fn_t)(struct ndr_push *, void *);
+typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *);
+
+typedef NTSTATUS (*ndr_push_flags_fn_t)(struct ndr_push *, int ndr_flags, void *);
+typedef NTSTATUS (*ndr_push_const_fn_t)(struct ndr_push *, int ndr_flags, const void *);
+typedef NTSTATUS (*ndr_pull_flags_fn_t)(struct ndr_pull *, int ndr_flags, void *);
+typedef NTSTATUS (*ndr_push_union_fn_t)(struct ndr_push *, int ndr_flags, uint32, void *);
+typedef NTSTATUS (*ndr_pull_union_fn_t)(struct ndr_pull *, int ndr_flags, uint32, void *);
+typedef void (*ndr_print_fn_t)(struct ndr_print *, const char *, void *);
+typedef void (*ndr_print_function_t)(struct ndr_print *, const char *, int, void *);
+typedef void (*ndr_print_union_fn_t)(struct ndr_print *, const char *, uint32, void *);
+
+#include "librpc/ndr/ndr_basic.h"
+#include "librpc/ndr/ndr_sec.h"
+
+/* now pull in the individual parsers */
+#include "librpc/gen_ndr/tables.h"
diff --git a/source/librpc/ndr/ndr.c b/source/librpc/ndr/ndr.c
new file mode 100644
index 00000000000..b44bf11c153
--- /dev/null
+++ b/source/librpc/ndr/ndr.c
@@ -0,0 +1,766 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ libndr interface
+
+ 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.
+*/
+
+/*
+ this provides the core routines for NDR parsing functions
+
+ see http://www.opengroup.org/onlinepubs/9629399/chap14.htm for details
+ of NDR encoding rules
+*/
+
+#include "includes.h"
+
+#define NDR_BASE_MARSHALL_SIZE 1024
+
+/*
+ work out the number of bytes needed to align on a n byte boundary
+*/
+size_t ndr_align_size(uint32 offset, size_t n)
+{
+ if ((offset & (n-1)) == 0) return 0;
+ return n - (offset & (n-1));
+}
+
+/*
+ initialise a ndr parse structure from a data blob
+*/
+struct ndr_pull *ndr_pull_init_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
+{
+ struct ndr_pull *ndr;
+
+ ndr = talloc(mem_ctx, sizeof(*ndr));
+ if (!ndr) return NULL;
+
+ ndr->flags = 0;
+ ndr->data = blob->data;
+ ndr->data_size = blob->length;
+ ndr->offset = 0;
+ ndr->mem_ctx = mem_ctx;
+
+ return ndr;
+}
+
+/*
+ create an ndr sub-context based on an existing context. The new context starts
+ at the current offset, with the given size limit
+*/
+NTSTATUS ndr_pull_subcontext(struct ndr_pull *ndr, struct ndr_pull *ndr2, uint32 size)
+{
+ NDR_PULL_NEED_BYTES(ndr, size);
+ *ndr2 = *ndr;
+ ndr2->data += ndr2->offset;
+ ndr2->offset = 0;
+ ndr2->data_size = size;
+ ndr2->flags = ndr->flags;
+ return NT_STATUS_OK;
+}
+
+
+/*
+ advance by 'size' bytes
+*/
+NTSTATUS ndr_pull_advance(struct ndr_pull *ndr, uint32 size)
+{
+ ndr->offset += size;
+ if (ndr->offset > ndr->data_size) {
+ return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
+ "ndr_pull_advance by %u failed",
+ size);
+ }
+ return NT_STATUS_OK;
+}
+
+/*
+ set the parse offset to 'ofs'
+*/
+NTSTATUS ndr_pull_set_offset(struct ndr_pull *ndr, uint32 ofs)
+{
+ ndr->offset = ofs;
+ if (ndr->offset > ndr->data_size) {
+ return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
+ "ndr_pull_set_offset %u failed",
+ ofs);
+ }
+ return NT_STATUS_OK;
+}
+
+/* save the offset/size of the current ndr state */
+void ndr_pull_save(struct ndr_pull *ndr, struct ndr_pull_save *save)
+{
+ save->offset = ndr->offset;
+ save->data_size = ndr->data_size;
+}
+
+/* restore the size/offset of a ndr structure */
+void ndr_pull_restore(struct ndr_pull *ndr, struct ndr_pull_save *save)
+{
+ ndr->offset = save->offset;
+ ndr->data_size = save->data_size;
+}
+
+
+/* create a ndr_push structure, ready for some marshalling */
+struct ndr_push *ndr_push_init_ctx(TALLOC_CTX *mem_ctx)
+{
+ struct ndr_push *ndr;
+
+ ndr = talloc(mem_ctx, sizeof(*ndr));
+ if (!ndr) {
+ return NULL;
+ }
+
+ ndr->mem_ctx = mem_ctx;
+ ndr->flags = 0;
+ ndr->alloc_size = NDR_BASE_MARSHALL_SIZE;
+ ndr->data = talloc(ndr->mem_ctx, ndr->alloc_size);
+ if (!ndr->data) {
+ return NULL;
+ }
+ ndr->offset = 0;
+ ndr->ptr_count = 0;
+ ndr->relative_list = NULL;
+ ndr->relative_list_end = NULL;
+
+ return ndr;
+}
+
+
+/* create a ndr_push structure, ready for some marshalling */
+struct ndr_push *ndr_push_init(void)
+{
+ struct ndr_push *ndr;
+ TALLOC_CTX *mem_ctx = talloc_init("ndr_push_init");
+ if (!mem_ctx) return NULL;
+ ndr = ndr_push_init_ctx(mem_ctx);
+ if (!ndr) {
+ talloc_destroy(mem_ctx);
+ }
+ return ndr;
+}
+
+/* free a ndr_push structure */
+void ndr_push_free(struct ndr_push *ndr)
+{
+ talloc_destroy(ndr->mem_ctx);
+}
+
+
+/* return a DATA_BLOB structure for the current ndr_push marshalled data */
+DATA_BLOB ndr_push_blob(struct ndr_push *ndr)
+{
+ DATA_BLOB blob;
+ blob.data = ndr->data;
+ blob.length = ndr->offset;
+ return blob;
+}
+
+
+/*
+ expand the available space in the buffer to 'size'
+*/
+NTSTATUS ndr_push_expand(struct ndr_push *ndr, uint32 size)
+{
+ if (ndr->alloc_size >= size) {
+ return NT_STATUS_OK;
+ }
+
+ ndr->alloc_size += NDR_BASE_MARSHALL_SIZE;
+ if (size > ndr->alloc_size) {
+ ndr->alloc_size = size;
+ }
+ ndr->data = talloc_realloc(ndr->mem_ctx, ndr->data, ndr->alloc_size);
+ if (!ndr->data) {
+ return ndr_push_error(ndr, NDR_ERR_ALLOC, "Failed to push_expand to %u",
+ ndr->alloc_size);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ set the push offset to 'ofs'
+*/
+NTSTATUS ndr_push_set_offset(struct ndr_push *ndr, uint32 ofs)
+{
+ NDR_CHECK(ndr_push_expand(ndr, ofs));
+ ndr->offset = ofs;
+ return NT_STATUS_OK;
+}
+
+/*
+ push a generic array
+*/
+NTSTATUS ndr_push_array(struct ndr_push *ndr, int ndr_flags, void *base,
+ size_t elsize, uint32 count,
+ NTSTATUS (*push_fn)(struct ndr_push *, int, void *))
+{
+ int i;
+ char *p = base;
+ if (!(ndr_flags & NDR_SCALARS)) goto buffers;
+ for (i=0;i<count;i++) {
+ NDR_CHECK(push_fn(ndr, NDR_SCALARS, p));
+ p += elsize;
+ }
+ if (!(ndr_flags & NDR_BUFFERS)) goto done;
+buffers:
+ p = base;
+ for (i=0;i<count;i++) {
+ NDR_CHECK(push_fn(ndr, NDR_BUFFERS, p));
+ p += elsize;
+ }
+done:
+ return NT_STATUS_OK;
+}
+
+/*
+ pull a constant sized array
+*/
+NTSTATUS ndr_pull_array(struct ndr_pull *ndr, int ndr_flags, void *base,
+ size_t elsize, uint32 count,
+ NTSTATUS (*pull_fn)(struct ndr_pull *, int, void *))
+{
+ int i;
+ char *p;
+ p = base;
+ if (!(ndr_flags & NDR_SCALARS)) goto buffers;
+ for (i=0;i<count;i++) {
+ NDR_CHECK(pull_fn(ndr, NDR_SCALARS, p));
+ p += elsize;
+ }
+ if (!(ndr_flags & NDR_BUFFERS)) goto done;
+buffers:
+ p = base;
+ for (i=0;i<count;i++) {
+ NDR_CHECK(pull_fn(ndr, NDR_BUFFERS, p));
+ p += elsize;
+ }
+done:
+ return NT_STATUS_OK;
+}
+
+
+/*
+ print a generic array
+*/
+void ndr_print_array(struct ndr_print *ndr, const char *name, void *base,
+ size_t elsize, uint32 count,
+ void (*print_fn)(struct ndr_print *, const char *, void *))
+{
+ int i;
+ char *p = base;
+ ndr->print(ndr, "%s: ARRAY(%d)", name, count);
+ ndr->depth++;
+ for (i=0;i<count;i++) {
+ char *idx=NULL;
+ asprintf(&idx, "[%d]", i);
+ if (idx) {
+ print_fn(ndr, idx, p);
+ free(idx);
+ }
+ p += elsize;
+ }
+ ndr->depth--;
+}
+
+
+
+void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...)
+{
+ va_list ap;
+ char *s = NULL;
+ int i;
+
+ va_start(ap, format);
+ vasprintf(&s, format, ap);
+ va_end(ap);
+
+ for (i=0;i<ndr->depth;i++) {
+ DEBUG(0,(" "));
+ }
+
+ DEBUG(0,("%s\n", s));
+ free(s);
+}
+
+/*
+ a useful helper function for printing idl structures via DEBUG()
+*/
+void ndr_print_debug(void (*fn)(struct ndr_print *, const char *, void *),
+ const char *name,
+ void *ptr)
+{
+ struct ndr_print ndr;
+
+ ndr.mem_ctx = talloc_init("ndr_print_debug");
+ if (!ndr.mem_ctx) return;
+ ndr.print = ndr_print_debug_helper;
+ ndr.depth = 1;
+ fn(&ndr, name, ptr);
+ talloc_destroy(ndr.mem_ctx);
+}
+
+
+/*
+ a useful helper function for printing idl unions via DEBUG()
+*/
+void ndr_print_union_debug(void (*fn)(struct ndr_print *, const char *, uint32, void *),
+ const char *name,
+ uint32 level,
+ void *ptr)
+{
+ struct ndr_print ndr;
+
+ ndr.mem_ctx = talloc_init("ndr_print_union");
+ if (!ndr.mem_ctx) return;
+ ndr.print = ndr_print_debug_helper;
+ ndr.depth = 1;
+ fn(&ndr, name, level, ptr);
+ talloc_destroy(ndr.mem_ctx);
+}
+
+/*
+ a useful helper function for printing idl function calls via DEBUG()
+*/
+void ndr_print_function_debug(void (*fn)(struct ndr_print *, const char *, int , void *),
+ const char *name,
+ int flags,
+ void *ptr)
+{
+ struct ndr_print ndr;
+
+ ndr.mem_ctx = talloc_init("ndr_print_function");
+ if (!ndr.mem_ctx) return;
+ ndr.print = ndr_print_debug_helper;
+ ndr.depth = 1;
+ fn(&ndr, name, flags, ptr);
+ talloc_destroy(ndr.mem_ctx);
+}
+
+
+static NTSTATUS ndr_map_error(enum ndr_err_code err)
+{
+ switch (err) {
+ case NDR_ERR_BUFSIZE:
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ case NDR_ERR_ALLOC:
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* we should all error codes to different status codes */
+ return NT_STATUS_INVALID_PARAMETER;
+}
+
+/*
+ return and possibly log an NDR error
+*/
+NTSTATUS ndr_pull_error(struct ndr_pull *ndr, enum ndr_err_code err, const char *format, ...)
+{
+ char *s=NULL;
+ va_list ap;
+
+ va_start(ap, format);
+ vasprintf(&s, format, ap);
+ va_end(ap);
+
+ DEBUG(3,("ndr_pull_error(%u): %s\n", err, s));
+
+ free(s);
+
+ return ndr_map_error(err);
+}
+
+/*
+ return and possibly log an NDR error
+*/
+NTSTATUS ndr_push_error(struct ndr_push *ndr, enum ndr_err_code err, const char *format, ...)
+{
+ char *s=NULL;
+ va_list ap;
+
+ va_start(ap, format);
+ vasprintf(&s, format, ap);
+ va_end(ap);
+
+ DEBUG(3,("ndr_push_error(%u): %s\n", err, s));
+
+ free(s);
+
+ return ndr_map_error(err);
+}
+
+
+/*
+ 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 *))
+{
+ struct ndr_pull ndr2;
+
+ NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2));
+ NDR_CHECK(fn(&ndr2, base));
+ 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 *))
+{
+ struct ndr_pull ndr2;
+
+ NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2));
+ NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, base));
+ 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 *))
+{
+ struct ndr_pull ndr2;
+
+ NDR_CHECK(ndr_pull_subcontext_header(ndr, sub_size, &ndr2));
+ NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, level, base));
+ 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;
+}
+
+
+/*
+ push a subcontext header
+*/
+static NTSTATUS ndr_push_subcontext_header(struct ndr_push *ndr,
+ size_t sub_size,
+ struct ndr_push *ndr2)
+{
+ switch (sub_size) {
+ case 0:
+ break;
+
+ case 2:
+ NDR_CHECK(ndr_push_uint16(ndr, ndr2->offset));
+ break;
+
+ case 4:
+ NDR_CHECK(ndr_push_uint32(ndr, ndr2->offset));
+ break;
+
+ default:
+ return ndr_push_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_push_subcontext_fn(struct ndr_push *ndr,
+ size_t sub_size,
+ void *base,
+ NTSTATUS (*fn)(struct ndr_push *, void *))
+{
+ struct ndr_push *ndr2;
+
+ ndr2 = ndr_push_init_ctx(ndr->mem_ctx);
+ if (!ndr2) return NT_STATUS_NO_MEMORY;
+
+ ndr2->flags = ndr->flags;
+ NDR_CHECK(fn(ndr2, base));
+ NDR_CHECK(ndr_push_subcontext_header(ndr, sub_size, ndr2));
+ NDR_CHECK(ndr_push_bytes(ndr, ndr2->data, ndr2->offset));
+ return NT_STATUS_OK;
+}
+
+/*
+ handle subcontext buffers for function that take a flags arg
+*/
+NTSTATUS ndr_push_subcontext_flags_fn(struct ndr_push *ndr,
+ size_t sub_size,
+ void *base,
+ NTSTATUS (*fn)(struct ndr_push *, int, void *))
+{
+ struct ndr_push *ndr2;
+
+ ndr2 = ndr_push_init_ctx(ndr->mem_ctx);
+ if (!ndr2) return NT_STATUS_NO_MEMORY;
+
+ ndr2->flags = ndr->flags;
+ NDR_CHECK(fn(ndr2, NDR_SCALARS|NDR_BUFFERS, base));
+ NDR_CHECK(ndr_push_subcontext_header(ndr, sub_size, ndr2));
+ NDR_CHECK(ndr_push_bytes(ndr, ndr2->data, ndr2->offset));
+ return NT_STATUS_OK;
+}
+
+/*
+ handle subcontext buffers for function that take a union
+*/
+NTSTATUS ndr_push_subcontext_union_fn(struct ndr_push *ndr,
+ size_t sub_size,
+ uint32 level,
+ void *base,
+ NTSTATUS (*fn)(struct ndr_push *, int, uint32, void *))
+{
+ struct ndr_push *ndr2;
+
+ ndr2 = ndr_push_init_ctx(ndr->mem_ctx);
+ if (!ndr2) return NT_STATUS_NO_MEMORY;
+
+ ndr2->flags = ndr->flags;
+ NDR_CHECK(fn(ndr2, NDR_SCALARS|NDR_BUFFERS, level, base));
+ NDR_CHECK(ndr_push_subcontext_header(ndr, sub_size, ndr2));
+ NDR_CHECK(ndr_push_bytes(ndr, ndr2->data, ndr2->offset));
+ return NT_STATUS_OK;
+}
+
+
+/*
+ mark the start of a structure
+*/
+NTSTATUS ndr_pull_struct_start(struct ndr_pull *ndr)
+{
+ struct ndr_ofs_list *ofs;
+ NDR_ALLOC(ndr, ofs);
+ ofs->offset = ndr->offset;
+ ofs->next = ndr->ofs_list;
+ ndr->ofs_list = ofs;
+ return NT_STATUS_OK;
+}
+
+/*
+ mark the end of a structure
+*/
+void ndr_pull_struct_end(struct ndr_pull *ndr)
+{
+ ndr->ofs_list = ndr->ofs_list->next;
+}
+
+/*
+ mark the start of a structure
+*/
+NTSTATUS ndr_push_struct_start(struct ndr_push *ndr)
+{
+ struct ndr_ofs_list *ofs;
+ NDR_PUSH_ALLOC(ndr, ofs);
+ ofs->offset = ndr->offset;
+ ofs->next = ndr->ofs_list;
+ ndr->ofs_list = ofs;
+ return NT_STATUS_OK;
+}
+
+/*
+ mark the end of a structure
+*/
+void ndr_push_struct_end(struct ndr_push *ndr)
+{
+ ndr->ofs_list = ndr->ofs_list->next;
+}
+
+
+/*
+ pull a relative structure
+*/
+NTSTATUS ndr_pull_relative(struct ndr_pull *ndr, const void **buf, size_t size,
+ NTSTATUS (*fn)(struct ndr_pull *, int ndr_flags, void *))
+{
+ struct ndr_pull ndr2;
+ uint32 ofs;
+ struct ndr_pull_save save;
+ void *p;
+
+ NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
+ if (ofs == 0) {
+ (*buf) = NULL;
+ return NT_STATUS_OK;
+ }
+ ndr_pull_save(ndr, &save);
+ NDR_CHECK(ndr_pull_set_offset(ndr, ofs + ndr->ofs_list->offset));
+ NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, ndr->data_size - ndr->offset));
+ /* strings must be allocated by the backend functions */
+ if (ndr->flags & LIBNDR_STRING_FLAGS) {
+ NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, &p));
+ } else {
+ NDR_ALLOC_SIZE(ndr, p, size);
+ NDR_CHECK(fn(&ndr2, NDR_SCALARS|NDR_BUFFERS, p));
+ }
+ (*buf) = p;
+ ndr_pull_restore(ndr, &save);
+ return NT_STATUS_OK;
+}
+
+/*
+ push a relative structure
+*/
+NTSTATUS ndr_push_relative(struct ndr_push *ndr, int ndr_flags, const void *p,
+ NTSTATUS (*fn)(struct ndr_push *, int , const void *))
+{
+ struct ndr_ofs_list *ofs;
+ if (ndr_flags & NDR_SCALARS) {
+ if (!p) {
+ NDR_CHECK(ndr_push_uint32(ndr, 0));
+ return NT_STATUS_OK;
+ }
+ NDR_PUSH_ALLOC(ndr, ofs);
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ ofs->offset = ndr->offset;
+ NDR_CHECK(ndr_push_uint32(ndr, 0xFFFFFFFF));
+ ofs->next = NULL;
+ if (ndr->relative_list_end) {
+ ndr->relative_list_end->next = ofs;
+ } else {
+ ndr->relative_list = ofs;
+ }
+ ndr->relative_list_end = ofs;
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ struct ndr_push_save save;
+ if (!p) {
+ return NT_STATUS_OK;
+ }
+ ofs = ndr->relative_list;
+ if (!ofs) {
+ return ndr_push_error(ndr, NDR_ERR_RELATIVE, "Empty relative stack");
+ }
+ ndr->relative_list = ndr->relative_list->next;
+ if (ndr->relative_list == NULL) {
+ ndr->relative_list_end = NULL;
+ }
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ ndr_push_save(ndr, &save);
+ ndr->offset = ofs->offset;
+ NDR_CHECK(ndr_push_uint32(ndr, save.offset - ndr->ofs_list->offset));
+ ndr_push_restore(ndr, &save);
+ NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p));
+ }
+ return NT_STATUS_OK;
+}
+
+
+/*
+ pull a union from a blob using NDR
+*/
+NTSTATUS ndr_pull_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, uint32 level, void *p,
+ NTSTATUS (*fn)(struct ndr_pull *, int ndr_flags, uint32, void *))
+{
+ struct ndr_pull *ndr;
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ return fn(ndr, NDR_SCALARS|NDR_BUFFERS, level, p);
+}
+
+/*
+ pull a struct from a blob using NDR
+*/
+NTSTATUS ndr_pull_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
+ NTSTATUS (*fn)(struct ndr_pull *, int , void *))
+{
+ struct ndr_pull *ndr;
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ return fn(ndr, NDR_SCALARS|NDR_BUFFERS, p);
+}
+
+/*
+ push a struct to a blob using NDR
+*/
+NTSTATUS ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
+ NTSTATUS (*fn)(struct ndr_push *, int , void *))
+{
+ NTSTATUS status;
+ struct ndr_push *ndr;
+ ndr = ndr_push_init_ctx(mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ status = fn(ndr, NDR_SCALARS|NDR_BUFFERS, p);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ *blob = ndr_push_blob(ndr);
+
+ return NT_STATUS_OK;
+}
diff --git a/source/librpc/ndr/ndr_basic.c b/source/librpc/ndr/ndr_basic.c
new file mode 100644
index 00000000000..0c63faf347d
--- /dev/null
+++ b/source/librpc/ndr/ndr_basic.c
@@ -0,0 +1,868 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling basic types
+
+ 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"
+
+#define NDR_BE(ndr) (((ndr)->flags & (LIBNDR_FLAG_BIGENDIAN|LIBNDR_FLAG_LITTLE_ENDIAN)) == LIBNDR_FLAG_BIGENDIAN)
+#define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
+#define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
+#define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
+#define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
+
+/*
+ parse a uint8
+*/
+NTSTATUS ndr_pull_uint8(struct ndr_pull *ndr, uint8 *v)
+{
+ NDR_PULL_NEED_BYTES(ndr, 1);
+ *v = CVAL(ndr->data, ndr->offset);
+ ndr->offset += 1;
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a uint16
+*/
+NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16 *v)
+{
+ NDR_PULL_ALIGN(ndr, 2);
+ NDR_PULL_NEED_BYTES(ndr, 2);
+ *v = NDR_SVAL(ndr, ndr->offset);
+ ndr->offset += 2;
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a uint32
+*/
+NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32 *v)
+{
+ NDR_PULL_ALIGN(ndr, 4);
+ NDR_PULL_NEED_BYTES(ndr, 4);
+ *v = NDR_IVAL(ndr, ndr->offset);
+ ndr->offset += 4;
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a HYPER_T
+*/
+NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
+{
+ NDR_PULL_ALIGN(ndr, 8);
+ NDR_PULL_NEED_BYTES(ndr, 8);
+ v->low = NDR_IVAL(ndr, ndr->offset);
+ v->high = NDR_IVAL(ndr, ndr->offset+4);
+ ndr->offset += 8;
+ return NT_STATUS_OK;
+}
+
+/*
+ pull a NTSTATUS
+*/
+NTSTATUS ndr_pull_NTSTATUS(struct ndr_pull *ndr, NTSTATUS *status)
+{
+ uint32 v;
+ NDR_CHECK(ndr_pull_uint32(ndr, &v));
+ *status = NT_STATUS(v);
+ return NT_STATUS_OK;
+}
+
+/*
+ push a NTSTATUS
+*/
+NTSTATUS ndr_push_NTSTATUS(struct ndr_push *ndr, NTSTATUS status)
+{
+ return ndr_push_uint32(ndr, NT_STATUS_V(status));
+}
+
+void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS *r)
+{
+ ndr->print(ndr, "%-25s: %s", name, nt_errstr(*r));
+}
+
+/*
+ pull a WERROR
+*/
+NTSTATUS ndr_pull_WERROR(struct ndr_pull *ndr, WERROR *status)
+{
+ uint32 v;
+ NDR_CHECK(ndr_pull_uint32(ndr, &v));
+ *status = W_ERROR(v);
+ return NT_STATUS_OK;
+}
+
+/*
+ push a WERROR
+*/
+NTSTATUS ndr_push_WERROR(struct ndr_push *ndr, WERROR status)
+{
+ return ndr_push_uint32(ndr, W_ERROR_V(status));
+}
+
+void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR *r)
+{
+ ndr->print(ndr, "%-25s: %s", name, win_errstr(*r));
+}
+
+/*
+ parse a set of bytes
+*/
+NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32 n)
+{
+ NDR_PULL_NEED_BYTES(ndr, n);
+ memcpy(data, ndr->data + ndr->offset, n);
+ ndr->offset += n;
+ return NT_STATUS_OK;
+}
+
+/*
+ pull an array of uint8
+*/
+NTSTATUS ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, char *data, uint32 n)
+{
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+ return ndr_pull_bytes(ndr, data, n);
+}
+
+
+/*
+ pull an array of uint16
+*/
+NTSTATUS ndr_pull_array_uint16(struct ndr_pull *ndr, int ndr_flags, uint16 *data, uint32 n)
+{
+ uint32 i;
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+ for (i=0;i<n;i++) {
+ NDR_CHECK(ndr_pull_uint16(ndr, &data[i]));
+ }
+ return NT_STATUS_OK;
+}
+
+/*
+ pull a const array of uint32
+*/
+NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32 *data, uint32 n)
+{
+ uint32 i;
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+ for (i=0;i<n;i++) {
+ NDR_CHECK(ndr_pull_uint32(ndr, &data[i]));
+ }
+ return NT_STATUS_OK;
+}
+
+/*
+ push a uint8
+*/
+NTSTATUS ndr_push_uint8(struct ndr_push *ndr, uint8 v)
+{
+ NDR_PUSH_NEED_BYTES(ndr, 1);
+ SCVAL(ndr->data, ndr->offset, v);
+ ndr->offset += 1;
+ return NT_STATUS_OK;
+}
+
+/*
+ push a uint16
+*/
+NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16 v)
+{
+ NDR_PUSH_ALIGN(ndr, 2);
+ NDR_PUSH_NEED_BYTES(ndr, 2);
+ NDR_SSVAL(ndr, ndr->offset, v);
+ ndr->offset += 2;
+ return NT_STATUS_OK;
+}
+
+/*
+ push a uint32
+*/
+NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32 v)
+{
+ NDR_PUSH_ALIGN(ndr, 4);
+ NDR_PUSH_NEED_BYTES(ndr, 4);
+ NDR_SIVAL(ndr, ndr->offset, v);
+ ndr->offset += 4;
+ return NT_STATUS_OK;
+}
+
+/*
+ push a HYPER_T
+*/
+NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
+{
+ NDR_PUSH_ALIGN(ndr, 8);
+ NDR_PUSH_NEED_BYTES(ndr, 8);
+ NDR_SIVAL(ndr, ndr->offset, v.low);
+ NDR_SIVAL(ndr, ndr->offset+4, v.high);
+ ndr->offset += 8;
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_push_align(struct ndr_push *ndr, size_t size)
+{
+ NDR_PUSH_ALIGN(ndr, size);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_pull_align(struct ndr_pull *ndr, size_t size)
+{
+ NDR_PULL_ALIGN(ndr, size);
+ return NT_STATUS_OK;
+}
+
+/*
+ push some bytes
+*/
+NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n)
+{
+ NDR_PUSH_NEED_BYTES(ndr, n);
+ memcpy(ndr->data + ndr->offset, data, n);
+ ndr->offset += n;
+ return NT_STATUS_OK;
+}
+
+/*
+ push some zero bytes
+*/
+NTSTATUS ndr_push_zero(struct ndr_push *ndr, uint32 n)
+{
+ NDR_PUSH_NEED_BYTES(ndr, n);
+ memset(ndr->data + ndr->offset, 0, n);
+ ndr->offset += n;
+ return NT_STATUS_OK;
+}
+
+/*
+ push an array of uint8
+*/
+NTSTATUS ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const char *data, uint32 n)
+{
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+ return ndr_push_bytes(ndr, data, n);
+}
+
+/*
+ push an array of uint16
+*/
+NTSTATUS ndr_push_array_uint16(struct ndr_push *ndr, int ndr_flags, const uint16 *data, uint32 n)
+{
+ int i;
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+ for (i=0;i<n;i++) {
+ NDR_CHECK(ndr_push_uint16(ndr, data[i]));
+ }
+ return NT_STATUS_OK;
+}
+
+/*
+ push an array of uint32
+*/
+NTSTATUS ndr_push_array_uint32(struct ndr_push *ndr, int ndr_flags, const uint32 *data, uint32 n)
+{
+ int i;
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+ for (i=0;i<n;i++) {
+ NDR_CHECK(ndr_push_uint32(ndr, data[i]));
+ }
+ return NT_STATUS_OK;
+}
+
+/*
+ save the current position
+ */
+void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save)
+{
+ save->offset = ndr->offset;
+}
+
+/*
+ restore the position
+ */
+void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save)
+{
+ ndr->offset = save->offset;
+}
+
+/*
+ push a 1 if a pointer is non-NULL, otherwise 0
+*/
+NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p)
+{
+ uint32 ptr = 0;
+ if (p) {
+ /* we do this to ensure that we generate unique ref ids,
+ which means we can handle the case where a MS programmer
+ forgot to mark a pointer as unique */
+ ndr->ptr_count++;
+ ptr = ndr->ptr_count;
+ }
+ return ndr_push_uint32(ndr, ptr);
+}
+
+
+/*
+ pull a general string from the wire
+*/
+NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
+{
+ char *as=NULL;
+ uint32 len1, ofs, len2;
+ uint16 len3;
+ int ret;
+ int chset = CH_UCS2;
+
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+
+ if (NDR_BE(ndr)) {
+ chset = CH_UCS2BE;
+ }
+
+ 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 ndr_pull_error(ndr, NDR_ERR_STRING,
+ "Bad string lengths len1=%u ofs=%u len2=%u\n",
+ len1, ofs, len2);
+ }
+ if (len2 == 0) {
+ *s = talloc_strdup(ndr->mem_ctx, "");
+ break;
+ }
+ NDR_PULL_NEED_BYTES(ndr, len2*2);
+ ret = convert_string_talloc(ndr->mem_ctx, chset, 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, chset, 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:
+ len1 = strnlen_w(ndr->data+ndr->offset,
+ (ndr->data_size - ndr->offset)/2);
+ if (len1*2+2 <= ndr->data_size - ndr->offset) {
+ len1++;
+ }
+ ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
+ ndr->data+ndr->offset,
+ len1*2,
+ (const void **)s);
+ if (ret == -1) {
+ return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
+ "Bad character conversion");
+ }
+ NDR_CHECK(ndr_pull_advance(ndr, len1*2));
+ 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 ndr_pull_error(ndr, NDR_ERR_STRING,
+ "Bad ascii string lengths len1=%u ofs=%u len2=%u\n",
+ len1, ofs, len2);
+ }
+ 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;
+
+ case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
+ NDR_CHECK(ndr_pull_uint16(ndr, &len3));
+ NDR_ALLOC_N(ndr, as, (len3+1));
+ NDR_CHECK(ndr_pull_bytes(ndr, as, len3));
+ as[len3] = 0;
+ (*s) = as;
+ break;
+
+ default:
+ return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
+ ndr->flags & LIBNDR_STRING_FLAGS);
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ push a general string onto the wire
+*/
+NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
+{
+ ssize_t s_len, c_len;
+ int ret;
+ int chset = CH_UCS2;
+
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+
+ if (NDR_BE(ndr)) {
+ chset = CH_UCS2BE;
+ }
+
+ s_len = s?strlen(s):0;
+ c_len = s?strlen_m(s):0;
+
+ 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, chset,
+ 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, chset,
+ 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, chset,
+ 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, chset,
+ 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;
+
+ case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
+ NDR_CHECK(ndr_push_uint16(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;
+
+ default:
+ return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
+ ndr->flags & LIBNDR_STRING_FLAGS);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ push a NTTIME
+*/
+NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, t.low));
+ NDR_CHECK(ndr_push_uint32(ndr, t.high));
+ return NT_STATUS_OK;
+}
+
+/*
+ pull a NTTIME
+*/
+NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, NTTIME *t)
+{
+ NDR_CHECK(ndr_pull_uint32(ndr, &t->low));
+ NDR_CHECK(ndr_pull_uint32(ndr, &t->high));
+ return NT_STATUS_OK;
+}
+
+/*
+ push a time_t
+*/
+NTSTATUS ndr_push_time_t(struct ndr_push *ndr, time_t t)
+{
+ return ndr_push_uint32(ndr, t);
+}
+
+/*
+ pull a time_t
+*/
+NTSTATUS ndr_pull_time_t(struct ndr_pull *ndr, time_t *t)
+{
+ uint32 tt;
+ NDR_CHECK(ndr_pull_uint32(ndr, &tt));
+ *t = tt;
+ return NT_STATUS_OK;
+}
+
+
+void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
+{
+ ndr->print(ndr, "%s: struct %s", name, type);
+}
+
+void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8 v)
+{
+ ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
+}
+
+void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16 v)
+{
+ ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
+}
+
+void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32 v)
+{
+ ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
+}
+
+void ndr_print_HYPER_T(struct ndr_print *ndr, const char *name, HYPER_T v)
+{
+ ndr->print(ndr, "%-25s: 0x%08x%08x", name, v.high, v.low);
+}
+
+void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
+{
+ if (p) {
+ ndr->print(ndr, "%-25s: *", name);
+ } else {
+ ndr->print(ndr, "%-25s: NULL", name);
+ }
+}
+
+void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
+{
+ if (s) {
+ ndr->print(ndr, "%-25s: '%s'", name, s);
+ } else {
+ ndr->print(ndr, "%-25s: NULL", name);
+ }
+}
+
+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));
+}
+
+void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
+{
+ if (t == (time_t)-1 || t == 0) {
+ ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
+ } else {
+ ndr->print(ndr, "%-25s: %s", name, http_timestring(ndr->mem_ctx, t));
+ }
+}
+
+void ndr_print_union(struct ndr_print *ndr, const char *name, uint16 level, const char *type)
+{
+ ndr->print(ndr, "%-25s: union %s(case %u)", name, type, level);
+}
+
+void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16 level)
+{
+ ndr->print(ndr, "UNKNOWN LEVEL %u", level);
+}
+
+void ndr_print_array_uint32(struct ndr_print *ndr, const char *name,
+ const uint32 *data, uint32 count)
+{
+ int i;
+
+ ndr->print(ndr, "%s: ARRAY(%d)", name, count);
+ ndr->depth++;
+ for (i=0;i<count;i++) {
+ char *idx=NULL;
+ asprintf(&idx, "[%d]", i);
+ if (idx) {
+ ndr_print_uint32(ndr, idx, data[i]);
+ free(idx);
+ }
+ }
+ ndr->depth--;
+}
+
+void ndr_print_array_uint16(struct ndr_print *ndr, const char *name,
+ const uint16 *data, uint32 count)
+{
+ int i;
+
+ ndr->print(ndr, "%s: ARRAY(%d)", name, count);
+ ndr->depth++;
+ for (i=0;i<count;i++) {
+ char *idx=NULL;
+ asprintf(&idx, "[%d]", i);
+ if (idx) {
+ ndr_print_uint16(ndr, idx, data[i]);
+ free(idx);
+ }
+ }
+ ndr->depth--;
+}
+
+void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
+ const uint8 *data, uint32 count)
+{
+ int i;
+
+ if (count <= 32 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
+ char s[65];
+ for (i=0;i<count;i++) {
+ snprintf(&s[i*2], 3, "%02x", data[i]);
+ }
+ s[i*2] = 0;
+ ndr->print(ndr, "%-25s: %s", name, s);
+ return;
+ }
+
+ ndr->print(ndr, "%s: ARRAY(%d)", name, count);
+ ndr->depth++;
+ for (i=0;i<count;i++) {
+ char *idx=NULL;
+ asprintf(&idx, "[%d]", i);
+ if (idx) {
+ ndr_print_uint8(ndr, idx, data[i]);
+ free(idx);
+ }
+ }
+ ndr->depth--;
+}
+
+/*
+ build a GUID from a string
+*/
+NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
+{
+ uint32 time_low;
+ uint32 time_mid, time_hi_and_version;
+ uint32 clock_seq[2];
+ uint32 node[6];
+ int i;
+
+ if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ &time_low, &time_mid, &time_hi_and_version,
+ &clock_seq[0], &clock_seq[1],
+ &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ guid->time_low = time_low;
+ guid->time_mid = time_mid;
+ guid->time_hi_and_version = time_hi_and_version;
+ guid->clock_seq[0] = clock_seq[0];
+ guid->clock_seq[1] = clock_seq[1];
+ for (i=0;i<6;i++) {
+ guid->node[i] = node[i];
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ its useful to be able to display these in debugging messages
+*/
+const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
+{
+ return talloc_asprintf(mem_ctx,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ guid->time_low, guid->time_mid,
+ guid->time_hi_and_version,
+ guid->clock_seq[0],
+ guid->clock_seq[1],
+ guid->node[0], guid->node[1],
+ guid->node[2], guid->node[3],
+ guid->node[4], guid->node[5]);
+}
+
+void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
+{
+ ndr->print(ndr, "%-25s: %s", name, GUID_string(ndr->mem_ctx, guid));
+}
+
+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);
+ if (r.length) {
+ dump_data(10, r.data, r.length);
+ }
+}
+
+
+/*
+ push a DATA_BLOB onto the wire.
+*/
+NTSTATUS ndr_push_DATA_BLOB(struct ndr_push *ndr, DATA_BLOB blob)
+{
+ if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
+ if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
+ blob.length = NDR_ALIGN(ndr, 2);
+ } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
+ blob.length = NDR_ALIGN(ndr, 4);
+ } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
+ blob.length = NDR_ALIGN(ndr, 8);
+ }
+ NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
+ data_blob_clear(&blob);
+ } else if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) {
+ NDR_CHECK(ndr_push_uint32(ndr, blob.length));
+ }
+ NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
+ return NT_STATUS_OK;
+}
+
+/*
+ pull a DATA_BLOB from the wire.
+*/
+NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, DATA_BLOB *blob)
+{
+ uint32 length;
+
+ if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
+ if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
+ length = NDR_ALIGN(ndr, 2);
+ } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
+ length = NDR_ALIGN(ndr, 4);
+ } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
+ length = NDR_ALIGN(ndr, 8);
+ }
+ if (ndr->data_size - ndr->offset < length) {
+ length = ndr->data_size - ndr->offset;
+ }
+ } else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
+ length = ndr->data_size - ndr->offset;
+ } else {
+ NDR_CHECK(ndr_pull_uint32(ndr, &length));
+ }
+ NDR_PULL_NEED_BYTES(ndr, length);
+ *blob = data_blob_talloc(ndr->mem_ctx, ndr->data+ndr->offset, length);
+ ndr->offset += length;
+ return NT_STATUS_OK;
+}
diff --git a/source/librpc/ndr/ndr_sec.c b/source/librpc/ndr/ndr_sec.c
new file mode 100644
index 00000000000..3ea0f4e3037
--- /dev/null
+++ b/source/librpc/ndr/ndr_sec.c
@@ -0,0 +1,185 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling security descriptors
+ and related structures
+
+ 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"
+
+/*
+ parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
+*/
+NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
+{
+ uint32 num_auths;
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+ NDR_CHECK(ndr_pull_uint32(ndr, &num_auths));
+ return ndr_pull_dom_sid(ndr, ndr_flags, sid);
+}
+
+/*
+ parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
+*/
+NTSTATUS ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, struct dom_sid *sid)
+{
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NT_STATUS_OK;
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, sid->num_auths));
+ return ndr_push_dom_sid(ndr, ndr_flags, sid);
+}
+
+
+/*
+ convert a dom_sid to a string
+*/
+const char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
+{
+ int i, ofs, maxlen;
+ uint32 ia;
+ char *ret;
+
+ if (!sid) {
+ return "(NULL SID)";
+ }
+
+ maxlen = sid->num_auths * 11 + 25;
+ ret = talloc(mem_ctx, maxlen);
+ if (!ret) return "(SID ERR)";
+
+ ia = (sid->id_auth[5]) +
+ (sid->id_auth[4] << 8 ) +
+ (sid->id_auth[3] << 16) +
+ (sid->id_auth[2] << 24);
+
+ ofs = snprintf(ret, maxlen, "S-%u-%lu",
+ (unsigned int)sid->sid_rev_num, (unsigned long)ia);
+
+ for (i = 0; i < sid->num_auths; i++) {
+ ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]);
+ }
+
+ return ret;
+}
+
+
+/*
+ print a dom_sid
+*/
+void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, struct dom_sid *sid)
+{
+ ndr->print(ndr, "%-25s: %s", name, dom_sid_string(ndr->mem_ctx, sid));
+}
+
+void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, struct dom_sid2 *sid)
+{
+ ndr_print_dom_sid(ndr, name, sid);
+}
+
+/*
+ return the wire size of a dom_sid
+*/
+size_t ndr_size_dom_sid(struct dom_sid *sid)
+{
+ if (!sid) return 0;
+ return 8 + 4*sid->num_auths;
+}
+
+/*
+ add a rid to a domain dom_sid to make a full dom_sid
+*/
+struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx,
+ const struct dom_sid *domain_sid,
+ uint32 rid)
+{
+ struct dom_sid *sid;
+
+ sid = talloc_p(mem_ctx, struct dom_sid);
+ if (!sid) return NULL;
+
+ *sid = *domain_sid;
+ sid->sub_auths = talloc_array_p(mem_ctx, uint32, sid->num_auths+1);
+ if (!sid->sub_auths) {
+ return NULL;
+ }
+ memcpy(sid->sub_auths, domain_sid->sub_auths, sid->num_auths*sizeof(uint32));
+ sid->sub_auths[sid->num_auths] = rid;
+ sid->num_auths++;
+ return sid;
+}
+
+/*
+ return the wire size of a security_ace
+*/
+size_t ndr_size_security_ace(struct security_ace *ace)
+{
+ if (!ace) return 0;
+ return 8 + ndr_size_dom_sid(&ace->trustee);
+}
+
+
+/*
+ return the wire size of a security_acl
+*/
+size_t ndr_size_security_acl(struct security_acl *acl)
+{
+ size_t ret;
+ int i;
+ if (!acl) return 0;
+ ret = 8;
+ for (i=0;i<acl->num_aces;i++) {
+ ret += ndr_size_security_ace(&acl->aces[i]);
+ }
+ return ret;
+}
+
+/*
+ return the wire size of a security descriptor
+*/
+size_t ndr_size_security_descriptor(struct security_descriptor *sd)
+{
+ size_t ret;
+ if (!sd) return 0;
+
+ ret = 20;
+ ret += ndr_size_dom_sid(sd->owner_sid);
+ ret += ndr_size_dom_sid(sd->group_sid);
+ ret += ndr_size_security_acl(sd->dacl);
+ ret += ndr_size_security_acl(sd->sacl);
+ return ret;
+}
+
+/*
+ talloc and copy a security descriptor
+ */
+struct security_descriptor *copy_security_descriptor(TALLOC_CTX *mem_ctx,
+ const struct security_descriptor *osd)
+{
+ struct security_descriptor *nsd;
+
+ /* FIXME */
+ DEBUG(1, ("copy_security_descriptor: sorry unimplemented yet\n"));
+ nsd = NULL;
+
+ return nsd;
+}
diff --git a/source/librpc/ndr/ndr_sec.h b/source/librpc/ndr/ndr_sec.h
new file mode 100644
index 00000000000..728d46535d8
--- /dev/null
+++ b/source/librpc/ndr/ndr_sec.h
@@ -0,0 +1,56 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ definitions for marshalling/unmarshalling security descriptors
+ and related structures
+
+ 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.
+*/
+
+
+/*
+ use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really
+ just a dom sid, but with the sub_auths represented as a conformant
+ array. As with all in-structure conformant arrays, the array length
+ is placed before the start of the structure. That's what gives rise
+ to the extra num_auths elemenent. We don't want the Samba code to
+ have to bother with such esoteric NDR details, so its easier to just
+ define it as a dom_sid and use pidl magic to make it all work. It
+ just means you need to mark a sid as a "dom_sid2" in the IDL when you
+ know it is of the conformant array variety
+*/
+#define dom_sid2 dom_sid
+
+/* query security descriptor */
+struct smb_query_secdesc {
+ struct {
+ uint16 fnum;
+ uint32 secinfo_flags;
+ } in;
+ struct {
+ struct security_descriptor *sd;
+ } out;
+};
+
+/* set security descriptor */
+struct smb_set_secdesc {
+ struct {
+ uint16 fnum;
+ uint32 secinfo_flags;
+ struct security_descriptor *sd;
+ } in;
+};
diff --git a/source/librpc/ndr/ndr_spoolss_buf.c b/source/librpc/ndr/ndr_spoolss_buf.c
new file mode 100644
index 00000000000..d8a3f6a07e3
--- /dev/null
+++ b/source/librpc/ndr/ndr_spoolss_buf.c
@@ -0,0 +1,93 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling spoolss subcontext buffer structures
+
+ Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Tim Potter 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"
+
+NTSTATUS pull_spoolss_PrinterInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ uint32 level, uint32 count,
+ union spoolss_PrinterInfo **info)
+{
+ int i;
+ struct ndr_pull *ndr;
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ NDR_ALLOC_N(ndr, *info, count);
+ for (i=0;i<count;i++) {
+ NDR_CHECK(ndr_pull_spoolss_PrinterInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i]));
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS pull_spoolss_FormInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ uint32 level, uint32 count,
+ union spoolss_FormInfo **info)
+{
+ int i;
+ struct ndr_pull *ndr;
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ NDR_ALLOC_N(ndr, *info, count);
+ for (i=0;i<count;i++) {
+ NDR_CHECK(ndr_pull_spoolss_FormInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i]));
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS pull_spoolss_JobInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ uint32 level, uint32 count,
+ union spoolss_JobInfo **info)
+{
+ int i;
+ struct ndr_pull *ndr;
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ NDR_ALLOC_N(ndr, *info, count);
+ for (i=0;i<count;i++) {
+ NDR_CHECK(ndr_pull_spoolss_JobInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i]));
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS pull_spoolss_DriverInfoArray(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ uint32 level, uint32 count,
+ union spoolss_DriverInfo **info)
+{
+ int i;
+ struct ndr_pull *ndr;
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ NDR_ALLOC_N(ndr, *info, count);
+ for (i=0;i<count;i++) {
+ NDR_CHECK(ndr_pull_spoolss_DriverInfo(ndr, NDR_SCALARS|NDR_BUFFERS, level, &(*info)[i]));
+ }
+ return NT_STATUS_OK;
+}
diff --git a/source/librpc/rpc/dcerpc.c b/source/librpc/rpc/dcerpc.c
new file mode 100644
index 00000000000..8987cead92f
--- /dev/null
+++ b/source/librpc/rpc/dcerpc.c
@@ -0,0 +1,860 @@
+/*
+ Unix SMB/CIFS implementation.
+ raw dcerpc operations
+
+ Copyright (C) Tim Potter 2003
+ 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"
+
+/* initialise a dcerpc pipe. This currently assumes a SMB named pipe
+ transport */
+struct dcerpc_pipe *dcerpc_pipe_init(void)
+{
+ struct dcerpc_pipe *p;
+
+ TALLOC_CTX *mem_ctx = talloc_init("dcerpc_tree");
+ if (mem_ctx == NULL)
+ return NULL;
+
+ p = talloc(mem_ctx, sizeof(*p));
+ if (!p) {
+ talloc_destroy(mem_ctx);
+ return NULL;
+ }
+
+ p->reference_count = 0;
+ p->mem_ctx = mem_ctx;
+ p->call_id = 1;
+ p->auth_info = NULL;
+ p->security_state = NULL;
+ p->flags = 0;
+ p->srv_max_xmit_frag = 0;
+ p->srv_max_recv_frag = 0;
+
+ return p;
+}
+
+/* close down a dcerpc over SMB pipe */
+void dcerpc_pipe_close(struct dcerpc_pipe *p)
+{
+ if (!p) return;
+ p->reference_count--;
+ if (p->reference_count <= 0) {
+ if (p->security_state) {
+ p->security_state->security_end(p->security_state);
+ }
+ p->transport.shutdown_pipe(p);
+ talloc_destroy(p->mem_ctx);
+ }
+}
+
+/* we need to be able to get/set the fragment length without doing a full
+ decode */
+void dcerpc_set_frag_length(DATA_BLOB *blob, uint16 v)
+{
+ if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
+ SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
+ } else {
+ RSSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
+ }
+}
+
+uint16 dcerpc_get_frag_length(const DATA_BLOB *blob)
+{
+ if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
+ return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
+ } else {
+ return RSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
+ }
+}
+
+void dcerpc_set_auth_length(DATA_BLOB *blob, uint16 v)
+{
+ if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
+ SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
+ } else {
+ RSSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
+ }
+}
+
+
+/*
+ parse a data blob into a dcerpc_packet structure. This handles both
+ input and output packets
+*/
+static NTSTATUS dcerpc_pull(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ struct dcerpc_packet *pkt)
+{
+ struct ndr_pull *ndr;
+
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ return ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+}
+
+/*
+ parse a possibly signed blob into a dcerpc request packet structure
+*/
+static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
+ DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ struct dcerpc_packet *pkt)
+{
+ struct ndr_pull *ndr;
+ NTSTATUS status;
+ struct dcerpc_auth auth;
+ DATA_BLOB auth_blob;
+
+ /* non-signed packets are simpler */
+ if (!p->auth_info || !p->security_state) {
+ return dcerpc_pull(blob, mem_ctx, pkt);
+ }
+
+ ndr = ndr_pull_init_blob(blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ /* pull the basic packet */
+ status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (pkt->ptype != DCERPC_PKT_RESPONSE) {
+ return status;
+ }
+
+ auth_blob.length = 8 + pkt->auth_length;
+
+ /* check for a valid length */
+ if (pkt->u.response.stub_and_verifier.length < auth_blob.length) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ auth_blob.data =
+ pkt->u.response.stub_and_verifier.data +
+ pkt->u.response.stub_and_verifier.length - auth_blob.length;
+ pkt->u.response.stub_and_verifier.length -= auth_blob.length;
+
+ /* pull the auth structure */
+ ndr = ndr_pull_init_blob(&auth_blob, mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ status = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+
+ /* check signature or unseal the packet */
+ switch (p->auth_info->auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ status = p->security_state->unseal_packet(p->security_state,
+ pkt->u.response.stub_and_verifier.data,
+ pkt->u.response.stub_and_verifier.length,
+ &auth.credentials);
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ status = p->security_state->check_packet(p->security_state,
+ pkt->u.response.stub_and_verifier.data,
+ pkt->u.response.stub_and_verifier.length,
+ &auth.credentials);
+ break;
+
+ case DCERPC_AUTH_LEVEL_NONE:
+ break;
+
+ default:
+ status = NT_STATUS_INVALID_LEVEL;
+ break;
+ }
+
+ /* remove the indicated amount of paddiing */
+ if (pkt->u.response.stub_and_verifier.length < auth.auth_pad_length) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+ pkt->u.response.stub_and_verifier.length -= auth.auth_pad_length;
+
+ return status;
+}
+
+
+/*
+ push a dcerpc request packet into a blob, possibly signing it.
+*/
+static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
+ DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ struct dcerpc_packet *pkt)
+{
+ NTSTATUS status;
+ struct ndr_push *ndr;
+
+ /* non-signed packets are simpler */
+ if (!p->auth_info || !p->security_state) {
+ return dcerpc_push_auth(blob, mem_ctx, pkt, p->auth_info);
+ }
+
+ ndr = ndr_push_init_ctx(mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* pad to 8 byte multiple */
+ p->auth_info->auth_pad_length = NDR_ALIGN(ndr, 8);
+ ndr_push_zero(ndr, p->auth_info->auth_pad_length);
+
+ /* sign or seal the packet */
+ switch (p->auth_info->auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ status = p->security_state->seal_packet(p->security_state,
+ ndr->data + DCERPC_REQUEST_LENGTH,
+ ndr->offset - DCERPC_REQUEST_LENGTH,
+ &p->auth_info->credentials);
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ status = p->security_state->sign_packet(p->security_state,
+ ndr->data + DCERPC_REQUEST_LENGTH,
+ ndr->offset - DCERPC_REQUEST_LENGTH,
+ &p->auth_info->credentials);
+ break;
+
+ case DCERPC_AUTH_LEVEL_NONE:
+ p->auth_info->credentials = data_blob(NULL, 0);
+ break;
+
+ default:
+ status = NT_STATUS_INVALID_LEVEL;
+ break;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* add the auth verifier */
+ status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, p->auth_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* extract the whole packet as a blob */
+ *blob = ndr_push_blob(ndr);
+
+ /* fill in the fragment length and auth_length, we can't fill
+ in these earlier as we don't know the signature length (it
+ could be variable length) */
+ dcerpc_set_frag_length(blob, blob->length);
+ dcerpc_set_auth_length(blob, p->auth_info->credentials.length);
+
+ data_blob_free(&p->auth_info->credentials);
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ fill in the fixed values in a dcerpc header
+*/
+static void init_dcerpc_hdr(struct dcerpc_pipe *p, struct dcerpc_packet *pkt)
+{
+ pkt->rpc_vers = 5;
+ pkt->rpc_vers_minor = 0;
+ if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ pkt->drep[0] = 0;
+ } else {
+ pkt->drep[0] = DCERPC_DREP_LE;
+ }
+ pkt->drep[1] = 0;
+ pkt->drep[2] = 0;
+ pkt->drep[3] = 0;
+}
+
+
+/*
+ perform a bind using the given syntax
+
+ the auth_info structure is updated with the reply authentication info
+ on success
+*/
+NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ const struct dcerpc_syntax_id *syntax,
+ const struct dcerpc_syntax_id *transfer_syntax)
+{
+ struct dcerpc_packet pkt;
+ NTSTATUS status;
+ DATA_BLOB blob;
+ struct dcerpc_syntax_id tsyntax;
+
+ init_dcerpc_hdr(p, &pkt);
+
+ pkt.ptype = DCERPC_PKT_BIND;
+ pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
+ pkt.call_id = p->call_id;
+ pkt.auth_length = 0;
+
+ pkt.u.bind.max_xmit_frag = 0x2000;
+ pkt.u.bind.max_recv_frag = 0x2000;
+ pkt.u.bind.assoc_group_id = 0;
+ pkt.u.bind.num_contexts = 1;
+ pkt.u.bind.ctx_list = talloc(mem_ctx, sizeof(pkt.u.bind.ctx_list[0]));
+ if (!pkt.u.bind.ctx_list) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ pkt.u.bind.ctx_list[0].context_id = 0;
+ pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1;
+ pkt.u.bind.ctx_list[0].abstract_syntax = *syntax;
+ tsyntax = *transfer_syntax;
+ pkt.u.bind.ctx_list[0].transfer_syntaxes = &tsyntax;
+ pkt.u.bind.auth_info = data_blob(NULL, 0);
+
+ /* construct the NDR form of the packet */
+ status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* send it on its way */
+ status = p->transport.full_request(p, mem_ctx, &blob, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* unmarshall the NDR */
+ status = dcerpc_pull(&blob, mem_ctx, &pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if ((pkt.ptype != DCERPC_PKT_BIND_ACK && pkt.ptype != DCERPC_PKT_ALTER_ACK) ||
+ pkt.u.bind_ack.num_results == 0 ||
+ pkt.u.bind_ack.ctx_list[0].result != 0) {
+ status = NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (pkt.ptype != DCERPC_PKT_ALTER_ACK) {
+ p->srv_max_xmit_frag = pkt.u.bind_ack.max_xmit_frag;
+ p->srv_max_recv_frag = pkt.u.bind_ack.max_recv_frag;
+ }
+
+ /* the bind_ack might contain a reply set of credentials */
+ if (p->auth_info && pkt.u.bind_ack.auth_info.length) {
+ status = ndr_pull_struct_blob(&pkt.u.bind_ack.auth_info,
+ mem_ctx,
+ p->auth_info,
+ (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
+ }
+
+ return status;
+}
+
+/*
+ perform a continued bind (and auth3)
+*/
+NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx)
+{
+ struct dcerpc_packet pkt;
+ NTSTATUS status;
+ DATA_BLOB blob;
+
+ init_dcerpc_hdr(p, &pkt);
+
+ pkt.ptype = DCERPC_PKT_AUTH3;
+ pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
+ pkt.call_id = p->call_id++;
+ pkt.auth_length = 0;
+ pkt.u.auth._pad = 0;
+ pkt.u.auth.auth_info = data_blob(NULL, 0);
+
+ /* construct the NDR form of the packet */
+ status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->auth_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* send it on its way */
+ status = p->transport.initial_request(p, mem_ctx, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return status;
+}
+
+
+/* perform a dcerpc bind, using the uuid as the key */
+NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ const char *uuid, unsigned version)
+{
+ struct dcerpc_syntax_id syntax;
+ struct dcerpc_syntax_id transfer_syntax;
+ NTSTATUS status;
+
+ status = GUID_from_string(uuid, &syntax.uuid);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(2,("Invalid uuid string in dcerpc_bind_byuuid\n"));
+ return status;
+ }
+ syntax.if_version = version;
+
+ status = GUID_from_string(NDR_GUID, &transfer_syntax.uuid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ transfer_syntax.if_version = NDR_GUID_VERSION;
+
+ return dcerpc_bind(p, mem_ctx, &syntax, &transfer_syntax);
+}
+
+/*
+ perform a full request/response pair on a dcerpc pipe
+*/
+NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
+ uint16 opnum,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *stub_data_in,
+ DATA_BLOB *stub_data_out)
+{
+
+ struct dcerpc_packet pkt;
+ NTSTATUS status;
+ DATA_BLOB blob, payload;
+ uint32 remaining, chunk_size;
+
+ init_dcerpc_hdr(p, &pkt);
+
+ remaining = stub_data_in->length;
+
+ /* we can write a full max_recv_frag size, minus the dcerpc
+ request header size */
+ chunk_size = p->srv_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH);
+
+ pkt.ptype = DCERPC_PKT_REQUEST;
+ pkt.call_id = p->call_id++;
+ pkt.auth_length = 0;
+ pkt.u.request.alloc_hint = remaining;
+ pkt.u.request.context_id = 0;
+ pkt.u.request.opnum = opnum;
+
+ /* we send a series of pdus without waiting for a reply until
+ the last pdu */
+ while (remaining > chunk_size) {
+ if (remaining == stub_data_in->length) {
+ pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST;
+ } else {
+ pkt.pfc_flags = 0;
+ }
+
+ pkt.u.request.stub_and_verifier.data = stub_data_in->data +
+ (stub_data_in->length - remaining);
+ pkt.u.request.stub_and_verifier.length = chunk_size;
+
+ status = dcerpc_push_request_sign(p, &blob, mem_ctx, &pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = p->transport.initial_request(p, mem_ctx, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ remaining -= chunk_size;
+ }
+
+ /* now we send a pdu with LAST_FRAG sent and get the first
+ part of the reply */
+ if (remaining == stub_data_in->length) {
+ pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
+ } else {
+ pkt.pfc_flags = DCERPC_PFC_FLAG_LAST;
+ }
+ pkt.u.request.stub_and_verifier.data = stub_data_in->data +
+ (stub_data_in->length - remaining);
+ pkt.u.request.stub_and_verifier.length = remaining;
+
+ status = dcerpc_push_request_sign(p, &blob, mem_ctx, &pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* send the pdu and get the initial response pdu */
+ status = p->transport.full_request(p, mem_ctx, &blob, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = dcerpc_pull_request_sign(p, &blob, mem_ctx, &pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (pkt.ptype == DCERPC_PKT_FAULT) {
+ p->last_fault_code = pkt.u.fault.status;
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+
+ if (pkt.ptype != DCERPC_PKT_RESPONSE) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!(pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
+ /* something is badly wrong! */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ payload = pkt.u.response.stub_and_verifier;
+
+ /* continue receiving fragments */
+ while (!(pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
+ uint32 length;
+
+ status = p->transport.secondary_request(p, mem_ctx, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = dcerpc_pull_request_sign(p, &blob, mem_ctx, &pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
+ /* start of another packet!? */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (pkt.ptype == DCERPC_PKT_FAULT) {
+ p->last_fault_code = pkt.u.fault.status;
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+
+ if (pkt.ptype != DCERPC_PKT_RESPONSE) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ length = pkt.u.response.stub_and_verifier.length;
+
+ payload.data = talloc_realloc(mem_ctx,
+ payload.data,
+ payload.length + length);
+ if (!payload.data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ memcpy(payload.data + payload.length,
+ pkt.u.response.stub_and_verifier.data,
+ length);
+
+ payload.length += length;
+ }
+
+ if (stub_data_out) {
+ *stub_data_out = payload;
+ }
+
+ if (!(pkt.drep[0] & DCERPC_DREP_LE)) {
+ p->flags |= DCERPC_PULL_BIGENDIAN;
+ } else {
+ p->flags &= ~DCERPC_PULL_BIGENDIAN;
+ }
+
+ return status;
+}
+
+
+/*
+ this is a paranoid NDR validator. For every packet we push onto the wire
+ we pull it back again, then push it again. Then we compare the raw NDR data
+ for that to the NDR we initially generated. If they don't match then we know
+ we must have a bug in either the pull or push side of our code
+*/
+static NTSTATUS dcerpc_ndr_validate_in(TALLOC_CTX *mem_ctx,
+ DATA_BLOB blob,
+ size_t struct_size,
+ NTSTATUS (*ndr_push)(struct ndr_push *, int, void *),
+ NTSTATUS (*ndr_pull)(struct ndr_pull *, int, void *))
+{
+ void *st;
+ struct ndr_pull *pull;
+ struct ndr_push *push;
+ NTSTATUS status;
+ DATA_BLOB blob2;
+
+ st = talloc(mem_ctx, struct_size);
+ if (!st) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ pull = ndr_pull_init_blob(&blob, mem_ctx);
+ if (!pull) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = ndr_pull(pull, NDR_IN, st);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ndr_pull_error(pull, NDR_ERR_VALIDATE,
+ "failed input validation pull - %s",
+ nt_errstr(status));
+ }
+
+ push = ndr_push_init_ctx(mem_ctx);
+ if (!push) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = ndr_push(push, NDR_IN, st);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed input validation push - %s",
+ nt_errstr(status));
+ }
+
+ blob2 = ndr_push_blob(push);
+
+ if (!data_blob_equal(&blob, &blob2)) {
+ DEBUG(3,("original:\n"));
+ dump_data(3, blob.data, blob.length);
+ DEBUG(3,("secondary:\n"));
+ dump_data(3, blob2.data, blob2.length);
+ return ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed input validation data - %s",
+ nt_errstr(status));
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ this is a paranoid NDR input validator. For every packet we pull
+ from the wire we push it back again then pull and push it
+ again. Then we compare the raw NDR data for that to the NDR we
+ initially generated. If they don't match then we know we must have a
+ bug in either the pull or push side of our code
+*/
+static NTSTATUS dcerpc_ndr_validate_out(TALLOC_CTX *mem_ctx,
+ void *struct_ptr,
+ size_t struct_size,
+ NTSTATUS (*ndr_push)(struct ndr_push *, int, void *),
+ NTSTATUS (*ndr_pull)(struct ndr_pull *, int, void *))
+{
+ void *st;
+ struct ndr_pull *pull;
+ struct ndr_push *push;
+ NTSTATUS status;
+ DATA_BLOB blob, blob2;
+
+ st = talloc(mem_ctx, struct_size);
+ if (!st) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ memcpy(st, struct_ptr, struct_size);
+
+ push = ndr_push_init_ctx(mem_ctx);
+ if (!push) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = ndr_push(push, NDR_OUT, struct_ptr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed output validation push - %s",
+ nt_errstr(status));
+ }
+
+ blob = ndr_push_blob(push);
+
+ pull = ndr_pull_init_blob(&blob, mem_ctx);
+ if (!pull) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ pull->flags |= LIBNDR_FLAG_REF_ALLOC;
+ status = ndr_pull(pull, NDR_OUT, st);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ndr_pull_error(pull, NDR_ERR_VALIDATE,
+ "failed output validation pull - %s",
+ nt_errstr(status));
+ }
+
+ push = ndr_push_init_ctx(mem_ctx);
+ if (!push) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = ndr_push(push, NDR_OUT, st);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed output validation push2 - %s",
+ nt_errstr(status));
+ }
+
+ blob2 = ndr_push_blob(push);
+
+ if (!data_blob_equal(&blob, &blob2)) {
+ DEBUG(3,("original:\n"));
+ dump_data(3, blob.data, blob.length);
+ DEBUG(3,("secondary:\n"));
+ dump_data(3, blob2.data, blob2.length);
+ return ndr_push_error(push, NDR_ERR_VALIDATE,
+ "failed output validation data - %s",
+ nt_errstr(status));
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ a useful helper function for synchronous rpc requests
+
+ this can be used when you have ndr push/pull functions in the
+ standard format
+*/
+NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
+ uint32 opnum,
+ TALLOC_CTX *mem_ctx,
+ NTSTATUS (*ndr_push)(struct ndr_push *, int, void *),
+ NTSTATUS (*ndr_pull)(struct ndr_pull *, int, void *),
+ void *struct_ptr,
+ size_t struct_size)
+{
+ struct ndr_push *push;
+ struct ndr_pull *pull;
+ NTSTATUS status;
+ DATA_BLOB request, response;
+
+ /* setup for a ndr_push_* call */
+ push = ndr_push_init();
+ if (!push) {
+ talloc_destroy(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ push->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ /* push the structure into a blob */
+ status = ndr_push(push, NDR_IN, struct_ptr);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ /* retrieve the blob */
+ request = ndr_push_blob(push);
+
+ if (p->flags & DCERPC_DEBUG_VALIDATE_IN) {
+ status = dcerpc_ndr_validate_in(mem_ctx, request, struct_size,
+ ndr_push, ndr_pull);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+ }
+
+ DEBUG(10,("rpc request data:\n"));
+ dump_data(10, request.data, request.length);
+
+ /* make the actual dcerpc request */
+ status = dcerpc_request(p, opnum, mem_ctx, &request, &response);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ /* prepare for ndr_pull_* */
+ pull = ndr_pull_init_blob(&response, mem_ctx);
+ if (!pull) {
+ goto failed;
+ }
+
+ if (p->flags & DCERPC_PULL_BIGENDIAN) {
+ pull->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ DEBUG(10,("rpc reply data:\n"));
+ dump_data(10, pull->data, pull->data_size);
+
+ /* pull the structure from the blob */
+ status = ndr_pull(pull, NDR_OUT, struct_ptr);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ /* possibly check the packet signature */
+
+
+ if (p->flags & DCERPC_DEBUG_VALIDATE_OUT) {
+ status = dcerpc_ndr_validate_out(mem_ctx, struct_ptr, struct_size,
+ ndr_push, ndr_pull);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+ }
+
+ if (pull->offset != pull->data_size) {
+ DEBUG(0,("Warning! %d unread bytes\n", pull->data_size - pull->offset));
+ status = NT_STATUS_INFO_LENGTH_MISMATCH;
+ goto failed;
+ }
+
+failed:
+ ndr_push_free(push);
+ return status;
+}
+
+
+/*
+ a useful function for retrieving the server name we connected to
+*/
+const char *dcerpc_server_name(struct dcerpc_pipe *p)
+{
+ if (!p->transport.peer_name) {
+ return "";
+ }
+ return p->transport.peer_name(p);
+}
diff --git a/source/librpc/rpc/dcerpc.h b/source/librpc/rpc/dcerpc.h
new file mode 100644
index 00000000000..55c81c374e5
--- /dev/null
+++ b/source/librpc/rpc/dcerpc.h
@@ -0,0 +1,117 @@
+/*
+ Unix SMB/CIFS implementation.
+ DCERPC interface structures
+
+ Copyright (C) Tim Potter 2003
+ 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.
+*/
+
+enum dcerpc_transport_t {NCACN_NP, NCACN_IP_TCP};
+
+/*
+ this defines a generic security context for signed/sealed dcerpc pipes.
+*/
+struct dcerpc_security {
+ void *private;
+ NTSTATUS (*unseal_packet)(struct dcerpc_security *,
+ uchar *data, size_t length, DATA_BLOB *sig);
+ NTSTATUS (*check_packet)(struct dcerpc_security *,
+ const uchar *data, size_t length, const DATA_BLOB *sig);
+ NTSTATUS (*seal_packet)(struct dcerpc_security *,
+ uchar *data, size_t length, DATA_BLOB *sig);
+ NTSTATUS (*sign_packet)(struct dcerpc_security *,
+ const uchar *data, size_t length, DATA_BLOB *sig);
+ void (*security_end)(struct dcerpc_security *);
+};
+
+
+struct dcerpc_pipe {
+ TALLOC_CTX *mem_ctx;
+ int reference_count;
+ uint32 call_id;
+ uint32 srv_max_xmit_frag;
+ uint32 srv_max_recv_frag;
+ unsigned flags;
+ struct dcerpc_security *security_state;
+ struct dcerpc_auth *auth_info;
+ const char *binding_string;
+
+ struct dcerpc_transport {
+ enum dcerpc_transport_t transport;
+ void *private;
+ NTSTATUS (*full_request)(struct dcerpc_pipe *,
+ TALLOC_CTX *, DATA_BLOB *, DATA_BLOB *);
+ NTSTATUS (*secondary_request)(struct dcerpc_pipe *, TALLOC_CTX *, DATA_BLOB *);
+ NTSTATUS (*initial_request)(struct dcerpc_pipe *, TALLOC_CTX *, DATA_BLOB *);
+ NTSTATUS (*shutdown_pipe)(struct dcerpc_pipe *);
+ const char *(*peer_name)(struct dcerpc_pipe *);
+ } transport;
+
+ /* the last fault code from a DCERPC fault */
+ uint32 last_fault_code;
+};
+
+/* dcerpc pipe flags */
+#define DCERPC_DEBUG_PRINT_IN (1<<0)
+#define DCERPC_DEBUG_PRINT_OUT (1<<1)
+#define DCERPC_DEBUG_PRINT_BOTH (DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT)
+
+#define DCERPC_DEBUG_VALIDATE_IN 4
+#define DCERPC_DEBUG_VALIDATE_OUT 8
+#define DCERPC_DEBUG_VALIDATE_BOTH (DCERPC_DEBUG_VALIDATE_IN | DCERPC_DEBUG_VALIDATE_OUT)
+
+#define DCERPC_SIGN 16
+#define DCERPC_SEAL 32
+
+#define DCERPC_PUSH_BIGENDIAN 64
+#define DCERPC_PULL_BIGENDIAN 128
+
+#define DCERPC_SCHANNEL 256
+
+/*
+ this is used to find pointers to calls
+*/
+struct dcerpc_interface_call {
+ const char *name;
+ size_t struct_size;
+ NTSTATUS (*ndr_push)(struct ndr_push *, int , void *);
+ NTSTATUS (*ndr_pull)(struct ndr_pull *, int , void *);
+ void (*ndr_print)(struct ndr_print *, const char *, int, void *);
+};
+
+struct dcerpc_endpoint_list {
+ uint32 count;
+ const char * const *names;
+};
+
+struct dcerpc_interface_table {
+ const char *name;
+ const char *uuid;
+ uint32 if_version;
+ uint32 num_calls;
+ const struct dcerpc_interface_call *calls;
+ const struct dcerpc_endpoint_list *endpoints;
+};
+
+
+/* this describes a binding to a particular transport/pipe */
+struct dcerpc_binding {
+ enum dcerpc_transport_t transport;
+ const char *host;
+ const char **options;
+ uint32 flags;
+};
diff --git a/source/librpc/rpc/dcerpc_auth.c b/source/librpc/rpc/dcerpc_auth.c
new file mode 100644
index 00000000000..2b01ad2d4e9
--- /dev/null
+++ b/source/librpc/rpc/dcerpc_auth.c
@@ -0,0 +1,43 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ dcerpc authentication 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"
+
+/*
+ do a non-athenticated dcerpc bind
+*/
+NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
+ const char *uuid, unsigned version)
+{
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS status;
+
+ mem_ctx = talloc_init("dcerpc_bind_auth_ntlm");
+ if (!mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dcerpc_bind_byuuid(p, mem_ctx, uuid, version);
+ talloc_destroy(mem_ctx);
+
+ return status;
+}
diff --git a/source/librpc/rpc/dcerpc_lsa.c b/source/librpc/rpc/dcerpc_lsa.c
new file mode 100644
index 00000000000..482853c0abd
--- /dev/null
+++ b/source/librpc/rpc/dcerpc_lsa.c
@@ -0,0 +1,79 @@
+/*
+ Unix SMB/CIFS implementation.
+ raw dcerpc operations
+
+ Copyright (C) Tim Potter 2004
+
+ 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"
+
+NTSTATUS lsa_OpenPolicy(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle)
+{
+ struct lsa_ObjectAttribute attr;
+ struct lsa_QosInfo qos;
+ struct lsa_OpenPolicy r;
+ NTSTATUS status;
+ uint16 system_name = '\\';
+
+ qos.len = 0;
+ qos.impersonation_level = 2;
+ qos.context_mode = 1;
+ qos.effective_only = 0;
+
+ attr.len = 0;
+ attr.root_dir = NULL;
+ attr.object_name = NULL;
+ attr.attributes = 0;
+ attr.sec_desc = NULL;
+ attr.sec_qos = &qos;
+
+ r.in.system_name = &system_name;
+ r.in.attr = &attr;
+ r.in.desired_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ r.out.handle = handle;
+
+ return dcerpc_lsa_OpenPolicy(p, mem_ctx, &r);
+}
+
+NTSTATUS lsa_OpenPolicy2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle)
+{
+ struct lsa_ObjectAttribute attr;
+ struct lsa_QosInfo qos;
+ struct lsa_OpenPolicy2 r;
+
+ qos.len = 0;
+ qos.impersonation_level = 2;
+ qos.context_mode = 1;
+ qos.effective_only = 0;
+
+ attr.len = 0;
+ attr.root_dir = NULL;
+ attr.object_name = NULL;
+ attr.attributes = 0;
+ attr.sec_desc = NULL;
+ attr.sec_qos = &qos;
+
+ r.in.system_name = "\\";
+ r.in.attr = &attr;
+ r.in.desired_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ r.out.handle = handle;
+
+ return dcerpc_lsa_OpenPolicy2(p, mem_ctx, &r);
+}
+
diff --git a/source/librpc/rpc/dcerpc_ntlm.c b/source/librpc/rpc/dcerpc_ntlm.c
new file mode 100644
index 00000000000..81f434cccfd
--- /dev/null
+++ b/source/librpc/rpc/dcerpc_ntlm.c
@@ -0,0 +1,197 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ dcerpc authentication 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"
+
+/*
+ wrappers for the ntlmssp_*() functions
+*/
+static NTSTATUS ntlm_unseal_packet(struct dcerpc_security *dcerpc_security,
+ uchar *data, size_t length, DATA_BLOB *sig)
+{
+ struct ntlmssp_state *ntlmssp_state = dcerpc_security->private;
+ return ntlmssp_unseal_packet(ntlmssp_state, data, length, sig);
+}
+
+static NTSTATUS ntlm_check_packet(struct dcerpc_security *dcerpc_security,
+ const uchar *data, size_t length,
+ const DATA_BLOB *sig)
+{
+ struct ntlmssp_state *ntlmssp_state = dcerpc_security->private;
+ return ntlmssp_check_packet(ntlmssp_state, data, length, sig);
+}
+
+static NTSTATUS ntlm_seal_packet(struct dcerpc_security *dcerpc_security,
+ uchar *data, size_t length,
+ DATA_BLOB *sig)
+{
+ struct ntlmssp_state *ntlmssp_state = dcerpc_security->private;
+ return ntlmssp_seal_packet(ntlmssp_state, data, length, sig);
+}
+
+static NTSTATUS ntlm_sign_packet(struct dcerpc_security *dcerpc_security,
+ const uchar *data, size_t length,
+ DATA_BLOB *sig)
+{
+ struct ntlmssp_state *ntlmssp_state = dcerpc_security->private;
+ return ntlmssp_sign_packet(ntlmssp_state, data, length, sig);
+}
+
+static void ntlm_security_end(struct dcerpc_security *dcerpc_security)
+{
+ struct ntlmssp_state *ntlmssp_state = dcerpc_security->private;
+ ntlmssp_end(&ntlmssp_state);
+}
+
+
+
+/*
+ do ntlm style authentication on a dcerpc pipe
+*/
+NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p,
+ const char *uuid, unsigned version,
+ const char *domain,
+ const char *username,
+ const char *password)
+{
+ NTSTATUS status;
+ struct ntlmssp_state *state;
+ TALLOC_CTX *mem_ctx;
+ DATA_BLOB credentials;
+
+ mem_ctx = talloc_init("dcerpc_bind_auth_ntlm");
+ if (!mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = ntlmssp_client_start(&state);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = ntlmssp_set_domain(state, domain);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = ntlmssp_set_username(state, username);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = ntlmssp_set_password(state, password);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ p->auth_info = talloc(p->mem_ctx, sizeof(*p->auth_info));
+ if (!p->auth_info) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ p->auth_info->auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
+
+ if (p->flags & DCERPC_SEAL) {
+ p->auth_info->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
+ state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL;
+ } else {
+ /* ntlmssp does not work on dcerpc with
+ AUTH_LEVEL_NONE */
+ state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ p->auth_info->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
+ }
+ p->auth_info->auth_pad_length = 0;
+ p->auth_info->auth_reserved = 0;
+ p->auth_info->auth_context_id = random();
+ p->auth_info->credentials = data_blob(NULL, 0);
+ p->security_state = NULL;
+
+ status = ntlmssp_update(state,
+ p->auth_info->credentials,
+ &credentials);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ goto done;
+ }
+
+ p->auth_info->credentials = data_blob_talloc(mem_ctx,
+ credentials.data,
+ credentials.length);
+ data_blob_free(&credentials);
+
+ status = dcerpc_bind_byuuid(p, mem_ctx, uuid, version);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+
+ status = ntlmssp_update(state,
+ p->auth_info->credentials,
+ &credentials);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ goto done;
+ }
+
+ p->auth_info->credentials = data_blob_talloc(mem_ctx,
+ credentials.data,
+ credentials.length);
+ data_blob_free(&credentials);
+
+ status = dcerpc_auth3(p, mem_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ p->security_state = talloc_p(p->mem_ctx, struct dcerpc_security);
+ if (!p->security_state) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ p->security_state->private = state;
+ p->security_state->unseal_packet = ntlm_unseal_packet;
+ p->security_state->check_packet = ntlm_check_packet;
+ p->security_state->seal_packet = ntlm_seal_packet;
+ p->security_state->sign_packet = ntlm_sign_packet;
+ p->security_state->security_end = ntlm_security_end;
+
+ switch (p->auth_info->auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ /* setup for signing */
+ status = ntlmssp_sign_init(state);
+ break;
+ }
+
+done:
+ talloc_destroy(mem_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ p->security_state = NULL;
+ p->auth_info = NULL;
+ }
+
+ return status;
+}
+
+
diff --git a/source/librpc/rpc/dcerpc_schannel.c b/source/librpc/rpc/dcerpc_schannel.c
new file mode 100644
index 00000000000..2a4c0a6bb1b
--- /dev/null
+++ b/source/librpc/rpc/dcerpc_schannel.c
@@ -0,0 +1,266 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ dcerpc schannel operations
+
+ Copyright (C) Andrew Tridgell 2004
+
+ 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"
+
+/*
+ wrappers for the schannel_*() functions
+*/
+static NTSTATUS schan_unseal_packet(struct dcerpc_security *dcerpc_security,
+ uchar *data, size_t length, DATA_BLOB *sig)
+{
+ struct schannel_state *schannel_state = dcerpc_security->private;
+ return schannel_unseal_packet(schannel_state, data, length, sig);
+}
+
+static NTSTATUS schan_check_packet(struct dcerpc_security *dcerpc_security,
+ const uchar *data, size_t length,
+ const DATA_BLOB *sig)
+{
+ struct schannel_state *schannel_state = dcerpc_security->private;
+ return schannel_check_packet(schannel_state, data, length, sig);
+}
+
+static NTSTATUS schan_seal_packet(struct dcerpc_security *dcerpc_security,
+ uchar *data, size_t length,
+ DATA_BLOB *sig)
+{
+ struct schannel_state *schannel_state = dcerpc_security->private;
+ return schannel_seal_packet(schannel_state, data, length, sig);
+}
+
+static NTSTATUS schan_sign_packet(struct dcerpc_security *dcerpc_security,
+ const uchar *data, size_t length,
+ DATA_BLOB *sig)
+{
+ struct schannel_state *schannel_state = dcerpc_security->private;
+ return schannel_sign_packet(schannel_state, data, length, sig);
+}
+
+static void schan_security_end(struct dcerpc_security *dcerpc_security)
+{
+ struct schannel_state *schannel_state = dcerpc_security->private;
+ schannel_end(&schannel_state);
+}
+
+
+/*
+ get a schannel key using a netlogon challenge on a secondary pipe
+*/
+NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
+ const char *domain,
+ const char *username,
+ const char *password,
+ int chan_type,
+ uint8 new_session_key[8])
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p2;
+ struct netr_ServerReqChallenge r;
+ struct netr_ServerAuthenticate2 a;
+ uint8 mach_pwd[16];
+ struct netr_CredentialState creds;
+ const char *workgroup, *workstation;
+ uint32 negotiate_flags = 0;
+
+ workstation = username;
+ workgroup = domain;
+
+ /*
+ step 1 - establish a netlogon connection, with no authentication
+ */
+ status = dcerpc_secondary_smb(p, &p2,
+ DCERPC_NETLOGON_NAME,
+ DCERPC_NETLOGON_UUID,
+ DCERPC_NETLOGON_VERSION);
+
+
+ /*
+ step 2 - request a netlogon challenge
+ */
+ r.in.server_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.computer_name = workstation;
+ generate_random_buffer(r.in.credentials.data, sizeof(r.in.credentials.data), False);
+
+ status = dcerpc_netr_ServerReqChallenge(p2, p->mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /*
+ step 3 - authenticate on the netlogon pipe
+ */
+ E_md4hash(password, mach_pwd);
+ creds_client_init(&creds, &r.in.credentials, &r.out.credentials, mach_pwd,
+ &a.in.credentials);
+
+ a.in.server_name = r.in.server_name;
+ a.in.username = talloc_asprintf(p->mem_ctx, "%s$", workstation);
+ a.in.secure_channel_type = chan_type;
+ a.in.computer_name = workstation;
+ a.in.negotiate_flags = &negotiate_flags;
+ a.out.negotiate_flags = &negotiate_flags;
+
+ status = dcerpc_netr_ServerAuthenticate2(p2, p->mem_ctx, &a);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ if (!creds_client_check(&creds, &a.out.credentials)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ the schannel session key is now in creds.session_key
+
+ we no longer need the netlogon pipe open
+ */
+ dcerpc_pipe_close(p2);
+
+ memcpy(new_session_key, creds.session_key, 8);
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ do a schannel style bind on a dcerpc pipe with the given schannel
+ key. The username is usually of the form HOSTNAME$ and the password
+ is the domain trust password
+*/
+NTSTATUS dcerpc_bind_auth_schannel_key(struct dcerpc_pipe *p,
+ const char *uuid, unsigned version,
+ const char *domain,
+ const char *username,
+ const uint8 session_key[8])
+{
+ NTSTATUS status;
+ uint8 full_session_key[16];
+ struct schannel_state *schannel_state;
+ const char *workgroup, *workstation;
+
+ memcpy(full_session_key, session_key, 8);
+ memset(full_session_key+8, 0, 8);
+
+ workstation = username;
+ workgroup = domain;
+
+ /*
+ perform a bind with security type schannel
+ */
+ p->auth_info = talloc(p->mem_ctx, sizeof(*p->auth_info));
+ if (!p->auth_info) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ p->auth_info->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
+
+ if (p->flags & DCERPC_SEAL) {
+ p->auth_info->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
+ } else {
+ /* note that DCERPC_AUTH_LEVEL_NONE does not make any
+ sense, and would be rejected by the server */
+ p->auth_info->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
+ }
+ p->auth_info->auth_pad_length = 0;
+ p->auth_info->auth_reserved = 0;
+ p->auth_info->auth_context_id = random();
+ p->security_state = NULL;
+
+ p->auth_info->credentials = data_blob_talloc(p->mem_ctx,
+ NULL,
+ 8 +
+ strlen(workgroup)+1 +
+ strlen(workstation)+1);
+ if (!p->auth_info->credentials.data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* oh, this is ugly! */
+ SIVAL(p->auth_info->credentials.data, 0, 0);
+ SIVAL(p->auth_info->credentials.data, 4, 3);
+ memcpy(p->auth_info->credentials.data+8, workgroup, strlen(workgroup)+1);
+ memcpy(p->auth_info->credentials.data+8+strlen(workgroup)+1,
+ workstation, strlen(workstation)+1);
+
+ /* send the authenticated bind request */
+ status = dcerpc_bind_byuuid(p, p->mem_ctx, uuid, version);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ p->security_state = talloc_p(p->mem_ctx, struct dcerpc_security);
+ if (!p->security_state) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ schannel_state = talloc_p(p->mem_ctx, struct schannel_state);
+ if (!schannel_state) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ status = schannel_start(&schannel_state, full_session_key, True);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ dump_data_pw("session key:\n", schannel_state->session_key, 16);
+
+ p->security_state->private = schannel_state;
+ p->security_state->unseal_packet = schan_unseal_packet;
+ p->security_state->check_packet = schan_check_packet;
+ p->security_state->seal_packet = schan_seal_packet;
+ p->security_state->sign_packet = schan_sign_packet;
+ p->security_state->security_end = schan_security_end;
+
+done:
+ return status;
+}
+
+
+/*
+ do a schannel style bind on a dcerpc pipe. The username is usually
+ of the form HOSTNAME$ and the password is the domain trust password
+*/
+NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
+ const char *uuid, unsigned version,
+ const char *domain,
+ const char *username,
+ const char *password)
+{
+ NTSTATUS status;
+ uint8 session_key[8];
+
+ status = dcerpc_schannel_key(p, domain, username, password,
+ lp_server_role() == ROLE_DOMAIN_BDC? SEC_CHAN_BDC:SEC_CHAN_WKSTA,
+ session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = dcerpc_bind_auth_schannel_key(p, uuid, version, domain, username, session_key);
+
+ return status;
+}
+
diff --git a/source/librpc/rpc/dcerpc_smb.c b/source/librpc/rpc/dcerpc_smb.c
new file mode 100644
index 00000000000..7822231b826
--- /dev/null
+++ b/source/librpc/rpc/dcerpc_smb.c
@@ -0,0 +1,391 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ dcerpc over SMB transport
+
+ Copyright (C) Tim Potter 2003
+ 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"
+
+/* transport private information used by SMB pipe transport */
+struct smb_private {
+ uint16 fnum;
+ struct cli_tree *tree;
+};
+
+static struct cli_request *dcerpc_raw_send(struct dcerpc_pipe *p, DATA_BLOB *blob)
+{
+ struct smb_private *smb = p->transport.private;
+ struct smb_trans2 trans;
+ uint16 setup[2];
+ struct cli_request *req;
+ TALLOC_CTX *mem_ctx;
+
+ mem_ctx = talloc_init("dcerpc_raw_send");
+ if (!mem_ctx) return NULL;
+
+ trans.in.data = *blob;
+ trans.in.params = data_blob(NULL, 0);
+
+ setup[0] = TRANSACT_DCERPCCMD;
+ setup[1] = smb->fnum;
+
+ trans.in.max_param = 0;
+ trans.in.max_data = 0x8000;
+ trans.in.max_setup = 0;
+ trans.in.setup_count = 2;
+ trans.in.flags = 0;
+ trans.in.timeout = 0;
+ trans.in.setup = setup;
+ trans.in.trans_name = "\\PIPE\\";
+
+ req = smb_raw_trans_send(smb->tree, &trans);
+
+ talloc_destroy(mem_ctx);
+
+ return req;
+}
+
+
+static NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p,
+ struct cli_request *req,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob)
+{
+ struct smb_private *smb = p->transport.private;
+ struct smb_trans2 trans;
+ NTSTATUS status;
+ uint16 frag_length;
+ DATA_BLOB payload;
+
+ status = smb_raw_trans_recv(req, mem_ctx, &trans);
+ /* STATUS_BUFFER_OVERFLOW means that there is more data
+ available via SMBreadX */
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
+ return status;
+ }
+
+ payload = trans.out.data;
+
+ if (trans.out.data.length < 16 ||
+ !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
+ goto done;
+ }
+
+ /* we might have recieved a partial fragment, in which case we
+ need to pull the rest of it */
+ frag_length = dcerpc_get_frag_length(&payload);
+ if (frag_length <= payload.length) {
+ goto done;
+ }
+
+ /* make sure the payload can hold the whole fragment */
+ payload.data = talloc_realloc(mem_ctx, payload.data, frag_length);
+ if (!payload.data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* the rest of the data is available via SMBreadX */
+ while (frag_length > payload.length) {
+ uint32 n;
+ union smb_read io;
+
+ n = frag_length - payload.length;
+ if (n > 0xFF00) {
+ n = 0xFF00;
+ }
+
+ io.generic.level = RAW_READ_READX;
+ io.readx.in.fnum = smb->fnum;
+ io.readx.in.mincnt = n;
+ io.readx.in.maxcnt = n;
+ io.readx.in.offset = 0;
+ io.readx.in.remaining = 0;
+ io.readx.out.data = payload.data + payload.length;
+ status = smb_raw_read(smb->tree, &io);
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
+ break;
+ }
+
+ n = io.readx.out.nread;
+ if (n == 0) {
+ status = NT_STATUS_UNSUCCESSFUL;
+ break;
+ }
+
+ payload.length += n;
+
+ /* if the SMBreadX returns NT_STATUS_OK then there
+ isn't any more data to be read */
+ if (NT_STATUS_IS_OK(status)) {
+ break;
+ }
+ }
+
+done:
+ if (blob) {
+ *blob = payload;
+ }
+
+ return status;
+}
+
+static NTSTATUS smb_full_request(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *request_blob,
+ DATA_BLOB *reply_blob)
+{
+ struct cli_request *req;
+ req = dcerpc_raw_send(p, request_blob);
+ return dcerpc_raw_recv(p, req, mem_ctx, reply_blob);
+}
+
+
+/*
+ retrieve a secondary pdu from a pipe
+*/
+static NTSTATUS smb_secondary_request(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob)
+{
+ struct smb_private *smb = p->transport.private;
+ union smb_read io;
+ uint32 n = 0x2000;
+ uint32 frag_length;
+ NTSTATUS status;
+
+ *blob = data_blob_talloc(mem_ctx, NULL, n);
+ if (!blob->data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ io.generic.level = RAW_READ_READX;
+ io.readx.in.fnum = smb->fnum;
+ io.readx.in.mincnt = n;
+ io.readx.in.maxcnt = n;
+ io.readx.in.offset = 0;
+ io.readx.in.remaining = 0;
+ io.readx.out.data = blob->data;
+
+ status = smb_raw_read(smb->tree, &io);
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
+ return status;
+ }
+
+ blob->length = io.readx.out.nread;
+
+ if (blob->length < 16) {
+ return status;
+ }
+
+ frag_length = dcerpc_get_frag_length(blob);
+ if (frag_length <= blob->length) {
+ return status;
+ }
+
+ blob->data = talloc_realloc(mem_ctx, blob->data, frag_length);
+ if (!blob->data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ while (frag_length > blob->length &&
+ NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
+
+ n = frag_length - blob->length;
+ if (n > 0xFF00) {
+ n = 0xFF00;
+ }
+
+ io.readx.in.mincnt = n;
+ io.readx.in.maxcnt = n;
+ io.readx.out.data = blob->data + blob->length;
+ status = smb_raw_read(smb->tree, &io);
+
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
+ return status;
+ }
+
+ n = io.readx.out.nread;
+ blob->length += n;
+ }
+
+ return status;
+}
+
+
+/*
+ send an initial pdu in a multi-pdu sequence
+*/
+static NTSTATUS smb_initial_request(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob)
+{
+ struct smb_private *smb = p->transport.private;
+ union smb_write io;
+ NTSTATUS status;
+
+ io.generic.level = RAW_WRITE_WRITEX;
+ io.writex.in.fnum = smb->fnum;
+ io.writex.in.offset = 0;
+ io.writex.in.wmode = PIPE_START_MESSAGE;
+ io.writex.in.remaining = blob->length;
+ io.writex.in.count = blob->length;
+ io.writex.in.data = blob->data;
+
+ status = smb_raw_write(smb->tree, &io);
+ if (NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* make sure it accepted it all */
+ if (io.writex.out.nwritten != blob->length) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return status;
+}
+
+
+/*
+ shutdown SMB pipe connection
+*/
+static NTSTATUS smb_shutdown_pipe(struct dcerpc_pipe *p)
+{
+ struct smb_private *smb = p->transport.private;
+ union smb_close c;
+
+ /* maybe we're still starting up */
+ if (!smb) return NT_STATUS_OK;
+
+ c.close.level = RAW_CLOSE_CLOSE;
+ c.close.in.fnum = smb->fnum;
+ c.close.in.write_time = 0;
+ smb_raw_close(smb->tree, &c);
+ cli_tree_close(smb->tree);
+
+ return NT_STATUS_OK;
+}
+
+/*
+ return SMB server name
+*/
+static const char *smb_peer_name(struct dcerpc_pipe *p)
+{
+ struct smb_private *smb = p->transport.private;
+ return smb->tree->session->transport->called.name;
+}
+
+/*
+ open a rpc connection to a named pipe
+*/
+NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
+ struct cli_tree *tree,
+ const char *pipe_name)
+{
+ struct smb_private *smb;
+ NTSTATUS status;
+ char *name = NULL;
+ union smb_open io;
+ TALLOC_CTX *mem_ctx;
+
+ asprintf(&name, "\\%s", pipe_name);
+ if (!name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ io.ntcreatex.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.flags = 0;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.access_mask =
+ STD_RIGHT_READ_CONTROL_ACCESS |
+ SA_RIGHT_FILE_WRITE_ATTRIBUTES |
+ SA_RIGHT_FILE_WRITE_EA |
+ GENERIC_RIGHTS_FILE_READ |
+ GENERIC_RIGHTS_FILE_WRITE;
+ io.ntcreatex.in.file_attr = 0;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.share_access =
+ NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = name;
+
+ mem_ctx = talloc_init("torture_rpc_connection");
+ if (!mem_ctx) {
+ free(name);
+ return NT_STATUS_NO_MEMORY;
+ }
+ status = smb_raw_open(tree, mem_ctx, &io);
+ free(name);
+ talloc_destroy(mem_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (!(*p = dcerpc_pipe_init())) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /*
+ fill in the transport methods
+ */
+ (*p)->transport.transport = NCACN_NP;
+ (*p)->transport.private = NULL;
+ (*p)->transport.full_request = smb_full_request;
+ (*p)->transport.secondary_request = smb_secondary_request;
+ (*p)->transport.initial_request = smb_initial_request;
+ (*p)->transport.shutdown_pipe = smb_shutdown_pipe;
+ (*p)->transport.peer_name = smb_peer_name;
+
+ smb = talloc((*p)->mem_ctx, sizeof(*smb));
+ if (!smb) {
+ dcerpc_pipe_close(*p);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ smb->fnum = io.ntcreatex.out.fnum;
+ smb->tree = tree;
+
+ (*p)->transport.private = smb;
+ tree->reference_count++;
+
+ return NT_STATUS_OK;
+}
+
+/*
+ return the SMB tree used for a dcerpc over SMB pipe
+*/
+struct cli_tree *dcerpc_smb_tree(struct dcerpc_pipe *p)
+{
+ struct smb_private *smb = p->transport.private;
+
+ if (p->transport.transport != NCACN_NP) {
+ return NULL;
+ }
+
+ return smb->tree;
+}
diff --git a/source/librpc/rpc/dcerpc_tcp.c b/source/librpc/rpc/dcerpc_tcp.c
new file mode 100644
index 00000000000..77b536b10cb
--- /dev/null
+++ b/source/librpc/rpc/dcerpc_tcp.c
@@ -0,0 +1,206 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ dcerpc over TCP transport
+
+ 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"
+
+/* transport private information used by TCP pipe transport */
+struct tcp_private {
+ int fd;
+ char *server_name;
+ uint32 port;
+};
+
+static NTSTATUS tcp_raw_recv(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob)
+{
+ struct tcp_private *tcp = p->transport.private;
+ ssize_t ret;
+ uint32 frag_length;
+ DATA_BLOB blob1;
+
+ blob1 = data_blob_talloc(mem_ctx, NULL, 16);
+ if (!blob1.data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = read_data(tcp->fd, blob1.data, blob1.length);
+ if (ret != blob1.length) {
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+
+ /* this could be a ncacn_http endpoint - this doesn't work
+ yet, but it goes close */
+ if (strncmp(blob1.data, "ncacn_http/1.0", 14) == 0) {
+ memmove(blob1.data, blob1.data+14, 2);
+ ret = read_data(tcp->fd, blob1.data+2, 14);
+ if (ret != 14) {
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+ }
+
+ /* we might have recieved a partial fragment, in which case we
+ need to pull the rest of it */
+ frag_length = dcerpc_get_frag_length(&blob1);
+ if (frag_length == blob1.length) {
+ *blob = blob1;
+ return NT_STATUS_OK;
+ }
+
+ *blob = data_blob_talloc(mem_ctx, NULL, frag_length);
+ if (!blob->data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ memcpy(blob->data, blob1.data, blob1.length);
+
+ ret = read_data(tcp->fd, blob->data + blob1.length, frag_length - blob1.length);
+ if (ret != frag_length - blob1.length) {
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS tcp_full_request(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *request_blob,
+ DATA_BLOB *reply_blob)
+{
+ struct tcp_private *tcp = p->transport.private;
+ ssize_t ret;
+
+ ret = write_data(tcp->fd, request_blob->data, request_blob->length);
+ if (ret != request_blob->length) {
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+
+ return tcp_raw_recv(p, mem_ctx, reply_blob);
+}
+
+
+/*
+ retrieve a secondary pdu from a pipe
+*/
+static NTSTATUS tcp_secondary_request(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob)
+{
+ return tcp_raw_recv(p, mem_ctx, blob);
+}
+
+
+/*
+ send an initial pdu in a multi-pdu sequence
+*/
+static NTSTATUS tcp_initial_request(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob)
+{
+ struct tcp_private *tcp = p->transport.private;
+ ssize_t ret;
+
+ ret = write_data(tcp->fd, blob->data, blob->length);
+ if (ret != blob->length) {
+ return NT_STATUS_NET_WRITE_FAULT;
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ shutdown TCP pipe connection
+*/
+static NTSTATUS tcp_shutdown_pipe(struct dcerpc_pipe *p)
+{
+ struct tcp_private *tcp = p->transport.private;
+
+ if (tcp) {
+ close(tcp->fd);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ return TCP server name
+*/
+static const char *tcp_peer_name(struct dcerpc_pipe *p)
+{
+ struct tcp_private *tcp = p->transport.private;
+ return tcp->server_name;
+}
+
+
+/*
+ open a rpc connection to a named pipe
+*/
+NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p,
+ const char *server,
+ uint32 port)
+{
+ struct tcp_private *tcp;
+ int fd;
+ struct in_addr addr;
+
+ if (port == 0) {
+ port = EPMAPPER_PORT;
+ }
+
+ addr.s_addr = interpret_addr(server);
+ if (addr.s_addr == 0) {
+ return NT_STATUS_BAD_NETWORK_NAME;
+ }
+
+ fd = open_socket_out(SOCK_STREAM, &addr, port, 30000);
+ if (fd == -1) {
+ return NT_STATUS_PORT_CONNECTION_REFUSED;
+ }
+
+ if (!(*p = dcerpc_pipe_init())) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /*
+ fill in the transport methods
+ */
+ (*p)->transport.transport = NCACN_IP_TCP;
+ (*p)->transport.private = NULL;
+ (*p)->transport.full_request = tcp_full_request;
+ (*p)->transport.secondary_request = tcp_secondary_request;
+ (*p)->transport.initial_request = tcp_initial_request;
+ (*p)->transport.shutdown_pipe = tcp_shutdown_pipe;
+ (*p)->transport.peer_name = tcp_peer_name;
+
+ tcp = talloc((*p)->mem_ctx, sizeof(*tcp));
+ if (!tcp) {
+ dcerpc_pipe_close(*p);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ tcp->fd = fd;
+ tcp->server_name = talloc_strdup((*p)->mem_ctx, server);
+
+ (*p)->transport.private = tcp;
+
+ return NT_STATUS_OK;
+}
diff --git a/source/librpc/rpc/dcerpc_util.c b/source/librpc/rpc/dcerpc_util.c
new file mode 100644
index 00000000000..ba61f28c95d
--- /dev/null
+++ b/source/librpc/rpc/dcerpc_util.c
@@ -0,0 +1,668 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ dcerpc utility functions
+
+ 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"
+
+/*
+ this ndr_size_* stuff should really be auto-generated ....
+*/
+
+static size_t ndr_size_epm_floor(struct epm_floor *fl)
+{
+ size_t ret = 5;
+ if (fl->lhs.protocol == EPM_PROTOCOL_UUID) {
+ ret += 18;
+ } else {
+ ret += fl->lhs.info.lhs_data.length;
+ }
+ ret += fl->rhs.rhs_data.length;
+ return ret;
+}
+
+size_t ndr_size_epm_towers(struct epm_towers *towers)
+{
+ size_t ret = 2;
+ int i;
+ for (i=0;i<towers->num_floors;i++) {
+ ret += ndr_size_epm_floor(&towers->floors[i]);
+ }
+ return ret;
+}
+
+/*
+ work out what TCP port to use for a given interface on a given host
+*/
+NTSTATUS dcerpc_epm_map_tcp_port(const char *server,
+ const char *uuid, unsigned version,
+ uint32 *port)
+{
+ struct dcerpc_pipe *p;
+ NTSTATUS status;
+ struct epm_Map r;
+ struct policy_handle handle;
+ struct GUID guid;
+ struct epm_twr_t twr, *twr_r;
+
+ if (strcasecmp(uuid, DCERPC_EPMAPPER_UUID) == 0 ||
+ strcasecmp(uuid, DCERPC_MGMT_UUID) == 0) {
+ /* don't lookup epmapper via epmapper! */
+ *port = EPMAPPER_PORT;
+ return NT_STATUS_OK;
+ }
+
+ status = dcerpc_pipe_open_tcp(&p, server, EPMAPPER_PORT);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* we can use the pipes memory context here as we will have a short
+ lived connection */
+ status = dcerpc_bind_byuuid(p, p->mem_ctx,
+ DCERPC_EPMAPPER_UUID,
+ DCERPC_EPMAPPER_VERSION);
+ if (!NT_STATUS_IS_OK(status)) {
+ dcerpc_pipe_close(p);
+ return status;
+ }
+
+ ZERO_STRUCT(handle);
+ ZERO_STRUCT(guid);
+
+ twr.towers.num_floors = 5;
+ twr.towers.floors = talloc(p->mem_ctx, sizeof(twr.towers.floors[0]) * 5);
+
+ /* what I'd like for christmas ... */
+
+ /* an RPC interface ... */
+ twr.towers.floors[0].lhs.protocol = EPM_PROTOCOL_UUID;
+ GUID_from_string(uuid, &twr.towers.floors[0].lhs.info.uuid.uuid);
+ twr.towers.floors[0].lhs.info.uuid.version = version;
+ twr.towers.floors[0].rhs.rhs_data = data_blob_talloc_zero(p->mem_ctx, 2);
+
+ /* encoded with NDR ... */
+ twr.towers.floors[1].lhs.protocol = EPM_PROTOCOL_UUID;
+ GUID_from_string(NDR_GUID, &twr.towers.floors[1].lhs.info.uuid.uuid);
+ twr.towers.floors[1].lhs.info.uuid.version = NDR_GUID_VERSION;
+ twr.towers.floors[1].rhs.rhs_data = data_blob_talloc_zero(p->mem_ctx, 2);
+
+ /* on an RPC connection ... */
+ twr.towers.floors[2].lhs.protocol = EPM_PROTOCOL_RPC_C;
+ twr.towers.floors[2].lhs.info.lhs_data = data_blob(NULL, 0);
+ twr.towers.floors[2].rhs.rhs_data = data_blob_talloc_zero(p->mem_ctx, 2);
+
+ /* on a TCP port ... */
+ twr.towers.floors[3].lhs.protocol = EPM_PROTOCOL_TCP;
+ twr.towers.floors[3].lhs.info.lhs_data = data_blob(NULL, 0);
+ twr.towers.floors[3].rhs.rhs_data = data_blob_talloc_zero(p->mem_ctx, 2);
+
+ /* on an IP link ... */
+ twr.towers.floors[4].lhs.protocol = EPM_PROTOCOL_IP;
+ twr.towers.floors[4].lhs.info.lhs_data = data_blob(NULL, 0);
+ twr.towers.floors[4].rhs.rhs_data = data_blob_talloc_zero(p->mem_ctx, 4);
+
+ /* with some nice pretty paper around it of course */
+ r.in.object = &guid;
+ r.in.map_tower = &twr;
+ r.in.entry_handle = &handle;
+ r.in.max_towers = 1;
+ r.out.entry_handle = &handle;
+
+ status = dcerpc_epm_Map(p, p->mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ dcerpc_pipe_close(p);
+ return status;
+ }
+ if (r.out.status != 0 || r.out.num_towers != 1) {
+ dcerpc_pipe_close(p);
+ return NT_STATUS_PORT_UNREACHABLE;
+ }
+
+ twr_r = r.out.towers[0].twr;
+ if (!twr_r) {
+ dcerpc_pipe_close(p);
+ return NT_STATUS_PORT_UNREACHABLE;
+ }
+
+ if (twr_r->towers.num_floors != 5 ||
+ twr_r->towers.floors[3].lhs.protocol != twr.towers.floors[3].lhs.protocol ||
+ twr_r->towers.floors[3].rhs.rhs_data.length != 2) {
+ dcerpc_pipe_close(p);
+ return NT_STATUS_PORT_UNREACHABLE;
+ }
+
+ *port = RSVAL(twr_r->towers.floors[3].rhs.rhs_data.data, 0);
+
+ dcerpc_pipe_close(p);
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ find the pipe name for a local IDL interface
+*/
+const char *idl_pipe_name(const char *uuid, uint32 if_version)
+{
+ int i;
+ for (i=0;dcerpc_pipes[i];i++) {
+ if (strcasecmp(dcerpc_pipes[i]->uuid, uuid) == 0 &&
+ dcerpc_pipes[i]->if_version == if_version) {
+ return dcerpc_pipes[i]->name;
+ }
+ }
+ return "UNKNOWN";
+}
+
+/*
+ find the number of calls defined by local IDL
+*/
+int idl_num_calls(const char *uuid, uint32 if_version)
+{
+ int i;
+ for (i=0;dcerpc_pipes[i];i++) {
+ if (strcasecmp(dcerpc_pipes[i]->uuid, uuid) == 0 &&
+ dcerpc_pipes[i]->if_version == if_version) {
+ return dcerpc_pipes[i]->num_calls;
+ }
+ }
+ return -1;
+}
+
+
+/*
+ find a dcerpc interface by name
+*/
+const struct dcerpc_interface_table *idl_iface_by_name(const char *name)
+{
+ int i;
+ for (i=0;dcerpc_pipes[i];i++) {
+ if (strcasecmp(dcerpc_pipes[i]->name, name) == 0) {
+ return dcerpc_pipes[i];
+ }
+ }
+ return NULL;
+}
+
+/*
+ find a dcerpc interface by uuid
+*/
+const struct dcerpc_interface_table *idl_iface_by_uuid(const char *uuid)
+{
+ int i;
+ for (i=0;dcerpc_pipes[i];i++) {
+ if (strcasecmp(dcerpc_pipes[i]->uuid, uuid) == 0) {
+ return dcerpc_pipes[i];
+ }
+ }
+ return NULL;
+}
+
+
+
+/*
+ push a dcerpc_packet into a blob, potentially with auth info
+*/
+NTSTATUS dcerpc_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ struct dcerpc_packet *pkt,
+ struct dcerpc_auth *auth_info)
+{
+ NTSTATUS status;
+ struct ndr_push *ndr;
+
+ ndr = ndr_push_init_ctx(mem_ctx);
+ if (!ndr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
+ ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+ }
+
+ if (auth_info) {
+ pkt->auth_length = auth_info->credentials.length;
+ } else {
+ pkt->auth_length = 0;
+ }
+
+ status = ndr_push_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (auth_info) {
+ status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth_info);
+ }
+
+ *blob = ndr_push_blob(ndr);
+
+ /* fill in the frag length */
+ dcerpc_set_frag_length(blob, blob->length);
+
+ return NT_STATUS_OK;
+}
+
+
+static const struct {
+ const char *name;
+ enum dcerpc_transport_t transport;
+} ncacn_transports[] = {
+ {"ncacn_np", NCACN_NP},
+ {"ncacn_ip_tcp", NCACN_IP_TCP}
+};
+
+static const struct {
+ const char *name;
+ uint32 flag;
+} ncacn_options[] = {
+ {"sign", DCERPC_SIGN},
+ {"seal", DCERPC_SEAL},
+ {"schannel", DCERPC_SCHANNEL},
+ {"validate", DCERPC_DEBUG_VALIDATE_BOTH},
+ {"print", DCERPC_DEBUG_PRINT_BOTH},
+ {"bigendian", DCERPC_PUSH_BIGENDIAN}
+};
+
+/*
+ form a binding string from a binding structure
+*/
+const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b)
+{
+ char *s = NULL;
+ int i;
+ const char *t_name=NULL;
+
+ for (i=0;i<ARRAY_SIZE(ncacn_transports);i++) {
+ if (ncacn_transports[i].transport == b->transport) {
+ t_name = ncacn_transports[i].name;
+ }
+ }
+ if (!t_name) {
+ return NULL;
+ }
+
+ s = talloc_asprintf(mem_ctx, "%s:%s:[", t_name, b->host);
+ if (!s) return NULL;
+
+ /* this is a *really* inefficent way of dealing with strings,
+ but this is rarely called and the strings are always short,
+ so I don't care */
+ for (i=0;b->options && b->options[i];i++) {
+ s = talloc_asprintf(mem_ctx, "%s%s,", s, b->options[i]);
+ if (!s) return NULL;
+ }
+ for (i=0;i<ARRAY_SIZE(ncacn_options);i++) {
+ if (b->flags & ncacn_options[i].flag) {
+ s = talloc_asprintf(mem_ctx, "%s%s,", s, ncacn_options[i].name);
+ if (!s) return NULL;
+ }
+ }
+ if (s[strlen(s)-1] == ',') {
+ s[strlen(s)-1] = 0;
+ }
+ s = talloc_asprintf(mem_ctx, "%s]", s);
+
+ return s;
+}
+
+/*
+ parse a binding string into a dcerpc_binding structure
+*/
+NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding *b)
+{
+ char *part1, *part2, *part3;
+ char *p;
+ int i, j, comma_count;
+
+ p = strchr(s, ':');
+ if (!p) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ part1 = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s));
+ if (!part1) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ s = p+1;
+
+ p = strchr(s, ':');
+ if (!p) {
+ p = strchr(s, '[');
+ if (p) {
+ part2 = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s));
+ part3 = talloc_strdup(mem_ctx, p+1);
+ if (part3[strlen(part3)-1] != ']') {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ part3[strlen(part3)-1] = 0;
+ } else {
+ part2 = talloc_strdup(mem_ctx, s);
+ part3 = NULL;
+ }
+ } else {
+ part2 = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s));
+ part3 = talloc_strdup(mem_ctx, p+1);
+ }
+ if (!part2) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0;i<ARRAY_SIZE(ncacn_transports);i++) {
+ if (strcasecmp(part1, ncacn_transports[i].name) == 0) {
+ b->transport = ncacn_transports[i].transport;
+ break;
+ }
+ }
+ if (i==ARRAY_SIZE(ncacn_transports)) {
+ DEBUG(0,("Unknown dcerpc transport '%s'\n", part1));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ b->host = part2;
+ b->options = NULL;
+ b->flags = 0;
+
+ if (!part3) {
+ return NT_STATUS_OK;
+ }
+
+ /* the [] brackets are optional */
+ if (*part3 == '[' && part3[strlen(part3)-1] == ']') {
+ part3++;
+ part3[strlen(part3)-1] = 0;
+ }
+
+ comma_count = count_chars(part3, ',');
+ b->options = talloc_array_p(mem_ctx, const char *, comma_count+2);
+ if (!b->options) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; (p = strchr(part3, ',')); i++) {
+ b->options[i] = talloc_strndup(mem_ctx, part3, PTR_DIFF(p, part3));
+ if (!b->options[i]) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ part3 = p+1;
+ }
+ b->options[i] = part3;
+ b->options[i+1] = NULL;
+
+ /* some options are pre-parsed for convenience */
+ for (i=0;b->options[i];i++) {
+ for (j=0;j<ARRAY_SIZE(ncacn_options);j++) {
+ if (strcasecmp(ncacn_options[j].name, b->options[i]) == 0) {
+ int k;
+ b->flags |= ncacn_options[j].flag;
+ for (k=i;b->options[k];k++) {
+ b->options[k] = b->options[k+1];
+ }
+ i--;
+ break;
+ }
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/* open a rpc connection to a rpc pipe on SMB using the binding
+ structure to determine the endpoint and options */
+static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
+ struct dcerpc_binding *binding,
+ const char *pipe_uuid,
+ uint32 pipe_version,
+ const char *domain,
+ const char *username,
+ const char *password)
+{
+ NTSTATUS status;
+ BOOL retry;
+ struct cli_state *cli;
+ const char *pipe_name;
+
+ if (!binding->options || !binding->options[0]) {
+ const struct dcerpc_interface_table *table = idl_iface_by_uuid(pipe_uuid);
+ if (!table) {
+ DEBUG(0,("Unknown interface endpoint '%s'\n", pipe_uuid));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ /* only try the first endpoint for now */
+ pipe_name = table->endpoints->names[0];
+ } else {
+ pipe_name = binding->options[0];
+ }
+
+ if (strncasecmp(pipe_name, "\\pipe\\", 6) == 0) {
+ pipe_name += 6;
+ }
+ if (strncasecmp(pipe_name, "/pipe/", 6) == 0) {
+ pipe_name += 6;
+ }
+
+ status = cli_full_connection(&cli, lp_netbios_name(),
+ binding->host, NULL,
+ "ipc$", "?????",
+ username, username[0]?domain:"",
+ password, 0, &retry);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to connect to %s - %s\n", binding->host, nt_errstr(status)));
+ return status;
+ }
+
+ status = dcerpc_pipe_open_smb(p, cli->tree, pipe_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to open pipe %s - %s\n", pipe_name, nt_errstr(status)));
+ cli_tdis(cli);
+ cli_shutdown(cli);
+ return status;
+ }
+
+ /* this ensures that the reference count is decremented so
+ a pipe close will really close the link */
+ cli_tree_close(cli->tree);
+
+ (*p)->flags = binding->flags;
+
+ if (binding->flags & DCERPC_SCHANNEL) {
+ const char *trust_password = secrets_fetch_machine_password();
+ if (!trust_password) {
+ DEBUG(0,("Unable to fetch machine password\n"));
+ goto done;
+ }
+ status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
+ lp_workgroup(),
+ lp_netbios_name(),
+ trust_password);
+ } else if (binding->flags & (DCERPC_SIGN | DCERPC_SEAL)) {
+ status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+ } else {
+ status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+ }
+
+done:
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
+ dcerpc_pipe_close(*p);
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/* open a rpc connection to a rpc pipe on SMP using the binding
+ structure to determine the endpoint and options */
+static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
+ struct dcerpc_binding *binding,
+ const char *pipe_uuid,
+ uint32 pipe_version,
+ const char *domain,
+ const char *username,
+ const char *password)
+{
+ NTSTATUS status;
+ uint32 port = 0;
+
+ if (binding->options && binding->options[0]) {
+ port = atoi(binding->options[0]);
+ }
+
+ if (port == 0) {
+ status = dcerpc_epm_map_tcp_port(binding->host,
+ pipe_uuid, pipe_version,
+ &port);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to map DCERPC/TCP port for '%s' - %s\n",
+ pipe_uuid, nt_errstr(status)));
+ return status;
+ }
+ DEBUG(1,("Mapped to DCERPC/TCP port %u\n", port));
+ }
+
+ status = dcerpc_pipe_open_tcp(p, binding->host, port);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to connect to %s:%d\n", binding->host, port));
+ return status;
+ }
+
+ /* it doesn't seem to work to do a null NTLMSSP session without either sign
+ or seal, so force signing if we are doing ntlmssp */
+ if (username[0] && !(binding->flags & (DCERPC_SIGN|DCERPC_SEAL))) {
+ binding->flags |= DCERPC_SIGN;
+ }
+
+ (*p)->flags = binding->flags;
+
+ if (!(binding->flags & (DCERPC_SIGN|DCERPC_SEAL)) && !username[0]) {
+ status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+ } else {
+ status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version,
+ domain, username, password);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
+ dcerpc_pipe_close(*p);
+ return status;
+ }
+
+ return status;
+}
+
+
+/* open a rpc connection to a rpc pipe, using the specified
+ binding structure to determine the endpoint and options */
+NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p,
+ struct dcerpc_binding *binding,
+ const char *pipe_uuid,
+ uint32 pipe_version,
+ const char *domain,
+ const char *username,
+ const char *password)
+{
+ NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
+
+ switch (binding->transport) {
+ case NCACN_NP:
+ status = dcerpc_pipe_connect_ncacn_np(p, binding, pipe_uuid, pipe_version,
+ domain, username, password);
+ break;
+ case NCACN_IP_TCP:
+ status = dcerpc_pipe_connect_ncacn_ip_tcp(p, binding, pipe_uuid, pipe_version,
+ domain, username, password);
+ break;
+ }
+
+ /* remember the binding string for possible secondary connections */
+ if (NT_STATUS_IS_OK(status)) {
+ (*p)->binding_string = dcerpc_binding_string((*p)->mem_ctx, binding);
+ }
+
+ return status;
+}
+
+
+/* open a rpc connection to a rpc pipe, using the specified string
+ binding to determine the endpoint and options */
+NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p,
+ const char *binding,
+ const char *pipe_uuid,
+ uint32 pipe_version,
+ const char *domain,
+ const char *username,
+ const char *password)
+{
+ struct dcerpc_binding b;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+
+ mem_ctx = talloc_init("dcerpc_pipe_connect");
+ if (!mem_ctx) return NT_STATUS_NO_MEMORY;
+
+ status = dcerpc_parse_binding(mem_ctx, binding, &b);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
+ talloc_destroy(mem_ctx);
+ return status;
+ }
+
+ DEBUG(3,("Using binding %s\n", dcerpc_binding_string(mem_ctx, &b)));
+
+ status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version, domain, username, password);
+
+ talloc_destroy(mem_ctx);
+ return status;
+}
+
+
+/*
+ create a secondary dcerpc connection on SMB
+ the secondary connection will be on the same SMB connection, but
+ use a new fnum
+*/
+NTSTATUS dcerpc_secondary_smb(struct dcerpc_pipe *p, struct dcerpc_pipe **p2,
+ const char *pipe_name,
+ const char *pipe_uuid,
+ uint32 pipe_version)
+{
+ NTSTATUS status;
+ struct cli_tree *tree;
+
+ tree = dcerpc_smb_tree(p);
+ if (!tree) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = dcerpc_pipe_open_smb(p2, tree, pipe_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ (*p2)->flags = p->flags;
+
+ status = dcerpc_bind_auth_none(*p2, pipe_uuid, pipe_version);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}