diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-10-21 14:51:13 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-10-21 14:51:13 +0200 |
commit | 5209a846a9157e649fcdcb561f7eaf19c8c0e465 (patch) | |
tree | b0a7e52b5646c8eec182dbc391e7934b6804488c /librpc | |
parent | 625359b2e266105022309df8985720108ecd6f67 (diff) | |
parent | 2ee8d29d22bcb1c350ab59d71b0aee548489bc9c (diff) | |
download | samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.tar.gz samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.tar.bz2 samba-5209a846a9157e649fcdcb561f7eaf19c8c0e465.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba into regsrv
Conflicts:
source4/lib/registry/ldb.c
source4/rpc_server/winreg/rpc_winreg.c
Diffstat (limited to 'librpc')
66 files changed, 16664 insertions, 0 deletions
diff --git a/librpc/idl/atsvc.idl b/librpc/idl/atsvc.idl new file mode 100644 index 0000000000..75e1daa882 --- /dev/null +++ b/librpc/idl/atsvc.idl @@ -0,0 +1,119 @@ +/* + atsvc interface definition +*/ + +[ uuid("1ff70682-0a51-30e8-076d-740be8cee98b"), + version(1.0), + pointer_default(unique), + helpstring("Microsoft AT-Scheduler Service"), + endpoint("ncacn_np:[\\pipe\\atsvc]", "ncalrpc:") +] interface atsvc +{ + typedef [bitmap32bit] bitmap { + First = 0x00000001, + Second = 0x00000002, + Third = 0x00000004, + Fourth = 0x00000008, + Fifth = 0x00000010, + Sixth = 0x00000020, + Seventh = 0x00000040, + Eight = 0x00000080, + Ninth = 0x00000100, + Tenth = 0x00000200, + Eleventh = 0x00000400, + Twelfth = 0x00000800, + Thitteenth = 0x00001000, + Fourteenth = 0x00002000, + Fifteenth = 0x00004000, + Sixteenth = 0x00008000, + Seventeenth = 0x00010000, + Eighteenth = 0x00020000, + Ninteenth = 0x00040000, + Twentyth = 0x00080000, + Twentyfirst = 0x00100000, + Twentysecond = 0x00200000, + Twentythird = 0x00400000, + Twentyfourth = 0x00800000, + Twentyfifth = 0x01000000, + Twentysixth = 0x02000000, + Twentyseventh = 0x04000000, + Twentyeighth = 0x08000000, + Twentyninth = 0x10000000, + Thirtieth = 0x20000000, + Thirtyfirst = 0x40000000 + } atsvc_DaysOfMonth; + + typedef [bitmap8bit] bitmap { + JOB_RUN_PERIODICALLY = 0x01, + JOB_EXEC_ERROR = 0x02, + JOB_RUNS_TODAY = 0x04, + JOB_ADD_CURRENT_DATE = 0x08, + JOB_NONINTERACTIVE = 0x10 + } atsvc_Flags; + + typedef [bitmap8bit] bitmap { + DAYSOFWEEK_MONDAY = 0x01, + DAYSOFWEEK_TUESDAY = 0x02, + DAYSOFWEEK_WEDNESDAY = 0x04, + DAYSOFWEEK_THURSDAY = 0x08, + DAYSOFWEEK_FRIDAY = 0x10, + DAYSOFWEEK_SATURDAY = 0x20, + DAYSOFWEEK_SUNDAY = 0x40 + } atsvc_DaysOfWeek; + + typedef struct { + uint32 job_time; + atsvc_DaysOfMonth days_of_month; + atsvc_DaysOfWeek days_of_week; + atsvc_Flags flags; + [string,charset(UTF16)] uint16 *command; + } atsvc_JobInfo; + + /******************/ + /* Function: 0x00 */ + [public] NTSTATUS atsvc_JobAdd( + [in,unique,string,charset(UTF16)] uint16 *servername, + [in] atsvc_JobInfo *job_info, + [out,ref] uint32 *job_id + ); + + /******************/ + /* Function: 0x01 */ + [public] NTSTATUS atsvc_JobDel( + [in,unique,string,charset(UTF16)] uint16 *servername, + [in] uint32 min_job_id, + [in] uint32 max_job_id + ); + + typedef struct { + uint32 job_id; + uint32 job_time; + atsvc_DaysOfMonth days_of_month; + atsvc_DaysOfWeek days_of_week; + atsvc_Flags flags; + [string,charset(UTF16)] uint16 *command; + } atsvc_JobEnumInfo; + + typedef struct { + uint32 entries_read; + [size_is(entries_read)] atsvc_JobEnumInfo *first_entry; + } atsvc_enum_ctr; + + /******************/ + /* Function: 0x02 */ + [public] NTSTATUS atsvc_JobEnum( + [in,unique,string,charset(UTF16)] uint16 *servername, + [in,out] atsvc_enum_ctr *ctr, + [in] uint32 preferred_max_len, + [out,ref] uint32 *total_entries, + [in,out,unique] uint32 *resume_handle + ); + + /******************/ + /* Function: 0x03 */ + [public] NTSTATUS atsvc_JobGetInfo( + [in,unique,string,charset(UTF16)] uint16 *servername, + [in] uint32 job_id, + [out] atsvc_JobInfo **job_info + ); +} diff --git a/librpc/idl/audiosrv.idl b/librpc/idl/audiosrv.idl new file mode 100644 index 0000000000..1b059868ff --- /dev/null +++ b/librpc/idl/audiosrv.idl @@ -0,0 +1,23 @@ +[ + uuid("0a74ef1c-41a4-4e06-83ae-dc74fb1cdd53"), + version(1.0), + pointer_default(unique), + helpstring("Audio Server") +] interface audiosrv +{ + [todo] void audiosrv_CreatezoneFactoriesList(); + [todo] void audiosrv_CreateGfxFactoriesList(); + [todo] void audiosrv_CreateGfxList(); + [todo] void audiosrv_RemoveGfx(); + [todo] void audiosrv_AddGfx(); + [todo] void audiosrv_ModifyGfx(); + [todo] void audiosrv_OpenGfx(); + [todo] void audiosrv_Logon(); + [todo] void audiosrv_Logoff(); + [todo] void audiosrv_RegisterSessionNotificationEvent(); + [todo] void audiosrv_UnregisterSessionNotificationEvent(); + [todo] void audiosrv_SessionConnectState(); + [todo] void audiosrv_DriverOpenDrvRegKey(); + [todo] void audiosrv_AdvisePreferredDeviceChange(); + [todo] void audiosrv_GetPnpInfo(); +} diff --git a/librpc/idl/browser.idl b/librpc/idl/browser.idl new file mode 100644 index 0000000000..5b05be9cbb --- /dev/null +++ b/librpc/idl/browser.idl @@ -0,0 +1,58 @@ +[ + uuid("6bffd098-a112-3610-9833-012892020162"), + version(0.0), + helpstring("Browsing"), + pointer_default(unique), + endpoint("ncacn_np:[\\pipe\\browser]", "ncacn_ip_tcp:", "ncalrpc:") +] +interface browser +{ + /******************/ + /* Function 0x00 */ + [todo] NTSTATUS BrowserrServerEnum(); + + /******************/ + /* Function 0x01 */ + [todo] NTSTATUS BrowserrDebugCall(); + + /******************/ + /* Function 0x02 */ + [todo] NTSTATUS BrowserrQueryOtherDomains(); + + /******************/ + /* Function 0x03 */ + [todo] NTSTATUS BrowserrResetNetlogonState(); + + /******************/ + /* Function 0x04 */ + [todo] NTSTATUS BrowserrDebugTrace(); + + /******************/ + /* Function 0x05 */ + [todo] NTSTATUS BrowserrQueryStatistics(); + + /******************/ + /* Function 0x06 */ + [todo] NTSTATUS BrowserResetStatistics(); + + /******************/ + /* Function 0x07 */ + [todo] NTSTATUS NetrBrowserStatisticsClear(); + + /******************/ + /* Function 0x08 */ + [todo] NTSTATUS NetrBrowserStatisticsGet(); + + /******************/ + /* Function 0x09 */ + [todo] NTSTATUS BrowserrSetNetlogonState(); + + /******************/ + /* Function 0x0a */ + [todo] NTSTATUS BrowserrQueryEmulatedDomains(); + + /******************/ + /* Function 0x0b */ + [todo] NTSTATUS BrowserrServerEnumEx(); + +} diff --git a/librpc/idl/dbgidl.idl b/librpc/idl/dbgidl.idl new file mode 100644 index 0000000000..0712392f00 --- /dev/null +++ b/librpc/idl/dbgidl.idl @@ -0,0 +1,9 @@ +[ + uuid("1d55b526-c137-46c5-ab79-638f2a68e869"), + version(1.0), + pointer_default(unique), + helpstring("Remote IDL debugger") +] interface dbgidl +{ + void dummy_dbgidl(); +} diff --git a/librpc/idl/dcom.idl b/librpc/idl/dcom.idl new file mode 100644 index 0000000000..977c7ed86a --- /dev/null +++ b/librpc/idl/dcom.idl @@ -0,0 +1,302 @@ +/** + DCOM interfaces + http://www.ietf.org/internet-drafts/draft-brown-dcom-v1-spec-04.txt + */ + +import "misc.idl"; + +[ + uuid("18f70770-8e64-11cf-9af1-0020af6e72f4"), + pointer_default(unique), + version(0.0) +] interface dcom_Unknown +{ + void UseProtSeq(); + void GetCustomProtseqInfo(); + void UpdateResolverBindings(); +} + +[ + object, + uuid("00000000-0000-0000-C000-000000000046"), + pointer_default(unique), + helpstring("Base interface for all COM interfaces") +] +interface IUnknown +{ + /*****************/ + /* Function 0x00 */ + /* Returns the interface with the specified IID + if implemented by this object */ + [local] WERROR QueryInterface([in,unique] GUID *iid, + [out,iid_is(riid)] IUnknown **data); + + /*****************/ + /* Function 0x01 */ + [local] uint32 AddRef(); + + /*****************/ + /* Function 0x02 */ + [local] uint32 Release(); +} + + +[ + object, + uuid("00000001-0000-0000-C000-000000000046"), + pointer_default(unique) +] interface IClassFactory : IUnknown +{ + [local] WERROR CreateInstance([in,unique] MInterfacePointer *pUnknown, + [in,unique] GUID *iid, + [out, iid_is(riid),unique] MInterfacePointer *ppv); + + [call_as(CreateInstance)] WERROR RemoteCreateInstance(); + + /* Set lock to TRUE when you want to do a lock + and set it to FALSE when you want to unlock */ + [local] WERROR LockServer([in] uint8 lock); + + [call_as(LockServer)] WERROR RemoteLockServer(); +} + +/* The remote version of IUnknown. This interface exists on every */ +/* OXID (whether an OXID represents either a thread or a process is */ +/* implementation specific). It is used by clients to query for new */ +/* interfaces, get additional references (for marshaling), and release */ +/* outstanding references. */ +/* This interface is passed along during OXID resolution. */ +/* */ +[ + uuid("00000131-0000-0000-C000-000000000046"), + object, + pointer_default(unique), + helpstring("Remote version of IUnknown") +] +interface IRemUnknown : IUnknown +{ + typedef [public] struct + { + WERROR hResult; /* result of call */ + STDOBJREF std; /* data for returned interface */ + } + REMQIRESULT; + + [call_as(QueryInterface)] WERROR RemQueryInterface ( + [in,unique] GUID *ripid, /* interface to QI on */ + [in] uint32 cRefs, /* count of AddRefs requested */ + [in] uint16 cIids, /* count of IIDs that follow */ + [in, unique, size_is(cIids)] GUID *iids, /* IIDs to QI for */ + [out, size_is(cIids), unique] MInterfacePointer *ip + ); + + typedef struct + { + GUID ipid; /* ipid to AddRef/Release */ + uint32 cPublicRefs; + uint32 cPrivateRefs; + } REMINTERFACEREF; + + [call_as(AddRef)] WERROR RemAddRef ( + [in] uint16 cInterfaceRefs, + [in, size_is(cInterfaceRefs)] REMINTERFACEREF InterfaceRefs[], + [out, size_is(cInterfaceRefs), unique] WERROR *pResults + ); + + [call_as(Release)] WERROR RemRelease ( + [in] uint16 cInterfaceRefs, + [in, size_is(cInterfaceRefs)] REMINTERFACEREF InterfaceRefs[] + ); +} + +[ + uuid("00000140-0000-0000-c000-000000000046"), + pointer_default(unique), + object +] interface IClassActivator : IUnknown +{ + void GetClassObject([in] GUID clsid, + [in] uint32 context, + [in] uint32 locale, + [in] GUID iid, + [out, iid_is(iid)] MInterfacePointer data); +} + +[ + uuid("00000136-0000-0000-c000-000000000046"), + pointer_default(unique), + object +] interface ISCMLocalActivator : IClassActivator +{ + WERROR ISCMLocalActivator_CreateInstance( ); +} + +[ + pointer_default(unique), + uuid("c6f3ee72-ce7e-11d1-b71e-00c04fc3111a") +] interface IMachineLocalActivator +{ + WERROR IMachineLocalActivator_foo(); +} + +[ + pointer_default(unique), + uuid("e60c73e6-88f9-11cf-9af1-0020af6e72f4") +] interface ILocalObjectExporter +{ + WERROR ILocalObjectExporter_Foo(); +} + +/* Looks like this is the equivalent of .NET's + System.Activator class */ +[ + uuid("000001a0-0000-0000-c000-000000000046"), + pointer_default(unique), + object +] + interface ISystemActivator : IClassActivator +{ + WERROR ISystemActivatorRemoteCreateInstance([in] hyper unknown1, /* OXID ? */ + [in] MInterfacePointer iface1, + [in] hyper unknown2, + [out] uint32 unknown3, + [out] MInterfacePointer iface2); +} + + + +/* Derived from IRemUnknown, this interface supports Remote Query interface */ +/* for objects that supply additional data beyond the STDOBJREF in their */ +/* marshaled interface packets. */ +[ + object, + pointer_default(unique), + uuid("00000143-0000-0000-C000-000000000046") +] + +interface IRemUnknown2 : IRemUnknown +{ + [call_as(QueryInterface2)] WERROR RemQueryInterface2 ( + [in, unique] GUID *ripid, + [in] uint16 cIids, + [in, size_is(cIids), unique] GUID *iids, + [out, size_is(cIids), unique] WERROR *phr, + [out, size_is(cIids), unique] MInterfacePointer *ppMIF + ); +} + +[ + object, + pointer_default(unique), + uuid("00020400-0000-0000-C000-000000000046") +] interface IDispatch : IUnknown +{ + /*****************/ + /* Function 0x03 */ + WERROR GetTypeInfoCount( + [out, unique] uint16 *pctinfo); + + typedef struct { + } REF_ITypeInfo; + + /*****************/ + /* Function 0x04 */ + WERROR GetTypeInfo ( + [in] uint16 iTInfo, + [in] uint32 lcid, + [out, unique] REF_ITypeInfo *ppTInfo); + + /*****************/ + /* Function 0x05 */ + WERROR GetIDsOfNames( + [in, unique] GUID *riid, + /*FIXME[in,size_is(cNames)] OLESTR *rgszNames[], */ + [in] uint16 cNames, + [in] uint32 lcid, + [out,size_is(cNames), unique] uint32 *rgDispId); + + typedef struct { + uint16 vartype; + uint16 FIXME; + } VARIANT; + + typedef struct { + uint16 FIXME; + } DISPPARAMS; + + /* Exception ? */ + typedef struct { + uint16 FIXME; + } EXCEPINFO; + + /*****************/ + /* Function 0x06 */ + WERROR Invoke( + [in] uint32 dispIdMember, + [in, unique] GUID *riid, + [in] uint32 lcid, + [in] uint16 wFlags, + [out,in, unique] DISPPARAMS *pDispParams, + [out, unique] VARIANT *pVarResult, + [out, unique] EXCEPINFO *pExcepInfo, + [out, unique] uint16 *puArgErr); +} + +[ + object, + local, + uuid("00000003-0000-0000-C000-000000000046") +] interface IMarshal : IUnknown +{ + WERROR MarshalInterface(); + WERROR UnMarshalInterface(); +} + +[ + uuid(DA23F6DB-6F45-466C-9EED-0B65286F2D78), + helpstring("ICoffeeMachine Interface"), + pointer_default(unique), + object +] interface ICoffeeMachine : IUnknown +{ + WERROR MakeCoffee([in,string,charset(UTF16)] uint16 *flavor); +} + +[ + uuid("db7c21f8-fe33-4c11-aea5-ceb56f076fbb"), + helpstring("coffeemachine class") +] coclass coffeemachine +{ + interface icoffeemachine; +} + +[ + object, + pointer_default(unique), + uuid("0000000C-0000-0000-C000-000000000046"), + helpstring("Stream") +] +interface IStream : IUnknown +{ + WERROR Read( + [out, size_is(num_requested), length_is(num_read)] uint8 pv[], + [in] uint32 num_requested, + [in, unique] uint32 *num_readx, + [out] uint32 num_read + ); + + WERROR Write( + [in,size_is(num_requested),unique] uint8 *data, + [in] uint32 num_requested, + [out] uint32 num_written); +} + +[ + uuid("5e9ddec7-5767-11cf-beab-00aa006c3606"), + progid("Samba.Simple"), + helpstring("simple class"), + internal +] coclass simple +{ + interface IStream; +} diff --git a/librpc/idl/dfs.idl b/librpc/idl/dfs.idl new file mode 100644 index 0000000000..1b145f3dfa --- /dev/null +++ b/librpc/idl/dfs.idl @@ -0,0 +1,419 @@ +/* + dfs interface definition +*/ + +import "misc.idl"; + +[ uuid("4fc742e0-4a10-11cf-8273-00aa004ae673"), + version(3.0), + pointer_default(unique), + helpstring("Settings for Microsoft Distributed File System"), + endpoint("ncacn_np:[\\pipe\\netdfs]", "ncacn_ip_tcp:", "ncalrpc:") +] interface netdfs +{ + /******************/ + /* Function: 0x00 */ + typedef [v1_enum] enum { + DFS_MANAGER_VERSION_NT4 = 1, + DFS_MANAGER_VERSION_W2K = 2, + DFS_MANAGER_VERSION_W2K3 = 4, + DFS_MANAGER_VERSION_W2K8 = 6 + } dfs_ManagerVersion; + + [public] void dfs_GetManagerVersion( + [out] dfs_ManagerVersion *version + ); + + + /******************/ + /* Function: 0x01 */ + WERROR dfs_Add ( + [in] [string,charset(UTF16)] uint16 *path, + [in] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *share, + [in,unique] [string,charset(UTF16)] uint16 *comment, + [in] uint32 flags + ); + + /******************/ + /* Function: 0x02 */ + WERROR dfs_Remove ( + [in] [string,charset(UTF16)] uint16 *dfs_entry_path, + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *sharename + ); + + /******************/ + /* Function: 0x03 */ + + typedef struct { + } dfs_Info0; + + typedef struct { + [string,charset(UTF16)] uint16 *path; + } dfs_Info1; + + typedef [public,bitmap32bit] bitmap { + DFS_VOLUME_STATE_OK = 0x1, + DFS_VOLUME_STATE_INCONSISTENT = 0x2, + DFS_VOLUME_STATE_OFFLINE = 0x3, + DFS_VOLUME_STATE_ONLINE = 0x4, + DFS_VOLUME_STATE_STANDALONE = DFS_VOLUME_FLAVOR_STANDALONE, + DFS_VOLUME_STATE_AD_BLOB = DFS_VOLUME_FLAVOR_AD_BLOB + } dfs_VolumeState; + + typedef struct { + [string,charset(UTF16)] uint16 *path; + [string,charset(UTF16)] uint16 *comment; + dfs_VolumeState state; + uint32 num_stores; + } dfs_Info2; + + const int DFS_STORAGE_STATES = 0xf; + + /* yes, this is a bitmap */ + typedef [public,bitmap32bit] bitmap { + DFS_STORAGE_STATE_OFFLINE = 1, + DFS_STORAGE_STATE_ONLINE = 2, + DFS_STORAGE_STATE_ACTIVE = 4 + } dfs_StorageState; + + typedef struct { + dfs_StorageState state; + [string,charset(UTF16)] uint16 *server; + [string,charset(UTF16)] uint16 *share; + } dfs_StorageInfo; + + typedef struct { + [string,charset(UTF16)] uint16 *path; + [string,charset(UTF16)] uint16 *comment; + dfs_VolumeState state; + uint32 num_stores; + [size_is(num_stores)] dfs_StorageInfo *stores; + } dfs_Info3; + + typedef struct { + [string,charset(UTF16)] uint16 *path; + [string,charset(UTF16)] uint16 *comment; + dfs_VolumeState state; + uint32 timeout; + GUID guid; + uint32 num_stores; + [size_is(num_stores)] dfs_StorageInfo *stores; + } dfs_Info4; + + /* verified with dfsutil */ + typedef [public,bitmap32bit] bitmap { + DFS_PROPERTY_FLAG_INSITE_REFERRALS = 0x01, + DFS_PROPERTY_FLAG_ROOT_SCALABILITY = 0x02, + DFS_PROPERTY_FLAG_SITE_COSTING = 0x04, + DFS_PROPERTY_FLAG_TARGET_FAILBACK = 0x08, + DFS_PROPERTY_FLAG_CLUSTER_ENABLED = 0x10 /* untested */ + } dfs_PropertyFlags; + + typedef struct { + [string,charset(UTF16)] uint16 *path; + [string,charset(UTF16)] uint16 *comment; + dfs_VolumeState state; + uint32 timeout; + GUID guid; + dfs_PropertyFlags flags; + uint32 pktsize; + uint32 num_stores; + } dfs_Info5; + + typedef [v1_enum] enum { + DFS_INVALID_PRIORITY_CLASS = -1, + DFS_SITE_COST_NORMAL_PRIORITY_CLASS = 0, + DFS_GLOBAL_HIGH_PRIORITY_CLASS = 1, + DFS_SITE_COST_HIGH_PRIORITY_CLASS = 2, + DFS_SITE_COST_LOW_PRIORITY_CLASS = 3, + DFS_GLOBAL_LOW_PRIORITY_CLASS = 4 + } dfs_Target_PriorityClass; + + typedef struct { + dfs_Target_PriorityClass target_priority_class; + uint16 target_priority_rank; + uint16 reserved; + } dfs_Target_Priority; + + typedef struct { + dfs_StorageInfo info; + dfs_Target_Priority target_priority; + } dfs_StorageInfo2; + + typedef struct { + [string,charset(UTF16)] uint16 *entry_path; + [string,charset(UTF16)] uint16 *comment; + dfs_VolumeState state; + uint32 timeout; + GUID guid; + dfs_PropertyFlags flags; + uint32 pktsize; + uint16 num_stores; + [size_is(num_stores)] dfs_StorageInfo2 *stores; + } dfs_Info6; + + typedef struct { + GUID generation_guid; + } dfs_Info7; + + typedef struct { + [string,charset(UTF16)] uint16 *comment; + } dfs_Info100; + + typedef struct { + dfs_StorageState state; + } dfs_Info101; + + typedef struct { + uint32 timeout; + } dfs_Info102; + + typedef struct { + dfs_PropertyFlags flags; + } dfs_Info103; + + typedef struct { + dfs_Target_Priority priority; + } dfs_Info104; + + typedef struct { + [string,charset(UTF16)] uint16 *comment; + dfs_VolumeState state; + uint32 timeout; + uint32 property_flag_mask; + uint32 property_flags; + } dfs_Info105; + + typedef struct { + dfs_StorageState state; + dfs_Target_Priority priority; + } dfs_Info106; + + typedef struct { + [string,charset(UTF16)] uint16 *dom_root; + } dfs_Info200; + + typedef enum { + DFS_VOLUME_FLAVOR_STANDALONE = 0x100, + DFS_VOLUME_FLAVOR_AD_BLOB = 0x200 + } dfs_VolumeFlavor; + + typedef struct { + dfs_VolumeFlavor flavor; + [string,charset(UTF16)] uint16 *dom_root; + } dfs_Info300; + + typedef union { + [case(0)] dfs_Info0 *info0; + [case(1)] dfs_Info1 *info1; + [case(2)] dfs_Info2 *info2; + [case(3)] dfs_Info3 *info3; + [case(4)] dfs_Info4 *info4; + [case(5)] dfs_Info5 *info5; + [case(6)] dfs_Info6 *info6; + [case(7)] dfs_Info7 *info7; + [case(100)] dfs_Info100 *info100; + [case(101)] dfs_Info101 *info101; + [case(102)] dfs_Info102 *info102; + [case(103)] dfs_Info103 *info103; + [case(104)] dfs_Info104 *info104; + [case(105)] dfs_Info105 *info105; + [case(106)] dfs_Info106 *info106; + } dfs_Info; + + WERROR dfs_SetInfo ( + [in] [string,charset(UTF16)] uint16 dfs_entry_path[], + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *sharename, + [in] uint32 level, + [in,ref,switch_is(level)] dfs_Info *info + ); + + /******************/ + /* Function: 0x04 */ + WERROR dfs_GetInfo ( + [in] [string,charset(UTF16)] uint16 dfs_entry_path[], + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *sharename, + [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_Info5 *s; + } dfs_EnumArray5; + + typedef struct { + uint32 count; + [size_is(count)] dfs_Info6 *s; + } dfs_EnumArray6; + + 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(5)] dfs_EnumArray5 *info5; + [case(6)] dfs_EnumArray6 *info6; + [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,unique] dfs_EnumStruct *info, + [in,out,unique] uint32 *total + ); + + /* Function 0x06 */ + [todo] WERROR dfs_Rename(); + + /* Function 0x07 */ + [todo] WERROR dfs_Move(); + + /* Function 0x08 */ + [todo] WERROR dfs_ManagerGetConfigInfo(); + + /* Function 0x09 */ + [todo] WERROR dfs_ManagerSendSiteInfo(); + + /* Function 0x0a */ + typedef struct { + uint32 unknown1; + [string,charset(UTF16)] uint16 *unknown2; + } dfs_UnknownStruct; + + WERROR dfs_AddFtRoot( + [in] [string,charset(UTF16)] uint16 servername[], + [in] [string,charset(UTF16)] uint16 dns_servername[], + [in] [string,charset(UTF16)] uint16 dfsname[], + [in] [string,charset(UTF16)] uint16 rootshare[], + [in] [string,charset(UTF16)] uint16 comment[], + [in] [string,charset(UTF16)] uint16 dfs_config_dn[], + [in] uint8 unknown1, + [in] uint32 flags, + [in,out,unique] dfs_UnknownStruct **unknown2 + ); + + /* Function 0x0b */ + WERROR dfs_RemoveFtRoot( + [in] [string,charset(UTF16)] uint16 servername[], + [in] [string,charset(UTF16)] uint16 dns_servername[], + [in] [string,charset(UTF16)] uint16 dfsname[], + [in] [string,charset(UTF16)] uint16 rootshare[], + [in] uint32 flags, + [in,out,unique] dfs_UnknownStruct **unknown + ); + + /* Function 0x0c */ + WERROR dfs_AddStdRoot( + [in] [string,charset(UTF16)] uint16 servername[], + [in] [string,charset(UTF16)] uint16 rootshare[], + [in] [string,charset(UTF16)] uint16 comment[], + [in] uint32 flags + ); + + /* Function 0x0d */ + WERROR dfs_RemoveStdRoot( + [in] [string,charset(UTF16)] uint16 servername[], + [in] [string,charset(UTF16)] uint16 rootshare[], + [in] uint32 flags + ); + + /* Function 0x0e */ + WERROR dfs_ManagerInitialize( + [in] [string,charset(UTF16)] uint16 *servername, + [in] uint32 flags + ); + + /* Function 0x0f */ + WERROR dfs_AddStdRootForced( + [in] [string,charset(UTF16)] uint16 servername[], + [in] [string,charset(UTF16)] uint16 rootshare[], + [in] [string,charset(UTF16)] uint16 comment[], + [in] [string,charset(UTF16)] uint16 store[] /* C:\\whatever */ + ); + + /* Function 0x10 */ + WERROR dfs_GetDcAddress( + [in] [string,charset(UTF16)] uint16 servername[], + [in,out,ref] [string,charset(UTF16)] uint16 **server_fullname, + [in,out,ref] boolean8 *is_root, + [in,out,ref] uint32 *ttl + ); + + /* Function 0x11 */ + WERROR dfs_SetDcAddress( + [in] [string,charset(UTF16)] uint16 servername[], + [in] [string,charset(UTF16)] uint16 server_fullname[], + [in] uint32 flags, + [in] uint32 ttl + ); + + /* Function 0x12 */ + WERROR dfs_FlushFtTable( + [in] [string,charset(UTF16)] uint16 servername[], + [in] [string,charset(UTF16)] uint16 rootshare[] + ); + + /* Function 0x13 */ + [todo] WERROR dfs_Add2(); + + /* Function 0x14 */ + [todo] WERROR dfs_Remove2(); + + /* Function 0x15 */ + [public] WERROR dfs_EnumEx( + [in] [string,charset(UTF16)] uint16 dfs_name[], + [in] uint32 level, + [in] uint32 bufsize, + [in,out,unique] dfs_EnumStruct *info, + [in,out,unique] uint32 *total + ); + + /* Function 0x16 */ + [todo] WERROR dfs_SetInfo2(); +} diff --git a/librpc/idl/dnsserver.idl b/librpc/idl/dnsserver.idl new file mode 100644 index 0000000000..86a8a14f13 --- /dev/null +++ b/librpc/idl/dnsserver.idl @@ -0,0 +1,12 @@ +/* + dnsserver interface definition +*/ + +[ uuid("50abc2a4-574d-40b3-9d66-ee4fd5fba076"), + version(5.0), + pointer_default(unique), + helpstring("DNS Server") +] interface dnsserver +{ + void dnsserver_foo(); +} diff --git a/librpc/idl/drsblobs.idl b/librpc/idl/drsblobs.idl new file mode 100644 index 0000000000..087f0c982d --- /dev/null +++ b/librpc/idl/drsblobs.idl @@ -0,0 +1,521 @@ +#include "idl_types.h" + +import "drsuapi.idl", "misc.idl", "samr.idl", "lsa.idl"; + +[ + uuid("12345778-1234-abcd-0001-00000001"), + version(0.0), + pointer_default(unique), + helpstring("Active Directory Replication LDAP Blobs") +] +interface drsblobs { + typedef bitmap drsuapi_DsReplicaSyncOptions drsuapi_DsReplicaSyncOptions; + typedef bitmap drsuapi_DsReplicaNeighbourFlags drsuapi_DsReplicaNeighbourFlags; + typedef [v1_enum] enum drsuapi_DsAttributeId drsuapi_DsAttributeId; + typedef [v1_enum] enum lsa_TrustAuthType lsa_TrustAuthType; + /* + * replPropertyMetaData + * w2k uses version 1 + * w2k3 uses version 1 + */ + typedef struct { + drsuapi_DsAttributeId attid; + uint32 version; + NTTIME_1sec originating_change_time; + GUID originating_invocation_id; + hyper originating_usn; + hyper local_usn; + } replPropertyMetaData1; + + typedef struct { + uint32 count; + uint32 reserved; + replPropertyMetaData1 array[count]; + } replPropertyMetaDataCtr1; + + typedef [nodiscriminant] union { + [case(1)] replPropertyMetaDataCtr1 ctr1; + } replPropertyMetaDataCtr; + + typedef [public] struct { + uint32 version; + uint32 reserved; + [switch_is(version)] replPropertyMetaDataCtr ctr; + } replPropertyMetaDataBlob; + + void decode_replPropertyMetaData( + [in] replPropertyMetaDataBlob blob + ); + + /* + * replUpToDateVector + * w2k uses version 1 + * w2k3 uses version 2 + */ + typedef struct { + uint32 count; + uint32 reserved; + drsuapi_DsReplicaCursor cursors[count]; + } replUpToDateVectorCtr1; + + typedef struct { + uint32 count; + uint32 reserved; + drsuapi_DsReplicaCursor2 cursors[count]; + } replUpToDateVectorCtr2; + + typedef [nodiscriminant] union { + [case(1)] replUpToDateVectorCtr1 ctr1; + [case(2)] replUpToDateVectorCtr2 ctr2; + } replUpToDateVectorCtr; + + typedef [public] struct { + uint32 version; + uint32 reserved; + [switch_is(version)] replUpToDateVectorCtr ctr; + } replUpToDateVectorBlob; + + void decode_replUpToDateVector( + [in] replUpToDateVectorBlob blob + ); + + /* + * repsFrom/repsTo + * w2k uses version 1 + * w2k3 uses version 1 + */ + typedef [public,gensize] struct { + [value(strlen(dns_name)+1)] uint32 __dns_name_size; + [charset(DOS)] uint8 dns_name[__dns_name_size]; + } repsFromTo1OtherInfo; + + typedef [public,gensize,flag(NDR_PAHEX)] struct { + /* this includes the 8 bytes of the repsFromToBlob header */ + [value(ndr_size_repsFromTo1(this, ndr->flags)+8)] uint32 blobsize; + uint32 consecutive_sync_failures; + NTTIME_1sec last_success; + NTTIME_1sec last_attempt; + WERROR result_last_attempt; + [relative] repsFromTo1OtherInfo *other_info; + [value(ndr_size_repsFromTo1OtherInfo(other_info, ndr->flags))] uint32 other_info_length; + drsuapi_DsReplicaNeighbourFlags replica_flags; + uint8 schedule[84]; + uint32 reserved; + drsuapi_DsReplicaHighWaterMark highwatermark; + GUID source_dsa_obj_guid; /* the 'objectGuid' field of the CN=NTDS Settings object */ + GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ + GUID transport_guid; + } repsFromTo1; + + typedef [nodiscriminant] union { + [case(1)] repsFromTo1 ctr1; + } repsFromTo; + + typedef [public] struct { + uint32 version; + uint32 reserved; + [switch_is(version)] repsFromTo ctr; + } repsFromToBlob; + + void decode_repsFromTo( + [in] repsFromToBlob blob + ); + + /* + * partialAttributeSet + * w2k uses version 1 + * w2k3 uses version 1 + */ + typedef struct { + uint32 count; + drsuapi_DsAttributeId array[count]; + } partialAttributeSetCtr1; + + typedef [nodiscriminant] union { + [case(1)] partialAttributeSetCtr1 ctr1; + } partialAttributeSetCtr; + + typedef [public] struct { + uint32 version; + uint32 reserved; + [switch_is(version)] partialAttributeSetCtr ctr; + } partialAttributeSetBlob; + + void decode_partialAttributeSet( + [in] partialAttributeSetBlob blob + ); + + /* + * prefixMap + * w2k unknown + * w2k3 unknown + * samba4 uses 0x44534442 'DSDB' + * + * as we windows don't return the prefixMap attribute when you ask for + * we don't know the format, but the attribute is not replicated + * so that we can choose our own format... + */ + typedef [v1_enum] enum { + PREFIX_MAP_VERSION_DSDB = 0x44534442 + } prefixMapVersion; + + typedef [nodiscriminant] union { + [case(PREFIX_MAP_VERSION_DSDB)] drsuapi_DsReplicaOIDMapping_Ctr dsdb; + } prefixMapCtr; + + typedef [public] struct { + prefixMapVersion version; + uint32 reserved; + [switch_is(version)] prefixMapCtr ctr; + } prefixMapBlob; + + void decode_prefixMap( + [in] prefixMapBlob blob + ); + + /* + * the cookie for the LDAP dirsync control + */ + typedef [nodiscriminant,gensize] union { + [case(0)]; + [default] replUpToDateVectorBlob uptodateness_vector; + } ldapControlDirSyncExtra; + + typedef struct { + [value(3)] uint32 u1; + NTTIME time; + uint32 u2; + uint32 u3; + [value(ndr_size_ldapControlDirSyncExtra(&extra, extra.uptodateness_vector.version, 0))] + uint32 extra_length; + drsuapi_DsReplicaHighWaterMark highwatermark; + GUID guid1; + [switch_is(extra_length)] ldapControlDirSyncExtra extra; + } ldapControlDirSyncBlob; + + typedef [public,relative_base] struct { + [charset(DOS),value("MSDS")] uint8 msds[4]; + [subcontext(0)] ldapControlDirSyncBlob blob; + } ldapControlDirSyncCookie; + + void decode_ldapControlDirSync( + [in] ldapControlDirSyncCookie cookie + ); + + typedef struct { + [value(2*strlen_m(name))] uint16 name_len; + [value(strlen(data))] uint16 data_len; + uint16 reserved; /* 2 for 'Packages', 1 for 'Primary:*', but should be ignored */ + [charset(UTF16)] uint8 name[name_len]; + /* + * the data field contains data as HEX strings + * + * 'Packages': + * data contains the list of packages + * as non termiated UTF16 strings with + * a UTF16 NULL byte as separator + * + * 'Primary:Kerberos-Newer-Keys': + * ... + * + * 'Primary:Kerberos': + * ... + * + * 'Primary:WDigest': + * ... + * + * 'Primary:CLEARTEXT': + * data contains the cleartext password + * as UTF16 string encoded as HEX string + */ + [charset(DOS)] uint8 data[data_len]; + } supplementalCredentialsPackage; + + /* this are 0x30 (48) whitespaces (0x20) */ + const string SUPPLEMENTAL_CREDENTIALS_PREFIX = " "; + + typedef [flag(NDR_PAHEX)] enum { + SUPPLEMENTAL_CREDENTIALS_SIGNATURE = 0x0050 + } supplementalCredentialsSignature; + + typedef [gensize] struct { + [value(SUPPLEMENTAL_CREDENTIALS_PREFIX),charset(UTF16)] uint16 prefix[0x30]; + [value(SUPPLEMENTAL_CREDENTIALS_SIGNATURE)] supplementalCredentialsSignature signature; + uint16 num_packages; + supplementalCredentialsPackage packages[num_packages]; + } supplementalCredentialsSubBlob; + + typedef [public] struct { + [value(0)] uint32 unknown1; + [value(ndr_size_supplementalCredentialsSubBlob(&sub, ndr->flags))] uint32 __ndr_size; + [value(0)] uint32 unknown2; + [subcontext(0),subcontext_size(__ndr_size)] supplementalCredentialsSubBlob sub; + [value(0)] uint8 unknown3; + } supplementalCredentialsBlob; + + void decode_supplementalCredentials( + [in] supplementalCredentialsBlob blob + ); + + typedef [public] struct { + [flag(STR_NOTERM|NDR_REMAINING)] string_array names; + } package_PackagesBlob; + + void decode_Packages( + [in] package_PackagesBlob blob + ); + + typedef struct { + [value(2*strlen_m(string))] uint16 length; + [value(2*strlen_m(string))] uint16 size; + [relative,subcontext(0),subcontext_size(size),flag(STR_NOTERM|NDR_REMAINING)] string *string; + } package_PrimaryKerberosString; + + typedef struct { + [value(0)] uint16 reserved1; + [value(0)] uint16 reserved2; + [value(0)] uint32 reserved3; + uint32 keytype; + [value((value?value->length:0))] uint32 value_len; + [relative,subcontext(0),subcontext_size(value_len),flag(NDR_REMAINING)] DATA_BLOB *value; + } package_PrimaryKerberosKey3; + + typedef struct { + uint16 num_keys; + uint16 num_old_keys; + package_PrimaryKerberosString salt; + package_PrimaryKerberosKey3 keys[num_keys]; + package_PrimaryKerberosKey3 old_keys[num_old_keys]; + [value(0)] uint32 padding1; + [value(0)] uint32 padding2; + [value(0)] uint32 padding3; + [value(0)] uint32 padding4; + [value(0)] uint32 padding5; + } package_PrimaryKerberosCtr3; + + typedef struct { + [value(0)] uint16 reserved1; + [value(0)] uint16 reserved2; + [value(0)] uint32 reserved3; + uint32 iteration_count; + uint32 keytype; + [value((value?value->length:0))] uint32 value_len; + [relative,subcontext(0),subcontext_size(value_len),flag(NDR_REMAINING)] DATA_BLOB *value; + } package_PrimaryKerberosKey4; + + typedef struct { + uint16 num_keys; + [value(0)] uint16 num_service_keys; + uint16 num_old_keys; + uint16 num_older_keys; + package_PrimaryKerberosString salt; + uint32 default_iteration_count; + package_PrimaryKerberosKey4 keys[num_keys]; + package_PrimaryKerberosKey4 service_keys[num_service_keys]; + package_PrimaryKerberosKey4 old_keys[num_old_keys]; + package_PrimaryKerberosKey4 older_keys[num_older_keys]; + } package_PrimaryKerberosCtr4; + + typedef [nodiscriminant] union { + [case(3)] package_PrimaryKerberosCtr3 ctr3; + [case(4)] package_PrimaryKerberosCtr4 ctr4; + } package_PrimaryKerberosCtr; + + typedef [public] struct { + uint16 version; + [value(0)] uint16 flags; + [switch_is(version)] package_PrimaryKerberosCtr ctr; + } package_PrimaryKerberosBlob; + + void decode_PrimaryKerberos( + [in] package_PrimaryKerberosBlob blob + ); + + typedef [public] struct { + [flag(NDR_REMAINING)] DATA_BLOB cleartext; + } package_PrimaryCLEARTEXTBlob; + + void decode_PrimaryCLEARTEXT( + [in] package_PrimaryCLEARTEXTBlob blob + ); + + typedef [flag(NDR_PAHEX)] struct { + uint8 hash[16]; + } package_PrimaryWDigestHash; + + typedef [public] struct { + [value(0x31)] uint16 unknown1; + [value(0x01)] uint8 unknown2; + uint8 num_hashes; + [value(0)] uint32 unknown3; + [value(0)] udlong uuknown4; + package_PrimaryWDigestHash hashes[num_hashes]; + } package_PrimaryWDigestBlob; + + void decode_PrimaryWDigest( + [in] package_PrimaryWDigestBlob blob + ); + + typedef struct { + [value(0)] uint32 size; + } AuthInfoNone; + + typedef struct { + [value(16)] uint32 size; + samr_Password password; + } AuthInfoNT4Owf; + + /* + * the secret value is encoded as UTF16 if it's a string + * but depending the AuthType, it might also be krb5 trusts have random bytes here, so converting to UTF16 + * mayfail... + * + * TODO: We should try handle the case of a random buffer in all places + * we deal with cleartext passwords from windows + * + * so we don't use this: + * + * uint32 value_len; + * [charset(UTF16)] uint8 value[value_len]; + */ + + typedef struct { + uint32 size; + uint8 password[size]; + } AuthInfoClear; + + typedef struct { + [value(4)] uint32 size; + uint32 version; + } AuthInfoVersion; + + typedef [nodiscriminant] union { + [case(TRUST_AUTH_TYPE_NONE)] AuthInfoNone none; + [case(TRUST_AUTH_TYPE_NT4OWF)] AuthInfoNT4Owf nt4owf; + [case(TRUST_AUTH_TYPE_CLEAR)] AuthInfoClear clear; + [case(TRUST_AUTH_TYPE_VERSION)] AuthInfoVersion version; + } AuthInfo; + + typedef [public] struct { + NTTIME LastUpdateTime; + lsa_TrustAuthType AuthType; + + [switch_is(AuthType)] AuthInfo AuthInfo; + [flag(NDR_ALIGN4)] DATA_BLOB _pad; + } AuthenticationInformation; + + typedef [nopull,nopush,noprint] struct { + /* sizeis here is bogus, but this is here just for the structure */ + [size_is(1)] AuthenticationInformation array[]; + } AuthenticationInformationArray; + + /* This is nopull,nopush because we pass count down to the + * manual parser of AuthenticationInformationArray */ + typedef [public,nopull,nopush,noprint,gensize] struct { + uint32 count; + [relative] AuthenticationInformationArray *current; + [relative] AuthenticationInformationArray *previous; + } trustAuthInOutBlob; + + void decode_trustAuthInOut( + [in] trustAuthInOutBlob blob + ); + + typedef [public,gensize] struct { + uint32 count; + [relative] AuthenticationInformation *current[count]; + } trustCurrentPasswords; + + typedef [public,nopull] struct { + uint8 confounder[512]; + [subcontext(0),subcontext_size(outgoing_size)] trustCurrentPasswords outgoing; + [subcontext(0),subcontext_size(incoming_size)] trustCurrentPasswords incoming; + [value(ndr_size_trustCurrentPasswords(&outgoing, ndr->flags))] uint32 outgoing_size; + [value(ndr_size_trustCurrentPasswords(&incoming, ndr->flags))] uint32 incoming_size; + } trustDomainPasswords; + + void decode_trustDomainPasswords( + [in] trustDomainPasswords blob + ); + + typedef [public] struct { + uint32 marker; + DATA_BLOB data; + } DsCompressedChunk; + + typedef struct { + uint16 __size; + [size_is(__size),charset(DOS)] uint8 *string; + } ExtendedErrorAString; + + typedef struct { + uint16 __size; + [size_is(__size),charset(UTF16)] uint16 *string; + } ExtendedErrorUString; + + typedef struct { + uint16 length; + [size_is(length)] uint8 *data; + } ExtendedErrorBlob; + + typedef enum { + EXTENDED_ERROR_COMPUTER_NAME_PRESENT = 1, + EXTENDED_ERROR_COMPUTER_NAME_NOT_PRESENT= 2 + } ExtendedErrorComputerNamePresent; + + typedef [switch_type(ExtendedErrorComputerNamePresent)] union { + [case(EXTENDED_ERROR_COMPUTER_NAME_PRESENT)] ExtendedErrorUString name; + [case(EXTENDED_ERROR_COMPUTER_NAME_NOT_PRESENT)]; + } ExtendedErrorComputerNameU; + + typedef struct { + ExtendedErrorComputerNamePresent present; + [switch_is(present)] ExtendedErrorComputerNameU n; + } ExtendedErrorComputerName; + + typedef enum { + EXTENDED_ERROR_PARAM_TYPE_ASCII_STRING = 1, + EXTENDED_ERROR_PARAM_TYPE_UNICODE_STRING = 2, + EXTENDED_ERROR_PARAM_TYPE_UINT32 = 3, + EXTENDED_ERROR_PARAM_TYPE_UINT16 = 4, + EXTENDED_ERROR_PARAM_TYPE_UINT64 = 5, + EXTENDED_ERROR_PARAM_TYPE_NONE = 6, + EXTENDED_ERROR_PARAM_TYPE_BLOB = 7 + } ExtendedErrorParamType; + + typedef [switch_type(ExtendedErrorParamType)] union { + [case(EXTENDED_ERROR_PARAM_TYPE_ASCII_STRING)] ExtendedErrorAString a_string; + [case(EXTENDED_ERROR_PARAM_TYPE_UNICODE_STRING)] ExtendedErrorUString u_string; + [case(EXTENDED_ERROR_PARAM_TYPE_UINT32)] uint32 uint32; + [case(EXTENDED_ERROR_PARAM_TYPE_UINT16)] uint16 uint16; + [case(EXTENDED_ERROR_PARAM_TYPE_UINT64)] hyper uint64; + [case(EXTENDED_ERROR_PARAM_TYPE_NONE)]; + [case(EXTENDED_ERROR_PARAM_TYPE_BLOB)] ExtendedErrorBlob blob; + } ExtendedErrorParamU; + + typedef struct { + ExtendedErrorParamType type; + [switch_is(type)] ExtendedErrorParamU p; + } ExtendedErrorParam; + + typedef [public] struct { + ExtendedErrorInfo *next; + ExtendedErrorComputerName computer_name; + hyper pid; + NTTIME time; + uint32 generating_component; + WERROR status; + uint16 detection_location; + uint16 flags; + uint16 num_params; + [size_is(num_params)] ExtendedErrorParam params[]; + } ExtendedErrorInfo; + + typedef struct { + [unique] ExtendedErrorInfo *info; + } ExtendedErrorInfoPtr; + + void decode_ExtendedErrorInfo ( + [in,subcontext(0xFFFFFC01)] ExtendedErrorInfoPtr ptr + ); +} diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl new file mode 100644 index 0000000000..e4b5dc1fd9 --- /dev/null +++ b/librpc/idl/drsuapi.idl @@ -0,0 +1,1602 @@ +#include "idl_types.h" + +import "security.idl", "misc.idl", "samr.idl"; + +[ + uuid("e3514235-4b06-11d1-ab04-00c04fc2dcd2"), + version(4.0), + endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]", "ncacn_ip_tcp:", "ncalrpc:"), + authservice("ldap"), + helpstring("Active Directory Replication"), + helper("../librpc/ndr/ndr_drsuapi.h"), + pointer_default(unique) +] +interface drsuapi +{ + typedef bitmap samr_GroupAttrs samr_GroupAttrs; + + /*****************/ + /* Function 0x00 */ + typedef [bitmap32bit] bitmap { + DRSUAPI_SUPPORTED_EXTENSION_BASE = 0x00000001, + DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION = 0x00000002, + DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI = 0x00000004, + DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2 = 0x00000008, + DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS = 0x00000010, + DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1 = 0x00000020, + DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION = 0x00000040, + DRSUAPI_SUPPORTED_EXTENSION_00000080 = 0x00000080, + DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE = 0x00000100, + DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2 = 0x00000200, + DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION = 0x00000400, + DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2 = 0x00000800, + DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD= 0x00001000, + DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND = 0x00002000, + DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO = 0x00004000, + DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION = 0x00008000, + DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01 = 0x00010000, + DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP = 0x00020000, + DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY = 0x00040000, + DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3 = 0x00080000, + DRSUAPI_SUPPORTED_EXTENSION_00100000 = 0x00100000, + DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2 = 0x00200000, + DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6 = 0x00400000, + DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS = 0x00800000, + DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8 = 0x01000000, + DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5 = 0x02000000, + DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6 = 0x04000000, + /* + * the following 3 have the same value + * repadmin.exe /bind says that + */ + DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3 = 0x08000000, + DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7 = 0x08000000, + DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT = 0x08000000, + DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS = 0x10000000, + DRSUAPI_SUPPORTED_EXTENSION_20000000 = 0x20000000, + DRSUAPI_SUPPORTED_EXTENSION_40000000 = 0x40000000, + DRSUAPI_SUPPORTED_EXTENSION_80000000 = 0x80000000 + } drsuapi_SupportedExtensions; + + typedef [bitmap32bit] bitmap { + DRSUAPI_SUPPORTED_EXTENSION_ADAM = 0x00000001, + DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2 = 0x00000002 + } drsuapi_SupportedExtensionsExt; + + /* this is used by w2k */ + typedef struct { + drsuapi_SupportedExtensions supported_extensions; + GUID site_guid; + uint32 pid; + } drsuapi_DsBindInfo24; + + /* this is used by w2k3 */ + typedef struct { + drsuapi_SupportedExtensions supported_extensions; + GUID site_guid; + uint32 pid; + uint32 repl_epoch; + } drsuapi_DsBindInfo28; + + /* this is used by w2k8 */ + typedef struct { + drsuapi_SupportedExtensions supported_extensions; + GUID site_guid; + uint32 pid; + uint32 repl_epoch; + drsuapi_SupportedExtensionsExt supported_extensions_ext; + GUID config_dn_guid; + } drsuapi_DsBindInfo48; + + typedef struct { + [flag(NDR_REMAINING)] DATA_BLOB info; + } drsuapi_DsBindInfoFallBack; + + typedef [nodiscriminant] union { + [case(24)][subcontext(4)] drsuapi_DsBindInfo24 info24; + [case(28)][subcontext(4)] drsuapi_DsBindInfo28 info28; + [case(48)][subcontext(4)] drsuapi_DsBindInfo48 info48; + [default][subcontext(4)] drsuapi_DsBindInfoFallBack FallBack; + } drsuapi_DsBindInfo; + + /* the drsuapi_DsBindInfoCtr was this before + * typedef [flag(NDR_PAHEX)] struct { + * [range(1,10000)] uint32 length; + * [size_is(length)] uint8 data[]; + * } drsuapi_DsBindInfo; + * + * but we don't want the caller to manually decode this blob, + * so we're doing it here + */ + + typedef struct { + [range(1,10000)] uint32 length; + [switch_is(length)] drsuapi_DsBindInfo info; + } drsuapi_DsBindInfoCtr; + + /* this is a magic guid you need to pass to DsBind to make drsuapi_DsWriteAccountSpn() work + * + * maybe the bind_guid could also be the invocation_id see drsuapi_DsReplicaConnection04 + */ + const char *DRSUAPI_DS_BIND_GUID = "e24d201a-4fd6-11d1-a3da-0000f875ae0d"; + /* + * this magic guid are needed to fetch the whole tree with drsuapi_DsGetNCChanges() + * as administrator and this values are also used in the destination_dsa_guid field + * of drsuapi_DsGetNCChangesReq5/8 and the source_dsa_guid is zero. + */ + const char *DRSUAPI_DS_BIND_GUID_W2K = "6abec3d1-3054-41c8-a362-5a0c5b7d5d71"; + const char *DRSUAPI_DS_BIND_GUID_W2K3 = "6afab99c-6e26-464a-975f-f58f105218bc"; + + [public] WERROR drsuapi_DsBind( + [in,unique] GUID *bind_guid, + [in,out,unique] drsuapi_DsBindInfoCtr *bind_info, + [out] policy_handle *bind_handle + ); + + /*****************/ + /* Function 0x01 */ + WERROR drsuapi_DsUnbind( + [in,out] policy_handle *bind_handle + ); + + /*****************/ + /* Function 0x02 */ + typedef [public,gensize] struct { + [value(ndr_size_drsuapi_DsReplicaObjectIdentifier(r, ndr->flags)-4)] uint32 __ndr_size; + [value(ndr_size_dom_sid28(&sid, ndr->flags))] uint32 __ndr_size_sid; + GUID guid; + dom_sid28 sid; + [value(strlen_m(dn))] uint32 __ndr_size_dn; + [charset(UTF16),size_is(__ndr_size_dn+1)] uint16 dn[]; + } drsuapi_DsReplicaObjectIdentifier; + + typedef [public] bitmap { + DRSUAPI_DS_REPLICA_SYNC_ASYNCHRONOUS_OPERATION = 0x00000001, + DRSUAPI_DS_REPLICA_SYNC_WRITEABLE = 0x00000002, + DRSUAPI_DS_REPLICA_SYNC_PERIODIC = 0x00000004, + DRSUAPI_DS_REPLICA_SYNC_INTERSITE_MESSAGING = 0x00000008, + DRSUAPI_DS_REPLICA_SYNC_ALL_SOURCES = 0x00000010, + DRSUAPI_DS_REPLICA_SYNC_FULL = 0x00000020, + DRSUAPI_DS_REPLICA_SYNC_URGENT = 0x00000040, + DRSUAPI_DS_REPLICA_SYNC_NO_DISCARD = 0x00000080, + DRSUAPI_DS_REPLICA_SYNC_FORCE = 0x00000100, + DRSUAPI_DS_REPLICA_SYNC_ADD_REFERENCE = 0x00000200, + DRSUAPI_DS_REPLICA_SYNC_NEVER_COMPLETED = 0x00000400, + DRSUAPI_DS_REPLICA_SYNC_TWO_WAY = 0x00000800, + DRSUAPI_DS_REPLICA_SYNC_NEVER_NOTIFY = 0x00001000, + DRSUAPI_DS_REPLICA_SYNC_INITIAL = 0x00002000, + DRSUAPI_DS_REPLICA_SYNC_USE_COMPRESSION = 0x00004000, + DRSUAPI_DS_REPLICA_SYNC_ABANDONED = 0x00008000, + DRSUAPI_DS_REPLICA_SYNC_INITIAL_IN_PROGRESS = 0x00010000, + DRSUAPI_DS_REPLICA_SYNC_PARTIAL_ATTRIBUTE_SET = 0x00020000, + DRSUAPI_DS_REPLICA_SYNC_REQUEUE = 0x00040000, + DRSUAPI_DS_REPLICA_SYNC_NOTIFICATION = 0x00080000, + DRSUAPI_DS_REPLICA_SYNC_ASYNCHRONOUS_REPLICA = 0x00100000, + DRSUAPI_DS_REPLICA_SYNC_CRITICAL = 0x00200000, + DRSUAPI_DS_REPLICA_SYNC_FULL_IN_PROGRESS = 0x00400000, + DRSUAPI_DS_REPLICA_SYNC_PREEMPTED = 0x00800000 + } drsuapi_DsReplicaSyncOptions; + + typedef struct { + drsuapi_DsReplicaObjectIdentifier *naming_context; + GUID source_dsa_guid; + astring *other_info; /* I assume this is related to the repsFromTo1OtherInfo dns_name */ + drsuapi_DsReplicaSyncOptions options; + } drsuapi_DsReplicaSyncRequest1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsReplicaSyncRequest1 req1; + } drsuapi_DsReplicaSyncRequest; + + WERROR drsuapi_DsReplicaSync( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,switch_is(level)] drsuapi_DsReplicaSyncRequest req + ); + + /*****************/ + /* Function 0x03 */ + typedef [public] struct { + hyper tmp_highest_usn; /* updated after each object update */ + hyper reserved_usn; + hyper highest_usn; /* updated after a full replication cycle */ + } drsuapi_DsReplicaHighWaterMark; + + typedef [public] struct { + GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ + hyper highest_usn; /* updated after a full replication cycle */ + } drsuapi_DsReplicaCursor; + + typedef struct { + [value(1)] uint32 version; + [value(0)] uint32 reserved1; + [range(0,0x100000)] uint32 count; + [value(0)] uint32 reserved2; + [size_is(count)] drsuapi_DsReplicaCursor cursors[]; + } drsuapi_DsReplicaCursorCtrEx; + + typedef [public] bitmap { + /* the _WRITEABLE flag indicates a replication with all attributes + * + * --metze + */ + DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE = 0x00000010, + DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP = 0x00000020, + DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS = 0x00000040, + DRSUAPI_DS_REPLICA_NEIGHBOUR_USE_ASYNC_INTERSIDE_TRANSPORT = 0x00000080, + DRSUAPI_DS_REPLICA_NEIGHBOUR_TWO_WAY_SYNC = 0x00000200, + DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS = 0x00000800, + DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_IN_PROGRESS = 0x00001000, /* was 0x00010000, */ + DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_NEXT_PACKET = 0x00002000, /* was 0x00020000, */ + DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED = 0x00200000, + DRSUAPI_DS_REPLICA_NEIGHBOUR_PREEMPTED = 0x01000000, + DRSUAPI_DS_REPLICA_NEIGHBOUR_IGNORE_CHANGE_NOTIFICATIONS = 0x04000000, + DRSUAPI_DS_REPLICA_NEIGHBOUR_DISABLE_SCHEDULED_SYNC = 0x08000000, + /* + * the following NOTE applies to DsGetNCChangesRequest5: + * - the data is only compressed when 10 or more objects are replicated + * - but there could also be a size limit of 35 KBytes or something like that + * - the reply is DsGetNCChangesCtr2 + * - maybe the same applies to DsGetNCChangesRequest8... + * + * --metze + */ + DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES = 0x10000000, + DRSUAPI_DS_REPLICA_NEIGHBOUR_NO_CHANGE_NOTIFICATIONS = 0x20000000, + DRSUAPI_DS_REPLICA_NEIGHBOUR_PARTIAL_ATTRIBUTE_SET = 0x40000000 + } drsuapi_DsReplicaNeighbourFlags; + + typedef [flag(NDR_PAHEX),v1_enum] enum { + DRSUAPI_EXOP_NONE = 0x00000000, + DRSUAPI_EXOP_FSMO_REQ_ROLE = 0x00000001, + DRSUAPI_EXOP_FSMO_RID_ALLOC = 0x00000002, + DRSUAPI_EXOP_FSMO_RID_REQ_ROLE = 0x00000003, + DRSUAPI_EXOP_FSMO_REQ_PDC = 0x00000004, + DRSUAPI_EXOP_FSMO_ABANDON_ROLE = 0x00000005, + DRSUAPI_EXOP_REPL_OBJ = 0x00000006, + DRSUAPI_EXOP_REPL_SECRET = 0x00000007 + } drsuapi_DsExtendedOperation; + + typedef [flag(NDR_PAHEX),v1_enum] enum { + DRSUAPI_EXOP_ERR_NONE = 0x00000000, + DRSUAPI_EXOP_ERR_SUCCESS = 0x00000001, + DRSUAPI_EXOP_ERR_UNKNOWN_OP = 0x00000002, + DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER = 0x00000003, + DRSUAPI_EXOP_ERR_UPDATE_ERR = 0x00000004, + DRSUAPI_EXOP_ERR_EXCEPTION = 0x00000005, + DRSUAPI_EXOP_ERR_UNKNOWN_CALLER = 0x00000006, + DRSUAPI_EXOP_ERR_RID_ALLOC = 0x00000007, + DRSUAPI_EXOP_ERR_FSMO_OWNER_DELETED = 0x00000008, + DRSUAPI_EXOP_ERR_FMSO_PENDING_OP = 0x00000009, + DRSUAPI_EXOP_ERR_MISMATCH = 0x0000000A, + DRSUAPI_EXOP_ERR_COULDNT_CONTACT = 0x0000000B, + DRSUAPI_EXOP_ERR_FSMO_REFUSING_ROLES = 0x0000000C, + DRSUAPI_EXOP_ERR_DIR_ERROR = 0x0000000D, + DRSUAPI_EXOP_ERR_FSMO_MISSING_SETTINGS = 0x0000000E, + DRSUAPI_EXOP_ERR_ACCESS_DENIED = 0x0000000F, + DRSUAPI_EXOP_ERR_PARAM_ERROR = 0x00000010 + } drsuapi_DsExtendedError; + + typedef struct { + GUID destination_dsa_guid; + GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ + [ref] drsuapi_DsReplicaObjectIdentifier *naming_context; + drsuapi_DsReplicaHighWaterMark highwatermark; + drsuapi_DsReplicaCursorCtrEx *uptodateness_vector; + drsuapi_DsReplicaNeighbourFlags replica_flags; + uint32 max_object_count; /* w2k3 uses min(133,max(100,max_object_count)) */ + uint32 max_ndr_size; /* w2k3 seems to ignore this */ + drsuapi_DsExtendedOperation extended_op; + hyper fsmo_info; + } drsuapi_DsGetNCChangesRequest5; + + /* + * In DRSUAPI all attributes with syntax 2.5.5.2 + * are identified by uint32 values + * + * the following table shows the mapping used between the two representations + * e.g. - objectClass 'nTDSDSA' has governsID: 1.2.840.113556.1.5.7000.47 + * and a UINT32-ID of '0x0017002F'. + * - so the OID 1.2.840.113556.1.5.7000.47 is splitted into a + * OID-prefix: 1.2.840.113556.1.5.7000 + * and a value: 47 => 0x2F + * - the mapping table gives a UINT32-prefix: 0x00170000 + * - and the UINT32-ID is 0x0017002F = 0x00170000 | 0x2F + * + * This prefix mapping table is replied in the drsuapi_DsReplicaOIDMapping_Ctr + * array. The following are the default mappings of w2k3 + * + * OID-prefix => UINT32-Id prefix + * + * 2.5.4.* => 0x00000000 (standard attributes RFC2256 core.schema) + * 2.5.6.* => 0x00010000 (standard object classes RFC2256 core.schema) + * 1.2.840.113556.1.2.* => 0x00020000 + * 1.2.840.113556.1.3.* => 0x00030000 + * 2.5.5.* => 0x00080000 (attributeSyntax OID's) + * 1.2.840.113556.1.4.* => 0x00090000 + * 1.2.840.113556.1.5.* => 0x000A0000 + * 2.16.840.1.113730.3.* => 0x00140000 + * 0.9.2342.19200300.100.1.* => 0x00150000 + * 2.16.840.1.113730.3.1.* => 0x00160000 + * 1.2.840.113556.1.5.7000.* => 0x00170000 + * 2.5.21.* => 0x00180000 (attrs for SubSchema) + * 2.5.18.* => 0x00190000 (createTimeStamp,modifyTimeStamp, SubSchema) + * 2.5.20.* => 0x001A0000 + * 1.3.6.1.4.1.1466.101.119.* => 0x001B0000 (dynamicObject, entryTTL) + * 2.16.840.1.113730.3.2.* => 0x001C0000 + * 1.3.6.1.4.1.250.1.* => 0x001D0000 + * 1.2.840.113549.1.9.* => 0x001E0000 (unstructuredAddress,unstructuredName) + * 0.9.2342.19200300.100.4.* => 0x001F0000 + * + * Here's a list of used 'attributeSyntax' OID's + * + * 2.5.5.1 => Object(DS-DN) string + * struct drsuapi_DsObjectIdentifier3 + * + * 2.5.5.2 => OID-string + * => all values are represented as uint32 values in drsuapi + * => governsID, attributeID and attributeSyntax returned as OID-Strings in LDAP + * => mayContain, mustContain and all other attributes with 2.5.5.2 syntax + * are returned as attribute names + * + * 2.5.5.4 => String(Teletex) case-insensitive string with teletex charset + * + * 2.5.5.5 => String(IA5) case-sensitive string + * + * 2.5.5.6 => String(Numeric) + * => eg. internationalISDNNumber + * + * 2.5.5.7 => Object(DN-Binary) B:<byte count>:<bytes>:<object DN> + * => e.g. wellKnownObjects + * + * 2.5.5.8 => BOOL + * + * 2.5.5.9 => int32 + * + * 2.5.5.10 => DATA_BLOB + * => struct GUID + * + * 2.5.5.11 => LDAP timestring + * => NTTIME_1sec + * + * 2.5.5.12 => String(Unicode) case-insensitive string + * => 'standard strings' + * + * 2.5.5.13 => Object(Presentation-Address) string + * => used in objectClass applicationEntity + * + * 2.5.5.14 => Object(DN-String) S:<char count>:<string>:<object DN> + * => not used + * + * 2.5.5.15 => ntSecurityDescriptor + * + * 2.5.5.16 => int64 + * + * 2.5.5.17 => dom_sid + */ + typedef [nopush,nopull] struct { + [range(0,10000),value(ndr_size_drsuapi_DsReplicaOID_oid(oid, 0))] uint32 __ndr_size; + [size_is(__ndr_size),charset(DOS)] uint8 *oid; /* it's encoded with asn1_write_OID_String() */ + } drsuapi_DsReplicaOID; + + typedef struct { + uint32 id_prefix; + drsuapi_DsReplicaOID oid; + } drsuapi_DsReplicaOIDMapping; + + typedef [public] struct { + [range(0,0x100000)] uint32 num_mappings; + [size_is(num_mappings)] drsuapi_DsReplicaOIDMapping *mappings; + } drsuapi_DsReplicaOIDMapping_Ctr; + + typedef [flag(NDR_PAHEX),v1_enum] enum { + DRSUAPI_OBJECTCLASS_top = 0x00010000, + DRSUAPI_OBJECTCLASS_classSchema = 0x0003000d, + DRSUAPI_OBJECTCLASS_attributeSchema = 0x0003000e + } drsuapi_DsObjectClassId; + + typedef [flag(NDR_PAHEX),v1_enum,public] enum { + DRSUAPI_ATTRIBUTE_objectClass = 0x00000000, + DRSUAPI_ATTRIBUTE_description = 0x0000000d, + DRSUAPI_ATTRIBUTE_member = 0x0000001f, + DRSUAPI_ATTRIBUTE_instanceType = 0x00020001, + DRSUAPI_ATTRIBUTE_whenCreated = 0x00020002, + DRSUAPI_ATTRIBUTE_hasMasterNCs = 0x0002000e, + DRSUAPI_ATTRIBUTE_governsID = 0x00020016, + DRSUAPI_ATTRIBUTE_attributeID = 0x0002001e, + DRSUAPI_ATTRIBUTE_attributeSyntax = 0x00020020, + DRSUAPI_ATTRIBUTE_isSingleValued = 0x00020021, + DRSUAPI_ATTRIBUTE_rangeLower = 0x00020022, + DRSUAPI_ATTRIBUTE_rangeUpper = 0x00020023, + DRSUAPI_ATTRIBUTE_dMDLocation = 0x00020024, + DRSUAPI_ATTRIBUTE_objectVersion = 0x0002004c, + DRSUAPI_ATTRIBUTE_invocationId = 0x00020073, + DRSUAPI_ATTRIBUTE_showInAdvancedViewOnly = 0x000200a9, + DRSUAPI_ATTRIBUTE_adminDisplayName = 0x000200c2, + DRSUAPI_ATTRIBUTE_adminDescription = 0x000200e2, + DRSUAPI_ATTRIBUTE_oMSyntax = 0x000200e7, + DRSUAPI_ATTRIBUTE_ntSecurityDescriptor = 0x00020119, + DRSUAPI_ATTRIBUTE_searchFlags = 0x0002014e, + DRSUAPI_ATTRIBUTE_lDAPDisplayName = 0x000201cc, + DRSUAPI_ATTRIBUTE_name = 0x00090001, + DRSUAPI_ATTRIBUTE_userAccountControl = 0x00090008, + DRSUAPI_ATTRIBUTE_currentValue = 0x0009001b, + DRSUAPI_ATTRIBUTE_homeDirectory = 0x0009002c, + DRSUAPI_ATTRIBUTE_homeDrive = 0x0009002d, + DRSUAPI_ATTRIBUTE_scriptPath = 0x0009003e, + DRSUAPI_ATTRIBUTE_profilePath = 0x0009008b, + DRSUAPI_ATTRIBUTE_objectSid = 0x00090092, + DRSUAPI_ATTRIBUTE_schemaIDGUID = 0x00090094, + DRSUAPI_ATTRIBUTE_dBCSPwd = 0x00090037,/* lmPwdHash */ + DRSUAPI_ATTRIBUTE_logonHours = 0x00090040, + DRSUAPI_ATTRIBUTE_userWorkstations = 0x00090056, + DRSUAPI_ATTRIBUTE_unicodePwd = 0x0009005a,/* ntPwdHash */ + DRSUAPI_ATTRIBUTE_ntPwdHistory = 0x0009005e, + DRSUAPI_ATTRIBUTE_priorValue = 0x00090064, + DRSUAPI_ATTRIBUTE_supplementalCredentials = 0x0009007d, + DRSUAPI_ATTRIBUTE_trustAuthIncoming = 0x00090081, + DRSUAPI_ATTRIBUTE_trustAuthOutgoing = 0x00090087, + DRSUAPI_ATTRIBUTE_lmPwdHistory = 0x000900a0, + DRSUAPI_ATTRIBUTE_sAMAccountName = 0x000900dd, + DRSUAPI_ATTRIBUTE_sAMAccountType = 0x0009012e, + DRSUAPI_ATTRIBUTE_fSMORoleOwner = 0x00090171, + DRSUAPI_ATTRIBUTE_systemFlags = 0x00090177, + DRSUAPI_ATTRIBUTE_serverReference = 0x00090203, + DRSUAPI_ATTRIBUTE_serverReferenceBL = 0x00090204, + DRSUAPI_ATTRIBUTE_initialAuthIncoming = 0x0009021b, + DRSUAPI_ATTRIBUTE_initialAuthOutgoing = 0x0009021c, + DRSUAPI_ATTRIBUTE_wellKnownObjects = 0x0009026a, + DRSUAPI_ATTRIBUTE_dNSHostName = 0x0009026b, + DRSUAPI_ATTRIBUTE_isMemberOfPartialAttributeSet = 0x0009027f, + DRSUAPI_ATTRIBUTE_userPrincipalName = 0x00090290, + DRSUAPI_ATTRIBUTE_groupType = 0x000902ee, + DRSUAPI_ATTRIBUTE_servicePrincipalName = 0x00090303, + DRSUAPI_ATTRIBUTE_objectCategory = 0x0009030e, + DRSUAPI_ATTRIBUTE_gPLink = 0x0009037b, + DRSUAPI_ATTRIBUTE_msDS_Behavior_Version = 0x000905b3, + DRSUAPI_ATTRIBUTE_msDS_KeyVersionNumber = 0x000906f6, + DRSUAPI_ATTRIBUTE_msDS_HasDomainNCs = 0x0009071c, + DRSUAPI_ATTRIBUTE_msDS_hasMasterNCs = 0x0009072c + } drsuapi_DsAttributeId; + + typedef struct { + [value(1)] uint32 version; + [value(0)] uint32 reserved1; + [range(1,0x100000)] uint32 num_attids; + [size_is(num_attids)] drsuapi_DsAttributeId attids[]; + } drsuapi_DsPartialAttributeSet; + + typedef struct { + GUID destination_dsa_guid; + GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ + [ref] drsuapi_DsReplicaObjectIdentifier *naming_context; + drsuapi_DsReplicaHighWaterMark highwatermark; + drsuapi_DsReplicaCursorCtrEx *uptodateness_vector; + drsuapi_DsReplicaNeighbourFlags replica_flags; + uint32 max_object_count; /* w2k3 uses min(133,max(100,max_object_count)) */ + uint32 max_ndr_size; /* w2k3 seems to ignore this */ + drsuapi_DsExtendedOperation extended_op; + hyper fsmo_info; + drsuapi_DsPartialAttributeSet *partial_attribute_set; + drsuapi_DsPartialAttributeSet *partial_attribute_set_ex; + drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr; + } drsuapi_DsGetNCChangesRequest8; + + typedef [switch_type(int32)] union { + [case(5)] drsuapi_DsGetNCChangesRequest5 req5; + [case(8)] drsuapi_DsGetNCChangesRequest8 req8; + } drsuapi_DsGetNCChangesRequest; + + typedef [public] struct { + GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ + hyper highest_usn; /* updated after a full replication cycle */ + NTTIME last_sync_success; + } drsuapi_DsReplicaCursor2; + + typedef struct { + [value(2)] uint32 version; + [value(0)] uint32 reserved1; + [range(0,0x100000)] uint32 count; + [value(0)] uint32 reserved2; + [size_is(count)] drsuapi_DsReplicaCursor2 cursors[]; + } drsuapi_DsReplicaCursor2CtrEx; + + /* Generic DATA_BLOB values */ + typedef struct { + [range(0,10485760),value(ndr_size_DATA_BLOB(0,blob,0))] uint32 __ndr_size; + DATA_BLOB *blob; + } drsuapi_DsAttributeValue; + + typedef struct { + [range(0,10485760)] uint32 num_values; + [size_is(num_values)] drsuapi_DsAttributeValue *values; + } drsuapi_DsAttributeValueCtr; + + /* DN String values */ + typedef [public,gensize] struct { + [value(ndr_size_drsuapi_DsReplicaObjectIdentifier3(r, ndr->flags))] uint32 __ndr_size; + [value(ndr_size_dom_sid28(&sid,ndr->flags))] uint32 __ndr_size_sid; + GUID guid; + dom_sid28 sid; + [value(strlen_m(dn))] uint32 __ndr_size_dn; + [charset(UTF16)] uint16 dn[__ndr_size_dn+1]; + } drsuapi_DsReplicaObjectIdentifier3; + + typedef [public,gensize] struct { + [value(ndr_size_drsuapi_DsReplicaObjectIdentifier3Binary(r, ndr->flags))] uint32 __ndr_size; + [value(ndr_size_dom_sid28(&sid,ndr->flags))] uint32 __ndr_size_sid; + GUID guid; + dom_sid28 sid; + [value(strlen_m(dn))] uint32 __ndr_size_dn; + [charset(UTF16)] uint16 dn[__ndr_size_dn+1]; + [value(binary.length + 4)] uint32 __ndr_size_binary; + [flag(NDR_REMAINING)] DATA_BLOB binary; + } drsuapi_DsReplicaObjectIdentifier3Binary; + + typedef [public] struct { + drsuapi_DsAttributeId attid; + drsuapi_DsAttributeValueCtr value_ctr; + } drsuapi_DsReplicaAttribute; + + typedef struct { + [range(0,1048576)] uint32 num_attributes; + [size_is(num_attributes)] drsuapi_DsReplicaAttribute *attributes; + } drsuapi_DsReplicaAttributeCtr; + + typedef [public] bitmap { + DRSUAPI_DS_REPLICA_OBJECT_FROM_MASTER = 0x00000001, + DRSUAPI_DS_REPLICA_OBJECT_DYNAMIC = 0x00000002, + DRSUAPI_DS_REPLICA_OBJECT_REMOTE_MODIFY = 0x00010000 + } drsuapi_DsReplicaObjectFlags; + + typedef [public] struct { + drsuapi_DsReplicaObjectIdentifier *identifier; + drsuapi_DsReplicaObjectFlags flags; + drsuapi_DsReplicaAttributeCtr attribute_ctr; + } drsuapi_DsReplicaObject; + + typedef struct { + uint32 version; + NTTIME_1sec originating_change_time; + GUID originating_invocation_id; + hyper originating_usn; + } drsuapi_DsReplicaMetaData; + + typedef [public] struct { + [range(0,1048576)] uint32 count; + [size_is(count)] drsuapi_DsReplicaMetaData meta_data[]; + } drsuapi_DsReplicaMetaDataCtr; + + typedef [public,noprint] struct { + drsuapi_DsReplicaObjectListItemEx *next_object; + drsuapi_DsReplicaObject object; + boolean32 is_nc_prefix; + GUID *parent_object_guid; + drsuapi_DsReplicaMetaDataCtr *meta_data_ctr; + } drsuapi_DsReplicaObjectListItemEx; + + typedef [public,gensize] struct { + GUID source_dsa_guid; /* the 'objectGUID' field of the CN=NTDS Settings object */ + GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ + drsuapi_DsReplicaObjectIdentifier *naming_context; + drsuapi_DsReplicaHighWaterMark old_highwatermark; + drsuapi_DsReplicaHighWaterMark new_highwatermark; + drsuapi_DsReplicaCursorCtrEx *uptodateness_vector; + drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr; + drsuapi_DsExtendedError extended_ret; /* w2k sends the nc_object_count value here */ + uint32 object_count; + /* this +55 is sometimes +56, so I don't know where this comes from... --metze */ + [value(ndr_size_drsuapi_DsGetNCChangesCtr1(r,ndr->flags)+55)] uint32 __ndr_size; + drsuapi_DsReplicaObjectListItemEx *first_object; + boolean32 more_data; + } drsuapi_DsGetNCChangesCtr1; + + /* + * if the DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE flag + * isn't there it means the value is deleted + */ + typedef [public] bitmap { + DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE = 0x00000001 + } drsuapi_DsLinkedAttributeFlags; + + typedef [public] struct { + drsuapi_DsReplicaObjectIdentifier *identifier; + drsuapi_DsAttributeId attid; + drsuapi_DsAttributeValue value; + drsuapi_DsLinkedAttributeFlags flags; + NTTIME_1sec originating_add_time; + drsuapi_DsReplicaMetaData meta_data; + } drsuapi_DsReplicaLinkedAttribute; + + typedef [public,gensize] struct { + GUID source_dsa_guid; /* the 'objectGUID' field of the CN=NTDS Settings object */ + GUID source_dsa_invocation_id; /* the 'invocationId' field of the CN=NTDS Settings object */ + drsuapi_DsReplicaObjectIdentifier *naming_context; + drsuapi_DsReplicaHighWaterMark old_highwatermark; + drsuapi_DsReplicaHighWaterMark new_highwatermark; + drsuapi_DsReplicaCursor2CtrEx *uptodateness_vector; + drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr; + drsuapi_DsExtendedError extended_ret; + uint32 object_count; + /* this +55 is sometimes +56, so I don't know where this comes from... --metze */ + [value(ndr_size_drsuapi_DsGetNCChangesCtr6(r,ndr->flags)+55)] uint32 __ndr_size; + drsuapi_DsReplicaObjectListItemEx *first_object; + boolean32 more_data; + uint32 nc_object_count; /* estimated amount of objects in the whole NC */ + uint32 nc_linked_attributes_count; /* estimated amount of linked values in the whole NC */ + [range(0,1048576)] uint32 linked_attributes_count; + [size_is(linked_attributes_count)] drsuapi_DsReplicaLinkedAttribute *linked_attributes; + WERROR drs_error; + } drsuapi_DsGetNCChangesCtr6; + + typedef [public] struct { + [subcontext(0xFFFFFC01)] drsuapi_DsGetNCChangesCtr1 ctr1; + } drsuapi_DsGetNCChangesCtr1TS; + + typedef [public] struct { + [subcontext(0xFFFFFC01)] drsuapi_DsGetNCChangesCtr6 ctr6; + } drsuapi_DsGetNCChangesCtr6TS; + + typedef [nopush] struct { + uint32 decompressed_length; + uint32 compressed_length; + [subcontext(4),subcontext_size(compressed_length), + compression(NDR_COMPRESSION_MSZIP,compressed_length,decompressed_length)] + drsuapi_DsGetNCChangesCtr1TS *ts; + } drsuapi_DsGetNCChangesMSZIPCtr1; + + typedef [nopush] struct { + uint32 decompressed_length; + uint32 compressed_length; + [subcontext(4),subcontext_size(compressed_length), + compression(NDR_COMPRESSION_MSZIP,compressed_length,decompressed_length)] + drsuapi_DsGetNCChangesCtr6TS *ts; + } drsuapi_DsGetNCChangesMSZIPCtr6; + + typedef [nopush] struct { + uint32 decompressed_length; + uint32 compressed_length; + [subcontext(4),subcontext_size(compressed_length), + compression(NDR_COMPRESSION_XPRESS,compressed_length,decompressed_length)] + drsuapi_DsGetNCChangesCtr1TS *ts; + } drsuapi_DsGetNCChangesXPRESSCtr1; + + typedef [nopush] struct { + uint32 decompressed_length; + uint32 compressed_length; + [subcontext(4),subcontext_size(compressed_length), + compression(NDR_COMPRESSION_XPRESS,compressed_length,decompressed_length)] + drsuapi_DsGetNCChangesCtr6TS *ts; + } drsuapi_DsGetNCChangesXPRESSCtr6; + + typedef [enum16bit] enum { + DRSUAPI_COMPRESSION_TYPE_MSZIP = 2, + DRSUAPI_COMPRESSION_TYPE_XPRESS = 3 + } drsuapi_DsGetNCChangesCompressionType; + + typedef [nodiscriminant,flag(NDR_PAHEX)] union { + [case(1|(DRSUAPI_COMPRESSION_TYPE_MSZIP<<16))] drsuapi_DsGetNCChangesMSZIPCtr1 mszip1; + [case(6|(DRSUAPI_COMPRESSION_TYPE_MSZIP<<16))] drsuapi_DsGetNCChangesMSZIPCtr6 mszip6; + [case(1|(DRSUAPI_COMPRESSION_TYPE_XPRESS<<16))] drsuapi_DsGetNCChangesXPRESSCtr1 xpress1; + [case(6|(DRSUAPI_COMPRESSION_TYPE_XPRESS<<16))] drsuapi_DsGetNCChangesXPRESSCtr6 xpress6; + } drsuapi_DsGetNCChangesCompressedCtr; + + typedef struct { + drsuapi_DsGetNCChangesMSZIPCtr1 mszip1; + } drsuapi_DsGetNCChangesCtr2; + + typedef struct { + [range(0,6)] int32 level; + [range(2,3)] drsuapi_DsGetNCChangesCompressionType type; + [switch_is(level | (type<<16))] drsuapi_DsGetNCChangesCompressedCtr ctr; + } drsuapi_DsGetNCChangesCtr7; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsGetNCChangesCtr1 ctr1; + [case(2)] drsuapi_DsGetNCChangesCtr2 ctr2; + [case(6)] drsuapi_DsGetNCChangesCtr6 ctr6; + [case(7)] drsuapi_DsGetNCChangesCtr7 ctr7; + } drsuapi_DsGetNCChangesCtr; + + WERROR drsuapi_DsGetNCChanges( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref,switch_is(level)] drsuapi_DsGetNCChangesRequest *req, + [out,ref] int32 *level_out, + [out,ref,switch_is(*level_out)] drsuapi_DsGetNCChangesCtr *ctr + ); + + /*****************/ + /* Function 0x04 */ + typedef bitmap { + DRSUAPI_DS_REPLICA_UPDATE_ASYNCHRONOUS_OPERATION = 0x00000001, + DRSUAPI_DS_REPLICA_UPDATE_WRITEABLE = 0x00000002, + DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE = 0x00000004, + DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE = 0x00000008, + DRSUAPI_DS_REPLICA_UPDATE_0x00000010 = 0x00000010 + } drsuapi_DsReplicaUpdateRefsOptions; + + typedef struct { + [ref] drsuapi_DsReplicaObjectIdentifier *naming_context; + [ref,charset(DOS),string] uint8 *dest_dsa_dns_name; + GUID dest_dsa_guid; + drsuapi_DsReplicaUpdateRefsOptions options; + } drsuapi_DsReplicaUpdateRefsRequest1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsReplicaUpdateRefsRequest1 req1; + } drsuapi_DsReplicaUpdateRefsRequest; + + WERROR drsuapi_DsReplicaUpdateRefs( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,switch_is(level)] drsuapi_DsReplicaUpdateRefsRequest req + ); + + /*****************/ + /* Function 0x05 */ + typedef bitmap { + DRSUAPI_DS_REPLICA_ADD_ASYNCHRONOUS_OPERATION = 0x00000001, + DRSUAPI_DS_REPLICA_ADD_WRITEABLE = 0x00000002 + /* TODO ... */ + } drsuapi_DsReplicaAddOptions; + + [todo] WERROR DRSUAPI_REPLICA_ADD(); + + /*****************/ + /* Function 0x06 */ + typedef bitmap { + DRSUAPI_DS_REPLICA_DELETE_ASYNCHRONOUS_OPERATION = 0x00000001, + DRSUAPI_DS_REPLICA_DELETE_WRITEABLE = 0x00000002 + /* TODO ... */ + } drsuapi_DsReplicaDeleteOptions; + + [todo] WERROR DRSUAPI_REPLICA_DEL(); + + /*****************/ + /* Function 0x07 */ + typedef bitmap { + DRSUAPI_DS_REPLICA_MODIFY_ASYNCHRONOUS_OPERATION = 0x00000001, + DRSUAPI_DS_REPLICA_MODIFY_WRITEABLE = 0x00000002 + } drsuapi_DsReplicaModifyOptions; + + [todo] WERROR DRSUAPI_REPLICA_MODIFY(); + + /*****************/ + /* Function 0x08 */ + [todo] WERROR DRSUAPI_VERIFY_NAMES(); + + /*****************/ + /* Function 0x09 */ + + /* how are type 4 and 7 different from 2 and 3 ? */ + typedef [v1_enum] enum { + DRSUAPI_DS_MEMBERSHIP_TYPE_UNIVERSAL_AND_DOMAIN_GROUPS = 1, + DRSUAPI_DS_MEMBERSHIP_TYPE_DOMAIN_LOCAL_GROUPS = 2, + DRSUAPI_DS_MEMBERSHIP_TYPE_DOMAIN_GROUPS = 3, + DRSUAPI_DS_MEMBERSHIP_TYPE_DOMAIN_LOCAL_GROUPS2 = 4, + DRSUAPI_DS_MEMBERSHIP_TYPE_UNIVERSAL_GROUPS = 5, + DRSUAPI_DS_MEMBERSHIP_TYPE_GROUPMEMBERS = 6, + DRSUAPI_DS_MEMBERSHIP_TYPE_DOMAIN_GROUPS2 = 7 + } drsuapi_DsMembershipType; + + typedef struct { + NTSTATUS status; + [range(0,10000)] uint32 num_memberships; + [range(0,10000)] uint32 num_sids; + [size_is(num_memberships)] drsuapi_DsReplicaObjectIdentifier **info_array; + [size_is(num_memberships)] samr_GroupAttrs *group_attrs; + [size_is(num_sids)] dom_sid28 **sids; + } drsuapi_DsGetMembershipsCtr1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsGetMembershipsCtr1 ctr1; + } drsuapi_DsGetMembershipsCtr; + + const int DRSUAPI_DS_MEMBERSHIP_FLAG_GROUP_ATTR = 0x1; + + typedef struct { + [range(1,10000)] uint32 count; + [size_is(count)] drsuapi_DsReplicaObjectIdentifier **info_array; + uint32 flags; + drsuapi_DsMembershipType type; + drsuapi_DsReplicaObjectIdentifier *domain; + } drsuapi_DsGetMembershipsRequest1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsGetMembershipsRequest1 req1; + } drsuapi_DsGetMembershipsRequest; + + [todo] WERROR drsuapi_DsGetMemberships( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref] [switch_is(level)] drsuapi_DsGetMembershipsRequest *req, + [out,ref] int32 *level_out, + [out,ref] [switch_is(*level_out)] drsuapi_DsGetMembershipsCtr *ctr + ); + + /*****************/ + /* Function 0x0a */ + [todo] WERROR DRSUAPI_INTER_DOMAIN_MOVE(); + + /*****************/ + /* Function 0x0b */ + typedef struct { + uint32 unknown1; + uint32 unknown2; + [range(0,0x00A00000)] uint32 length; + [size_is(length)] uint8 *data; + } drsuapi_DsGetNT4ChangeLogRequest1; + + typedef [switch_type(uint32)] union { + [case(1)] drsuapi_DsGetNT4ChangeLogRequest1 req1; + } drsuapi_DsGetNT4ChangeLogRequest; + + typedef struct { + [range(0,0x00A00000)] uint32 length1; + [range(0,0x00A00000)] uint32 length2; + hyper unknown1; + NTTIME time2; + hyper unknown3; + NTTIME time4; + hyper unknown5; + NTTIME time6; + NTSTATUS status; + [size_is(length1)] uint8 *data1; + [size_is(length2)] uint8 *data2; + } drsuapi_DsGetNT4ChangeLogInfo1; + + typedef [switch_type(uint32)] union { + [case(1)] drsuapi_DsGetNT4ChangeLogInfo1 info1; + } drsuapi_DsGetNT4ChangeLogInfo; + + [todo] WERROR drsuapi_DsGetNT4ChangeLog( + [in] policy_handle *bind_handle, + [in] uint32 level, + [in,ref] [switch_is(level)] drsuapi_DsGetNT4ChangeLogRequest *req, + [out,ref] uint32 *level_out, + [out,ref] [switch_is(*level_out)] drsuapi_DsGetNT4ChangeLogInfo *info + ); + + /*****************/ + /* Function 0x0c */ + typedef [v1_enum] enum { + DRSUAPI_DS_NAME_STATUS_OK = 0, + DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR = 1, + DRSUAPI_DS_NAME_STATUS_NOT_FOUND = 2, + DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE = 3, + DRSUAPI_DS_NAME_STATUS_NO_MAPPING = 4, + DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY = 5, + DRSUAPI_DS_NAME_STATUS_NO_SYNTACTICAL_MAPPING = 6, + DRSUAPI_DS_NAME_STATUS_TRUST_REFERRAL = 7 + } drsuapi_DsNameStatus; + + typedef [v1_enum] enum { + DRSUAPI_DS_NAME_FLAG_NO_FLAGS = 0x0, + DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1, + DRSUAPI_DS_NAME_FLAG_EVAL_AT_DC = 0x2, + DRSUAPI_DS_NAME_FLAG_GCVERIFY = 0x4, + DRSUAPI_DS_NAME_FLAG_TRUST_REFERRAL = 0x8 + } drsuapi_DsNameFlags; + + typedef [v1_enum] enum { + DRSUAPI_DS_NAME_FORMAT_UNKNOWN = 0, + DRSUAPI_DS_NAME_FORMAT_FQDN_1779 = 1, + DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT = 2, + DRSUAPI_DS_NAME_FORMAT_DISPLAY = 3, + DRSUAPI_DS_NAME_FORMAT_GUID = 6, + DRSUAPI_DS_NAME_FORMAT_CANONICAL = 7, + DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL = 8, + DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX = 9, + DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL = 10, + DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY = 11, + DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN = 12 + } drsuapi_DsNameFormat; + + typedef struct { + [string,charset(UTF16)] uint16 *str; + } drsuapi_DsNameString; + + typedef struct { + uint32 codepage; /* 0x000004e4 - 1252 is german codepage*/ + uint32 language; /* 0x00000407 - german language ID*/ + drsuapi_DsNameFlags format_flags; + drsuapi_DsNameFormat format_offered; + drsuapi_DsNameFormat format_desired; + [range(1,10000)] uint32 count; + [size_is(count)] drsuapi_DsNameString *names; + } drsuapi_DsNameRequest1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsNameRequest1 req1; + } drsuapi_DsNameRequest; + + typedef struct { + drsuapi_DsNameStatus status; + [charset(UTF16),string] uint16 *dns_domain_name; + [charset(UTF16),string] uint16 *result_name; + } drsuapi_DsNameInfo1; + + typedef struct { + uint32 count; + [size_is(count)] drsuapi_DsNameInfo1 *array; + } drsuapi_DsNameCtr1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsNameCtr1 *ctr1; + } drsuapi_DsNameCtr; + + WERROR drsuapi_DsCrackNames( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref,switch_is(level)] drsuapi_DsNameRequest *req, + [out,ref] int32 *level_out, + [out,ref,switch_is(*level_out)] drsuapi_DsNameCtr *ctr + ); + + /*****************/ + /* Function 0x0d */ + typedef [v1_enum] enum { + DRSUAPI_DS_SPN_OPERATION_ADD = 0, + DRSUAPI_DS_SPN_OPERATION_REPLACE= 1, + DRSUAPI_DS_SPN_OPERATION_DELETE = 2 + } drsuapi_DsSpnOperation; + + typedef struct { + drsuapi_DsSpnOperation operation; + uint32 unknown1; + [charset(UTF16),string] uint16 *object_dn; + [range(0,10000)] uint32 count; + [size_is(count)] drsuapi_DsNameString *spn_names; + } drsuapi_DsWriteAccountSpnRequest1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsWriteAccountSpnRequest1 req1; + } drsuapi_DsWriteAccountSpnRequest; + + typedef struct { + WERROR status; + } drsuapi_DsWriteAccountSpnResult1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsWriteAccountSpnResult1 res1; + } drsuapi_DsWriteAccountSpnResult; + + WERROR drsuapi_DsWriteAccountSpn( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref,switch_is(level)] drsuapi_DsWriteAccountSpnRequest *req, + [out,ref] int32 *level_out, + [out,ref,switch_is(*level_out)] drsuapi_DsWriteAccountSpnResult *res + ); + + /*****************/ + /* Function 0x0e */ + typedef struct { + [charset(UTF16),string] uint16 *server_dn; + [charset(UTF16),string] uint16 *domain_dn; + boolean32 commit; + } drsuapi_DsRemoveDSServerRequest1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsRemoveDSServerRequest1 req1; + } drsuapi_DsRemoveDSServerRequest; + + typedef struct { + boolean32 last_dc_in_domain; + } drsuapi_DsRemoveDSServerResult1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsRemoveDSServerResult1 res1; + } drsuapi_DsRemoveDSServerResult; + + WERROR drsuapi_DsRemoveDSServer( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref,switch_is(level)] drsuapi_DsRemoveDSServerRequest *req, + [out,ref] int32 *level_out, + [out,ref,switch_is(*level_out)] drsuapi_DsRemoveDSServerResult *res + ); + + /*****************/ + /* Function 0x0f */ + [todo] WERROR DRSUAPI_REMOVE_DS_DOMAIN(); + + /*****************/ + /* Function 0x10 */ + typedef struct { + [charset(UTF16),string] uint16 *domain_name; /* netbios or dns */ + int32 level; /* specifies the switch level for the request */ + } drsuapi_DsGetDCInfoRequest1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsGetDCInfoRequest1 req1; + } drsuapi_DsGetDCInfoRequest; + + typedef struct { + [charset(UTF16),string] uint16 *netbios_name; + [charset(UTF16),string] uint16 *dns_name; + [charset(UTF16),string] uint16 *site_name; + [charset(UTF16),string] uint16 *computer_dn; + [charset(UTF16),string] uint16 *server_dn; + uint32 is_pdc; + uint32 is_enabled; + } drsuapi_DsGetDCInfo1; + + typedef struct { + [range(0,10000)] uint32 count; + [size_is(count)] drsuapi_DsGetDCInfo1 *array; + } drsuapi_DsGetDCInfoCtr1; + + typedef struct { + [charset(UTF16),string] uint16 *netbios_name; + [charset(UTF16),string] uint16 *dns_name; + [charset(UTF16),string] uint16 *site_name; + [charset(UTF16),string] uint16 *site_dn; + [charset(UTF16),string] uint16 *computer_dn; + [charset(UTF16),string] uint16 *server_dn; + [charset(UTF16),string] uint16 *ntds_dn; + uint32 is_pdc; + uint32 is_enabled; + uint32 is_gc; + GUID site_guid; + GUID computer_guid; + GUID server_guid; + GUID ntds_guid; + } drsuapi_DsGetDCInfo2; + + typedef struct { + [range(0,10000)] uint32 count; + [size_is(count)] drsuapi_DsGetDCInfo2 *array; + } drsuapi_DsGetDCInfoCtr2; + + typedef struct { + [charset(UTF16),string] uint16 *netbios_name; + [charset(UTF16),string] uint16 *dns_name; + [charset(UTF16),string] uint16 *site_name; + [charset(UTF16),string] uint16 *site_dn; + [charset(UTF16),string] uint16 *computer_dn; + [charset(UTF16),string] uint16 *server_dn; + [charset(UTF16),string] uint16 *ntds_dn; + uint32 is_pdc; + uint32 is_enabled; + uint32 is_gc; + uint32 is_rodc; + GUID site_guid; + GUID computer_guid; + GUID server_guid; + GUID ntds_guid; + } drsuapi_DsGetDCInfo3; + + typedef struct { + [range(0,10000)] uint32 count; + [size_is(count)] drsuapi_DsGetDCInfo3 *array; + } drsuapi_DsGetDCInfoCtr3; + + /* + * this represents an active connection to the + * Directory System Agent (DSA) + * this can be via LDAP or DRSUAPI + */ + typedef struct { + [flag(NDR_BIG_ENDIAN)] ipv4address client_ip_address; + uint32 unknown2; + uint32 connection_time; /* in seconds */ + uint32 unknown4; + uint32 unknown5; + uint32 unknown6; + /* + * client_account can be the following: + * "W2K3\Administrator" + * "Administrator@W2K3" + * "cn=Administrator,cn=Users,DC=w2k3,DC=vmnet1,DC=vm,DC=base" + * "" + * or NULL + */ + [charset(UTF16),string] uint16 *client_account; + } drsuapi_DsGetDCConnection01; + + typedef struct { + [range(0,10000)] uint32 count; + [size_is(count)] drsuapi_DsGetDCConnection01 *array; + } drsuapi_DsGetDCConnectionCtr01; + + typedef [v1_enum] enum { + DRSUAPI_DC_INFO_CTR_1 = 1, + DRSUAPI_DC_INFO_CTR_2 = 2, + DRSUAPI_DC_INFO_CTR_3 = 3, + DRSUAPI_DC_CONNECTION_CTR_01 = -1 + } drsuapi_DsGetDCInfoCtrLevels; + + typedef [switch_type(int32)] union { + [case(DRSUAPI_DC_INFO_CTR_1)] drsuapi_DsGetDCInfoCtr1 ctr1; + [case(DRSUAPI_DC_INFO_CTR_2)] drsuapi_DsGetDCInfoCtr2 ctr2; + [case(DRSUAPI_DC_INFO_CTR_3)] drsuapi_DsGetDCInfoCtr3 ctr3; + [case(DRSUAPI_DC_CONNECTION_CTR_01)] drsuapi_DsGetDCConnectionCtr01 ctr01; + } drsuapi_DsGetDCInfoCtr; + + WERROR drsuapi_DsGetDomainControllerInfo( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref,switch_is(level)] drsuapi_DsGetDCInfoRequest *req, + [out,ref] int32 *level_out, + [out,ref,switch_is(*level_out)] drsuapi_DsGetDCInfoCtr *ctr + ); + + /*****************/ + /* Function 0x11 */ + typedef [public,noprint] struct { + drsuapi_DsReplicaObjectListItem *next_object; + drsuapi_DsReplicaObject object; + } drsuapi_DsReplicaObjectListItem; + + /* + * The DsAddEntry() call which creates a nTDSDSA object, + * also adds a servicePrincipalName in the following form + * to the computer account of the new domain controller + * referenced by the "serverReferenece" attribute. + * + * E3514235-4B06-11D1-AB04-00C04FC2DCD2/<new-ntdsdsa-object-guid-as-string>/<domain-dns-name> + * + * also note that the "serverReference" isn't added to the new object! + */ + const char *DRSUAPI_NTDSDSA_KRB5_SERVICE_GUID = "E3514235-4B06-11D1-AB04-00C04FC2DCD2"; + + /* + * please note the the current idl + * for DsAddEntry does only parse + * what I saw between 2 w2k3 boxes + * in my dssync experiments I got some other replies + * so all I want to say is that this is very incomplete yet... + * --metze + */ + typedef struct { + drsuapi_DsReplicaObjectListItem first_object; + } drsuapi_DsAddEntryRequest2; + + typedef [switch_type(int32)] union { + [case(2)] drsuapi_DsAddEntryRequest2 req2; + } drsuapi_DsAddEntryRequest; + + typedef struct { + uint32 unknown1; + WERROR status; + uint32 unknown2; + uint16 unknown3; + } drsuapi_DsAddEntryErrorInfoX; + + typedef struct { + [range(0,10485760)] uint32 size; + [size_is(size)] uint8 *data; + } drsuapi_DsAddEntryExtraErrorBuffer; + + typedef struct { + drsuapi_DsAddEntryErrorInfoX error; + drsuapi_DsAttributeId attid; + uint32 unknown2; + drsuapi_DsAddEntryExtraErrorBuffer buffer; + } drsuapi_DsAddEntryExtraError1; + + typedef /*[noprint]*/ struct { + drsuapi_DsAddEntryErrorListItem1 *next; + drsuapi_DsAddEntryExtraError1 error; + } drsuapi_DsAddEntryErrorListItem1; + + typedef struct { + drsuapi_DsReplicaObjectIdentifier *id; + WERROR status; + drsuapi_DsAddEntryErrorListItem1 first; + } drsuapi_DsAddEntryErrorInfo1; + + typedef [switch_type(uint32)] union { + [case(1)] drsuapi_DsAddEntryErrorInfo1 error1; +/* [case(2)] drsuapi_DsAddEntryErrorInfo2 error2; + [case(3)] drsuapi_DsAddEntryErrorInfo3 error3; +*/ [case(4)] drsuapi_DsAddEntryErrorInfoX errorX; + [case(5)] drsuapi_DsAddEntryErrorInfoX errorX; + [case(6)] drsuapi_DsAddEntryErrorInfoX errorX; + [case(7)] drsuapi_DsAddEntryErrorInfoX errorX; + } drsuapi_DsAddEntryErrorInfo; + + typedef struct { + WERROR status; + uint32 level; + [switch_is(level)] drsuapi_DsAddEntryErrorInfo *info; + } drsuapi_DsAddEntryError1; + + typedef [switch_type(uint32)] union { + [case(1)] drsuapi_DsAddEntryError1 info1; + } drsuapi_DsAddEntryError; + + typedef struct { + GUID guid; + dom_sid28 sid; + } drsuapi_DsReplicaObjectIdentifier2; + + typedef struct { + drsuapi_DsReplicaObjectIdentifier *id; + uint32 unknown1; + drsuapi_DsAddEntryErrorInfoX error; + [range(0,10000)] uint32 count; + [size_is(count)] drsuapi_DsReplicaObjectIdentifier2 *objects; + } drsuapi_DsAddEntryCtr2; + + typedef struct { + drsuapi_DsReplicaObjectIdentifier *id; + uint32 level; + [switch_is(level)] drsuapi_DsAddEntryError *error; + [range(0,10000)] uint32 count; + [size_is(count)] drsuapi_DsReplicaObjectIdentifier2 *objects; + } drsuapi_DsAddEntryCtr3; + + typedef [switch_type(int32)] union { + [case(2)] drsuapi_DsAddEntryCtr2 ctr2; + [case(3)] drsuapi_DsAddEntryCtr3 ctr3; + } drsuapi_DsAddEntryCtr; + + [public] WERROR drsuapi_DsAddEntry( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref,switch_is(level)] drsuapi_DsAddEntryRequest *req, + [out,ref] int32 *level_out, + [out,ref,switch_is(*level_out)] drsuapi_DsAddEntryCtr *ctr + ); + + /*****************/ + /* Function 0x12 */ + [todo] WERROR DRSUAPI_EXECUTE_KCC(); + + /*****************/ + /* Function 0x13 */ + typedef [v1_enum] enum { + DRSUAPI_DS_REPLICA_GET_INFO = 1, + DRSUAPI_DS_REPLICA_GET_INFO2 = 2 + } drsuapi_DsReplicaGetInfoLevel; + + typedef [v1_enum] enum { + DRSUAPI_DS_REPLICA_INFO_NEIGHBORS = 0, + DRSUAPI_DS_REPLICA_INFO_CURSORS = 1, + DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA = 2, + DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES = 3, + DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES = 4, + DRSUAPI_DS_REPLICA_INFO_PENDING_OPS = 5, + DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA = 6, + DRSUAPI_DS_REPLICA_INFO_CURSORS2 = 7, + DRSUAPI_DS_REPLICA_INFO_CURSORS3 = 8, + DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2 = 9, + DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2 = 10, + DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02 = -2, + DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04 = -4, + DRSUAPI_DS_REPLICA_INFO_CURSORS05 = -5, + DRSUAPI_DS_REPLICA_INFO_06 = -6 + } drsuapi_DsReplicaInfoType; + + typedef struct { + drsuapi_DsReplicaInfoType info_type; + [charset(UTF16),string] uint16 *object_dn; + GUID guid1; + } drsuapi_DsReplicaGetInfoRequest1; + + typedef struct { + drsuapi_DsReplicaInfoType info_type; + [charset(UTF16),string] uint16 *object_dn; + GUID guid1; + uint32 unknown1; + [charset(UTF16),string] uint16 *string1; + [charset(UTF16),string] uint16 *string2; + uint32 unknown2; + } drsuapi_DsReplicaGetInfoRequest2; + + typedef [switch_type(drsuapi_DsReplicaGetInfoLevel)] union { + [case(DRSUAPI_DS_REPLICA_GET_INFO)] drsuapi_DsReplicaGetInfoRequest1 req1; + [case(DRSUAPI_DS_REPLICA_GET_INFO2)] drsuapi_DsReplicaGetInfoRequest2 req2; + } drsuapi_DsReplicaGetInfoRequest; + + typedef struct { + [charset(UTF16),string] uint16 *naming_context_dn; + [charset(UTF16),string] uint16 *source_dsa_obj_dn; + [charset(UTF16),string] uint16 *source_dsa_address; + [charset(UTF16),string] uint16 *transport_obj_dn; + drsuapi_DsReplicaNeighbourFlags replica_flags; + uint32 reserved; + GUID naming_context_obj_guid; + GUID source_dsa_obj_guid; + GUID source_dsa_invocation_id; + GUID transport_obj_guid; + hyper tmp_highest_usn; + hyper highest_usn; + NTTIME last_success; + NTTIME last_attempt; + WERROR result_last_attempt; + uint32 consecutive_sync_failures; + } drsuapi_DsReplicaNeighbour; + + typedef struct { + uint32 count; + uint32 reserved; + [size_is(count)] drsuapi_DsReplicaNeighbour array[]; + } drsuapi_DsReplicaNeighbourCtr; + + typedef struct { + uint32 count; + uint32 reserved; + [size_is(count)] drsuapi_DsReplicaCursor array[]; + } drsuapi_DsReplicaCursorCtr; + + typedef struct { + [charset(UTF16),string] uint16 *attribute_name; + uint32 version; + NTTIME originating_change_time; + GUID originating_invocation_id; + hyper originating_usn; + hyper local_usn; + } drsuapi_DsReplicaObjMetaData; + + typedef struct { + uint32 count; + uint32 reserved; + [size_is(count)] drsuapi_DsReplicaObjMetaData array[]; + } drsuapi_DsReplicaObjMetaDataCtr; + + typedef struct { + [charset(UTF16),string] uint16 *dsa_obj_dn; + GUID dsa_obj_guid; + NTTIME first_failure; + uint32 num_failures; + WERROR last_result; + } drsuapi_DsReplicaKccDsaFailure; + + typedef struct { + uint32 count; + uint32 reserved; + [size_is(count)] drsuapi_DsReplicaKccDsaFailure array[]; + } drsuapi_DsReplicaKccDsaFailuresCtr; + + typedef enum { + DRSUAPI_DS_REPLICA_OP_TYPE_SYNC = 0, + DRSUAPI_DS_REPLICA_OP_TYPE_ADD = 1, + DRSUAPI_DS_REPLICA_OP_TYPE_DELETE = 2, + DRSUAPI_DS_REPLICA_OP_TYPE_MODIFY = 3, + DRSUAPI_DS_REPLICA_OP_TYPE_UPDATE_REFS = 4 + } drsuapi_DsReplicaOpType; + + typedef [switch_type(drsuapi_DsReplicaOpType)] union { + [case(DRSUAPI_DS_REPLICA_OP_TYPE_SYNC)] drsuapi_DsReplicaSyncOptions sync; + [case(DRSUAPI_DS_REPLICA_OP_TYPE_ADD)] drsuapi_DsReplicaAddOptions add; + [case(DRSUAPI_DS_REPLICA_OP_TYPE_DELETE)] drsuapi_DsReplicaDeleteOptions op_delete; + [case(DRSUAPI_DS_REPLICA_OP_TYPE_MODIFY)] drsuapi_DsReplicaModifyOptions modify; + [case(DRSUAPI_DS_REPLICA_OP_TYPE_UPDATE_REFS)] drsuapi_DsReplicaUpdateRefsOptions update_refs; + [default] uint32 unknown; + } drsuapi_DsRplicaOpOptions; + + typedef struct { + NTTIME operation_start; + uint32 serial_num; /* unique till reboot */ + uint32 priority; + drsuapi_DsReplicaOpType operation_type; + [switch_is(operation_type)] drsuapi_DsRplicaOpOptions options; + [charset(UTF16),string] uint16 *nc_dn; + [charset(UTF16),string] uint16 *remote_dsa_obj_dn; + [charset(UTF16),string] uint16 *remote_dsa_address; + GUID nc_obj_guid; + GUID remote_dsa_obj_guid; + } drsuapi_DsReplicaOp; + + typedef struct { + NTTIME time; + uint32 count; + [size_is(count)] drsuapi_DsReplicaOp array[]; + } drsuapi_DsReplicaOpCtr; + + typedef struct { + [charset(UTF16),string] uint16 *attribute_name; + [charset(UTF16),string] uint16 *object_dn; + [value(ndr_size_DATA_BLOB(0,binary,0))] uint32 __ndr_size_binary; + DATA_BLOB *binary; + NTTIME deleted; + NTTIME created; + uint32 version; + NTTIME originating_change_time; + GUID originating_invocation_id; + hyper originating_usn; + hyper local_usn; + } drsuapi_DsReplicaAttrValMetaData; + + typedef struct { + uint32 count; + int32 enumeration_context; + [size_is(count)] drsuapi_DsReplicaAttrValMetaData array[]; + } drsuapi_DsReplicaAttrValMetaDataCtr; + + typedef struct { + uint32 count; + int32 enumeration_context; + [size_is(count)] drsuapi_DsReplicaCursor2 array[]; + } drsuapi_DsReplicaCursor2Ctr; + + typedef struct { + GUID source_dsa_invocation_id; + hyper highest_usn; + NTTIME last_sync_success; + [charset(UTF16),string] uint16 *source_dsa_obj_dn; + } drsuapi_DsReplicaCursor3; + + typedef struct { + uint32 count; + int32 enumeration_context; + [size_is(count)] drsuapi_DsReplicaCursor3 array[]; + } drsuapi_DsReplicaCursor3Ctr; + + typedef struct { + [charset(UTF16),string] uint16 *attribute_name; + uint32 version; + NTTIME originating_change_time; + GUID originating_invocation_id; + hyper originating_usn; + hyper local_usn; + [charset(UTF16),string] uint16 *originating_dsa_dn; + } drsuapi_DsReplicaObjMetaData2; + + typedef struct { + uint32 count; + int32 enumeration_context; + [size_is(count)] drsuapi_DsReplicaObjMetaData2 array[]; + } drsuapi_DsReplicaObjMetaData2Ctr; + + typedef struct { + [charset(UTF16),string] uint16 *attribute_name; + [charset(UTF16),string] uint16 *object_dn; + [value(ndr_size_DATA_BLOB(0,binary,0))] uint32 __ndr_size_binary; + DATA_BLOB *binary; + NTTIME deleted; + NTTIME created; + uint32 version; + NTTIME originating_change_time; + GUID originating_invocation_id; + hyper originating_usn; + hyper local_usn; + [charset(UTF16),string] uint16 *originating_dsa_dn; + } drsuapi_DsReplicaAttrValMetaData2; + + typedef struct { + uint32 count; + int32 enumeration_context; + [size_is(count)] drsuapi_DsReplicaAttrValMetaData2 array[]; + } drsuapi_DsReplicaAttrValMetaData2Ctr; + + typedef struct { + hyper u1; /* session number? */ + uint32 u2; + uint32 u3; + GUID bind_guid; + NTTIME_1sec bind_time; + [flag(NDR_BIG_ENDIAN)] ipv4address client_ip_address; + uint32 u5; /* this is the same value the client used as pid in the DsBindInfoX struct */ + } drsuapi_DsReplicaConnection04; + + typedef struct { + [range(0,10000)] uint32 count; + uint32 reserved; + [size_is(count)] drsuapi_DsReplicaConnection04 array[]; + } drsuapi_DsReplicaConnection04Ctr; + + typedef struct { + [charset(UTF16),string] uint16 *str1; + uint32 u1; + uint32 u2; + uint32 u3; + uint32 u4; + uint32 u5; + hyper u6; + uint32 u7; + } drsuapi_DsReplica06; + + typedef struct { + [range(0,256)] uint32 count; + uint32 reserved; + [size_is(count)] drsuapi_DsReplica06 array[]; + } drsuapi_DsReplica06Ctr; + + typedef [switch_type(drsuapi_DsReplicaInfoType)] union { + [case(DRSUAPI_DS_REPLICA_INFO_NEIGHBORS)] drsuapi_DsReplicaNeighbourCtr *neighbours; + [case(DRSUAPI_DS_REPLICA_INFO_CURSORS)] drsuapi_DsReplicaCursorCtr *cursors; + [case(DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA)] drsuapi_DsReplicaObjMetaDataCtr *objmetadata; + [case(DRSUAPI_DS_REPLICA_INFO_KCC_DSA_CONNECT_FAILURES)] drsuapi_DsReplicaKccDsaFailuresCtr *connectfailures; + [case(DRSUAPI_DS_REPLICA_INFO_KCC_DSA_LINK_FAILURES)] drsuapi_DsReplicaKccDsaFailuresCtr *linkfailures; + [case(DRSUAPI_DS_REPLICA_INFO_PENDING_OPS)] drsuapi_DsReplicaOpCtr *pendingops; + [case(DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA)] drsuapi_DsReplicaAttrValMetaDataCtr *attrvalmetadata; + [case(DRSUAPI_DS_REPLICA_INFO_CURSORS2)] drsuapi_DsReplicaCursor2Ctr *cursors2; + [case(DRSUAPI_DS_REPLICA_INFO_CURSORS3)] drsuapi_DsReplicaCursor3Ctr *cursors3; + [case(DRSUAPI_DS_REPLICA_INFO_OBJ_METADATA2)] drsuapi_DsReplicaObjMetaData2Ctr *objmetadata2; + [case(DRSUAPI_DS_REPLICA_INFO_ATTRIBUTE_VALUE_METADATA2)] drsuapi_DsReplicaAttrValMetaData2Ctr *attrvalmetadata2; + [case(DRSUAPI_DS_REPLICA_INFO_NEIGHBORS02)] drsuapi_DsReplicaNeighbourCtr *neighbours02; + [case(DRSUAPI_DS_REPLICA_INFO_CONNECTIONS04)] drsuapi_DsReplicaConnection04Ctr *connections04; + [case(DRSUAPI_DS_REPLICA_INFO_CURSORS05)] drsuapi_DsReplicaCursorCtrEx *cursors05; + [case(DRSUAPI_DS_REPLICA_INFO_06)] drsuapi_DsReplica06Ctr *i06; + } drsuapi_DsReplicaInfo; + + WERROR drsuapi_DsReplicaGetInfo( + [in] policy_handle *bind_handle, + [in] drsuapi_DsReplicaGetInfoLevel level, + [in,ref,switch_is(level)] drsuapi_DsReplicaGetInfoRequest *req, + [out,ref] drsuapi_DsReplicaInfoType *info_type, + [out,ref,switch_is(*info_type)] drsuapi_DsReplicaInfo *info + ); + + /*****************/ + /* Function 0x14 */ + [todo] WERROR DRSUAPI_ADD_SID_HISTORY(); + + /*****************/ + /* Function 0x15 */ + + typedef struct { + [range(0,10000)] uint32 num_entries; + [size_is(num_entries)] drsuapi_DsGetMembershipsCtr1 **ctrl_array; + } drsuapi_DsGetMemberships2Ctr1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsGetMembershipsCtr1 ctr1; + } drsuapi_DsGetMemberships2Ctr; + + typedef struct { + [range(1,10000)] uint32 num_req; + [size_is(num_req)] drsuapi_DsGetMembershipsRequest1 **req_array; + } drsuapi_DsGetMemberships2Request1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_DsGetMemberships2Request1 req1; + } drsuapi_DsGetMemberships2Request; + + WERROR drsuapi_DsGetMemberships2( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref] [switch_is(level)] drsuapi_DsGetMemberships2Request *req, + [out,ref] int32 *level_out, + [out,ref] [switch_is(*level_out)] drsuapi_DsGetMemberships2Ctr *ctr + ); + + /*****************/ + /* Function 0x16 */ + [todo] WERROR DRSUAPI_REPLICA_VERIFY_OBJECTS(); + + /*****************/ + /* Function 0x17 */ + [todo] WERROR DRSUAPI_GET_OBJECT_EXISTENCE(); + + /*****************/ + /* Function 0x18 */ + typedef struct { + WERROR error_code; + uint32 site_cost; + } drsuapi_DsSiteCostInfo; + + typedef struct { + [range(0,10000)] uint32 num_info; + [size_is(num_info)] drsuapi_DsSiteCostInfo *info; + uint32 unknown; + } drsuapi_QuerySitesByCostCtr1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_QuerySitesByCostCtr1 ctr1; + } drsuapi_QuerySitesByCostCtr; + + typedef struct { + [charset(UTF16),string] uint16 *site_from; + [range(1,10000)] uint32 num_req; + [size_is(num_req)] [charset(UTF16),string] uint16 **site_to; + uint32 flags; + } drsuapi_QuerySitesByCostRequest1; + + typedef [switch_type(int32)] union { + [case(1)] drsuapi_QuerySitesByCostRequest1 req1; + } drsuapi_QuerySitesByCostRequest; + + WERROR drsuapi_QuerySitesByCost( + [in] policy_handle *bind_handle, + [in] int32 level, + [in,ref] [switch_is(level)] drsuapi_QuerySitesByCostRequest *req, + [out,ref] int32 *level_out, + [out,ref] [switch_is(*level_out)] drsuapi_QuerySitesByCostCtr *ctr + ); +} diff --git a/librpc/idl/dsbackup.idl b/librpc/idl/dsbackup.idl new file mode 100644 index 0000000000..72e8bf9c2b --- /dev/null +++ b/librpc/idl/dsbackup.idl @@ -0,0 +1,34 @@ +[ + uuid("ecec0d70-a603-11d0-96b1-00a0c91ece30"), + version(1.0), + pointer_default(unique), + helpstring("Backup support for Active Directory") +] interface ad_backup +{ + [todo] void HrRBackupPrepare(); + [todo] void HrRBackupEnd(); + [todo] void HrRBackupGetAttachmentInformation(); + [todo] void HrRBackupOpenFile(); + [todo] void HrRBackupRead(); + [todo] void HrRBackupClose(); + [todo] void HrRBackupGetBackupLogs(); + [todo] void HrRBackupTruncateLogs(); + [todo] void HrRBackupPing(); +} + +[ + uuid("16e0cf3a-a604-11d0-96b1-00a0c91ece30"), + version(1.0), + pointer_default(unique), + helpstring("Restoring Active Directory backups") +] interface ad_restore +{ + [todo] void HrRIsNTDSOnline(); + [todo] void HrRRestorePrepare(); + [todo] void HrRRestoreRegister(); + [todo] void HrRRestoreRegisterComplete(); + [todo] void HrRRestoreGetDatabaseLocations(); + [todo] void HrRRestoreEnd(); + [todo] void HrRRestoreSetCurrentLogNumber(); + [todo] void HrRRestoreCheckLogsForBackup(); +} diff --git a/librpc/idl/dssetup.idl b/librpc/idl/dssetup.idl new file mode 100644 index 0000000000..14de9f7633 --- /dev/null +++ b/librpc/idl/dssetup.idl @@ -0,0 +1,101 @@ +/* + dssetup interface definition +*/ + +import "misc.idl"; + +[ + uuid("3919286a-b10c-11d0-9ba8-00c04fd92ef5"), + version(0.0), + endpoint("ncacn_np:[\\pipe\\lsarpc]", "ncacn_np:[\\pipe\\lsass]", "ncacn_ip_tcp:", "ncalrpc:"), + pointer_default(unique), + helpstring("Active Directory Setup") +] interface dssetup +{ + /**********************************************/ + /* Function 0x00 */ + + typedef enum { + DS_ROLE_STANDALONE_WORKSTATION = 0, + DS_ROLE_MEMBER_WORKSTATION = 1, + DS_ROLE_STANDALONE_SERVER = 2, + DS_ROLE_MEMBER_SERVER = 3, + DS_ROLE_BACKUP_DC = 4, + DS_ROLE_PRIMARY_DC = 5 + } dssetup_DsRole; + + typedef [bitmap32bit] bitmap { + DS_ROLE_PRIMARY_DS_RUNNING = 0x00000001, + DS_ROLE_PRIMARY_DS_MIXED_MODE = 0x00000002, + DS_ROLE_UPGRADE_IN_PROGRESS = 0x00000004, + DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT = 0x01000000 + } dssetup_DsRoleFlags; + + typedef struct { + dssetup_DsRole role; + dssetup_DsRoleFlags flags; + [charset(UTF16),string] uint16 *domain; + [charset(UTF16),string] uint16 *dns_domain; + [charset(UTF16),string] uint16 *forest; + GUID domain_guid; + } dssetup_DsRolePrimaryDomInfoBasic; + + typedef [v1_enum] enum { + DS_ROLE_NOT_UPGRADING = 0, + DS_ROLE_UPGRADING = 1 + } dssetup_DsUpgrade; + + typedef enum { + DS_ROLE_PREVIOUS_UNKNOWN = 0, + DS_ROLE_PREVIOUS_PRIMARY = 1, + DS_ROLE_PREVIOUS_BACKUP = 2 + } dssetup_DsPrevious; + + typedef struct { + dssetup_DsUpgrade upgrading; + dssetup_DsPrevious previous_role; + } dssetup_DsRoleUpgradeStatus; + + typedef enum { + DS_ROLE_OP_IDLE = 0, + DS_ROLE_OP_ACTIVE = 1, + DS_ROLE_OP_NEEDS_REBOOT = 2 + } dssetup_DsRoleOp; + + typedef struct { + dssetup_DsRoleOp status; + } dssetup_DsRoleOpStatus; + + typedef enum { + DS_ROLE_BASIC_INFORMATION = 1, + DS_ROLE_UPGRADE_STATUS = 2, + DS_ROLE_OP_STATUS = 3 + } dssetup_DsRoleInfoLevel; + + typedef [switch_type(dssetup_DsRoleInfoLevel)] union { + [case(DS_ROLE_BASIC_INFORMATION)] dssetup_DsRolePrimaryDomInfoBasic basic; + [case(DS_ROLE_UPGRADE_STATUS)] dssetup_DsRoleUpgradeStatus upgrade; + [case(DS_ROLE_OP_STATUS)] dssetup_DsRoleOpStatus opstatus; + } dssetup_DsRoleInfo; + + WERROR dssetup_DsRoleGetPrimaryDomainInformation( + [in] dssetup_DsRoleInfoLevel level, + [out,switch_is(level),unique] dssetup_DsRoleInfo *info + ); + + /* + w2k3 has removed all the calls below from their implementation. + These stubs are left here only as a way of documenting the names + of the calls in case they ever turn up on the wire. + */ + [todo] WERROR dssetup_DsRoleDnsNameToFlatName(); + [todo] WERROR dssetup_DsRoleDcAsDc(); + [todo] WERROR dssetup_DsRoleDcAsReplica(); + [todo] WERROR dssetup_DsRoleDemoteDc(); + [todo] WERROR dssetup_DsRoleGetDcOperationProgress(); + [todo] WERROR dssetup_DsRoleGetDcOperationResults(); + [todo] WERROR dssetup_DsRoleCancel(); + [todo] WERROR dssetup_DsRoleServerSaveStateForUpgrade(); + [todo] WERROR dssetup_DsRoleUpgradeDownlevelServer(); + [todo] WERROR dssetup_DsRoleAbortDownlevelServerUpgrade(); +} diff --git a/librpc/idl/echo.idl b/librpc/idl/echo.idl new file mode 100644 index 0000000000..bf1e318674 --- /dev/null +++ b/librpc/idl/echo.idl @@ -0,0 +1,127 @@ + +[ + uuid("60a15ec5-4de8-11d7-a637-005056a20182"), + endpoint("ncacn_np:[\\pipe\\rpcecho]", "ncacn_ip_tcp:", "ncalrpc:"), + pointer_default(unique), + version(1.0), + helpstring("Simple echo pipe") +] +interface rpcecho +{ + /* Add one to an integer */ + void echo_AddOne( + [in] uint32 in_data, + [out] uint32 *out_data + ); + /* 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,size_is(len)] uint8 data[] + ); + /* Source data from server */ + void echo_SourceData( + [in] uint32 len, + [out,size_is(len)] uint8 data[] + ); + + /* test strings */ + void echo_TestCall ( + [in,string,charset(UTF16)] uint16 *s1, + [out,string,charset(UTF16)] uint16 **s2 + ); + + + /* test some alignment issues */ + typedef [public] struct { + uint8 v; + } echo_info1; + + typedef struct { + uint16 v; + } echo_info2; + + typedef struct { + uint32 v; + } echo_info3; + + struct echo_info4 { + hyper v; + }; + + typedef struct { + uint8 v1; + hyper v2; + } echo_info5; + + typedef struct { + uint8 v1; + echo_info1 info1; + } echo_info6; + + typedef struct { + uint8 v1; + struct echo_info4 info4; + } echo_info7; + + typedef [switch_type(uint16)] union { + [case(1)] echo_info1 info1; + [case(2)] echo_info2 info2; + [case(3)] echo_info3 info3; + [case(4)] struct 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 + ); + + uint32 echo_TestSleep( + [in] uint32 seconds + ); + + typedef enum { + ECHO_ENUM1 = 1, + ECHO_ENUM2 = 2 + } echo_Enum1; + + typedef [v1_enum] enum { + ECHO_ENUM1_32 = 1, + ECHO_ENUM2_32 = 2 + } echo_Enum1_32; + + typedef struct { + echo_Enum1 e1; + echo_Enum1_32 e2; + } echo_Enum2; + + typedef [switch_type(uint16)] union { + [case(ECHO_ENUM1)] echo_Enum1 e1; + [case(ECHO_ENUM2)] echo_Enum2 e2; + } echo_Enum3; + + void echo_TestEnum( + [in,out,ref] echo_Enum1 *foo1, + [in,out,ref] echo_Enum2 *foo2, + [in,out,ref,switch_is(*foo1)] echo_Enum3 *foo3 + ); + + typedef struct { + uint32 x; + [size_is(x)] uint16 surrounding[*]; + } echo_Surrounding; + + void echo_TestSurrounding( + [in,out,ref] echo_Surrounding *data + ); + + uint16 echo_TestDoublePointer([in] uint16 ***data); +} diff --git a/librpc/idl/efs.idl b/librpc/idl/efs.idl new file mode 100644 index 0000000000..4279b08d13 --- /dev/null +++ b/librpc/idl/efs.idl @@ -0,0 +1,108 @@ +/* + IDL definitions from original packet-dcerpc-efs.c + by Jean-Baptiste Marchand +*/ + +import "security.idl"; + +[ + uuid("c681d488-d850-11d0-8c52-00c04fd90f7e"), + version(1.0), + pointer_default(unique) +] interface efs +{ + +WERROR EfsRpcOpenFileRaw( + [out,ref] policy_handle *pvContext, + [in] [charset(UTF16),string] uint16 FileName[], + [in] uint32 Flags + ); + +[todo] WERROR EfsRpcReadFileRaw( + [in,ref] policy_handle *pvContext +/* incomplete */ +); + + +[todo] WERROR EfsRpcWriteFileRaw( + [in,ref] policy_handle *pvContext +/* incomplete */ +); + +void EfsRpcCloseRaw( + [in,out,ref] policy_handle *pvContext +); + +WERROR EfsRpcEncryptFileSrv( + [in] [charset(UTF16),string] uint16 Filename[] +); + +WERROR EfsRpcDecryptFileSrv( + [in] [charset(UTF16),string] uint16 FileName[], + [in] uint32 Reserved +); + +typedef struct { + uint32 cbData; + [size_is(cbData), unique] uint8 *pbData; +} EFS_HASH_BLOB; + +typedef struct { + uint32 cbTotalLength; + [unique] dom_sid *pUserSid; + [unique] EFS_HASH_BLOB *pHash; + [unique] [charset(UTF16),string] uint16 *lpDisplayInformation; +} ENCRYPTION_CERTIFICATE_HASH; + +typedef struct { + uint32 nCert_Hash; + /* this is a pointer to an array of pointers */ + [size_is(nCert_Hash)] ENCRYPTION_CERTIFICATE_HASH *pUsers[*]; +} ENCRYPTION_CERTIFICATE_HASH_LIST; + +WERROR EfsRpcQueryUsersOnFile( + [in] [charset(UTF16),string] uint16 FileName[], + [out,ref,unique] ENCRYPTION_CERTIFICATE_HASH_LIST **pUsers +); + +WERROR EfsRpcQueryRecoveryAgents( + [in] [charset(UTF16),string] uint16 FileName[], + [out,ref,unique] ENCRYPTION_CERTIFICATE_HASH_LIST **pRecoveryAgents +); + +[todo] WERROR EfsRpcRemoveUsersFromFile( + [in] [charset(UTF16),string] uint16 FileName[] + /* [in] ENCRYPTION_CERTIFICATE_LIST Hashes*/ +); + +[todo] WERROR EfsRpcAddUsersToFile( + [in] [charset(UTF16),string] uint16 FileName[] + /* [in] ENCRYPTION_CERTIFICATE_LIST Hashes*/ +); + +typedef struct { + uint32 dwCertEncodingType; + uint32 cbData; + [size_is(cbData)] [unique] uint8 *pbData; +} EFS_CERTIFICATE_BLOB; + +typedef struct { + uint32 TotalLength; + [unique] dom_sid *pUserSid; + [unique] EFS_CERTIFICATE_BLOB *pCertBlob; +} ENCRYPTION_CERTIFICATE; + +WERROR EfsRpcSetFileEncryptionKey( + [in] [unique] ENCRYPTION_CERTIFICATE *pEncryptionCertificate +); + +[todo] WERROR EfsRpcNotSupported( +); + +[todo] WERROR EfsRpcFileKeyInfo( +); + +[todo] WERROR EfsRpcDuplicateEncryptionInfoFile( +); + +} diff --git a/librpc/idl/epmapper.idl b/librpc/idl/epmapper.idl new file mode 100644 index 0000000000..ea04878094 --- /dev/null +++ b/librpc/idl/epmapper.idl @@ -0,0 +1,314 @@ +#include "idl_types.h" + +/* + endpoint mapper interface + Related links: + http://www.opengroup.org/onlinepubs/9629399/apdxo.htm : The official IDL for this pipe + http://www.opengroup.org/onlinepubs/9629399/apdxl.htm : Details on towers +http://www.opengroup.org/onlinepubs/9629399/chap6.htm#tagcjh_11_02_03_01: binding strings + +*/ + +import "misc.idl"; + +[ + uuid("e1af8308-5d1f-11c9-91a4-08002b14a0fa"), + version(3.0), + endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]", + "ncalrpc:[EPMAPPER]"), + helpstring("EndPoint Mapper"), + pointer_default(ptr) +] +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; + const int EPMAPPER_STATUS_NO_MEMORY = 0x16C9A012; + const int EPMAPPER_STATUS_OK = 0; + + + + typedef [enum8bit] enum { + + /* Level 4 and higher */ + EPM_PROTOCOL_DNET_NSP = 0x04, + EPM_PROTOCOL_OSI_TP4 = 0x05, + EPM_PROTOCOL_OSI_CLNS = 0x06, + EPM_PROTOCOL_TCP = 0x07, + EPM_PROTOCOL_UDP = 0x08, + EPM_PROTOCOL_IP = 0x09, + /* These 4 are protocol identifiers, always at level 3 or lower */ + EPM_PROTOCOL_NCADG = 0x0a, /* Connectionless RPC */ + EPM_PROTOCOL_NCACN = 0x0b, + EPM_PROTOCOL_NCALRPC = 0x0c, /* Local RPC */ + EPM_PROTOCOL_UUID = 0x0d, + EPM_PROTOCOL_IPX = 0x0e, + EPM_PROTOCOL_SMB = 0x0f, + EPM_PROTOCOL_PIPE = 0x10, + EPM_PROTOCOL_NETBIOS = 0x11, + EPM_PROTOCOL_NETBEUI = 0x12, + EPM_PROTOCOL_SPX = 0x13, + EPM_PROTOCOL_NB_IPX = 0x14, /* NetBIOS over IPX */ + EPM_PROTOCOL_DSP = 0x16, /* AppleTalk Data Stream Protocol */ + EPM_PROTOCOL_DDP = 0x17, /* AppleTalk Data Datagram Protocol */ + EPM_PROTOCOL_APPLETALK = 0x18, /* AppleTalk */ + EPM_PROTOCOL_VINES_SPP = 0x1a, + EPM_PROTOCOL_VINES_IPC = 0x1b, /* Inter Process Communication */ + EPM_PROTOCOL_STREETTALK = 0x1c, /* Vines Streettalk */ + EPM_PROTOCOL_HTTP = 0x1f, + EPM_PROTOCOL_UNIX_DS = 0x20, /* Unix domain socket */ + EPM_PROTOCOL_NULL = 0x21 + } epm_protocol; + + typedef struct { + /*FIXME */ + } epm_rhs_dnet_nsp; + + typedef struct { + /*FIXME*/ + } epm_rhs_osi_tp4; + + typedef struct { + /*FIXME*/ + } epm_rhs_osi_clns; + + typedef struct { + uint16 port; + } epm_rhs_udp; + + typedef struct { + uint16 port; + } epm_rhs_tcp; + + typedef struct { + ipv4address ipaddr; + } epm_rhs_ip; + + typedef struct { + uint16 minor_version; + } epm_rhs_ncadg; + + typedef struct { + uint16 minor_version; + } epm_rhs_ncacn; + + typedef struct { + [flag(NDR_REMAINING)] DATA_BLOB unknown; + } epm_rhs_uuid; + + typedef struct { + /*FIXME */ + } epm_rhs_ipx; + + typedef struct { + astring unc; + } epm_rhs_smb; + + typedef struct { + astring path; + } epm_rhs_pipe; + + typedef struct { + astring name; + } epm_rhs_netbios; + + typedef struct { + } epm_rhs_netbeui; + + typedef struct { + } epm_rhs_spx; + + typedef struct { + } epm_rhs_nb_ipx; + + typedef struct { + uint16 port; + } epm_rhs_http; + + typedef struct { + astring path; + } epm_rhs_unix_ds; + + typedef struct { + } epm_rhs_null; + + typedef struct { + uint16 minor_version; + } epm_rhs_ncalrpc; + + typedef struct { + } epm_rhs_appletalk; + + typedef struct { + } epm_rhs_atalk_stream; + + typedef struct { + } epm_rhs_atalk_datagram; + + typedef struct { + uint16 port; + } epm_rhs_vines_spp; + + typedef struct { + uint16 port; + } epm_rhs_vines_ipc; + + typedef struct { + astring streettalk; + } epm_rhs_streettalk; + + typedef [flag(NDR_BIG_ENDIAN),nodiscriminant] union { + [case(EPM_PROTOCOL_DNET_NSP)] epm_rhs_dnet_nsp dnet_nsp; + [case(EPM_PROTOCOL_OSI_TP4)] epm_rhs_osi_tp4 osi_tp4; + [case(EPM_PROTOCOL_OSI_CLNS)] epm_rhs_osi_clns osi_clns; + [case(EPM_PROTOCOL_TCP)] epm_rhs_tcp tcp; + [case(EPM_PROTOCOL_UDP)] epm_rhs_udp udp; + [case(EPM_PROTOCOL_IP)] epm_rhs_ip ip; + [case(EPM_PROTOCOL_NCADG)] epm_rhs_ncadg ncadg; + [case(EPM_PROTOCOL_NCACN)] epm_rhs_ncacn ncacn; + [case(EPM_PROTOCOL_NCALRPC)] epm_rhs_ncalrpc ncalrpc; + [case(EPM_PROTOCOL_UUID)] epm_rhs_uuid uuid; + [case(EPM_PROTOCOL_IPX)] epm_rhs_ipx ipx; + [case(EPM_PROTOCOL_SMB)] epm_rhs_smb smb; + [case(EPM_PROTOCOL_PIPE)] epm_rhs_pipe pipe; + [case(EPM_PROTOCOL_NETBIOS)] epm_rhs_netbios netbios; + [case(EPM_PROTOCOL_NETBEUI)] epm_rhs_netbeui netbeui; + [case(EPM_PROTOCOL_SPX)] epm_rhs_spx spx; + [case(EPM_PROTOCOL_NB_IPX)] epm_rhs_nb_ipx nb_ipx; + [case(EPM_PROTOCOL_DSP)] epm_rhs_atalk_stream atalk_stream; + [case(EPM_PROTOCOL_DDP)] epm_rhs_atalk_datagram atalk_datagram; + [case(EPM_PROTOCOL_APPLETALK)] epm_rhs_appletalk appletalk; + [case(EPM_PROTOCOL_VINES_SPP)] epm_rhs_vines_spp vines_spp; + [case(EPM_PROTOCOL_VINES_IPC)] epm_rhs_vines_ipc vines_ipc; + [case(EPM_PROTOCOL_STREETTALK)] epm_rhs_streettalk streettalk; + [case(EPM_PROTOCOL_HTTP)] epm_rhs_http http; + [case(EPM_PROTOCOL_UNIX_DS)] epm_rhs_unix_ds unix_ds; + [case(EPM_PROTOCOL_NULL)] epm_rhs_null null; + [default] [flag(NDR_REMAINING)] DATA_BLOB unknown; + } epm_rhs; + + typedef struct { + epm_protocol protocol; + [flag(NDR_REMAINING)] DATA_BLOB lhs_data; + } epm_lhs; + + typedef struct { + [subcontext(2)] epm_lhs lhs; + [subcontext(2),switch_is(lhs.protocol)] 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 [gensize,flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN)] struct { + uint16 num_floors; + epm_floor floors[num_floors]; + } epm_tower; + + typedef struct { + [value(ndr_size_epm_tower(&tower, ndr->flags))] uint32 tower_length; + [subcontext(4)] epm_tower tower; + } epm_twr_t; + + typedef struct { + GUID object; + epm_twr_t *tower; + /* + * In theory this should be: + * [charset(DOS),string] uint8 annotation[64] + * But midl treats this as: + * [charset(DOS),string] uint8 annotation[] + * and pidl doesn't support this yet + */ + [value(0)] uint32 __annotation_offset; + [value(strlen(annotation)+1)] uint32 __annotation_length; + [charset(DOS)] uint8 annotation[__annotation_length]; + } epm_entry_t; + + typedef struct { + GUID uuid; + uint16 vers_major; + uint16 vers_minor; + } rpc_if_id_t; + + /**********************/ + /* Function 0x0 */ + error_status_t epm_Insert( + [in] uint32 num_ents, + [in,size_is(num_ents)] epm_entry_t entries[], + [in] uint32 replace + ); + + /**********************/ + /* Function 0x1 */ + error_status_t epm_Delete( + [in] uint32 num_ents, + [in, size_is(num_ents)] epm_entry_t entries[] + ); + + /**********************/ + /* Function 0x02 */ + error_status_t epm_Lookup( + [in] uint32 inquiry_type, + [in,ptr] GUID *object, + [in,ptr] rpc_if_id_t *interface_id, + [in] uint32 vers_option, + [in,out] 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[] + ); + + + /**********************/ + /* Function 0x03 */ + + typedef struct { + epm_twr_t *twr; + } epm_twr_p_t; + + [public] error_status_t epm_Map( + [in,ptr] GUID *object, + [in,ptr] epm_twr_t *map_tower, + [in,out] policy_handle *entry_handle, + [in] uint32 max_towers, + [out] uint32 *num_towers, + [out, length_is(*num_towers), size_is(max_towers)] epm_twr_p_t towers[] + ); + + + /**********************/ + /* Function 0x04 */ + error_status_t epm_LookupHandleFree( + [in,out] policy_handle *entry_handle + ); + + /**********************/ + /* Function 0x05 */ + error_status_t epm_InqObject( + [in] GUID *epm_object + ); + + + /**********************/ + /* Function 0x06 */ + error_status_t epm_MgmtDelete( + [in] uint32 object_speced, + [in,ptr] GUID *object, + [in,ptr] epm_twr_t *tower + ); + + /**********************/ + /* Function 0x07 */ + [todo] error_status_t epm_MapAuth(); +} diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl new file mode 100644 index 0000000000..ce25dd65ff --- /dev/null +++ b/librpc/idl/eventlog.idl @@ -0,0 +1,181 @@ +#include "idl_types.h" + +/* + eventlog interface definition +*/ + +import "lsa.idl", "security.idl"; + +[ uuid("82273fdc-e32a-18c3-3f78-827929dc23ea"), + version(0.0), + helpstring("Event Logger") +] interface eventlog +{ + typedef bitmap { + EVENTLOG_SEQUENTIAL_READ = 0x0001, + EVENTLOG_SEEK_READ = 0x0002, + EVENTLOG_FORWARDS_READ = 0x0004, + EVENTLOG_BACKWARDS_READ = 0x0008 + } eventlogReadFlags; + + typedef bitmap { + EVENTLOG_SUCCESS = 0x0000, + EVENTLOG_ERROR_TYPE = 0x0001, + EVENTLOG_WARNING_TYPE = 0x0002, + EVENTLOG_INFORMATION_TYPE = 0x0004, + EVENTLOG_AUDIT_SUCCESS = 0x0008, + EVENTLOG_AUDIT_FAILURE = 0x0010 + } eventlogEventTypes; + + typedef struct { + uint16 unknown0; + uint16 unknown1; + } eventlog_OpenUnknown0; + + typedef [public] struct { + uint32 size; + uint32 reserved; + uint32 record_number; + uint32 time_generated; + uint32 time_written; + uint32 event_id; + uint16 event_type; + uint16 num_of_strings; + uint16 event_category; + uint16 reserved_flags; + uint32 closing_record_number; + uint32 stringoffset; + uint32 sid_length; + uint32 sid_offset; + uint32 data_length; + uint32 data_offset; + nstring source_name; + nstring computer_name; + nstring strings[num_of_strings]; + astring raw_data; + } eventlog_Record; + + /******************/ + /* Function: 0x00 */ + NTSTATUS eventlog_ClearEventLogW( + [in] policy_handle *handle, + [in,unique] lsa_String *backupfile + ); + + /******************/ + /* Function: 0x01 */ + [todo] NTSTATUS eventlog_BackupEventLogW(); + + /******************/ + /* Function: 0x02 */ + NTSTATUS eventlog_CloseEventLog( + [in,out] policy_handle *handle + ); + + /******************/ + /* Function: 0x03 */ + [todo] NTSTATUS eventlog_DeregisterEventSource(); + + /******************/ + /* Function: 0x04 */ + NTSTATUS eventlog_GetNumRecords( + [in] policy_handle *handle, + [out] uint32 *number + ); + + /******************/ + /* Function: 0x05 */ + NTSTATUS eventlog_GetOldestRecord( + [in] policy_handle *handle, + [out,ref] uint32 *oldest_entry + ); + + /******************/ + /* Function: 0x06 */ + [todo] NTSTATUS eventlog_ChangeNotify(); + + /******************/ + /* Function: 0x07 */ + NTSTATUS eventlog_OpenEventLogW( + [in,unique] eventlog_OpenUnknown0 *unknown0, + [in,ref] lsa_String *logname, + [in,ref] lsa_String *servername, + [in] uint32 unknown2, + [in] uint32 unknown3, + [out] policy_handle *handle + ); + + /******************/ + /* Function: 0x08 */ + [todo] NTSTATUS eventlog_RegisterEventSourceW(); + + /******************/ + /* Function: 0x09 */ + [todo] NTSTATUS eventlog_OpenBackupEventLogW(); + + /******************/ + /* Function: 0x0a */ + NTSTATUS eventlog_ReadEventLogW( + [in] policy_handle *handle, + [in] uint32 flags, + [in] uint32 offset, + [in] [range(0,0x7FFFF)] uint32 number_of_bytes, + [out,ref,size_is(number_of_bytes)] uint8 *data, + [out,ref] uint32 *sent_size, + [out,ref] uint32 *real_size + ); + + /*****************/ + /* Function 0x0b */ + [todo] NTSTATUS eventlog_ReportEventW(); + + /*****************/ + /* Function 0x0c */ + [todo] NTSTATUS eventlog_ClearEventLogA(); + + /******************/ + /* Function: 0x0d */ + [todo] NTSTATUS eventlog_BackupEventLogA(); + + /*****************/ + /* Function 0x0e */ + [todo] NTSTATUS eventlog_OpenEventLogA(); + + /*****************/ + /* Function 0x0f */ + [todo] NTSTATUS eventlog_RegisterEventSourceA(); + + /*****************/ + /* Function 0x10 */ + [todo] NTSTATUS eventlog_OpenBackupEventLogA(); + + /*****************/ + /* Function 0x11 */ + [todo] NTSTATUS eventlog_ReadEventLogA(); + + /*****************/ + /* Function 0x12 */ + [todo] NTSTATUS eventlog_ReportEventA(); + + /*****************/ + /* Function 0x13 */ + [todo] NTSTATUS eventlog_RegisterClusterSvc(); + + /*****************/ + /* Function 0x14 */ + [todo] NTSTATUS eventlog_DeregisterClusterSvc(); + + /*****************/ + /* Function 0x15 */ + [todo] NTSTATUS eventlog_WriteClusterEvents(); + + /*****************/ + /* Function 0x16 */ + [todo] NTSTATUS eventlog_GetLogIntormation(); + + /*****************/ + /* Function 0x17 */ + NTSTATUS eventlog_FlushEventLog( + [in] policy_handle *handle + ); +} diff --git a/librpc/idl/frsapi.idl b/librpc/idl/frsapi.idl new file mode 100644 index 0000000000..11593f479a --- /dev/null +++ b/librpc/idl/frsapi.idl @@ -0,0 +1,121 @@ +#include "idl_types.h" + +import "misc.idl"; + +[ + uuid("d049b186-814f-11d1-9a3c-00c04fc9b232"), + version(1.1), + endpoint("ncacn_ip_tcp:", "ncalrpc:"), + helpstring("File Replication API"), + pointer_default(unique) +] +interface frsapi +{ + /****************/ + /* Function 0x00 */ + [todo] void FRSAPI_VERIFY_PROMOTION(); + + /****************/ + /* Function 0x01 */ + [todo] void FRSAPI_PROMOTION_STATUS(); + + /****************/ + /* Function 0x02 */ + [todo] void FRSAPI_START_DEMOTION(); + + /****************/ + /* Function 0x03 */ + [todo] void FRSAPI_COMMIT_DEMOTION(); + + /****************/ + /* Function 0x04 */ + + /* The DsPollingLongInterval and DsPollingShortInterval attributes + represent registry attributes below HKLM\System\CCS\Services\NtFrs */ + + WERROR frsapi_SetDsPollingIntervalW( + [in] uint32 CurrentInterval, + [in] uint32 DsPollingLongInterval, + [in] uint32 DsPollingShortInterval + ); + + /****************/ + /* Function 0x05 */ + WERROR frsapi_GetDsPollingIntervalW( + [out] uint32 *CurrentInterval, + [out] uint32 *DsPollingLongInterval, + [out] uint32 *DsPollingShortInterval + ); + + /****************/ + /* Function 0x06 */ + [todo] void FRSAPI_VERIFY_PROMOTION_W(); + + /****************/ + /* Function 0x07 */ + typedef [v1_enum] enum { + FRSAPI_INFO_VERSION = 0, + FRSAPI_INFO_SETS = 1, + FRSAPI_INFO_DS = 2, + FRSAPI_INFO_MEMORY = 3, + FRSAPI_INFO_IDTABLE = 4, + FRSAPI_INFO_OUTLOG = 5, + FRSAPI_INFO_INLOG = 6, + FRSAPI_INFO_THREADS = 7, + FRSAPI_INFO_STAGE = 8, + FRSAPI_INFO_CONFIGTABLE = 9 + } frsapi_InfoEnum; + + typedef struct { + uint32 length; + GUID guid; + uint32 length2; + uint32 unknown1; + frsapi_InfoEnum level; + uint32 query_counter; + uint32 unknown2; + uint32 offset; + uint32 blob_len; + /* [size_is(length-offset)] uint8 *data; */ + [subcontext_size(length-offset),subcontext(0),flag(NDR_REMAINING)] DATA_BLOB blob; + } frsapi_Info; + + WERROR frsapi_InfoW( + [in] [range(0,0x10000)] uint32 length, + /* [in,out] [size_is(length)] [unique] uint8 *data */ + [in,out,unique] frsapi_Info *info + + ); + + /****************/ + /* Function 0x08 */ + typedef [v1_enum] enum { + FRSAPI_REPLICA_SET_TYPE_0 = 0x00000000, + FRSAPI_REPLICA_SET_TYPE_DOMAIN = 0x00000002, + FRSAPI_REPLICA_SET_TYPE_DFS = 0x00000003 + } frsapi_ReplicaSetType; + + WERROR frsapi_IsPathReplicated( + [in,unique] [string,charset(UTF16)] uint16 *path, + [in] frsapi_ReplicaSetType replica_set_type, + [out] uint32 *unknown1, + [out] uint32 *unknown2, + [out] uint32 *unknown3, + [out] GUID *replica_set_guid + ); + + /****************/ + /* Function 0x09 */ + [todo] void FRSAPI_WRITER_COMMAND(); + + /****************/ + /* Function 0x0a */ + /* not supported before w2k3 sp2 */ + WERROR frsapi_ForceReplication( + [in,unique] GUID *guid1, + [in,unique] GUID *guid2, + [in,unique] [charset(UTF16),string] uint16 *replica_set, + [in,unique] [charset(UTF16),string] uint16 *partner_name + ); + +} diff --git a/librpc/idl/frsrpc.idl b/librpc/idl/frsrpc.idl new file mode 100644 index 0000000000..1019a25b28 --- /dev/null +++ b/librpc/idl/frsrpc.idl @@ -0,0 +1,168 @@ +#include "idl_types.h" + +import "misc.idl"; + +[ + uuid("f5cc59b4-4264-101a-8c59-08002b2f8426"), + version(1.1), + endpoint("ncacn_ip_tcp:", "ncalrpc:"), + helpstring("File Replication Service"), + pointer_default(unique) +] +interface frsrpc +{ + /*****************/ + /* Function 0x00 */ + + /* TAG:3 this TLV contains a GUID and the name of the server sending + * the call + */ + typedef struct { + [subcontext(4)] GUID unknown1; + [subcontext(4)] nstring source_server; + } frsrpc_FrsSendCommPktChunkDataSSRV; + + /* TAG:4 this TLV contains a GUID and the name of the destination + * server the PDU is sent to + */ + typedef struct { + [subcontext(4)] GUID unknown1; + [subcontext(4)] nstring dest_server; + } frsrpc_FrsSendCommPktChunkDataDSRV; + + /* TAG:18 this TLV contains a timestamp + */ + typedef struct { + [subcontext(4)] NTTIME time; + } frsrpc_FrsSendCommPktChunkDataTS; + + + typedef struct { + uint32 unknown1; + } frsrpc_FrsSendCommPktChunkDataA; + + typedef struct { + uint32 unknown1; + GUID unknown2; + [subcontext(4)] nstring unknown3; + } frsrpc_FrsSendCommPktChunkDataB; + + typedef struct { + uint32 unknown1; + GUID unknown2; + } frsrpc_FrsSendCommPktChunkDataC; + + typedef [nodiscriminant] union { + [default,flag(NDR_REMAINING)] DATA_BLOB blob; + [case(1)] frsrpc_FrsSendCommPktChunkDataA A; + [case(2)] frsrpc_FrsSendCommPktChunkDataA A; + [case(3)] frsrpc_FrsSendCommPktChunkDataSSRV SSRV; + [case(4)] frsrpc_FrsSendCommPktChunkDataDSRV DSRV; + [case(5)] frsrpc_FrsSendCommPktChunkDataB B; + [case(8)] frsrpc_FrsSendCommPktChunkDataB B; + [case(6)] frsrpc_FrsSendCommPktChunkDataC C; + [case(18)] frsrpc_FrsSendCommPktChunkDataTS TS; + [case(19)] frsrpc_FrsSendCommPktChunkDataA A; + } frsrpc_FrsSendCommPktChunkData; + + typedef struct { + uint16 type; + [subcontext(4),switch_is(type)] frsrpc_FrsSendCommPktChunkData data; + } frsrpc_FrsSendCommPktChunk; + + typedef [flag(NDR_NOALIGN)] struct { + frsrpc_FrsSendCommPktChunk chunk1; + frsrpc_FrsSendCommPktChunk chunk2; + frsrpc_FrsSendCommPktChunk chunk3; + frsrpc_FrsSendCommPktChunk chunk4; + frsrpc_FrsSendCommPktChunk chunk5; + frsrpc_FrsSendCommPktChunk chunk6; + frsrpc_FrsSendCommPktChunk chunk7; + frsrpc_FrsSendCommPktChunk chunk8; + frsrpc_FrsSendCommPktChunk chunk9; + } frsrpc_FrsSendCommPktChunkCtr; + + typedef struct { + uint32 unknown1; + uint32 unknown2; + uint32 unknown3; + uint32 unknown4; + uint32 tlv_size; + uint32 unknown6; + uint32 unknown7; /* This may be a UNIQUE pointer? */ + uint32 unknown8; + uint32 unknown9; + /* + * The format of this blob is this a concatenation + * of TLVs which are not really NDR encoded. + * + * The individual TLVs are encoded as : + * struct { + * uint16 type; + * [subcontext(4),switch_is(type)] chunk_data data; + * } chunk; + * + * some of the chunk are like this: + * + * struct { + * uint32 unknown; // 0x00000010 + * struct GUID guid; + * lstring string; + * } ...; + * + * + * The tags are (might be) : + * 3: Source server sending the PDU + * 4: Destination server the PDU is sent to + * 18: Timestamp + * + */ + [subcontext(4)/*,size_is(tlv_size)*/] frsrpc_FrsSendCommPktChunkCtr *chunks; + uint32 unknown10; + uint32 unknown11; + } frsrpc_FrsSendCommPktReq; + + WERROR frsrpc_FrsSendCommPkt( + [in] frsrpc_FrsSendCommPktReq req + ); + + /*****************/ + /* Function 0x01 */ + [todo] void FRSRPC_VERIFY_PROMOTION_PARENT(); + + /*****************/ + /* Function 0x02 */ + [todo] void FRSRPC_START_PROMOTION_PARENT(); + + /*****************/ + /* Function 0x03 */ + [todo] void FRSRPC_NOP(); + + /*****************/ + /* Function 0x04 */ + [todo] void FRSRPC_BACKUP_COMPLETE(); + + /*****************/ + /* Function 0x05 */ + [todo] void FRSRPC_BACKUP_COMPLETE_5(); + + /*****************/ + /* Function 0x06 */ + [todo] void FRSRPC_BACKUP_COMPLETE_6(); + + /*****************/ + /* Function 0x07 */ + [todo] void FRSRPC_BACKUP_COMPLETE_7(); + + /*****************/ + /* Function 0x08 */ + [todo] void FRSRPC_BACKUP_COMPLETE_8(); + + /*****************/ + /* Function 0x09 */ + [todo] void FRSRPC_BACKUP_COMPLETE_9(); + + /*****************/ + /* Function 0x0a */ + [todo] void FRSRPC_VERIFY_PROMOTION_PARENT_EX(); +} diff --git a/librpc/idl/idl_types.h b/librpc/idl/idl_types.h new file mode 100644 index 0000000000..9885ca5bf6 --- /dev/null +++ b/librpc/idl/idl_types.h @@ -0,0 +1,69 @@ +#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 +#define STR_BYTESIZE LIBNDR_FLAG_STR_BYTESIZE +#define STR_CONFORMANT LIBNDR_FLAG_STR_CONFORMANT +#define STR_CHARLEN LIBNDR_FLAG_STR_CHARLEN +#define STR_UTF8 LIBNDR_FLAG_STR_UTF8 + +/* + a null terminated UCS2 string +*/ +#define nstring [flag(STR_NULLTERM)] 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], 32 bits +*/ +#define asclstr [flag(STR_ASCII|STR_SIZE4)] string + +/* + an ascii string prefixed with [size], 16 bits + null terminated +*/ +#define ascstr3 [flag(STR_ASCII|STR_SIZE2)] string + +/* + an ascii string prefixed with [size] [offset] [length], all 32 bits + not null terminated +*/ +#define ascstr_noterm [flag(STR_NOTERM|STR_ASCII|STR_SIZE4|STR_LEN4)] string + +/* + a null terminated ascii string +*/ +#define astring [flag(STR_ASCII|STR_NULLTERM)] string + +/* + a null terminated UTF8 string +*/ +#define utf8string [flag(STR_UTF8|STR_NULLTERM)] string + +/* + a null terminated UCS2 string +*/ +#define nstring_array [flag(STR_NULLTERM)] string_array + +#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 +#define NDR_BIG_ENDIAN LIBNDR_FLAG_BIGENDIAN + +/* + this is used to control formatting of uint8 arrays +*/ +#define NDR_PAHEX LIBNDR_PRINT_ARRAY_HEX diff --git a/librpc/idl/initshutdown.idl b/librpc/idl/initshutdown.idl new file mode 100644 index 0000000000..02b2501c1d --- /dev/null +++ b/librpc/idl/initshutdown.idl @@ -0,0 +1,45 @@ +#include "idl_types.h" + +/* + initshutdown interface definition +*/ + +import "lsa.idl"; + +[ + uuid("894de0c0-0d55-11d3-a322-00c04fa321a1"), + version(1.0), + endpoint("ncacn_np:[\\pipe\\InitShutdown]"), + pointer_default(unique), + helpstring("Init shutdown service") +] interface initshutdown +{ + WERROR initshutdown_Init( + [in,unique] uint16 *hostname, + /* + * Note: lsa_String and winreg_String both result + * in WERR_INVALID_PARAM + */ + [in,unique] lsa_StringLarge *message, + [in] uint32 timeout, + [in] uint8 force_apps, + [in] uint8 do_reboot + ); + + WERROR initshutdown_Abort( + [in,unique] uint16 *server + ); + + WERROR initshutdown_InitEx( + [in,unique] uint16 *hostname, + /* + * Note: lsa_String and winreg_String both result + * in WERR_INVALID_PARAM + */ + [in,unique] lsa_StringLarge *message, + [in] uint32 timeout, + [in] uint8 force_apps, + [in] uint8 do_reboot, + [in] uint32 reason + ); +} diff --git a/librpc/idl/keysvc.idl b/librpc/idl/keysvc.idl new file mode 100644 index 0000000000..9d05f7d8dc --- /dev/null +++ b/librpc/idl/keysvc.idl @@ -0,0 +1,16 @@ +/* + cryptographic key services interface +*/ + + +/* Also seen as: 0d72a7d4-6148-11d1-b4aa-00c04fb66ea0 */ +[ + uuid("8d0ffe72-d252-11d0-bf8f-00c04fd9126b"), + pointer_default(unique), + version(1.0), + helpstring("Cryptographic Key Services") +] +interface keysvc +{ + WERROR keysvc_Unknown0(); +} diff --git a/librpc/idl/krb5pac.idl b/librpc/idl/krb5pac.idl new file mode 100644 index 0000000000..a498b795f8 --- /dev/null +++ b/librpc/idl/krb5pac.idl @@ -0,0 +1,134 @@ +/* + krb5 PAC +*/ + +#include "idl_types.h" + +import "security.idl", "netlogon.idl", "samr.idl"; + +[ + uuid("12345778-1234-abcd-0000-00000000"), + version(0.0), + pointer_default(unique), + helpstring("Active Directory KRB5 PAC") +] +interface krb5pac +{ + typedef struct { + NTTIME logon_time; + [value(2*strlen_m(account_name))] uint16 size; + [charset(UTF16)] uint8 account_name[size]; + } PAC_LOGON_NAME; + + typedef [public,flag(NDR_PAHEX)] struct { + uint32 type; + [flag(NDR_REMAINING)] DATA_BLOB signature; + } PAC_SIGNATURE_DATA; + + typedef [gensize] struct { + netr_SamInfo3 info3; + dom_sid2 *res_group_dom_sid; + samr_RidWithAttributeArray res_groups; + } PAC_LOGON_INFO; + + typedef struct { + [value(2*strlen_m(upn_name))] uint16 upn_size; + uint16 upn_offset; + [value(2*strlen_m(domain_name))] uint16 domain_size; + uint16 domain_offset; + uint16 unknown3; /* 0x01 */ + uint16 unknown4; + uint32 unknown5; + [charset(UTF16)] uint8 upn_name[upn_size+2]; + [charset(UTF16)] uint8 domain_name[domain_size+2]; + uint32 unknown6; /* padding */ + } PAC_UNKNOWN_12; + + typedef [public] struct { + PAC_LOGON_INFO *info; + } PAC_LOGON_INFO_CTR; + + typedef [public,v1_enum] enum { + PAC_TYPE_LOGON_INFO = 1, + PAC_TYPE_SRV_CHECKSUM = 6, + PAC_TYPE_KDC_CHECKSUM = 7, + PAC_TYPE_LOGON_NAME = 10, + PAC_TYPE_CONSTRAINED_DELEGATION = 11, + PAC_TYPE_UNKNOWN_12 = 12 + } PAC_TYPE; + + typedef struct { + [flag(NDR_REMAINING)] DATA_BLOB remaining; + } DATA_BLOB_REM; + + typedef [public,nodiscriminant,gensize] union { + [case(PAC_TYPE_LOGON_INFO)][subcontext(0xFFFFFC01)] PAC_LOGON_INFO_CTR logon_info; + [case(PAC_TYPE_SRV_CHECKSUM)] PAC_SIGNATURE_DATA srv_cksum; + [case(PAC_TYPE_KDC_CHECKSUM)] PAC_SIGNATURE_DATA kdc_cksum; + [case(PAC_TYPE_LOGON_NAME)] PAC_LOGON_NAME logon_name; + /* when new PAC info types are added they are supposed to be done + in such a way that they are backwards compatible with existing + servers. This makes it safe to just use a [default] for + unknown types, which lets us ignore the data */ + [default] [subcontext(0)] DATA_BLOB_REM unknown; + /* [case(PAC_TYPE_UNKNOWN_12)] PAC_UNKNOWN_12 unknown; */ + } PAC_INFO; + + typedef [public,nopush,nopull,noprint] struct { + PAC_TYPE type; + [value(_ndr_size_PAC_INFO(info, type, 0))] uint32 _ndr_size; + [relative,switch_is(type),subcontext(0),subcontext_size(_subcontext_size_PAC_INFO(r, ndr->flags)),flag(NDR_ALIGN8)] PAC_INFO *info; + [value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */ + } PAC_BUFFER; + + typedef [public] struct { + uint32 num_buffers; + uint32 version; + PAC_BUFFER buffers[num_buffers]; + } PAC_DATA; + + typedef [public] struct { + PAC_TYPE type; + uint32 ndr_size; + [relative,subcontext(0),subcontext_size(NDR_ROUND(ndr_size,8)),flag(NDR_ALIGN8)] DATA_BLOB_REM *info; + [value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */ + } PAC_BUFFER_RAW; + + typedef [public] struct { + uint32 num_buffers; + uint32 version; + PAC_BUFFER_RAW buffers[num_buffers]; + } PAC_DATA_RAW; + + const int NETLOGON_GENERIC_KRB5_PAC_VALIDATE = 3; + + typedef [public] struct { + [value(NETLOGON_GENERIC_KRB5_PAC_VALIDATE)] uint32 MessageType; + uint32 ChecksumLength; + int32 SignatureType; + uint32 SignatureLength; + [flag(NDR_REMAINING)] DATA_BLOB ChecksumAndSignature; + } PAC_Validate; + + void decode_pac( + [in] PAC_DATA pac + ); + + void decode_pac_raw( + [in] PAC_DATA_RAW pac + ); + + void decode_login_info( + [in] PAC_LOGON_INFO logon_info + ); + + void decode_pac_validate( + [in] PAC_Validate pac_validate + ); + + /* used for samba3 netsamlogon cache */ + typedef [public] struct { + time_t timestamp; + netr_SamInfo3 info3; + } netsamlogoncache_entry; +} diff --git a/librpc/idl/mgmt.idl b/librpc/idl/mgmt.idl new file mode 100644 index 0000000000..35857f26cd --- /dev/null +++ b/librpc/idl/mgmt.idl @@ -0,0 +1,75 @@ +/* + dcerpc remote management interface +*/ + +import "misc.idl"; + +[ + uuid("afa8bd80-7d8a-11c9-bef4-08002b102989"), + version(1.0), + pointer_default(unique), + helpstring("DCE/RPC Remote Management") +] +interface mgmt +{ + typedef struct { + ndr_syntax_id *id; + } ndr_syntax_id_p; + + typedef struct { + uint32 count; + [size_is(count)] ndr_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,ref] mgmt_statistics *statistics + ); + + + /***********************/ + /* Function 0x02 */ + boolean32 mgmt_is_server_listening ( + [out,ref] 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] [string,charset(DOS)] uint8 princ_name[] + ); +} diff --git a/librpc/idl/misc.idl b/librpc/idl/misc.idl new file mode 100644 index 0000000000..ff548fe804 --- /dev/null +++ b/librpc/idl/misc.idl @@ -0,0 +1,54 @@ +/* + miscellaneous IDL structures +*/ + + +[ + pointer_default(unique) +] +interface misc +{ + typedef [public,noprint,gensize,noejs] struct { + uint32 time_low; + uint16 time_mid; + uint16 time_hi_and_version; + uint8 clock_seq[2]; + uint8 node[6]; + } GUID; + + typedef [public] struct { + GUID uuid; + uint32 if_version; + } ndr_syntax_id; + + typedef [public] struct { + uint32 handle_type; + GUID uuid; + } policy_handle; + + /* secure channel types */ + /* Only SEC_CHAN_WKSTA can forward requests to other domains. */ + + typedef [public] enum { + SEC_CHAN_NULL = 0, + SEC_CHAN_WKSTA = 2, + SEC_CHAN_DNS_DOMAIN = 3, + SEC_CHAN_DOMAIN = 4, + SEC_CHAN_BDC = 6 + } netr_SchannelType; + + /* SAM database types */ + typedef [public,v1_enum] enum { + SAM_DATABASE_DOMAIN = 0, /* Domain users and groups */ + SAM_DATABASE_BUILTIN = 1, /* BUILTIN users and groups */ + SAM_DATABASE_PRIVS = 2 /* Privileges */ + } netr_SamDatabaseID; + + typedef [public,v1_enum] enum { + SAMR_REJECT_OTHER = 0, + SAMR_REJECT_TOO_SHORT = 1, + SAMR_REJECT_IN_HISTORY = 2, + SAMR_REJECT_COMPLEXITY = 5 + } samr_RejectReason; + +} diff --git a/librpc/idl/msgsvc.idl b/librpc/idl/msgsvc.idl new file mode 100644 index 0000000000..d196daf06b --- /dev/null +++ b/librpc/idl/msgsvc.idl @@ -0,0 +1,22 @@ +/* Works over UDP */ + +[ + uuid("17fdd703-1827-4e34-79d4-24a55c53bb37"), + version(1.0), + pointer_default(unique), + helpstring("Messaging Service") +] interface msgsvc +{ + [todo] void NetrMessageNameAdd(); + [todo] void NetrMessageNameEnum(); + [todo] void NetrMessageNameGetInfo(); + [todo] void NetrMessageNameDel(); +} + +[ + uuid("5a7b91f8-ff00-11d0-a9b2-00c04fb6e6fc"), + version(1.0) +] interface msgsvcsend +{ + [todo] void NetrSendMessage(); +} diff --git a/librpc/idl/nbt.idl b/librpc/idl/nbt.idl new file mode 100644 index 0000000000..f3590fcf2b --- /dev/null +++ b/librpc/idl/nbt.idl @@ -0,0 +1,650 @@ +#include "idl_types.h" + +/* + IDL structures for NBT operations + + NBT is not traditionally encoded using IDL/NDR. This is a bit of an + experiment, and I may well switch us back to a more traditional + encoding if it doesn't work out +*/ + +import "misc.idl", "security.idl", "svcctl.idl", "samr.idl"; +[ + helper("../libcli/netlogon.h", "../libcli/nbt/libnbt.h") +] +interface nbt +{ + const int NBT_NAME_SERVICE_PORT = 137; + const int NBT_DGRAM_SERVICE_PORT = 138; + + typedef [bitmap16bit] bitmap { + NBT_RCODE = 0x000F, + NBT_FLAG_BROADCAST = 0x0010, + NBT_FLAG_RECURSION_AVAIL = 0x0080, + NBT_FLAG_RECURSION_DESIRED = 0x0100, + NBT_FLAG_TRUNCATION = 0x0200, + NBT_FLAG_AUTHORITIVE = 0x0400, + NBT_OPCODE = 0x7800, + NBT_FLAG_REPLY = 0x8000 + } nbt_operation; + + /* the opcodes are in the operation field, masked with + NBT_OPCODE */ + typedef enum { + NBT_OPCODE_QUERY = (0x0<<11), + NBT_OPCODE_REGISTER = (0x5<<11), + NBT_OPCODE_RELEASE = (0x6<<11), + NBT_OPCODE_WACK = (0x7<<11), + NBT_OPCODE_REFRESH = (0x8<<11), + NBT_OPCODE_REFRESH2 = (0x9<<11), + NBT_OPCODE_MULTI_HOME_REG = (0xf<<11) + } nbt_opcode; + + /* rcode values */ + typedef enum { + NBT_RCODE_OK = 0x0, + NBT_RCODE_FMT = 0x1, + NBT_RCODE_SVR = 0x2, + NBT_RCODE_NAM = 0x3, + NBT_RCODE_IMP = 0x4, + NBT_RCODE_RFS = 0x5, + NBT_RCODE_ACT = 0x6, + NBT_RCODE_CFT = 0x7 + } nbt_rcode; + + /* we support any 8bit name type, but by defining the common + ones here we get better debug displays */ + typedef [enum8bit] enum { + NBT_NAME_CLIENT = 0x00, + NBT_NAME_MS = 0x01, + NBT_NAME_USER = 0x03, + NBT_NAME_SERVER = 0x20, + NBT_NAME_PDC = 0x1B, + NBT_NAME_LOGON = 0x1C, + NBT_NAME_MASTER = 0x1D, + NBT_NAME_BROWSER = 0x1E + } nbt_name_type; + + /* the ndr parser for nbt_name is separately defined in + nbtname.c (along with the parsers for nbt_string) */ + typedef [public,nopull,nopush] struct { + string name; + string scope; + nbt_name_type type; + } nbt_name; + + typedef [public,enum16bit] enum { + NBT_QCLASS_IP = 0x01 + } nbt_qclass; + + typedef [public,enum16bit] enum { + NBT_QTYPE_ADDRESS = 0x0001, + NBT_QTYPE_NAMESERVICE = 0x0002, + NBT_QTYPE_NULL = 0x000A, + NBT_QTYPE_NETBIOS = 0x0020, + NBT_QTYPE_STATUS = 0x0021 + } nbt_qtype; + + typedef struct { + nbt_name name; + nbt_qtype question_type; + nbt_qclass question_class; + } nbt_name_question; + + /* these are the possible values of the NBT_NM_OWNER_TYPE + field */ + typedef enum { + NBT_NODE_B = 0x0000, + NBT_NODE_P = 0x2000, + NBT_NODE_M = 0x4000, + NBT_NODE_H = 0x6000 + } nbt_node_type; + + typedef [bitmap16bit] bitmap { + NBT_NM_PERMANENT = 0x0200, + NBT_NM_ACTIVE = 0x0400, + NBT_NM_CONFLICT = 0x0800, + NBT_NM_DEREGISTER = 0x1000, + NBT_NM_OWNER_TYPE = 0x6000, + NBT_NM_GROUP = 0x8000 + } nb_flags; + + typedef struct { + nb_flags nb_flags; + ipv4address ipaddr; + } nbt_rdata_address; + + typedef struct { + uint16 length; + nbt_rdata_address addresses[length/6]; + } nbt_rdata_netbios; + + typedef struct { + uint8 unit_id[6]; + uint8 jumpers; + uint8 test_result; + uint16 version_number; + uint16 period_of_statistics; + uint16 number_of_crcs; + uint16 number_alignment_errors; + uint16 number_of_collisions; + uint16 number_send_aborts; + uint32 number_good_sends; + uint32 number_good_receives; + uint16 number_retransmits; + uint16 number_no_resource_conditions; + uint16 number_free_command_blocks; + uint16 total_number_command_blocks; + uint16 max_total_number_command_blocks; + uint16 number_pending_sessions; + uint16 max_number_pending_sessions; + uint16 max_total_sessions_possible; + uint16 session_data_packet_size; + } nbt_statistics; + + typedef struct { + [charset(DOS)] uint8 name[15]; + nbt_name_type type; + nb_flags nb_flags; + } nbt_status_name; + + typedef struct { + [value(num_names * 18 + 47)] uint16 length; + uint8 num_names; + nbt_status_name names[num_names]; + nbt_statistics statistics; + } nbt_rdata_status; + + typedef struct { + uint16 length; + uint8 data[length]; + } nbt_rdata_data; + + typedef [nodiscriminant,public] union { + [case(NBT_QTYPE_NETBIOS)] nbt_rdata_netbios netbios; + [case(NBT_QTYPE_STATUS)] nbt_rdata_status status; + [default] nbt_rdata_data data; + } nbt_rdata; + +/* + * this macro works around the problem + * that we need to use nbt_rdata_data + * together with NBT_QTYPE_NETBIOS + * for WACK replies + */ + typedef [flag(LIBNDR_PRINT_ARRAY_HEX),nopush] struct { + nbt_name name; + nbt_qtype rr_type; + nbt_qclass rr_class; + uint32 ttl; + [switch_is(rr_type)] nbt_rdata rdata; + } nbt_res_rec; + + typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct { + uint16 name_trn_id; + nbt_operation operation; + uint16 qdcount; + uint16 ancount; + uint16 nscount; + uint16 arcount; + nbt_name_question questions[qdcount]; + nbt_res_rec answers[ancount]; + nbt_res_rec nsrecs[nscount]; + nbt_res_rec additional[arcount]; + [flag(NDR_REMAINING)] DATA_BLOB padding; + } nbt_name_packet; + + + /* + NBT DGRAM packets (UDP/138) + */ + + typedef [enum8bit] enum { + DGRAM_DIRECT_UNIQUE = 0x10, + DGRAM_DIRECT_GROUP = 0x11, + DGRAM_BCAST = 0x12, + DGRAM_ERROR = 0x13, + DGRAM_QUERY = 0x14, + DGRAM_QUERY_POSITIVE = 0x15, + DGRAM_QUERY_NEGATIVE = 0x16 + } dgram_msg_type; + + typedef [bitmap8bit] bitmap { + DGRAM_FLAG_MORE = 0x01, + DGRAM_FLAG_FIRST = 0x02, + DGRAM_FLAG_NODE_TYPE = 0x0C + } dgram_flags; + + typedef [enum8bit] enum { + DGRAM_NODE_B = 0x00, + DGRAM_NODE_P = 0x04, + DGRAM_NODE_M = 0x08, + DGRAM_NODE_NBDD = 0x0C + } dgram_node_type; + + /* a dgram_message is the main dgram body in general use */ + + /* the most common datagram type is a SMB_TRANSACTION + operation, where a SMB packet is used in the data section + of a dgram_message to hold a trans request, which in turn + holds a small command structure. It's a very strange beast + indeed. To make the code cleaner we define a basic SMB + packet in IDL here. This is not a general purpose SMB + packet, and won't be used in the core SMB client/server + code, but it does make working with these types of dgrams + easier */ + + const string NBT_MAILSLOT_NETLOGON = "\\MAILSLOT\\NET\\NETLOGON"; + const string NBT_MAILSLOT_NTLOGON = "\\MAILSLOT\\NET\\NTLOGON"; + const string NBT_MAILSLOT_GETDC = "\\MAILSLOT\\NET\\GETDC"; + const string NBT_MAILSLOT_BROWSE = "\\MAILSLOT\\BROWSE"; + + typedef [enum8bit] enum { + SMB_TRANSACTION = 0x25 + } smb_command; + + typedef struct { + [range(17,17),value(17)] uint8 wct; + uint16 total_param_count; + uint16 total_data_count; + uint16 max_param_count; + uint16 max_data_count; + uint8 max_setup_count; + uint8 pad; + uint16 trans_flags; + uint32 timeout; + uint16 reserved; + uint16 param_count; + uint16 param_offset; + uint16 data_count; + uint16 data_offset; + [range(3,3),value(3)] uint8 setup_count; + uint8 pad2; + uint16 opcode; + uint16 priority; + uint16 _class; + [value(strlen(mailslot_name)+1+data.length)] + uint16 byte_count; + astring mailslot_name; + [flag(NDR_REMAINING)] DATA_BLOB data; + } smb_trans_body; + + typedef [nodiscriminant] union { + [case(SMB_TRANSACTION)] smb_trans_body trans; + } smb_body; + + + typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN|NDR_PAHEX),public] struct { + smb_command smb_command; + uint8 err_class; + uint8 pad; + uint16 err_code; + uint8 flags; + uint16 flags2; + uint16 pid_high; + uint8 signature[8]; + uint16 reserved; + uint16 tid; + uint16 pid; + uint16 vuid; + uint16 mid; + [switch_is(smb_command)] smb_body body; + } dgram_smb_packet; + + const uint32 DGRAM_SMB = 0xff534d42; /* 0xffSMB */ + + typedef [nodiscriminant] union { + [case(DGRAM_SMB)] dgram_smb_packet smb; + } dgram_message_body; + + typedef struct { + uint16 length; + uint16 offset; + nbt_name source_name; + nbt_name dest_name; + uint32 dgram_body_type; + [switch_is(dgram_body_type)] dgram_message_body body; + } dgram_message; + + typedef [enum8bit] enum { + DGRAM_ERROR_NAME_NOT_PRESENT = 0x82, + DGRAM_ERROR_INVALID_SOURCE = 0x83, + DGRAM_ERROR_INVALID_DEST = 0x84 + } dgram_err_code; + + typedef [nodiscriminant] union { + [case(DGRAM_DIRECT_UNIQUE)] dgram_message msg; + [case(DGRAM_DIRECT_GROUP)] dgram_message msg; + [case(DGRAM_BCAST)] dgram_message msg; + [case(DGRAM_ERROR)] dgram_err_code error; + [case(DGRAM_QUERY)] nbt_name dest_name; + [case(DGRAM_QUERY_POSITIVE)] nbt_name dest_name; + [case(DGRAM_QUERY_NEGATIVE)] nbt_name dest_name; + } dgram_data; + + typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct { + dgram_msg_type msg_type; + dgram_flags flags; + uint16 dgram_id; + ipv4address src_addr; + uint16 src_port; + [switch_is(msg_type)] dgram_data data; + } nbt_dgram_packet; + + + /****************************************** + * \MAILSLOT\NET\NETLOGON mailslot requests + * and + * \MAILSLOT\NET\NTLOGON mailslot requests + */ + + typedef [public,gensize] struct { + uint32 sockaddr_family; + [flag(NDR_BIG_ENDIAN)] ipv4address pdc_ip; + [flag(NDR_REMAINING)] DATA_BLOB remaining; + } nbt_sockaddr; + + typedef [bitmap32bit,public] bitmap { + NBT_SERVER_PDC = 0x00000001, + NBT_SERVER_GC = 0x00000004, + NBT_SERVER_LDAP = 0x00000008, + NBT_SERVER_DS = 0x00000010, + NBT_SERVER_KDC = 0x00000020, + NBT_SERVER_TIMESERV = 0x00000040, + NBT_SERVER_CLOSEST = 0x00000080, + NBT_SERVER_WRITABLE = 0x00000100, + NBT_SERVER_GOOD_TIMESERV = 0x00000200, + NBT_SERVER_NDNC = 0x00000400, + NBT_SERVER_SELECT_SECRET_DOMAIN_6 = 0x00000800, + NBT_SERVER_FULL_SECRET_DOMAIN_6 = 0x00001000 + } nbt_server_type; + + typedef [bitmap32bit,public] bitmap { + NETLOGON_NT_VERSION_1 = 0x00000001, + NETLOGON_NT_VERSION_5 = 0x00000002, + NETLOGON_NT_VERSION_5EX = 0x00000004, + NETLOGON_NT_VERSION_5EX_WITH_IP = 0x00000008, + NETLOGON_NT_VERSION_WITH_CLOSEST_SITE = 0x00000010, + NETLOGON_NT_VERSION_AVIOD_NT4EMUL = 0x01000000, + NETLOGON_NT_VERSION_PDC = 0x10000000, + NETLOGON_NT_VERSION_IP = 0x20000000, + NETLOGON_NT_VERSION_LOCAL = 0x40000000, + NETLOGON_NT_VERSION_GC = 0x80000000 + } netlogon_nt_version_flags; + + typedef [enum16bit,public] enum { + LOGON_PRIMARY_QUERY = 7, /* Was also NETLOGON_QUERY_FOR_PDC */ + NETLOGON_ANNOUNCE_UAS = 10, + NETLOGON_RESPONSE_FROM_PDC = 12, + LOGON_SAM_LOGON_REQUEST = 18, /* Was also NETLOGON_QUERY_FOR_PDC2, NTLOGON_SAM_LOGON */ + LOGON_SAM_LOGON_RESPONSE = 19, /* Was also NTLOGON_SAM_LOGON_REPLY */ + LOGON_SAM_LOGON_PAUSE_RESPONSE = 20, + LOGON_SAM_LOGON_USER_UNKNOWN = 21, /* Was also NTLOGON_SAM_LOGON_REPLY15 */ + LOGON_SAM_LOGON_RESPONSE_EX = 23, /* was NETLOGON_RESPONSE_FROM_PDC2 */ + LOGON_SAM_LOGON_PAUSE_RESPONSE_EX = 24, + LOGON_SAM_LOGON_USER_UNKNOWN_EX = 25 /* was NETLOGON_RESPONSE_FROM_PDC_USER */ + } netlogon_command; + + typedef bitmap samr_AcctFlags samr_AcctFlags; + + /* query to dc hand marshaled, as it has 'optional' + * parts */ + typedef [nopull,nopush] struct { + uint16 request_count; + nstring computer_name; + nstring user_name; + astring mailslot_name; + samr_AcctFlags acct_control; + [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size; + /* The manual alignment is required because this + * structure is marked flag(NDR_NOALIGN) via the + * nbt_netlogon_packet below. + * + * However, both MUST only be present if sid_size > 0 + */ + [flag(NDR_ALIGN4)] DATA_BLOB _pad; + [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid; + netlogon_nt_version_flags nt_version; + uint16 lmnt_token; + uint16 lm20_token; + } NETLOGON_SAM_LOGON_REQUEST; + + typedef [flag(NDR_NOALIGN),public] struct { + netlogon_command command; + nstring server; + nstring user_name; + nstring domain; + netlogon_nt_version_flags nt_version; + uint16 lmnt_token; + uint16 lm20_token; + } NETLOGON_SAM_LOGON_RESPONSE_NT40; + + typedef [flag(NDR_NOALIGN),public] struct { + netlogon_command command; + nstring pdc_name; + nstring user_name; + nstring domain_name; + GUID domain_uuid; + GUID zero_uuid; + nbt_string forest; + nbt_string dns_domain; + nbt_string pdc_dns_name; + ipv4address pdc_ip; + nbt_server_type server_type; + netlogon_nt_version_flags nt_version; + uint16 lmnt_token; + uint16 lm20_token; + } NETLOGON_SAM_LOGON_RESPONSE; + + /* response from pdc hand marshaled (we have an additional + * function that uses this structure), as it has 'optional' + * parts */ + typedef [flag(NDR_NOALIGN),public] struct { + netlogon_command command; + uint16 sbz; /* From the docs */ + nbt_server_type server_type; + GUID domain_uuid; + nbt_string forest; + nbt_string dns_domain; + nbt_string pdc_dns_name; + nbt_string domain; + nbt_string pdc_name; + nbt_string user_name; + nbt_string server_site; + nbt_string client_site; + + /* Optional on NETLOGON_NT_VERSION_5EX_WITH_IP */ + [value(ndr_size_nbt_sockaddr(&sockaddr, ndr->flags))] uint8 sockaddr_size; + [subcontext(0),subcontext_size(sockaddr_size)] nbt_sockaddr sockaddr; + + /* Optional on NETLOGON_NT_VERSION_WITH_CLOSEST_SITE */ + nbt_string next_closest_site; + + netlogon_nt_version_flags nt_version; + uint16 lmnt_token; + uint16 lm20_token; + } NETLOGON_SAM_LOGON_RESPONSE_EX; + + /* query for pdc request */ + typedef struct { + astring computer_name; + astring mailslot_name; + [flag(NDR_ALIGN2)] DATA_BLOB _pad; + nstring unicode_name; + netlogon_nt_version_flags nt_version; + uint16 lmnt_token; + uint16 lm20_token; + } nbt_netlogon_query_for_pdc; + + /* response from pdc */ + typedef [flag(NDR_NOALIGN),public] struct { + netlogon_command command; + astring pdc_name; + [flag(NDR_ALIGN2)] DATA_BLOB _pad; + nstring unicode_pdc_name; + nstring domain_name; + netlogon_nt_version_flags nt_version; + uint16 lmnt_token; + uint16 lm20_token; + } nbt_netlogon_response_from_pdc; + + typedef enum netr_SamDatabaseID netr_SamDatabaseID; + + /* used to announce SAM changes - MS-NRPC 2.2.1.5.1 */ + typedef struct { + netr_SamDatabaseID db_index; + hyper serial; + NTTIME timestamp; + } nbt_db_change_info; + + typedef struct { + uint32 serial_lo; + time_t timestamp; + uint32 pulse; + uint32 random; + astring pdc_name; + astring domain; + [flag(NDR_ALIGN2)] DATA_BLOB _pad; + nstring unicode_pdc_name; + nstring unicode_domain; + uint32 db_count; + nbt_db_change_info dbchange[db_count]; + [value(ndr_size_dom_sid0(&sid, ndr->flags))] uint32 sid_size; + [subcontext(0),subcontext_size(sid_size)] dom_sid0 sid; + uint32 message_format_version; + uint32 message_token; + } NETLOGON_DB_CHANGE; + + typedef [nodiscriminant] union { + [case(LOGON_SAM_LOGON_REQUEST)] NETLOGON_SAM_LOGON_REQUEST logon; + [case(LOGON_PRIMARY_QUERY)] nbt_netlogon_query_for_pdc pdc; + [case(NETLOGON_ANNOUNCE_UAS)] NETLOGON_DB_CHANGE uas; + } nbt_netlogon_request; + +#if 0 + [case(NETLOGON_RESPONSE_FROM_PDC)] nbt_netlogon_response_from_pdc response; + [case(NETLOGON_RESPONSE_FROM_PDC_USER)] nbt_netlogon_response_from_pdc2 response2; + + [case(LOGON_SAM_LOGON_PAUSE_RESPONSE)] NETLOGON_SAM_LOGON_RESPONSE reply; + [case(LOGON_SAM_LOGON_RESPONSE)] NETLOGON_SAM_LOGON_RESPONSE reply; + [case(LOGON_SAM_LOGON_USER_UNKNOWN)] NETLOGON_SAM_LOGON_RESPONSE reply; + [case(LOGON_SAM_LOGON_RESPONSE_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex; + [case(LOGON_SAM_LOGON_PAUSE_RESPONSE_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex; + [case(LOGON_SAM_LOGON_USER_UNKNOWN_EX)] NETLOGON_SAM_LOGON_RESPONSE_EX reply_ex; +#endif + + typedef [flag(NDR_NOALIGN),public] struct { + netlogon_command command; + [switch_is(command)] nbt_netlogon_request req; + } nbt_netlogon_packet; + + /********************************************************/ + /* \MAILSLOT\BROWSE mailslot requests */ + /* for details see http://ubiqx.org/cifs/Browsing.html */ + /********************************************************/ + typedef bitmap svcctl_ServerType svcctl_ServerType; + + typedef [enum8bit] enum { + HostAnnouncement = 1, + AnnouncementRequest = 2, + Election = 8, + GetBackupListReq = 9, + GetBackupListResp = 10, + BecomeBackup = 11, + DomainAnnouncement = 12, + MasterAnnouncement = 13, + ResetBrowserState = 14, + LocalMasterAnnouncement = 15 + } nbt_browse_opcode; + + typedef struct { + uint8 UpdateCount; + uint32 Periodicity; + [charset(DOS)] uint8 ServerName[16]; + uint8 OSMajor; + uint8 OSMinor; + svcctl_ServerType ServerType; + uint8 BroMajorVer; + uint8 BroMinorVer; + uint16 Signature; + astring Comment; + } nbt_browse_host_announcement; + + typedef struct { + uint8 Unused; + astring ResponseName; + } nbt_browse_announcement_request; + + typedef struct { + uint8 Version; + uint32 Criteria; + uint32 UpTime; /* In milliseconds */ + uint32 Reserved; /* Must be zero */ + astring ServerName; + } nbt_browse_election_request; + + typedef struct { + uint8 ReqCount; + uint32 Token; + } nbt_browse_backup_list_request; + + typedef struct { + uint8 BackupCount; + uint32 Token; + nbt_name BackupServerList[BackupCount];/* TODO: this is wrong */ + } nbt_browse_backup_list_response; + + typedef struct { + astring BrowserName; + } nbt_browse_become_backup; + + typedef struct { + uint8 UpdateCount; + uint32 Periodicity; + [charset(DOS)] uint8 ServerName[16]; + uint8 OSMajor; + uint8 OSMinor; + svcctl_ServerType ServerType; + uint32 MysteriousField; + astring Comment; + } nbt_browse_domain_announcement; + + typedef struct { + astring ServerName; + } nbt_browse_master_announcement; + + typedef struct { + uint8 Command; + } nbt_browse_reset_state; + + typedef struct { + uint8 UpdateCount; + uint32 Periodicity; + [charset(DOS)] uint8 ServerName[16]; + uint8 OSMajor; + uint8 OSMinor; + svcctl_ServerType ServerType; + uint8 BroMajorVer; + uint8 BroMinorVer; + uint16 Signature; + astring Comment; + } nbt_browse_local_master_announcement; + + typedef [nodiscriminant] union { + [case(HostAnnouncement)] nbt_browse_host_announcement host_annoucement; + [case(AnnouncementRequest)] nbt_browse_announcement_request announcement_request; + [case(Election)] nbt_browse_election_request election_request; + [case(GetBackupListReq)] nbt_browse_backup_list_request backup_list_request; + [case(GetBackupListResp)] nbt_browse_backup_list_response backup_list_response; + [case(BecomeBackup)] nbt_browse_become_backup become_backup; + [case(DomainAnnouncement)] nbt_browse_domain_announcement domain_announcement; + [case(MasterAnnouncement)] nbt_browse_master_announcement master_announcement; + [case(ResetBrowserState)] nbt_browse_reset_state reset_browser_state; + [case(LocalMasterAnnouncement)] nbt_browse_local_master_announcement local_master_announcement; + } nbt_browse_payload; + + typedef [public,flag(NDR_NOALIGN)] struct { + nbt_browse_opcode opcode; + [switch_is(opcode)] nbt_browse_payload payload; + } nbt_browse_packet; +} diff --git a/librpc/idl/notify.idl b/librpc/idl/notify.idl new file mode 100644 index 0000000000..3ce2f40ed8 --- /dev/null +++ b/librpc/idl/notify.idl @@ -0,0 +1,58 @@ +#include "idl_types.h" + +/* + IDL structures for notify change code + + this defines the structures used in the notify database code, and + the change notify buffers +*/ + +import "security.idl"; + +[ + pointer_default(unique) +] +interface notify +{ + + /* structure used in the notify database */ + typedef [public] struct { + server_id server; + uint32 filter; /* filter to apply in this directory */ + uint32 subdir_filter; /* filter to apply in child directories */ + utf8string path; + uint32 path_len; /* saves some computation on search */ + pointer private_data; + } notify_entry; + + /* + to allow for efficient search for matching entries, we + divide them by the directory depth, with a separate array + per depth. The entries within each depth are sorted by path, + allowing for a bisection search. + + The max_mask and max_mask_subdir at each depth is the + bitwise or of the filters and subdir filters for all entries + at that depth. This allows a depth to be quickly skipped if + no entries will match the target filter + */ + typedef struct { + uint32 max_mask; + uint32 max_mask_subdir; + uint32 num_entries; + notify_entry entries[num_entries]; + } notify_depth; + + typedef [public] struct { + uint32 num_depths; + notify_depth depth[num_depths]; + } notify_array; + + /* structure sent between servers in notify messages */ + typedef [public] struct { + uint32 action; + utf8string path; + pointer private_data; + } notify_event; + +} diff --git a/librpc/idl/ntsvcs.idl b/librpc/idl/ntsvcs.idl new file mode 100644 index 0000000000..809ead90c3 --- /dev/null +++ b/librpc/idl/ntsvcs.idl @@ -0,0 +1,381 @@ +/* + plug and play services +*/ + +[ + uuid("8d9f4e40-a03d-11ce-8f69-08003e30051b"), + version(1.0), + helpstring("Plug and Play services") +] +interface ntsvcs +{ + /******************/ + /* Function: 0x00 */ + + [todo] WERROR PNP_Disconnect(); + + /******************/ + /* Function: 0x01 */ + + [todo] WERROR PNP_Connect(); + + /******************/ + /* Function: 0x02 */ + + WERROR PNP_GetVersion( + [out,ref] uint16 *version + ); + + /******************/ + /* Function: 0x03 */ + + [todo] WERROR PNP_GetGlobalState(); + + /******************/ + /* Function: 0x04 */ + + [todo] WERROR PNP_InitDetection(); + + /******************/ + /* Function: 0x05 */ + + [todo] WERROR PNP_ReportLogOn(); + + /******************/ + /* Function: 0x06 */ + + WERROR PNP_ValidateDeviceInstance( + [in,ref] [string,charset(UTF16)] uint16 *devicepath, + [in] uint32 flags + ); + + /******************/ + /* Function: 0x07 */ + + [todo] WERROR PNP_GetRootDeviceInstance(); + + /******************/ + /* Function: 0x08 */ + + [todo] WERROR PNP_GetRelatedDeviceInstance(); + + /******************/ + /* Function: 0x09 */ + + [todo] WERROR PNP_EnumerateSubKeys(); + + /******************/ + /* Function: 0x0a */ + + [todo] WERROR PNP_GetDeviceList( + [in,unique] [string,charset(UTF16)] uint16 *filter, + [out,ref] [size_is(*length),length_is(*length)] uint16 *buffer, + [in,out,ref] uint32 *length, + [in] uint32 flags + ); + + /******************/ + /* Function: 0x0b */ + + WERROR PNP_GetDeviceListSize( + [in,unique] [string,charset(UTF16)] uint16 *devicename, + [out,ref] uint32 *size, + [in] uint32 flags + ); + + /******************/ + /* Function: 0x0c */ + + [todo] WERROR PNP_GetDepth(); + + /******************/ + /* Function: 0x0d */ + + const int DEV_REGPROP_DESC = 1; + + WERROR PNP_GetDeviceRegProp( + [in,ref] [string,charset(UTF16)] uint16 *devicepath, + [in] uint32 property, + [in,out,ref] uint32 *reg_data_type, + [out,ref] [size_is(*buffer_size)] [length_is(*buffer_size)] uint8 *buffer, + [in,out,ref] uint32 *buffer_size, + [in,out,ref] uint32 *needed, + [in] uint32 flags + ); + + /******************/ + /* Function: 0x0e */ + + [todo] WERROR PNP_SetDeviceRegProp(); + + /******************/ + /* Function: 0x0f */ + + [todo] WERROR PNP_GetClassInstance(); + + /******************/ + /* Function: 0x10 */ + + [todo] WERROR PNP_CreateKey(); + + /******************/ + /* Function: 0x11 */ + + [todo] WERROR PNP_DeleteRegistryKey(); + + /******************/ + /* Function: 0x12 */ + + [todo] WERROR PNP_GetClassCount(); + + /******************/ + /* Function: 0x13 */ + + [todo] WERROR PNP_GetClassName(); + + /******************/ + /* Function: 0x14 */ + + [todo] WERROR PNP_DeleteClassKey(); + + /******************/ + /* Function: 0x15 */ + + [todo] WERROR PNP_GetInterfaceDeviceAlias(); + + /******************/ + /* Function: 0x16 */ + + [todo] WERROR PNP_GetInterfaceDeviceList(); + + /******************/ + /* Function: 0x17 */ + + [todo] WERROR PNP_GetInterfaceDeviceListSize(); + + /******************/ + /* Function: 0x18 */ + + [todo] WERROR PNP_RegisterDeviceClassAssociation(); + + /******************/ + /* Function: 0x19 */ + + [todo] WERROR PNP_UnregisterDeviceClassAssociation(); + + /******************/ + /* Function: 0x1a */ + + [todo] WERROR PNP_GetClassRegProp(); + + /******************/ + /* Function: 0x1b */ + + [todo] WERROR PNP_SetClassRegProp(); + + /******************/ + /* Function: 0x1c */ + + [todo] WERROR PNP_CreateDevInst(); + + /******************/ + /* Function: 0x1d */ + + [todo] WERROR PNP_DeviceInstanceAction(); + + /******************/ + /* Function: 0x1e */ + + [todo] WERROR PNP_GetDeviceStatus(); + + /******************/ + /* Function: 0x1f */ + + [todo] WERROR PNP_SetDeviceProblem(); + + /******************/ + /* Function: 0x20 */ + + [todo] WERROR PNP_DisableDevInst(); + + /******************/ + /* Function: 0x21 */ + + [todo] WERROR PNP_UninstallDevInst(); + + /******************/ + /* Function: 0x22 */ + + [todo] WERROR PNP_AddID(); + + /******************/ + /* Function: 0x23 */ + + [todo] WERROR PNP_RegisterDriver(); + + /******************/ + /* Function: 0x24 */ + + [todo] WERROR PNP_QueryRemove(); + + /******************/ + /* Function: 0x25 */ + + [todo] WERROR PNP_RequestDeviceEject(); + + /******************/ + /* Function: 0x26 */ + + [todo] WERROR PNP_IsDockStationPresent(); + + /******************/ + /* Function: 0x27 */ + + [todo] WERROR PNP_RequestEjectPC(); + + /******************/ + /* Function: 0x28 */ + + WERROR PNP_HwProfFlags( + [in] uint32 unknown1, + [in,ref] [string,charset(UTF16)] uint16 *devicepath, + [in] uint32 unknown2, + [in,out,ref] uint32 *unknown3, + [in,out,unique] uint16 *unknown4, + [in,unique] [string,charset(UTF16)] uint16 *unknown5, + [out,unique] [string,charset(UTF16)] uint16 **unknown5a, + [in] uint32 unknown6, + [in] uint32 unknown7 + ); + + /******************/ + /* Function: 0x29 */ + + typedef struct { + uint32 unknown1; + uint16 unknown2[160]; + uint32 unknown3; + } PNP_HwProfInfo; + + WERROR PNP_GetHwProfInfo( + [in] uint32 idx, + [in,out,ref] PNP_HwProfInfo *info, + [in] uint32 unknown1, + [in] uint32 unknown2 + ); + + /******************/ + /* Function: 0x2a */ + + [todo] WERROR PNP_AddEmptyLogConf(); + + /******************/ + /* Function: 0x2b */ + + [todo] WERROR PNP_FreeLogConf(); + + /******************/ + /* Function: 0x2c */ + + [todo] WERROR PNP_GetFirstLogConf(); + + /******************/ + /* Function: 0x2d */ + + [todo] WERROR PNP_GetNextLogConf(); + + /******************/ + /* Function: 0x2e */ + + [todo] WERROR PNP_GetLogConfPriority(); + + /******************/ + /* Function: 0x2f */ + + [todo] WERROR PNP_AddResDes(); + + /******************/ + /* Function: 0x30 */ + + [todo] WERROR PNP_FreeResDes(); + + /******************/ + /* Function: 0x31 */ + + [todo] WERROR PNP_GetNextResDes(); + + /******************/ + /* Function: 0x32 */ + + [todo] WERROR PNP_GetResDesData(); + + /******************/ + /* Function: 0x33 */ + + [todo] WERROR PNP_GetResDesDataSize(); + + /******************/ + /* Function: 0x34 */ + + [todo] WERROR PNP_ModifyResDes(); + + /******************/ + /* Function: 0x35 */ + + [todo] WERROR PNP_DetectResourceLimit(); + + /******************/ + /* Function: 0x36 */ + + [todo] WERROR PNP_QueryResConfList(); + + /******************/ + /* Function: 0x37 */ + + [todo] WERROR PNP_SetHwProf(); + + /******************/ + /* Function: 0x38 */ + + [todo] WERROR PNP_QueryArbitratorFreeData(); + + /******************/ + /* Function: 0x39 */ + + [todo] WERROR PNP_QueryArbitratorFreeSize(); + + /******************/ + /* Function: 0x3a */ + + [todo] WERROR PNP_RunDetection(); + + /******************/ + /* Function: 0x3b */ + + [todo] WERROR PNP_RegisterNotification(); + + /******************/ + /* Function: 0x3c */ + + [todo] WERROR PNP_UnregisterNotification(); + + /******************/ + /* Function: 0x3d */ + + [todo] WERROR PNP_GetCustomDevProp(); + + /******************/ + /* Function: 0x3e */ + + [todo] WERROR PNP_GetVersionInternal(); + + /******************/ + /* Function: 0x3f */ + + [todo] WERROR PNP_GetBlockedDriverInfo(); + + /******************/ + /* Function: 0x40 */ + + [todo] WERROR PNP_GetServerSideDeviceInstallFlags(); +} diff --git a/librpc/idl/orpc.idl b/librpc/idl/orpc.idl new file mode 100644 index 0000000000..d023865035 --- /dev/null +++ b/librpc/idl/orpc.idl @@ -0,0 +1,230 @@ +#include "idl_types.h" + +/** + DCOM interfaces + http://www.ietf.org/internet-drafts/draft-brown-dcom-v1-spec-04.txt + */ + +import "misc.idl"; + +[ + pointer_default(unique) +] +interface ObjectRpcBaseTypes +{ + /* COM_MINOR_VERSION = 1 (NT4.0, SP1, SP2, DCOM95). */ + /* - Initial Release */ + /* - Must be used when talking to downlevel machines, including */ + /* on Remote Activation calls. */ + /* COM_MINOR_VERSION = 2 (NT4.0 SP3 and beyond). */ + /* - Added ResolveOxid2 to IObjectExporter to retrieve the */ + /* COM version number of the server. Passed to the NDR engine */ + /* to fix fatal endian-ness flaw in the way OLEAUTOMATION marshals */ + /* BSTRS. Previous way used trailing padding, which is not NDR */ + /* compatible. See Bug# 69189. */ + /* COM_MINOR_VERSION = 3 (NT4.0 SP4 and DCOM95 builds 1018 and beyond) */ + /* - OLEAUT32 added two new types to the SAFEARRAY, but SAFEARRAY */ + /* previously included the "default" keyword, which prevented */ + /* downlevel NDR engines from correctly handling any extensions. */ + /* Machines with version >=5.3 don't use "default" and will */ + /* gracefully handle future extensions to SAFEARRAY. */ + /* old constants (for convenience) */ + + /* current version */ + const uint16 COM_MAJOR_VERSION = 5; + const uint16 COM_MINOR_VERSION = 1; + + /* Body Extensions */ + const string dcom_ext_debugging = "f1f19680-4d2a-11ce-a66a-0020af6e72f4"; + const string dcom_ext_extended_error = "f1f19681-4d2a-11ce-a66a-0020af6e72f4"; + + /* Component Object Model version number */ + + + typedef [public] struct + { + uint16 MajorVersion; /* Major version number */ + uint16 MinorVersion; /* Minor version number */ + } COMVERSION; + + /* enumeration of additional information present in the call packet. */ + typedef bitmap { + ORPCF_NULL = 0x00, /* no additional info in packet */ + ORPCF_LOCAL = 0x01, /* call is local to this machine */ + ORPCF_RESERVED1 = 0x02, /* reserved for local use */ + ORPCF_RESERVED2 = 0x04, /* reserved for local use */ + ORPCF_RESERVED3 = 0x08, /* reserved for local use */ + ORPCF_RESERVED4 = 0x10 /* reserved for local use */ + } ORPC_FLAGS; + + /* Extension to implicit parameters. */ + typedef [public] struct + { + GUID id; /* Extension identifier. */ + uint32 size; /* Extension size. */ + [size_is(((size+7)&~7))] uint8 data[]; /* Extension data. */ + } ORPC_EXTENT; + + + /* Array of extensions. */ + typedef struct + { + uint32 size; /* Num extents. */ + uint32 reserved; /* Must be zero. */ + [size_is(((size+1)&~1))] ORPC_EXTENT **extent; /* extents */ + } ORPC_EXTENT_ARRAY; + + + /* implicit 'this' pointer which is the first [in] parameter on */ + /* every ORPC call. */ + typedef [public] struct + { + COMVERSION version; /* COM version number */ + uint32 flags; /* ORPCF flags for presence of other data */ + uint32 reserved1; /* set to zero */ + GUID cid; /* causality id of caller */ + /* Extensions. */ + [unique] ORPC_EXTENT_ARRAY *extensions; + } ORPCTHIS; + + + /* implicit 'that' pointer which is the first [out] parameter on */ + /* every ORPC call. */ + typedef [public] struct + { + uint32 flags; /* ORPCF flags for presence of other data */ + /* Extensions. */ + [unique] ORPC_EXTENT_ARRAY *extensions; + } ORPCTHAT; + + + /* DUALSTRINGARRAYS are the return type for arrays of network addresses, */ + /* arrays of endpoints and arrays of both used in many ORPC interfaces */ + typedef [public,flag(NDR_NOALIGN)] struct + { + uint16 wTowerId; /* Cannot be zero. */ + nstring NetworkAddr; + } STRINGBINDING; + + typedef [public,nopush,nopull,noprint] struct + { + STRINGBINDING **stringbindings; + } STRINGARRAY; + + typedef [public,nopush,nopull,noprint] struct + { + STRINGBINDING **stringbindings; + SECURITYBINDING **securitybindings; + } DUALSTRINGARRAY; + + const uint16 COM_C_AUTHZ_NONE = 0xffff; + typedef [public,flag(NDR_NOALIGN)] struct + { + uint16 wAuthnSvc; /* Cannot be zero. */ + uint16 wAuthzSvc; + nstring PrincName; + } SECURITYBINDING; + + /* signature value for OBJREF (object reference, actually the */ + /* marshaled form of a COM interface). + * MEOW apparently stands for "Microsoft Extended Object Wireformat" + */ + const uint32 OBJREF_SIGNATURE = 0x574f454d; /* 'MEOW' */ + + /* flag values for OBJREF */ + typedef enum { + OBJREF_NULL = 0x0, /* NULL pointer */ + OBJREF_STANDARD = 0x1, /* standard marshaled objref */ + OBJREF_HANDLER = 0x2, /* handler marshaled objref */ + OBJREF_CUSTOM = 0x4 /* custom marshaled objref */ + } OBJREF_FLAGS; + + /* Flag values for a STDOBJREF (standard part of an OBJREF). */ + /* SORF_OXRES1 - SORF_OXRES8 are reserved for the object exporters */ + /* use only, object importers must ignore them and must not enforce MBZ. */ + typedef bitmap { + SORF_NULL = 0x0000, /* convenient for initializing SORF */ + SORF_OXRES1 = 0x0001, /* reserved for exporter */ + SORF_OXRES2 = 0x0020, /* reserved for exporter */ + SORF_OXRES3 = 0x0040, /* reserved for exporter */ + SORF_OXRES4 = 0x0080, /* reserved for exporter */ + SORF_OXRES5 = 0x0100, /* reserved for exporter */ + SORF_OXRES6 = 0x0200, /* reserved for exporter */ + SORF_OXRES7 = 0x0400, /* reserved for exporter */ + SORF_OXRES8 = 0x0800, /* reserved for exporter */ + SORF_NOPING = 0x1000 /* Pinging is not required */ + } STDOBJREF_FLAGS; + + /* standard object reference */ + typedef [public] struct + { + uint32 flags; /* STDOBJREF flags (see above) */ + uint32 cPublicRefs; /* count of references passed */ + hyper oxid; /* oxid of server with this oid */ + hyper oid; /* oid of object with this ipid */ + GUID ipid; /* ipid of interface pointer to this object */ + } STDOBJREF; + + typedef struct + { + STDOBJREF std; /* standard objref */ + STRINGARRAY saResAddr; /* resolver address */ + } u_standard; + + typedef struct + { + STDOBJREF std; /* standard objref */ + GUID clsid; /* Clsid of handler code */ + STRINGARRAY saResAddr; /* resolver address */ + } u_handler; + + typedef struct + { + GUID clsid; /* Clsid of unmarshaling code */ + uint32 cbExtension; /* size of extension data */ + uint32 size; /* size of data that follows */ + uint8 pData[size]; /* extension + class specific data */ + } u_custom; + + typedef struct + { + } u_null; + + typedef [nodiscriminant] union + { + [case(OBJREF_NULL)] u_null u_null; + [case(OBJREF_STANDARD)] u_standard u_standard; + [case(OBJREF_HANDLER)] u_handler u_handler; + [case(OBJREF_CUSTOM)] u_custom u_custom; + } OBJREF_Types; + + /* OBJREF is the format of a marshaled interface pointer. */ + typedef [public,flag(NDR_LITTLE_ENDIAN)] struct + { + uint32 signature; + uint32 flags; /* OBJREF flags (see above) */ + GUID iid; /* interface identifier */ + [switch_is(flags), switch_type(uint32)] OBJREF_Types u_objref; + } OBJREF; + + /* wire representation of a marshalled interface pointer */ + typedef [public] struct + { + uint32 size; + [subcontext(4)] OBJREF obj; + } MInterfacePointer; + + typedef [v1_enum,public] enum + { + COM_OK = 0x00000000, + COM_OUTOFMEMORY = 0x80000002, + COM_INVALIDARG = 0x80000003, + COM_NOINTERFACE = 0x80000004, + COM_ACCESSDENIED = 0x80070005, + COM_INVALID_OXID = 0x80070776, + COM_INVALID_OID = 0x80070777, + COM_INVALID_SET = 0x80070778, + COM_UNEXPECTED = 0x8000FFFF, + COM_CLSNOTFOUND = 0x80040154 + } COMRESULT; +} diff --git a/librpc/idl/oxidresolver.idl b/librpc/idl/oxidresolver.idl new file mode 100644 index 0000000000..95c8a1c5f0 --- /dev/null +++ b/librpc/idl/oxidresolver.idl @@ -0,0 +1,94 @@ +/** + DCOM interfaces + http://www.grimes.demon.co.uk/DCOM/DCOMSpec.htm + */ + +/* + The OXID Resolver can turn a OXID (Object Exporter ID) into a + RPC binding string that can be used to contact an object + + (used by DCOM) + */ + +import "misc.idl", "orpc.idl"; + +[ + uuid("99fcfec4-5260-101b-bbcb-00aa0021347a"), + helpstring("Object Exporter ID Resolver"), + endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]", "ncalrpc:"), + pointer_default(unique) +] +interface IOXIDResolver +{ +#define OXID hyper +#define SETID hyper +#define IPID GUID +#define OID GUID + + /* Method to get the protocol sequences, string bindings */ + /* and machine id for an object server given its OXID. */ + + [idempotent] WERROR ResolveOxid ( + [in] OXID pOxid, + [in] uint16 cRequestedProtseqs, + [in, size_is(cRequestedProtseqs)] uint16 arRequestedProtseqs[], + [out] DUALSTRINGARRAY **ppdsaOxidBindings, + [out,ref] IPID *pipidRemUnknown, + [out,ref] uint32 *pAuthnHint + ); + + /* Simple ping is used to ping a Set. Client machines use this */ + /* to inform the object exporter that it is still using the */ + /* members of the set. */ + /* Returns S_TRUE if the SetId is known by the object exporter, */ + /* S_FALSE if not. */ + [idempotent] WERROR SimplePing ( + [in] SETID *SetId /* Must not be zero */ + ); + + /* Complex ping is used to create sets of OIDs to ping. The */ + /* whole set can subsequently be pinged using SimplePing, */ + /* thus reducing network traffic. */ + [idempotent] WERROR ComplexPing ( + [in,out,ref] SETID *SetId, /* In of 0 on first call for new set. */ + [in] uint16 SequenceNum, + [in] uint16 cAddToSet, + [in] uint16 cDelFromSet, + /* add these OIDs to the set */ + [in, size_is(cAddToSet)] OID AddToSet[], + /*remove these OIDs from the set */ + [in, size_is(cDelFromSet)] OID DelFromSet[], + [out,ref] uint16 *PingBackoffFactor/* 2^factor = multipler */ + ); + + /* In some cases the client maybe unsure that a particular */ + /* binding will reach the server. (For example, when the oxid */ + /* bindings have more than one TCP/IP binding) This call */ + /* can be used to validate the binding */ + /* from the client. */ + [idempotent] WERROR ServerAlive (); + + /* Method to get the protocol sequences, string bindings, */ + /* RemoteUnknown IPID and COM version for an object server */ + /* given its OXID. Supported by DCOM */ + /* version 5.2 and above. Looks like that means + * Windows 2003/XP and above */ + [idempotent] WERROR ResolveOxid2 ( + [in] OXID pOxid, + [in] uint16 cRequestedProtseqs, + [in, size_is(cRequestedProtseqs)] uint16 arRequestedProtseqs[], + [out] DUALSTRINGARRAY **pdsaOxidBindings, + [out,ref] IPID *ipidRemUnknown, + [out,ref] uint32 *AuthnHint, + [out,ref] COMVERSION *ComVersion + ); + typedef struct { + COMVERSION version; + uint32 unknown1; + } COMINFO; + + [idempotent] WERROR ServerAlive2 ( + [out,ref] COMINFO *info, + [out,ref] DUALSTRINGARRAY *dualstring, + [out] uint8 unknown2[3]); +} diff --git a/librpc/idl/policyagent.idl b/librpc/idl/policyagent.idl new file mode 100644 index 0000000000..ab137faf27 --- /dev/null +++ b/librpc/idl/policyagent.idl @@ -0,0 +1,13 @@ + +/* IPSec policy agent (Win2k) */ +[ + uuid("d335b8f6-cb31-11d0-b0f9-006097ba4e54"), + version(1.5), + pointer_default(unique), + helpstring("IPSec Policy Agent") +] interface policyagent +{ + /*****************/ + /* Function 0x00 */ + [todo] WERROR policyagent_Dummy(); +} diff --git a/librpc/idl/protected_storage.idl b/librpc/idl/protected_storage.idl new file mode 100644 index 0000000000..7841f91ca9 --- /dev/null +++ b/librpc/idl/protected_storage.idl @@ -0,0 +1,14 @@ +/* + protected_storage interface definitions + Also seen with UUID: +*/ + +[ uuid("c9378ff1-16f7-11d0-a0b2-00aa0061426a"), + version(1.0), + pointer_default(unique) +] interface protected_storage +{ + /*****************************/ + /* Function 0x00 */ + WERROR ps_XXX (); +} diff --git a/librpc/idl/remact.idl b/librpc/idl/remact.idl new file mode 100644 index 0000000000..2165ecfc81 --- /dev/null +++ b/librpc/idl/remact.idl @@ -0,0 +1,46 @@ +/** + DCOM interfaces + http://www.grimes.demon.co.uk/DCOM/DCOMSpec.htm + */ + +import "misc.idl", "orpc.idl"; + +[ + uuid("4d9f4ab8-7d1c-11cf-861e-0020af6e7c57"), + pointer_default(unique), + endpoint("ncalrpc:", "ncacn_ip_tcp:[135]", "ncacn_np:[\\pipe\\epmapper]") +] +interface IRemoteActivation +{ + typedef enum + { + RPC_C_IMP_LEVEL_DEFAULT = 0, + RPC_C_IMP_LEVEL_ANONYMOUS = 1, + RPC_C_IMP_LEVEL_IDENTIFY = 2, + RPC_C_IMP_LEVEL_IMPERSONATE = 3, + RPC_C_IMP_LEVEL_DELEGATE = 4 + } imp_levels; + + const uint32 MODE_GET_CLASS_OBJECT = 0xffffffff; + WERROR RemoteActivation ( + [in] ORPCTHIS this, + [out,ref] ORPCTHAT *that, + [in] GUID Clsid, + [in] [string,charset(UTF16)] uint16 *pwszObjectName, + [in] MInterfacePointer *pObjectStorage, + [in] uint32 ClientImpLevel, + [in] uint32 Mode, + [in,range(1,32768)] uint32 Interfaces, + [in,size_is(Interfaces)] GUID *pIIDs, + [in] uint16 num_protseqs, + [in, size_is(num_protseqs)] uint16 protseq[*], + [out,ref] hyper *pOxid, + [out,ref] DUALSTRINGARRAY *pdsaOxidBindings, + [out,ref] GUID *ipidRemUnknown, + [out,ref] uint32 *AuthnHint, + [out,ref] COMVERSION *ServerVersion, + [out,ref] WERROR *hr, + [out,size_is(Interfaces)] MInterfacePointer *ifaces[], + [out,size_is(Interfaces)] WERROR results[] + ); +} diff --git a/librpc/idl/rot.idl b/librpc/idl/rot.idl new file mode 100644 index 0000000000..78eee48807 --- /dev/null +++ b/librpc/idl/rot.idl @@ -0,0 +1,44 @@ +import "orpc.idl"; + +[ + uuid("b9e79e60-3d52-11ce-aaa1-00006901293f"), + version(0.2), + pointer_default(unique), + endpoint("ncacn_np:[\\pipe\\epmapper]", "ncacn_ip_tcp:[135]", + "ncalrpc:[EPMAPPER]") +] interface rot +{ + WERROR rot_add ( + [in] uint32 flags, + [in] MInterfacePointer *unk, + [in] MInterfacePointer *moniker, + [out] uint32 *rotid + ); + + WERROR rot_remove ( + [in] uint32 rotid + ); + + WERROR rot_is_listed ( + [in] MInterfacePointer *moniker + ); + + WERROR rot_get_interface_pointer ( + [in] MInterfacePointer *moniker, + [out] MInterfacePointer *ip + ); + + WERROR rot_set_modification_time ( + [in] uint32 rotid, + [in] NTTIME *t + ); + + WERROR rot_get_modification_time ( + [in] MInterfacePointer *moniker, + [out] NTTIME *t + ); + + WERROR rot_enum ( + [out] MInterfacePointer *EnumMoniker + ); +} diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl new file mode 100644 index 0000000000..6704e300a5 --- /dev/null +++ b/librpc/idl/security.idl @@ -0,0 +1,394 @@ +#include "idl_types.h" + +/* + security IDL structures +*/ + +import "misc.idl"; + +/* + 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 +*/ +cpp_quote("#define dom_sid2 dom_sid") + +/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */ +cpp_quote("#define dom_sid28 dom_sid") + +/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */ +cpp_quote("#define dom_sid0 dom_sid") + +[ + pointer_default(unique) +] +interface security +{ + /* + access masks are divided up like this: + 0xabccdddd + where + a = generic rights bits SEC_GENERIC_ + b = flags SEC_FLAG_ + c = standard rights bits SEC_STD_ + d = object type specific bits SEC_{FILE,DIR,REG,xxx}_ + + common combinations of bits are prefixed with SEC_RIGHTS_ + */ + const int SEC_MASK_GENERIC = 0xF0000000; + const int SEC_MASK_FLAGS = 0x0F000000; + const int SEC_MASK_STANDARD = 0x00FF0000; + const int SEC_MASK_SPECIFIC = 0x0000FFFF; + + /* generic bits */ + const int SEC_GENERIC_ALL = 0x10000000; + const int SEC_GENERIC_EXECUTE = 0x20000000; + const int SEC_GENERIC_WRITE = 0x40000000; + const int SEC_GENERIC_READ = 0x80000000; + + /* flag bits */ + const int SEC_FLAG_SYSTEM_SECURITY = 0x01000000; + const int SEC_FLAG_MAXIMUM_ALLOWED = 0x02000000; + + /* standard bits */ + const int SEC_STD_DELETE = 0x00010000; + const int SEC_STD_READ_CONTROL = 0x00020000; + const int SEC_STD_WRITE_DAC = 0x00040000; + const int SEC_STD_WRITE_OWNER = 0x00080000; + const int SEC_STD_SYNCHRONIZE = 0x00100000; + const int SEC_STD_REQUIRED = 0x000F0000; + const int SEC_STD_ALL = 0x001F0000; + + /* file specific bits */ + const int SEC_FILE_READ_DATA = 0x00000001; + const int SEC_FILE_WRITE_DATA = 0x00000002; + const int SEC_FILE_APPEND_DATA = 0x00000004; + const int SEC_FILE_READ_EA = 0x00000008; + const int SEC_FILE_WRITE_EA = 0x00000010; + const int SEC_FILE_EXECUTE = 0x00000020; + const int SEC_FILE_READ_ATTRIBUTE = 0x00000080; + const int SEC_FILE_WRITE_ATTRIBUTE = 0x00000100; + const int SEC_FILE_ALL = 0x000001ff; + + /* directory specific bits */ + const int SEC_DIR_LIST = 0x00000001; + const int SEC_DIR_ADD_FILE = 0x00000002; + const int SEC_DIR_ADD_SUBDIR = 0x00000004; + const int SEC_DIR_READ_EA = 0x00000008; + const int SEC_DIR_WRITE_EA = 0x00000010; + const int SEC_DIR_TRAVERSE = 0x00000020; + const int SEC_DIR_DELETE_CHILD = 0x00000040; + const int SEC_DIR_READ_ATTRIBUTE = 0x00000080; + const int SEC_DIR_WRITE_ATTRIBUTE = 0x00000100; + + /* registry entry specific bits */ + const int SEC_REG_QUERY_VALUE = 0x00000001; + const int SEC_REG_SET_VALUE = 0x00000002; + const int SEC_REG_CREATE_SUBKEY = 0x00000004; + const int SEC_REG_ENUM_SUBKEYS = 0x00000008; + const int SEC_REG_NOTIFY = 0x00000010; + const int SEC_REG_CREATE_LINK = 0x00000020; + + /* ldap specific access bits */ + const int SEC_ADS_CREATE_CHILD = 0x00000001; + const int SEC_ADS_DELETE_CHILD = 0x00000002; + const int SEC_ADS_LIST = 0x00000004; + const int SEC_ADS_SELF_WRITE = 0x00000008; + const int SEC_ADS_READ_PROP = 0x00000010; + const int SEC_ADS_WRITE_PROP = 0x00000020; + const int SEC_ADS_DELETE_TREE = 0x00000040; + const int SEC_ADS_LIST_OBJECT = 0x00000080; + const int SEC_ADS_CONTROL_ACCESS = 0x00000100; + + /* invalid bits */ + const int SEC_MASK_INVALID = 0x0ce0fe00; + + /* generic->specific mappings for files */ + const int SEC_RIGHTS_FILE_READ = SEC_STD_READ_CONTROL | + SEC_STD_SYNCHRONIZE | + SEC_FILE_READ_DATA | + SEC_FILE_READ_ATTRIBUTE | + SEC_FILE_READ_EA; + + const int SEC_RIGHTS_FILE_WRITE = SEC_STD_READ_CONTROL | + SEC_STD_SYNCHRONIZE | + SEC_FILE_WRITE_DATA | + SEC_FILE_WRITE_ATTRIBUTE | + SEC_FILE_WRITE_EA | + SEC_FILE_APPEND_DATA; + + const int SEC_RIGHTS_FILE_EXECUTE = SEC_STD_SYNCHRONIZE | + SEC_STD_READ_CONTROL | + SEC_FILE_READ_ATTRIBUTE | + SEC_FILE_EXECUTE; + + const int SEC_RIGHTS_FILE_ALL = SEC_STD_ALL | SEC_FILE_ALL; + + /* generic->specific mappings for directories (same as files) */ + const int SEC_RIGHTS_DIR_READ = SEC_RIGHTS_FILE_READ; + const int SEC_RIGHTS_DIR_WRITE = SEC_RIGHTS_FILE_WRITE; + const int SEC_RIGHTS_DIR_EXECUTE = SEC_RIGHTS_FILE_EXECUTE; + const int SEC_RIGHTS_DIR_ALL = SEC_RIGHTS_FILE_ALL; + + + /***************************************************************/ + /* WELL KNOWN SIDS */ + + /* a NULL sid */ + const string SID_NULL = "S-1-0-0"; + + /* the world domain */ + const string NAME_WORLD = "WORLD"; + + const string SID_WORLD_DOMAIN = "S-1-1"; + const string SID_WORLD = "S-1-1-0"; + + /* SECURITY_CREATOR_SID_AUTHORITY */ + const string SID_CREATOR_OWNER_DOMAIN = "S-1-3"; + const string SID_CREATOR_OWNER = "S-1-3-0"; + const string SID_CREATOR_GROUP = "S-1-3-1"; + const string SID_OWNER_RIGHTS = "S-1-3-4"; + + /* SECURITY_NT_AUTHORITY */ + const string NAME_NT_AUTHORITY = "NT AUTHORITY"; + + const string SID_NT_AUTHORITY = "S-1-5"; + const string SID_NT_DIALUP = "S-1-5-1"; + const string SID_NT_NETWORK = "S-1-5-2"; + const string SID_NT_BATCH = "S-1-5-3"; + const string SID_NT_INTERACTIVE = "S-1-5-4"; + const string SID_NT_SERVICE = "S-1-5-6"; + const string SID_NT_ANONYMOUS = "S-1-5-7"; + const string SID_NT_PROXY = "S-1-5-8"; + const string SID_NT_ENTERPRISE_DCS = "S-1-5-9"; + const string SID_NT_SELF = "S-1-5-10"; + const string SID_NT_AUTHENTICATED_USERS = "S-1-5-11"; + const string SID_NT_RESTRICTED = "S-1-5-12"; + const string SID_NT_TERMINAL_SERVER_USERS = "S-1-5-13"; + const string SID_NT_REMOTE_INTERACTIVE = "S-1-5-14"; + const string SID_NT_THIS_ORGANISATION = "S-1-5-15"; + const string SID_NT_IUSR = "S-1-5-17"; + const string SID_NT_SYSTEM = "S-1-5-18"; + const string SID_NT_LOCAL_SERVICE = "S-1-5-19"; + const string SID_NT_NETWORK_SERVICE = "S-1-5-20"; + const string SID_NT_DIGEST_AUTHENTICATION = "S-1-5-64-21"; + const string SID_NT_NTLM_AUTHENTICATION = "S-1-5-64-10"; + const string SID_NT_SCHANNEL_AUTHENTICATION = "S-1-5-64-14"; + const string SID_NT_OTHER_ORGANISATION = "S-1-5-1000"; + + /* SECURITY_BUILTIN_DOMAIN_RID */ + const string NAME_BUILTIN = "BUILTIN"; + + const string SID_BUILTIN = "S-1-5-32"; + const string SID_BUILTIN_ADMINISTRATORS = "S-1-5-32-544"; + const string SID_BUILTIN_USERS = "S-1-5-32-545"; + const string SID_BUILTIN_GUESTS = "S-1-5-32-546"; + const string SID_BUILTIN_POWER_USERS = "S-1-5-32-547"; + const string SID_BUILTIN_ACCOUNT_OPERATORS = "S-1-5-32-548"; + const string SID_BUILTIN_SERVER_OPERATORS = "S-1-5-32-549"; + const string SID_BUILTIN_PRINT_OPERATORS = "S-1-5-32-550"; + const string SID_BUILTIN_BACKUP_OPERATORS = "S-1-5-32-551"; + const string SID_BUILTIN_REPLICATOR = "S-1-5-32-552"; + const string SID_BUILTIN_RAS_SERVERS = "S-1-5-32-553"; + const string SID_BUILTIN_PREW2K = "S-1-5-32-554"; + + /* well-known domain RIDs */ + const int DOMAIN_RID_LOGON = 9; + const int DOMAIN_RID_ADMINISTRATOR = 500; + const int DOMAIN_RID_GUEST = 501; + const int DOMAIN_RID_ADMINS = 512; + const int DOMAIN_RID_USERS = 513; + const int DOMAIN_RID_DOMAIN_MEMBERS = 515; + const int DOMAIN_RID_DCS = 516; + const int DOMAIN_RID_CERT_ADMINS = 517; + const int DOMAIN_RID_SCHEMA_ADMINS = 518; + const int DOMAIN_RID_ENTERPRISE_ADMINS = 519; + + + /* + privilege IDs. Please keep the IDs below 64. If we get more + than 64 then we need to change security_token + */ + typedef enum { + SEC_PRIV_SECURITY = 1, + SEC_PRIV_BACKUP = 2, + SEC_PRIV_RESTORE = 3, + SEC_PRIV_SYSTEMTIME = 4, + SEC_PRIV_SHUTDOWN = 5, + SEC_PRIV_REMOTE_SHUTDOWN = 6, + SEC_PRIV_TAKE_OWNERSHIP = 7, + SEC_PRIV_DEBUG = 8, + SEC_PRIV_SYSTEM_ENVIRONMENT = 9, + SEC_PRIV_SYSTEM_PROFILE = 10, + SEC_PRIV_PROFILE_SINGLE_PROCESS = 11, + SEC_PRIV_INCREASE_BASE_PRIORITY = 12, + SEC_PRIV_LOAD_DRIVER = 13, + SEC_PRIV_CREATE_PAGEFILE = 14, + SEC_PRIV_INCREASE_QUOTA = 15, + SEC_PRIV_CHANGE_NOTIFY = 16, + SEC_PRIV_UNDOCK = 17, + SEC_PRIV_MANAGE_VOLUME = 18, + SEC_PRIV_IMPERSONATE = 19, + SEC_PRIV_CREATE_GLOBAL = 20, + SEC_PRIV_ENABLE_DELEGATION = 21, + SEC_PRIV_INTERACTIVE_LOGON = 22, + SEC_PRIV_NETWORK_LOGON = 23, + SEC_PRIV_REMOTE_INTERACTIVE_LOGON = 24 + } sec_privilege; + + + typedef [bitmap8bit] bitmap { + SEC_ACE_FLAG_OBJECT_INHERIT = 0x01, + SEC_ACE_FLAG_CONTAINER_INHERIT = 0x02, + SEC_ACE_FLAG_NO_PROPAGATE_INHERIT = 0x04, + SEC_ACE_FLAG_INHERIT_ONLY = 0x08, + SEC_ACE_FLAG_INHERITED_ACE = 0x10, + SEC_ACE_FLAG_VALID_INHERIT = 0x0f, + SEC_ACE_FLAG_SUCCESSFUL_ACCESS = 0x40, + SEC_ACE_FLAG_FAILED_ACCESS = 0x80 + } security_ace_flags; + + typedef [enum8bit] enum { + SEC_ACE_TYPE_ACCESS_ALLOWED = 0, + SEC_ACE_TYPE_ACCESS_DENIED = 1, + SEC_ACE_TYPE_SYSTEM_AUDIT = 2, + SEC_ACE_TYPE_SYSTEM_ALARM = 3, + SEC_ACE_TYPE_ALLOWED_COMPOUND = 4, + SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT = 5, + SEC_ACE_TYPE_ACCESS_DENIED_OBJECT = 6, + SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT = 7, + SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT = 8 + } security_ace_type; + + typedef [bitmap32bit] bitmap { + SEC_ACE_OBJECT_TYPE_PRESENT = 0x00000001, + SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x00000002 + } security_ace_object_flags; + + typedef [nodiscriminant] union { + /* this is the 'schemaIDGUID' attribute of the attribute object in the schema naming context */ + [case(SEC_ACE_OBJECT_TYPE_PRESENT)] GUID type; + [default]; + } security_ace_object_type; + + typedef [nodiscriminant] union { + /* this is the 'schemaIDGUID' attribute of the objectclass object in the schema naming context + * (of the parent container) + */ + [case(SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] GUID inherited_type; + [default]; + } security_ace_object_inherited_type; + + typedef struct { + security_ace_object_flags flags; + [switch_is(flags & SEC_ACE_OBJECT_TYPE_PRESENT)] security_ace_object_type type; + [switch_is(flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] security_ace_object_inherited_type inherited_type; + } security_ace_object; + + typedef [nodiscriminant] union { + [case(SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT)] security_ace_object object; + [case(SEC_ACE_TYPE_ACCESS_DENIED_OBJECT)] security_ace_object object; + [case(SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT)] security_ace_object object; + [case(SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT)] security_ace_object object; + [default]; + } security_ace_object_ctr; + + typedef [public,gensize,nosize] struct { + security_ace_type type; /* SEC_ACE_TYPE_* */ + security_ace_flags flags; /* SEC_ACE_FLAG_* */ + [value(ndr_size_security_ace(r,ndr->flags))] uint16 size; + uint32 access_mask; + [switch_is(type)] security_ace_object_ctr object; + dom_sid trustee; + } security_ace; + + typedef enum { + SECURITY_ACL_REVISION_NT4 = 2, + SECURITY_ACL_REVISION_ADS = 4 + } security_acl_revision; + + const uint NT4_ACL_REVISION = SECURITY_ACL_REVISION_NT4; + + typedef [public,gensize,nosize] struct { + security_acl_revision revision; + [value(ndr_size_security_acl(r,ndr->flags))] uint16 size; + [range(0,1000)] uint32 num_aces; + security_ace aces[num_aces]; + } security_acl; + + /* default revision for new ACLs */ + typedef [enum8bit] enum { + SECURITY_DESCRIPTOR_REVISION_1 = 1 + } security_descriptor_revision; + + const int SD_REVISION = SECURITY_DESCRIPTOR_REVISION_1; + + /* security_descriptor->type bits */ + typedef [bitmap16bit] bitmap { + SEC_DESC_OWNER_DEFAULTED = 0x0001, + SEC_DESC_GROUP_DEFAULTED = 0x0002, + SEC_DESC_DACL_PRESENT = 0x0004, + SEC_DESC_DACL_DEFAULTED = 0x0008, + SEC_DESC_SACL_PRESENT = 0x0010, + SEC_DESC_SACL_DEFAULTED = 0x0020, + SEC_DESC_DACL_TRUSTED = 0x0040, + SEC_DESC_SERVER_SECURITY = 0x0080, + SEC_DESC_DACL_AUTO_INHERIT_REQ = 0x0100, + SEC_DESC_SACL_AUTO_INHERIT_REQ = 0x0200, + SEC_DESC_DACL_AUTO_INHERITED = 0x0400, + SEC_DESC_SACL_AUTO_INHERITED = 0x0800, + SEC_DESC_DACL_PROTECTED = 0x1000, + SEC_DESC_SACL_PROTECTED = 0x2000, + SEC_DESC_RM_CONTROL_VALID = 0x4000, + SEC_DESC_SELF_RELATIVE = 0x8000 + } security_descriptor_type; + + typedef [gensize,nosize,public,flag(NDR_LITTLE_ENDIAN)] struct { + security_descriptor_revision revision; + security_descriptor_type 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 { + [range(0,0x40000),value(ndr_size_security_descriptor(sd,ndr->flags))] uint32 sd_size; + [subcontext(4)] security_descriptor *sd; + } sec_desc_buf; + + typedef [public] struct { + dom_sid *user_sid; + dom_sid *group_sid; + uint32 num_sids; + [size_is(num_sids)] dom_sid *sids[*]; + udlong privilege_mask; + } security_token; + + /* bits that determine which parts of a security descriptor + are being queried/set */ + typedef [public,bitmap32bit] bitmap { + SECINFO_OWNER = 0x00000001, + SECINFO_GROUP = 0x00000002, + SECINFO_DACL = 0x00000004, + SECINFO_SACL = 0x00000008, + SECINFO_UNPROTECTED_SACL = 0x10000000, + SECINFO_UNPROTECTED_DACL = 0x20000000, + SECINFO_PROTECTED_SACL = 0x40000000, + SECINFO_PROTECTED_DACL = 0x80000000 + } security_secinfo; + + typedef [public,bitmap32bit] bitmap { + KERB_ENCTYPE_DES_CBC_CRC = 0x00000001, + KERB_ENCTYPE_DES_CBC_MD5 = 0x00000002, + KERB_ENCTYPE_RC4_HMAC_MD5 = 0x00000004, + KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 = 0x00000008, + KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010 + } kerb_EncTypes; +} diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl new file mode 100644 index 0000000000..6b4b0b8a16 --- /dev/null +++ b/librpc/idl/spoolss.idl @@ -0,0 +1,1571 @@ +#include "idl_types.h" + +/* + spoolss interface definitions +*/ +import "misc.idl", "security.idl", "winreg.idl"; + +[ uuid("12345678-1234-abcd-ef00-0123456789ab"), + version(1.0), + endpoint("ncacn_np:[\\pipe\\spoolss]"), + pointer_default(unique), + helpstring("Spooler SubSystem"), + helper("librpc/ndr/ndr_spoolss_buf.h") +] interface spoolss +{ + typedef [v1_enum] enum winreg_Type winreg_Type; + typedef struct { + uint16 year; + uint16 month; + uint16 day_of_week; + uint16 day; + uint16 hour; + uint16 minute; + uint16 second; + uint16 millisecond; + } spoolss_Time; + + typedef struct { + [relative] nstring *printername; + [relative] nstring *servername; + uint32 cjobs; + uint32 total_jobs; + uint32 total_bytes; + spoolss_Time time; + uint32 global_counter; + uint32 total_pages; + uint32 version; + uint32 unknown10; + uint32 unknown11; + uint32 unknown12; + uint32 session_counter; + uint32 unknown14; + uint32 printer_errors; + uint32 unknown16; + uint32 unknown17; + uint32 unknown18; + uint32 unknown19; + uint32 change_id; + uint32 unknown21; + uint32 status; + uint32 unknown23; + uint32 c_setprinter; + uint16 unknown25; + uint16 unknown26; + uint32 unknown27; + uint32 unknown28; + uint32 unknown29; + } spoolss_PrinterInfo0; + + typedef [public,gensize] struct { + [charset(UTF16)] uint16 devicename[32]; + uint16 specversion; + uint16 driverversion; + uint16 size; + [value(r->driverextra_data.length)] uint16 __driverextra_length; + 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; + [charset(UTF16)] uint16 formname[32]; + 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; + [subcontext_size(__driverextra_length),subcontext(0),flag(NDR_REMAINING)] DATA_BLOB driverextra_data; + } spoolss_DeviceMode; + + typedef [public] bitmap { + PRINTER_ENUM_DEFAULT = 0x00000001, + PRINTER_ENUM_LOCAL = 0x00000002, + PRINTER_ENUM_CONNECTIONS = 0x00000004, + PRINTER_ENUM_FAVORITE = 0x00000004, + PRINTER_ENUM_NAME = 0x00000008, + PRINTER_ENUM_REMOTE = 0x00000010, + PRINTER_ENUM_SHARED = 0x00000020, + PRINTER_ENUM_NETWORK = 0x00000040, + PRINTER_ENUM_EXPAND = 0x00004000, + PRINTER_ENUM_CONTAINER = 0x00008000, + PRINTER_ENUM_ICON1 = 0x00010000, + PRINTER_ENUM_ICON2 = 0x00020000, + PRINTER_ENUM_ICON3 = 0x00040000, + PRINTER_ENUM_ICON4 = 0x00080000, + PRINTER_ENUM_ICON5 = 0x00100000, + PRINTER_ENUM_ICON6 = 0x00200000, + PRINTER_ENUM_ICON7 = 0x00400000, + PRINTER_ENUM_ICON8 = 0x00800000, + PRINTER_ENUM_HIDE = 0x01000000 + } spoolss_EnumPrinterFlags; + + typedef struct { + spoolss_EnumPrinterFlags flags; + [relative] nstring *name; + [relative] nstring *description; + [relative] nstring *comment; + } spoolss_PrinterInfo1; + + typedef bitmap { + PRINTER_ATTRIBUTE_QUEUED = 0x00000001, + PRINTER_ATTRIBUTE_DIRECT = 0x00000002, + PRINTER_ATTRIBUTE_DEFAULT = 0x00000004, + PRINTER_ATTRIBUTE_SHARED = 0x00000008, + PRINTER_ATTRIBUTE_NETWORK = 0x00000010, + PRINTER_ATTRIBUTE_HIDDEN = 0x00000020, + PRINTER_ATTRIBUTE_LOCAL = 0x00000040, + PRINTER_ATTRIBUTE_ENABLE_DEVQ = 0x00000080, + PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS = 0x00000100, + PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST = 0x00000200, + PRINTER_ATTRIBUTE_WORK_OFFLINE = 0x00000400, + PRINTER_ATTRIBUTE_ENABLE_BIDI = 0x00000800, + PRINTER_ATTRIBUTE_RAW_ONLY = 0x00001000, + PRINTER_ATTRIBUTE_PUBLISHED = 0x00002000, + PRINTER_ATTRIBUTE_FAX = 0x00004000, + PRINTER_ATTRIBUTE_TS = 0x00008000 + } spoolss_PrinterAttributes; + + typedef bitmap { + PRINTER_STATUS_PAUSED = 0x00000001, + PRINTER_STATUS_ERROR = 0x00000002, + PRINTER_STATUS_PENDING_DELETION = 0x00000004, + PRINTER_STATUS_PAPER_JAM = 0x00000008, + PRINTER_STATUS_PAPER_OUT = 0x00000010, + PRINTER_STATUS_MANUAL_FEED = 0x00000020, + PRINTER_STATUS_PAPER_PROBLEM = 0x00000040, + PRINTER_STATUS_OFFLINE = 0x00000080, + PRINTER_STATUS_IO_ACTIVE = 0x00000100, + PRINTER_STATUS_BUSY = 0x00000200, + PRINTER_STATUS_PRINTING = 0x00000400, + PRINTER_STATUS_OUTPUT_BIN_FULL = 0x00000800, + PRINTER_STATUS_NOT_AVAILABLE = 0x00001000, + PRINTER_STATUS_WAITING = 0x00002000, + PRINTER_STATUS_PROCESSING = 0x00004000, + PRINTER_STATUS_INITIALIZING = 0x00008000, + PRINTER_STATUS_WARMING_UP = 0x00010000, + PRINTER_STATUS_TONER_LOW = 0x00020000, + PRINTER_STATUS_NO_TONER = 0x00040000, + PRINTER_STATUS_PAGE_PUNT = 0x00080000, + PRINTER_STATUS_USER_INTERVENTION= 0x00100000, + PRINTER_STATUS_OUT_OF_MEMORY = 0x00200000, + PRINTER_STATUS_DOOR_OPEN = 0x00400000, + PRINTER_STATUS_SERVER_UNKNOWN = 0x00800000, + PRINTER_STATUS_POWER_SAVE = 0x01000000 + } spoolss_PrinterStatus; + + typedef struct { + [relative] nstring *servername; + [relative] nstring *printername; + [relative] nstring *sharename; + [relative] nstring *portname; + [relative] nstring *drivername; + [relative] nstring *comment; + [relative] nstring *location; + [relative,subcontext(0)] spoolss_DeviceMode *devmode; + [relative] nstring *sepfile; + [relative] nstring *printprocessor; + [relative] nstring *datatype; + [relative] nstring *parameters; + [relative,subcontext(0)] security_descriptor *secdesc; + spoolss_PrinterAttributes attributes; + uint32 priority; + uint32 defaultpriority; + uint32 starttime; + uint32 untiltime; + spoolss_PrinterStatus status; + uint32 cjobs; + uint32 averageppm; + } spoolss_PrinterInfo2; + + typedef struct { + [relative,subcontext(0)] security_descriptor *secdesc; + } spoolss_PrinterInfo3; + + typedef struct { + [relative] nstring *printername; + [relative] nstring *servername; + spoolss_PrinterAttributes attributes; + } spoolss_PrinterInfo4; + + typedef struct { + [relative] nstring *printername; + [relative] nstring *portname; + spoolss_PrinterAttributes attributes; + uint32 device_not_selected_timeout; + uint32 transmission_retry_timeout; + } spoolss_PrinterInfo5; + + typedef struct { + spoolss_PrinterStatus status; + } spoolss_PrinterInfo6; + + typedef bitmap { + DSPRINT_PUBLISH = 0x00000001, + DSPRINT_UPDATE = 0x00000002, + DSPRINT_UNPUBLISH = 0x00000004, + DSPRINT_REPUBLISH = 0x00000008, + DSPRINT_PENDING = 0x80000000 + } spoolss_DsPrintAction; + + typedef struct { + [relative] nstring *guid; /* text form of printer guid */ + spoolss_DsPrintAction action; + } spoolss_PrinterInfo7; + + typedef struct { + [relative,subcontext(0)] spoolss_DeviceMode *devmode; + } spoolss_DeviceModeInfo; + + typedef [nodiscriminant,relative_base,public] union { + [case(0)] spoolss_PrinterInfo0 info0; + [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; + [case(8)] spoolss_DeviceModeInfo info8; + [case(9)] spoolss_DeviceModeInfo info9; + [default]; + } spoolss_PrinterInfo; + + /******************/ + /* Function: 0x00 */ + /* we are using this as internal parsing code */ + [public,noopnum,noprint] WERROR _spoolss_EnumPrinters( + [in] spoolss_EnumPrinterFlags flags, + [in,unique] [string,charset(UTF16)] uint16 *server, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count + ); + [public,noopnum,noprint] void __spoolss_EnumPrinters( + [in] uint32 level, + [in] uint32 count, + [out,switch_is(level)] spoolss_PrinterInfo info[count] + ); + [nopull,nopush] WERROR spoolss_EnumPrinters( + [in] spoolss_EnumPrinterFlags flags, + [in,unique] [string,charset(UTF16)] uint16 *server, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + /* what we have here is a subcontext containing an array of no discriminant unions + * and the array has no size in front + */ + [out,unique,switch_is(level),size_is(count)] spoolss_PrinterInfo *info, + [out] uint32 needed, + [out] uint32 count + ); + + /******************/ + /* Function: 0x01 */ + typedef struct { + [value(_ndr_size_spoolss_DeviceMode(devmode, ndr->flags))] uint32 _ndr_size; + [subcontext(4),subcontext_size(_ndr_size)] spoolss_DeviceMode *devmode; + } spoolss_DevmodeContainer; + + [public] WERROR spoolss_OpenPrinter( + [in,unique] [string,charset(UTF16)] uint16 *printername, + [in,unique] [string,charset(UTF16)] uint16 *datatype, + [in] spoolss_DevmodeContainer devmode_ctr, + [in] uint32 access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x02 */ + 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,relative_base,public] union { + [case(1)] spoolss_JobInfo1 info1; + [case(2)]; /* TODO */ + [case(3)]; /* TODO */ + [default]; + } spoolss_JobInfo; + + typedef struct { + uint32 level; + [switch_is(level)] spoolss_JobInfo info; + } spoolss_JobInfoContainer; + + typedef [v1_enum] enum { + SPOOLSS_JOB_CONTROL_PAUSE = 1, + SPOOLSS_JOB_CONTROL_RESUME = 2, + SPOOLSS_JOB_CONTROL_CANCEL = 3, + SPOOLSS_JOB_CONTROL_RESTART = 4, + SPOOLSS_JOB_CONTROL_DELETE = 5, + SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER = 6, + SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED = 7 + } spoolss_JobControl; + + WERROR spoolss_SetJob( + [in,ref] policy_handle *handle, + [in] uint32 job_id, + [in,unique] spoolss_JobInfoContainer *ctr, + [in] spoolss_JobControl command + ); + + /******************/ + /* Function: 0x03 */ + WERROR spoolss_GetJob( + [in,ref] policy_handle *handle, + [in] uint32 job_id, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_JobInfo *info, + [out] uint32 needed + ); + + /******************/ + /* Function: 0x04 */ + [public,noopnum,noprint] WERROR _spoolss_EnumJobs( + [in,ref] policy_handle *handle, + [in] uint32 firstjob, + [in] uint32 numjobs, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count + ); + [public,noopnum,noprint] void __spoolss_EnumJobs( + [in] uint32 level, + [in] uint32 count, + [out,switch_is(level)] spoolss_JobInfo info[count] + ); + [nopull,nopush] WERROR spoolss_EnumJobs( + [in,ref] policy_handle *handle, + [in] uint32 firstjob, + [in] uint32 numjobs, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,switch_is(level),size_is(count)] spoolss_JobInfo *info, + [out] uint32 needed, + [out] uint32 count + ); + + /******************/ + /* Function: 0x05 */ + [todo] WERROR spoolss_AddPrinter( + /* This function is not implemented in Samba 3 as no + clients have been observed using it. */ + ); + + /******************/ + /* Function: 0x06 */ + [todo] WERROR spoolss_DeletePrinter( + ); + + /******************/ + /* Function: 0x07 */ + typedef [v1_enum] enum { + SPOOLSS_PRINTER_CONTROL_UNPAUSE = 0, + SPOOLSS_PRINTER_CONTROL_PAUSE = 1, + SPOOLSS_PRINTER_CONTROL_RESUME = 2, + SPOOLSS_PRINTER_CONTROL_PURGE = 3, + SPOOLSS_PRINTER_CONTROL_SET_STATUS = 4 + } spoolss_PrinterControl; + + typedef [switch_type(uint32)] union { + [case(0)] spoolss_PrinterInfo0 *info0; + [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; + [case(8)] spoolss_DeviceModeInfo *info8; + [case(9)] spoolss_DeviceModeInfo *info9; + [default]; + } spoolss_SetPrinterInfo; + + WERROR spoolss_SetPrinter( + [in,ref] policy_handle *handle, + [in] uint32 level, + [in,switch_is(level)] spoolss_SetPrinterInfo info, + [in] spoolss_DevmodeContainer devmode_ctr, + [in] sec_desc_buf secdesc_ctr, + [in] spoolss_PrinterControl command + ); + + /******************/ + /* Function: 0x08 */ + [public] WERROR spoolss_GetPrinter( + [in,ref] policy_handle *handle, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_PrinterInfo *info, + [out] uint32 needed + ); + + /******************/ + /* Function: 0x09 */ + [todo] WERROR spoolss_AddPrinterDriver( + ); + + typedef struct { + [relative] nstring *driver_name; + } spoolss_DriverInfo1; + + typedef [v1_enum] enum { + SPOOLSS_DRIVER_VERSION_9X = 0, + SPOOLSS_DRIVER_VERSION_NT35 = 1, + SPOOLSS_DRIVER_VERSION_NT4 = 2, + SPOOLSS_DRIVER_VERSION_200X = 3 + } spoolss_DriverOSVersion; + + typedef struct { + spoolss_DriverOSVersion version; + [relative] nstring *driver_name; + [relative] nstring *architecture; + [relative] nstring *driver_path; + [relative] nstring *data_file; + [relative] nstring *config_file; + } spoolss_DriverInfo2; + + typedef struct { + spoolss_DriverOSVersion 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_array *dependent_files; + [relative] nstring *monitor_name; + [relative] nstring *default_datatype; + } spoolss_DriverInfo3; + + typedef struct { + spoolss_DriverOSVersion 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_array *dependent_files; + [relative] nstring *monitor_name; + [relative] nstring *default_datatype; + [relative] nstring_array *previous_names; + } spoolss_DriverInfo4; + + typedef struct { + spoolss_DriverOSVersion version; + [relative] nstring *driver_name; + [relative] nstring *architecture; + [relative] nstring *driver_path; + [relative] nstring *data_file; + [relative] nstring *config_file; + uint32 driver_attributes; + uint32 config_version; + uint32 driver_version; + } spoolss_DriverInfo5; + + typedef struct { + spoolss_DriverOSVersion 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_array *dependent_files; + [relative] nstring *monitor_name; + [relative] nstring *default_datatype; + [relative] nstring_array *previous_names; + NTTIME driver_data; + hyper driver_version; + [relative] nstring *manufacturer_name; + [relative] nstring *manufacturer_url; + [relative] nstring *hardware_id; + [relative] nstring *provider; + } spoolss_DriverInfo6; + + typedef [nodiscriminant,relative_base,public] union { + [case(1)] spoolss_DriverInfo1 info1; + [case(2)] spoolss_DriverInfo2 info2; + [case(3)] spoolss_DriverInfo3 info3; + [case(4)] spoolss_DriverInfo4 info4; + [case(5)] spoolss_DriverInfo5 info5; + [case(6)] spoolss_DriverInfo6 info6; + [default]; + } spoolss_DriverInfo; + + /******************/ + /* Function: 0x0a */ + [public,noopnum,noprint] WERROR _spoolss_EnumPrinterDrivers( + [in,unique] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *environment, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count + ); + [public,noopnum,noprint] void __spoolss_EnumPrinterDrivers( + [in] uint32 level, + [in] uint32 count, + [out,switch_is(level)] spoolss_DriverInfo info[count] + ); + [nopull,nopush] WERROR spoolss_EnumPrinterDrivers( + [in,unique] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *environment, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,switch_is(level),size_is(count)] spoolss_DriverInfo *info, + [out] uint32 needed, + [out] uint32 count + ); + + /******************/ + /* Function: 0x0b */ + [todo] WERROR spoolss_GetPrinterDriver( + ); + + /******************/ + /* Function: 0x0c */ + typedef struct { + nstring directory_name; + } spoolss_DriverDirectoryInfo1; + + /* NOTE: it's seems that w2k3 completly ignores the level + in its server code + */ + typedef [nodiscriminant,relative_base,gensize,public] union { + [case(1)] spoolss_DriverDirectoryInfo1 info1; + [default] spoolss_DriverDirectoryInfo1 info1; + } spoolss_DriverDirectoryInfo; + + [public] WERROR spoolss_GetPrinterDriverDirectory( + [in,unique] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *environment, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_DriverDirectoryInfo *info, + [out] uint32 needed + ); + + /******************/ + /* Function: 0x0d */ + WERROR spoolss_DeletePrinterDriver( + [in,ref] policy_handle *handle, + [in,unique] [string,charset(UTF16)] uint16 *server, + [in] [string,charset(UTF16)] uint16 architecture[], + [in] [string,charset(UTF16)] uint16 driver[] + ); + + /******************/ + /* Function: 0x0e */ + [todo] WERROR spoolss_AddPrintProcessor( + ); + + /******************/ + /* Function: 0x0f */ + typedef struct { + [relative] nstring *print_processor_name; + } spoolss_PrintProcessorInfo1; + + typedef [nodiscriminant,relative_base,public] union { + [case(1)] spoolss_PrintProcessorInfo1 info1; + [default]; + } spoolss_PrintProcessorInfo; + + [public,noopnum,noprint] WERROR _spoolss_EnumPrintProcessors( + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *environment, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count + ); + [public,noopnum,noprint] void __spoolss_EnumPrintProcessors( + [in] uint32 level, + [in] uint32 count, + [out,switch_is(level)] spoolss_PrintProcessorInfo info[count] + ); + [nopull,nopush] WERROR spoolss_EnumPrintProcessors( + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *environment, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,switch_is(level),size_is(count)] spoolss_PrintProcessorInfo *info, + [out] uint32 needed, + [out] uint32 count + ); + + /******************/ + /* Function: 0x10 */ + [todo] WERROR spoolss_GetPrintProcessorDirectory( + ); + + /******************/ + /* Function: 0x11 */ + typedef struct { + [string,charset(UTF16)] uint16 *document_name; + [string,charset(UTF16)] uint16 *output_file; + [string,charset(UTF16)] uint16 *datatype; + } spoolss_DocumentInfo1; + + typedef [switch_type(uint32)] union { + [case(1)] spoolss_DocumentInfo1 *info1; + [case(2)]; /* TODO */ + [case(3)]; /* TODO */ + [default]; + } spoolss_DocumentInfo; + + WERROR spoolss_StartDocPrinter( + [in,ref] policy_handle *handle, + [in] uint32 level, + [in,switch_is(level)] spoolss_DocumentInfo info, + [out] uint32 job_id + ); + + /******************/ + /* Function: 0x12 */ + WERROR spoolss_StartPagePrinter( + [in,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x13 */ + WERROR spoolss_WritePrinter( + [in,ref] policy_handle *handle, + [in] DATA_BLOB data, + [in,value(r->in.data.length)] uint32 _data_size, + [out] uint32 num_written + ); + + /******************/ + /* Function: 0x14 */ + WERROR spoolss_EndPagePrinter( + [in,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x15 */ + WERROR spoolss_AbortPrinter( + [in,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x16 */ + WERROR spoolss_ReadPrinter( + [in,ref] policy_handle *handle, + [in] uint32 data_size, + [out] DATA_BLOB data, + [out,value(r->out.data.length)] uint32 _data_size + ); + + /******************/ + /* Function: 0x17 */ + WERROR spoolss_EndDocPrinter( + [in,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x18 */ + [todo] WERROR spoolss_AddJob( + ); + + /******************/ + /* Function: 0x19 */ + [todo] WERROR spoolss_ScheduleJob( + ); + + /******************/ + /* Function: 0x1a */ + const string SPOOLSS_ARCHITECTURE_NT_X86 = "Windows NT x86"; + + typedef [public,gensize] struct { + [value(ndr_size_spoolss_OSVersion(r,ndr->flags))] uint32 _ndr_size; + uint32 major; + uint32 minor; + uint32 build; + [value(2)] uint32 unknown; + [subcontext(0),subcontext_size(256)] nstring extra_string; + } spoolss_OSVersion; + + typedef [public,gensize] struct { + [value(ndr_size_spoolss_OSVersionEx(r,ndr->flags))] uint32 _ndr_size; + uint32 major; + uint32 minor; + uint32 build; + [value(2)] uint32 unknown1; + [subcontext(0),subcontext_size(256)] nstring extra_string; + uint32 unknown2;/* service pack number? I saw 0 from w2k3 and 1 from winxp sp1*/ + uint32 unknown3;/* hmm? w2k3: 131346(0x20112) winxp sp1: 503382272 0x1E010100 */ + } spoolss_OSVersionEx; + + typedef [v1_enum] enum { + SPOOLSS_PRINTER_DATA_TYPE_NULL = 0, + SPOOLSS_PRINTER_DATA_TYPE_STRING = 1, + SPOOLSS_PRINTER_DATA_TYPE_BINARY = 3, + SPOOLSS_PRINTER_DATA_TYPE_UINT32 = 4, + SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY = 7 + } spoolss_PrinterDataType; + + typedef [nodiscriminant,public,gensize] union { + [case(SPOOLSS_PRINTER_DATA_TYPE_NULL)]; + [case(SPOOLSS_PRINTER_DATA_TYPE_STRING)] nstring string; + [case(SPOOLSS_PRINTER_DATA_TYPE_BINARY),flag(NDR_REMAINING)] DATA_BLOB binary; + [case(SPOOLSS_PRINTER_DATA_TYPE_UINT32)] uint32 value; + [case(SPOOLSS_PRINTER_DATA_TYPE_STRING_ARRAY)] nstring_array string_array; + [default,flag(NDR_REMAINING)] DATA_BLOB data; + } spoolss_PrinterData; + + [noopnum,noprint,public] WERROR _spoolss_GetPrinterData( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 value_name[], + [in] uint32 offered, + [out] spoolss_PrinterDataType type, + [out] DATA_BLOB data, + [out] uint32 needed + ); + [noopnum,noprint,public] void __spoolss_GetPrinterData( + [in] spoolss_PrinterDataType type, + [out,switch_is(type)] spoolss_PrinterData data + ); + [nopull,nopush,public] WERROR spoolss_GetPrinterData( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 value_name[], + [in] uint32 offered, + [out] spoolss_PrinterDataType type, + [out,subcontext(4),subcontext_size(offered),switch_is(type)] spoolss_PrinterData data, + [out] uint32 needed + ); + + /******************/ + /* Function: 0x1b */ + [noopnum,nopull,noprint,public] WERROR _spoolss_SetPrinterData( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 value_name[], + [in] spoolss_PrinterDataType type, + [in] DATA_BLOB data, + [in] uint32 _offered + ); + [noopnum,nopull,noprint,public] void __spoolss_SetPrinterData( + [in] spoolss_PrinterDataType type, + [out,switch_is(type)] spoolss_PrinterData data + ); + [nopush] WERROR spoolss_SetPrinterData( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 value_name[], + [in] spoolss_PrinterDataType type, + [in,subcontext(4),switch_is(type)] spoolss_PrinterData data, + [in,value(ndr_size_spoolss_PrinterData(&data,type,flags))] uint32 _offered + ); + + /******************/ + /* Function: 0x1c */ + [todo] WERROR spoolss_WaitForPrinterChange( + ); + + /******************/ + /* Function: 0x1d */ + [public] WERROR spoolss_ClosePrinter( + [in,out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x1e */ + typedef [v1_enum] enum { + SPOOLSS_FORM_USER = 0, + SPOOLSS_FORM_BUILTIN = 1, + SPOOLSS_FORM_PRINTER = 2 + } spoolss_FormFlags; + + typedef struct { + uint32 width; + uint32 height; + } spoolss_FormSize; + + typedef struct { + uint32 left; + uint32 top; + uint32 right; + uint32 bottom; + } spoolss_FormArea; + + typedef struct { + spoolss_FormFlags flags; + [relative] nstring *form_name; + spoolss_FormSize size; + spoolss_FormArea area; + } spoolss_FormInfo1; + + typedef [nodiscriminant,relative_base,public,gensize] union { + [case(1)] spoolss_FormInfo1 info1; + [default]; + } spoolss_FormInfo; + + typedef struct { + spoolss_FormFlags flags; + [string,charset(UTF16)] uint16 *form_name; + spoolss_FormSize size; + spoolss_FormArea area; + } spoolss_AddFormInfo1; + + typedef [switch_type(uint32)] union { + [case(1)] spoolss_AddFormInfo1 *info1; + } spoolss_AddFormInfo; + + 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] [string,charset(UTF16)] uint16 form_name[] + ); + + /******************/ + /* Function: 0x20 */ + WERROR spoolss_GetForm( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 form_name[], + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_FormInfo *info, + [out] uint32 needed + ); + + /******************/ + /* Function: 0x21 */ + WERROR spoolss_SetForm( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 form_name[], + [in] uint32 level, + [in,switch_is(level)] spoolss_AddFormInfo info + ); + + /******************/ + /* Function: 0x22 */ + [public,noopnum,noprint] WERROR _spoolss_EnumForms( + [in,ref] policy_handle *handle, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count + ); + [public,noopnum,noprint] void __spoolss_EnumForms( + [in] uint32 level, + [in] uint32 count, + [out,switch_is(level)] spoolss_FormInfo info[count] + ); + [nopull,nopush] WERROR spoolss_EnumForms( + [in,ref] policy_handle *handle, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,switch_is(level),size_is(count)] spoolss_FormInfo *info, + [out] uint32 needed, + [out] uint32 count + ); + + typedef struct { + [relative] nstring *port_name; + } spoolss_PortInfo1; + + typedef bitmap { + SPOOLSS_PORT_TYPE_WRITE = 0x00000001, + SPOOLSS_PORT_TYPE_READ = 0x00000002, + SPOOLSS_PORT_TYPE_REDIRECTED = 0x00000004, + SPOOLSS_PORT_TYPE_NET_ATTACHED = 0x00000008 + } spoolss_PortType; + + typedef struct { + [relative] nstring *port_name; + [relative] nstring *monitor_name; + [relative] nstring *description; + spoolss_PortType port_type; + uint32 reserved; + } spoolss_PortInfo2; + + typedef [nodiscriminant,relative_base,public] union { + [case(1)] spoolss_PortInfo1 info1; + [case(2)] spoolss_PortInfo2 info2; + [case(3)]; /* TODO */ + [default]; + } spoolss_PortInfo; + + /******************/ + /* Function: 0x23 */ + [public,noopnum,noprint] WERROR _spoolss_EnumPorts( + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count + ); + [public,noopnum,noprint] void __spoolss_EnumPorts( + [in] uint32 level, + [in] uint32 count, + [out,switch_is(level)] spoolss_PortInfo info[count] + ); + [nopull,nopush] WERROR spoolss_EnumPorts( + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,switch_is(level),size_is(count)] spoolss_PortInfo *info, + [out] uint32 needed, + [out] uint32 count + ); + + /******************/ + /* Function: 0x24 */ + typedef struct { + [relative] nstring *monitor_name; + } spoolss_MonitorInfo1; + + typedef struct { + [relative] nstring *monitor_name; + [relative] nstring *environment; + [relative] nstring *dll_name; + } spoolss_MonitorInfo2; + + typedef [nodiscriminant,relative_base,public] union { + [case(1)] spoolss_MonitorInfo1 info1; + [case(2)] spoolss_MonitorInfo2 info2; + [default]; + } spoolss_MonitorInfo; + + [public,noopnum,noprint] WERROR _spoolss_EnumMonitors( + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count + ); + [public,noopnum,noprint] void __spoolss_EnumMonitors( + [in] uint32 level, + [in] uint32 count, + [out,switch_is(level)] spoolss_MonitorInfo info[count] + ); + [nopull,nopush] WERROR spoolss_EnumMonitors( + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [out,unique,switch_is(level),size_is(count)] spoolss_MonitorInfo *info, + [out] uint32 needed, + [out] uint32 count + ); + + /******************/ + /* Function: 0x25 */ + WERROR spoolss_AddPort( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in] uint32 unknown, + [in] [string,charset(UTF16)] uint16 monitor_name[] + ); + + /******************/ + /* Function: 0x26 */ + [todo] WERROR spoolss_ConfigurePort( + ); + + /******************/ + /* Function: 0x27 */ + [todo] WERROR spoolss_DeletePort( + ); + + /******************/ + /* Function: 0x28 */ + [todo] WERROR spoolss_CreatePrinterIC( + ); + + /******************/ + /* Function: 0x29 */ + [todo] WERROR spoolss_PlayGDIScriptOnPrinterIC( + ); + + /******************/ + /* Function: 0x2a */ + [todo] WERROR spoolss_DeletePrinterIC( + ); + + /******************/ + /* Function: 0x2b */ + [todo] WERROR spoolss_AddPrinterConnection( + ); + + /******************/ + /* Function: 0x2c */ + [todo] WERROR spoolss_DeletePrinterConnection( + ); + + /******************/ + /* Function: 0x2d */ + [todo] WERROR spoolss_PrinterMessageBox( + /* Marked as obsolete in MSDN. "Not necessary and has + no effect". */ + ); + + /******************/ + /* Function: 0x2e */ + [todo] WERROR spoolss_AddMonitor( + ); + + /******************/ + /* Function: 0x2f */ + [todo] WERROR spoolss_DeleteMonitor( + ); + + /******************/ + /* Function: 0x30 */ + [todo] WERROR spoolss_DeletePrintProcessor( + ); + + /******************/ + /* Function: 0x31 */ + [todo] WERROR spoolss_AddPrintProvidor( + ); + + /******************/ + /* Function: 0x32 */ + [todo] WERROR spoolss_DeletePrintProvidor( + ); + + /******************/ + /* Function: 0x33 */ + [todo] WERROR spoolss_EnumPrintProcDataTypes( + ); + + /******************/ + /* Function: 0x34 */ + [todo] WERROR spoolss_ResetPrinter( + ); + + /******************/ + /* Function: 0x35 */ + WERROR spoolss_GetPrinterDriver2( + [in,ref] policy_handle *handle, + [in,unique] [string,charset(UTF16)] uint16 *architecture, + [in] uint32 level, + [in,unique] DATA_BLOB *buffer, + [in] uint32 offered, + [in] uint32 client_major_version, + [in] uint32 client_minor_version, + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 server_major_version, + [out] uint32 server_minor_version + ); + + /******************/ + /* Function: 0x36 */ + [todo] WERROR spoolss_FindFirstPrinterChangeNotification( + ); + + /******************/ + /* Function: 0x37 */ + [todo] WERROR spoolss_FindNextPrinterChangeNotification( + ); + + /******************/ + /* Function: 0x38 */ + [public] WERROR spoolss_FindClosePrinterNotify( + [in,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x39 */ + [todo] WERROR spoolss_RouterFindFirstPrinterChangeNotificationOld( + ); + + /******************/ + /* Function: 0x3a */ + [public] WERROR spoolss_ReplyOpenPrinter( + [in,string,charset(UTF16)] uint16 server_name[], + [in] uint32 printer_local, + [in] winreg_Type type, + [in] uint32 unknown1, + [in] uint32 unknown2, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x3b */ + [todo] WERROR spoolss_RouterReplyPrinter( + ); + + /******************/ + /* Function: 0x3c */ + [public] WERROR spoolss_ReplyClosePrinter( + [in,out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x3d */ + [todo] WERROR spoolss_AddPortEx( + ); + + /******************/ + /* Function: 0x3e */ + [todo] WERROR spoolss_RouterFindFirstPrinterChangeNotification( + ); + + /******************/ + /* Function: 0x3f */ + [todo] WERROR spoolss_SpoolerInit( + ); + + /******************/ + /* Function: 0x40 */ + [todo] WERROR spoolss_ResetPrinterEx( + ); + + typedef [enum16bit] enum { + SPOOLSS_FIELD_SERVER_NAME = 0, + SPOOLSS_FIELD_PRINTER_NAME = 1, + SPOOLSS_FIELD_SHARE_NAME = 2, + SPOOLSS_FIELD_PORT_NAME = 3, + SPOOLSS_FIELD_DRIVER_NAME = 4, + SPOOLSS_FIELD_COMMENT = 5, + SPOOLSS_FIELD_LOCATION = 6, + SPOOLSS_FIELD_DEVMODE = 7, + SPOOLSS_FIELD_SEPFILE = 8, + SPOOLSS_FIELD_PRINT_PROCESSOR = 9, + SPOOLSS_FIELD_PARAMETERS = 10, + SPOOLSS_FIELD_DATATYPE = 11, + SPOOLSS_FIELD_SECURITY_DESCRIPTOR=12, + SPOOLSS_FIELD_ATTRIBUTES = 13, + SPOOLSS_FIELD_PRIORITY = 14, + SPOOLSS_FIELD_DEFAULT_PRIORITY = 15, + SPOOLSS_FIELD_START_TIME = 16, + SPOOLSS_FIELD_UNTIL_TIME = 17, + SPOOLSS_FIELD_STATUS = 18, + SPOOLSS_FIELD_STATUS_STRING = 19, + SPOOLSS_FIELD_CJOBS = 20, + SPOOLSS_FIELD_AVERAGE_PPM = 21, + SPOOLSS_FIELD_TOTAL_PAGES = 22, + SPOOLSS_FIELD_PAGES_PRINTED = 23, + SPOOLSS_FIELD_TOTAL_BYTES = 24, + SPOOLSS_FIELD_BYTES_PRINTED = 25 + } spoolss_Field; + + typedef [enum16bit] enum { + SPOOLSS_NOTIFY_PRINTER = 0, + SPOOLSS_NOTIFY_JOB = 1 + } spoolss_NotifyType; + + /******************/ + /* Function: 0x41 */ + typedef struct { + spoolss_NotifyType type; + uint16 u1; + uint32 u2; + uint32 u3; + uint32 count; + [size_is(count)] spoolss_Field *fields; + } spoolss_NotifyOptionsArray; + + typedef struct { + uint32 version; + uint32 flags; + uint32 count; + [size_is(count)] spoolss_NotifyOptionsArray *options; + } spoolss_NotifyOptionsContainer; + + [public] WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx( + [in,ref] policy_handle *handle, + [in] uint32 flags, + [in] uint32 options, + [in,unique] [string,charset(UTF16)] uint16 *str, + [in] uint32 printer_local, + [in,unique] spoolss_NotifyOptionsContainer *t1 + ); + + /******************/ + /* Function: 0x42 */ + [todo] WERROR spoolss_RouterRefreshPrinterChangeNotification( + ); + + typedef struct { + uint32 size; + [size_is(size/2),unique,charset(UTF16)] uint16 *string; + } spoolss_NotifyUTF16String; + + typedef struct { + uint32 size; + [size_is(size),charset(DOS)] uint8 *string; + } spoolss_NotifyDOSString; + + typedef struct { + uint16 data[8]; + } spoolss_NotifyBlobData; + + typedef struct { + uint32 len; + [unique] spoolss_NotifyBlobData *data; + } spoolss_NotifyBlob; + + typedef [switch_type(uint32)] union { + [case(1)] dlong integer; + [case(2)] spoolss_NotifyUTF16String utf16_string; + [case(3)] spoolss_NotifyDOSString ascii_string; + [case(4)] spoolss_NotifyBlob blob; + [case(5)] spoolss_NotifyDOSString ascii_string; + } spoolss_NotifyData; + + typedef struct { + spoolss_NotifyType type; + spoolss_Field field; + uint32 variable_type; + uint32 job_id; + [switch_is(variable_type)] spoolss_NotifyData data; + } spoolss_Notify; + + typedef struct { + uint32 version; + uint32 flags; + uint32 count; + [size_is(count)] spoolss_Notify notifies[]; + } spoolss_NotifyInfo; + + /******************/ + /* Function: 0x43 */ + [public] WERROR spoolss_RemoteFindNextPrinterChangeNotifyEx( + [in,ref] policy_handle *handle, + [in] uint32 change_low, + [in,unique] spoolss_NotifyOptionsContainer *container, + [out, unique] spoolss_NotifyInfo *info + ); + + /******************/ + /* Function: 0x44 */ + [todo] WERROR spoolss_44( + ); + + typedef struct { + uint32 size; + [string,charset(UTF16)] uint16 *client; + [string,charset(UTF16)] uint16 *user; + uint32 build; + uint32 major; + uint32 minor; + uint32 processor; + } spoolss_UserLevel1; + + typedef union { + [case(1)] spoolss_UserLevel1 *level1; + } spoolss_UserLevel; + + typedef bitmap { + SERVER_ACCESS_ADMINISTER = 0x00000001, + SERVER_ACCESS_ENUMERATE = 0x00000002, + PRINTER_ACCESS_ADMINISTER = 0x00000004, + PRINTER_ACCESS_USE = 0x00000008, + JOB_ACCESS_ADMINISTER = 0x00000010 + } spoolss_AccessRights; + + /* Access rights for print servers */ + const int SERVER_ALL_ACCESS = SEC_STD_REQUIRED | + SERVER_ACCESS_ADMINISTER | + SERVER_ACCESS_ENUMERATE; + + const int SERVER_READ = SEC_STD_READ_CONTROL | + SERVER_ACCESS_ENUMERATE; + + const int SERVER_WRITE = STANDARD_RIGHTS_WRITE_ACCESS | + SERVER_ACCESS_ADMINISTER | + SERVER_ACCESS_ENUMERATE; + + const int SERVER_EXECUTE = SEC_STD_READ_CONTROL | + SERVER_ACCESS_ENUMERATE; + + /* Access rights for printers */ + const int PRINTER_ALL_ACCESS = SEC_STD_REQUIRED | + PRINTER_ACCESS_ADMINISTER | + PRINTER_ACCESS_USE; + + const int PRINTER_READ = SEC_STD_READ_CONTROL | + PRINTER_ACCESS_USE; + + const int PRINTER_WRITE = STANDARD_RIGHTS_WRITE_ACCESS | + PRINTER_ACCESS_USE; + + const int PRINTER_EXECUTE = SEC_STD_READ_CONTROL | + PRINTER_ACCESS_USE; + + /* Access rights for jobs */ + const int JOB_ALL_ACCESS = SEC_STD_REQUIRED | + JOB_ACCESS_ADMINISTER; + + const int JOB_READ = SEC_STD_READ_CONTROL | + JOB_ACCESS_ADMINISTER; + + const int JOB_WRITE = STANDARD_RIGHTS_WRITE_ACCESS | + JOB_ACCESS_ADMINISTER; + + const int JOB_EXECUTE = SEC_STD_READ_CONTROL | + JOB_ACCESS_ADMINISTER; + + /* ACE masks for various print permissions */ + const int PRINTER_ACE_FULL_CONTROL = SEC_GENERIC_ALL | + PRINTER_ALL_ACCESS; + + const int PRINTER_ACE_MANAGE_DOCUMENTS = SEC_GENERIC_ALL | + READ_CONTROL_ACCESS; + + const int PRINTER_ACE_PRINT = GENERIC_EXECUTE_ACCESS | + READ_CONTROL_ACCESS | + PRINTER_ACCESS_USE; + + /******************/ + /* Function: 0x45 */ + [public] WERROR spoolss_OpenPrinterEx( + [in,unique] [string,charset(UTF16)] uint16 *printername, + [in,unique] [string,charset(UTF16)] uint16 *datatype, + [in] spoolss_DevmodeContainer devmode_ctr, + [in] uint32 access_mask, + [in] uint32 level, + [in,switch_is(level)] spoolss_UserLevel userlevel, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x46 */ + WERROR spoolss_AddPrinterEx( + [in,unique] [string,charset(UTF16)] uint16 *server, + [in] uint32 level, + [in,unique,switch_is(level)] spoolss_PrinterInfo *info, + [in] spoolss_DevmodeContainer devmode_ctr, + [in,unique] security_descriptor *secdesc, + [in] uint32 ulevel, + [in,switch_is(ulevel)] spoolss_UserLevel userlevel + ); + + /******************/ + /* Function: 0x47 */ + [todo] WERROR spoolss_47( + ); + + /******************/ + /* Function: 0x48 */ + WERROR spoolss_EnumPrinterData( + [in,ref] policy_handle *handle, + [in] uint32 enum_index, + [out,ref,size_is(value_offered/2),charset(UTF16)] uint16 *value_name, + [in] uint32 value_offered, + [out,ref] uint32 *value_needed, + [out,ref] uint32 *printerdata_type, + [out,ref] DATA_BLOB *buffer, + [in] uint32 data_offered, + [out,ref] uint32 *data_needed + ); + + /******************/ + /* Function: 0x49 */ + WERROR spoolss_DeletePrinterData( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 value_name[] + ); + + /******************/ + /* Function: 0x4a */ + [todo] WERROR spoolss_4a( + ); + + /******************/ + /* Function: 0x4b */ + [todo] WERROR spoolss_4b( + ); + + /******************/ + /* Function: 0x4c */ + [todo] WERROR spoolss_4c( + ); + + /******************/ + /* Function: 0x4d */ + WERROR spoolss_SetPrinterDataEx( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 key_name[], + [in] [string,charset(UTF16)] uint16 value_name[], + [in] uint32 type, + [in] DATA_BLOB buffer, + [in] uint32 offered + ); + + /******************/ + /* Function: 0x4e */ + WERROR spoolss_GetPrinterDataEx( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 key_name[], + [in] [string,charset(UTF16)] uint16 value_name[], + [in] uint32 offered, + [out] uint32 type, + [out] DATA_BLOB buffer, + [out] uint32 needed + ); + + /******************/ + /* Function: 0x4f */ + [public] WERROR spoolss_EnumPrinterDataEx( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 key_name[], + [in] uint32 offered, + [out] DATA_BLOB buffer, + [out] uint32 needed, + [out] uint32 count + ); + + /******************/ + /* Function: 0x50 */ + [public] WERROR spoolss_EnumPrinterKey( + [in, ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 key_name[], + [out] uint32 key_buffer_size, + [out] uint16 key_buffer[key_buffer_size], + [in,out] uint32 needed + ); + + /******************/ + /* Function: 0x51 */ + WERROR spoolss_DeletePrinterDataEx( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 key_name[], + [in] [string,charset(UTF16)] uint16 value_name[] + ); + + /******************/ + /* Function: 0x52 */ + [todo] WERROR spoolss_DeletePrinterKey( + ); + + /******************/ + /* Function: 0x53 */ + [todo] WERROR spoolss_53( + ); + + /******************/ + /* Function: 0x54 */ + [todo] WERROR spoolss_DeletePrinterDriverEx( + ); + + /******************/ + /* Function: 0x55 */ + [todo] WERROR spoolss_55( + ); + + /******************/ + /* Function: 0x56 */ + [todo] WERROR spoolss_56( + ); + + /******************/ + /* Function: 0x57 */ + [todo] WERROR spoolss_57( + ); + + /******************/ + /* Function: 0x58 */ + WERROR spoolss_XcvData( + [in,ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 function_name[], + [in] DATA_BLOB in_data, + [in,value(r->in.in_data.length)] uint32 _in_data_length, + [in] uint32 offered, + [in] uint32 unknown1, + [out] DATA_BLOB out_data, + [out] uint32 needed, + [out] uint32 unknown2 + ); + + /******************/ + /* Function: 0x59 */ + [public,todo] WERROR spoolss_AddPrinterDriverEx( + ); + + /******************/ + /* Function: 0x5a */ + [todo] WERROR spoolss_5a( + ); + + /******************/ + /* Function: 0x5b */ + [todo] WERROR spoolss_5b( + ); + + /******************/ + /* Function: 0x5c */ + [todo] WERROR spoolss_5c( + ); + + /******************/ + /* Function: 0x5d */ + [todo] WERROR spoolss_5d( + ); + + /******************/ + /* Function: 0x5e */ + [todo] WERROR spoolss_5e( + ); + + /******************/ + /* Function: 0x5f */ + [todo] WERROR spoolss_5f( + ); +} diff --git a/librpc/idl/svcctl.idl b/librpc/idl/svcctl.idl new file mode 100644 index 0000000000..3eb686fe15 --- /dev/null +++ b/librpc/idl/svcctl.idl @@ -0,0 +1,542 @@ +#include "idl_types.h" + +/* + svcctl interface definitions +*/ + +import "misc.idl"; +[ uuid("367abb81-9844-35f1-ad32-98f038001003"), + version(2.0), + pointer_default(unique), + endpoint("ncacn_np:[\\pipe\\svcctl]", "ncalrpc:"), + helpstring("Service Control") +] interface svcctl +{ + typedef struct { + uint32 is_locked; + [string,charset(UTF16)] uint16 *lock_owner; + uint32 lock_duration; + } SERVICE_LOCK_STATUS; + + typedef struct { + uint32 type; + uint32 state; + uint32 controls_accepted; + WERROR win32_exit_code; + uint32 service_exit_code; + uint32 check_point; + uint32 wait_hint; + } SERVICE_STATUS; + + typedef struct { + [relative] astring *service_name; + [relative] astring *display_name; + SERVICE_STATUS status; + } ENUM_SERVICE_STATUS; + + const int SERVICE_TYPE_KERNEL_DRIVER = 0x01; + const int SERVICE_TYPE_FS_DRIVER = 0x02; + const int SERVICE_TYPE_ADAPTER = 0x04; + const int SERVICE_TYPE_RECOGNIZER_DRIVER = 0x08; + const int SERVICE_TYPE_DRIVER=SERVICE_TYPE_KERNEL_DRIVER|SERVICE_TYPE_FS_DRIVER|SERVICE_TYPE_RECOGNIZER_DRIVER; + const int SERVICE_TYPE_WIN32_OWN_PROCESS = 0x10; + const int SERVICE_TYPE_WIN32_SHARE_PROCESS = 0x20; + const int SERVICE_TYPE_WIN32=SERVICE_TYPE_WIN32_OWN_PROCESS|SERVICE_TYPE_WIN32_SHARE_PROCESS; + + const int SERVICE_STATE_ACTIVE = 0x01; + const int SERVICE_STATE_INACTIVE = 0x02; + const int SERVICE_STATE_ALL = 0x03; + + typedef [public,bitmap32bit] bitmap { + SV_TYPE_WORKSTATION = 0x00000001, + SV_TYPE_SERVER = 0x00000002, + SV_TYPE_SQLSERVER = 0x00000004, + SV_TYPE_DOMAIN_CTRL = 0x00000008, + SV_TYPE_DOMAIN_BAKCTRL = 0x00000010, + SV_TYPE_TIME_SOURCE = 0x00000020, + SV_TYPE_AFP = 0x00000040, + SV_TYPE_NOVELL = 0x00000080, + + SV_TYPE_DOMAIN_MEMBER = 0x00000100, + SV_TYPE_PRINTQ_SERVER = 0x00000200, + SV_TYPE_DIALIN_SERVER = 0x00000400, + SV_TYPE_SERVER_UNIX = 0x00000800, + SV_TYPE_NT = 0x00001000, + SV_TYPE_WFW = 0x00002000, + SV_TYPE_SERVER_MFPN = 0x00004000, + SV_TYPE_SERVER_NT = 0x00008000, + SV_TYPE_POTENTIAL_BROWSER = 0x00010000, + SV_TYPE_BACKUP_BROWSER = 0x00020000, + SV_TYPE_MASTER_BROWSER = 0x00040000, + SV_TYPE_DOMAIN_MASTER = 0x00080000, + SV_TYPE_SERVER_OSF = 0x00100000, + SV_TYPE_SERVER_VMS = 0x00200000, + SV_TYPE_WIN95_PLUS = 0x00400000, + SV_TYPE_DFS_SERVER = 0x00800000, + SV_TYPE_ALTERNATE_XPORT = 0x20000000, + SV_TYPE_LOCAL_LIST_ONLY = 0x40000000, + SV_TYPE_DOMAIN_ENUM = 0x80000000 + } svcctl_ServerType; + + const uint32 SV_TYPE_ALL = 0xFFFFFFFF; + + /*****************/ + /* Function 0x00 */ + WERROR svcctl_CloseServiceHandle( + [in,out,ref] policy_handle *handle + ); + + /*****************/ + /* Function 0x01 */ + + typedef enum { + FIXME=1 + } SERVICE_CONTROL; + + WERROR svcctl_ControlService( + [in,ref] policy_handle *handle, + [in] uint32 control, + [out,ref] SERVICE_STATUS *service_status + ); + + /*****************/ + /* Function 0x02 */ + WERROR svcctl_DeleteService( + [in,ref] policy_handle *handle + ); + + /*****************/ + /* Function 0x03 */ + + WERROR svcctl_LockServiceDatabase( + [in,ref] policy_handle *handle, + [out,ref] policy_handle *lock + ); + + /*****************/ + /* Function 0x04 */ + WERROR svcctl_QueryServiceObjectSecurity( + [in] policy_handle *handle, + [in] uint32 security_flags, + [out,ref,size_is(buffer_size)] uint8 *buffer, + [in,range(0,0x40000)] uint32 buffer_size, + [out,ref,range(0,0x40000)] uint32 *needed + ); + + /*****************/ + /* Function 0x05 */ + WERROR svcctl_SetServiceObjectSecurity( + [in] policy_handle *handle, + [in] uint32 security_flags, + [in,ref,size_is(buffer_size)] uint8 *buffer, + [in] uint32 buffer_size + ); + + /*****************/ + /* Function 0x06 */ + WERROR svcctl_QueryServiceStatus( + [in,ref] policy_handle *handle, + [out,ref] SERVICE_STATUS *service_status + ); + + /*****************/ + /* Function 0x07 */ + [todo] WERROR svcctl_SetServiceStatus( + ); + + /*****************/ + /* Function 0x08 */ + WERROR svcctl_UnlockServiceDatabase( + [in,out,ref] policy_handle *lock + ); + + /*****************/ + /* Function 0x09 */ + [todo] WERROR svcctl_NotifyBootConfigStatus( + ); + + /*****************/ + /* Function 0x0a */ + WERROR svcctl_SCSetServiceBitsW( + [in,ref] policy_handle *handle, + [in] uint32 bits, + [in] boolean32 bitson, + [in] boolean32 immediate + ); + + /*****************/ + /* Function 0x0b */ + WERROR svcctl_ChangeServiceConfigW( + [in,ref] policy_handle *handle, + [in] uint32 type, + [in] uint32 start, + [in] uint32 error, + [in,unique] [string,charset(UTF16)] uint16 *binary_path, + [in,unique] [string,charset(UTF16)] uint16 *load_order_group, + [out,ref] uint32 *tag_id, + [in,unique] [string,charset(UTF16)] uint16 *dependencies, + [in,unique] [string,charset(UTF16)] uint16 *service_start_name, + [in,unique] [string,charset(UTF16)] uint16 *password, + [in,unique] [string,charset(UTF16)] uint16 *display_name + ); + + /*****************/ + /* Function 0x0c */ + WERROR svcctl_CreateServiceW( + [in,ref] policy_handle *scmanager_handle, + [in] [string,charset(UTF16)] uint16 ServiceName[], + [in,unique] [string,charset(UTF16)] uint16 *DisplayName, + [in] uint32 desired_access, + [in] uint32 type, + [in] uint32 start_type, + [in] uint32 error_control, + [in] [string,charset(UTF16)] uint16 binary_path[], + [in,unique] [string,charset(UTF16)] uint16 *LoadOrderGroupKey, + [in,out,unique] uint32 *TagId, + [in,unique,size_is(dependencies_size)] uint8 *dependencies, + [in] uint32 dependencies_size, + [in,unique] [string,charset(UTF16)] uint16 *service_start_name, + [in,unique,size_is(password_size)] uint8 *password, + [in] uint32 password_size, + [out,ref] policy_handle *handle + ); + + /*****************/ + /* Function 0x0d */ + WERROR svcctl_EnumDependentServicesW( + [in,ref] policy_handle *service, + [in] uint32 state, + [out,ref,size_is(buf_size)] uint8 *service_status, + [in,range(0,0x40000)] uint32 buf_size, + [out,ref,range(0,0x40000)] uint32 *bytes_needed, + [out,ref,range(0,0x40000)] uint32 *services_returned + ); + + /*****************/ + /* Function 0x0e */ + WERROR svcctl_EnumServicesStatusW( + [in,ref] policy_handle *handle, + [in] uint32 type, + [in] uint32 state, + [in] uint32 buf_size, + [out,size_is(buf_size)] uint8 service[*], + [out,ref] uint32 *bytes_needed, + [out,ref] uint32 *services_returned, + [in,out,unique] uint32 *resume_handle + ); + + /*****************/ + /* Function 0x0f */ + typedef [bitmap32bit] bitmap { + SC_RIGHT_MGR_CONNECT = 0x0001, + SC_RIGHT_MGR_CREATE_SERVICE = 0x0002, + SC_RIGHT_MGR_ENUMERATE_SERVICE = 0x0004, + SC_RIGHT_MGR_LOCK = 0x0008, + SC_RIGHT_MGR_QUERY_LOCK_STATUS = 0x0010, + SC_RIGHT_MGR_MODIFY_BOOT_CONFIG = 0x0020 + } svcctl_MgrAccessMask; + + WERROR svcctl_OpenSCManagerW( + [in,unique] [string,charset(UTF16)] uint16 *MachineName, + [in,unique] [string,charset(UTF16)] uint16 *DatabaseName, + [in] svcctl_MgrAccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /*****************/ + /* Function 0x10 */ + typedef [bitmap32bit] bitmap { + SC_RIGHT_SVC_QUERY_CONFIG = 0x0001, + SC_RIGHT_SVC_CHANGE_CONFIG = 0x0002, + SC_RIGHT_SVC_QUERY_STATUS = 0x0004, + SC_RIGHT_SVC_ENUMERATE_DEPENDENTS = 0x0008, + SC_RIGHT_SVC_START = 0x0010, + SC_RIGHT_SVC_STOP = 0x0020, + SC_RIGHT_SVC_PAUSE_CONTINUE = 0x0040, + SC_RIGHT_SVC_INTERROGATE = 0x0080, + SC_RIGHT_SVC_USER_DEFINED_CONTROL = 0x0100 + } svcctl_ServiceAccessMask; + + WERROR svcctl_OpenServiceW( + [in,ref] policy_handle *scmanager_handle, + [in] [string,charset(UTF16)] uint16 ServiceName[], + [in] svcctl_ServiceAccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /*****************/ + /* Function 0x11 */ + + typedef [public,gensize] struct { + uint32 service_type; + uint32 start_type; + uint32 error_control; + [string,charset(UTF16)] [range(0,8192)] uint16 *executablepath; + [string,charset(UTF16)] [range(0,8192)] uint16 *loadordergroup; + uint32 tag_id; + [string,charset(UTF16)] [range(0,8192)] uint16 *dependencies; + [string,charset(UTF16)] [range(0,8192)] uint16 *startname; + [string,charset(UTF16)] [range(0,8192)] uint16 *displayname; + } QUERY_SERVICE_CONFIG; + + WERROR svcctl_QueryServiceConfigW( + [in,ref] policy_handle *handle, + [out] QUERY_SERVICE_CONFIG *query, + [in] [range(0,8192)] uint32 buf_size, + [out,ref] [range(0,8192)] uint32 *bytes_needed + ); + + /*****************/ + /* Function 0x12 */ + WERROR svcctl_QueryServiceLockStatusW( + [in,ref] policy_handle *handle, + [in] uint32 buf_size, + [out,ref] SERVICE_LOCK_STATUS *lock_status, + [out,ref] uint32 *required_buf_size + ); + + /*****************/ + /* Function 0x13 */ + WERROR svcctl_StartServiceW( + [in,ref] policy_handle *handle, + [in] uint32 NumArgs, + [in,unique/*FIXME:,length_is(NumArgs)*/] [string,charset(UTF16)] uint16 *Arguments + ); + + /*****************/ + /* Function 0x14 */ + WERROR svcctl_GetServiceDisplayNameW( + [in,ref] policy_handle *handle, + [in,unique] [string,charset(UTF16)] uint16 *service_name, + [out,ref] [string,charset(UTF16)] uint16 **display_name, + [in,out,unique] uint32 *display_name_length + ); + + /*****************/ + /* Function 0x15 */ + WERROR svcctl_GetServiceKeyNameW( + [in,ref] policy_handle *handle, + [in,unique] [string,charset(UTF16)] uint16 *service_name, + [out,ref] [string,charset(UTF16)] uint16 **key_name, + [in,out,unique] uint32 *display_name_length + ); + + /*****************/ + /* Function 0x16 */ + WERROR svcctl_SCSetServiceBitsA( + [in,ref] policy_handle *handle, + [in] uint32 bits, + [in] boolean32 bitson, + [in] boolean32 immediate + ); + + /*****************/ + /* Function 0x17 */ + WERROR svcctl_ChangeServiceConfigA( + [in,ref] policy_handle *handle, + [in] uint32 type, + [in] uint32 start, + [in] uint32 error, + [in,unique] [string,charset(UTF16)] uint16 *binary_path, + [in,unique] [string,charset(UTF16)] uint16 *load_order_group, + [out,ref] uint32 *tag_id, + [in,unique] [string,charset(UTF16)] uint16 *dependencies, + [in,unique] [string,charset(UTF16)] uint16 *service_start_name, + [in,unique] [string,charset(UTF16)] uint16 *password, + [in,unique] [string,charset(UTF16)] uint16 *display_name + ); + + /*****************/ + /* Function 0x18 */ + WERROR svcctl_CreateServiceA( + [in,ref] policy_handle *handle, + [in,unique] [string,charset(UTF16)] uint16 *ServiceName, + [in,unique] [string,charset(UTF16)] uint16 *DisplayName, + [in] uint32 desired_access, + [in] uint32 type, + [in] uint32 start_type, + [in] uint32 error_control, + [in,unique] [string,charset(UTF16)] uint16 *binary_path, + [in,unique] [string,charset(UTF16)] uint16 *LoadOrderGroupKey, + [out,unique] uint32 *TagId, + [in,unique] [string,charset(UTF16)] uint16 *dependencies, + [in,unique] [string,charset(UTF16)] uint16 *service_start_name, + [in,unique] [string,charset(UTF16)] uint16 *password + ); + + /*****************/ + /* Function 0x19 */ + WERROR svcctl_EnumDependentServicesA( + [in,ref] policy_handle *service, + [in] uint32 state, + [out,unique] ENUM_SERVICE_STATUS *service_status, + [in] uint32 buf_size, + [out,ref] uint32 *bytes_needed, + [out,ref] uint32 *services_returned + ); + + /*****************/ + /* Function 0x1a */ + WERROR svcctl_EnumServicesStatusA( + [in,ref] policy_handle *handle, + [in] uint32 type, + [in] uint32 state, + [in] uint32 buf_size, + [out,size_is(buf_size)] uint8 service[*], + [out,ref] uint32 *bytes_needed, + [out,ref] uint32 *services_returned, + [in,out,unique] uint32 *resume_handle + ); + + /*****************/ + /* Function 0x1b */ + WERROR svcctl_OpenSCManagerA( + [in,unique] [string,charset(UTF16)] uint16 *MachineName, + [in,unique] [string,charset(UTF16)] uint16 *DatabaseName, + [in] uint32 access_mask, + [out,ref] policy_handle *handle + ); + + /*****************/ + /* Function 0x1c */ + WERROR svcctl_OpenServiceA( + [in,ref] policy_handle *scmanager_handle, + [in,unique] [string,charset(UTF16)] uint16 *ServiceName, + [in] uint32 access_mask + ); + + /*****************/ + /* Function 0x1d */ + WERROR svcctl_QueryServiceConfigA( + [in,ref] policy_handle *handle, + [out] uint8 query[buf_size], /*QUERYU_SERVICE_CONFIG */ + [in] uint32 buf_size, + [out,ref] uint32 *bytes_needed + ); + + /*****************/ + /* Function 0x1e */ + WERROR svcctl_QueryServiceLockStatusA( + [in,ref] policy_handle *handle, + [in] uint32 buf_size, + [out,ref] SERVICE_LOCK_STATUS *lock_status, + [out,ref] uint32 *required_buf_size + ); + + /*****************/ + /* Function 0x1f */ + WERROR svcctl_StartServiceA( + [in,ref] policy_handle *handle, + [in] uint32 NumArgs, + [in,unique/*FIXME:,length_is(NumArgs)*/] [string,charset(UTF16)] uint16 *Arguments + ); + + /*****************/ + /* Function 0x20 */ + WERROR svcctl_GetServiceDisplayNameA( + [in,ref] policy_handle *handle, + [in,unique] [string,charset(UTF16)] uint16 *service_name, + [out,ref] [string,charset(UTF16)] uint16 **display_name, + [in,out,unique] uint32 *display_name_length + ); + + /*****************/ + /* Function 0x21 */ + WERROR svcctl_GetServiceKeyNameA( + [in,ref] policy_handle *handle, + [in,unique] [string,charset(UTF16)] uint16 *service_name, + [out,ref] [string,charset(UTF16)] uint16 **key_name, + [in,out,unique] uint32 *display_name_length + ); + + /*****************/ + /* Function 0x22 */ + [todo] WERROR svcctl_GetCurrentGroupeStateW( + ); + + /*****************/ + /* Function 0x23 */ + [todo] WERROR svcctl_EnumServiceGroupW( + ); + + /*****************/ + /* Function 0x24 */ + WERROR svcctl_ChangeServiceConfig2A( + [in,ref] policy_handle *handle, + [in] uint32 info_level, + [in,unique] uint8 *info + ); + + /*****************/ + /* Function 0x25 */ + WERROR svcctl_ChangeServiceConfig2W( + [in,ref] policy_handle *handle, + [in] uint32 info_level, + [in,unique] uint8 *info + ); + + /*****************/ + /* Function 0x26 */ + WERROR svcctl_QueryServiceConfig2A( + [in,ref] policy_handle *handle, + [in] uint32 info_level, + [out] uint8 buffer[buf_size], + [in] uint32 buf_size, + [out,ref] uint32 *bytes_needed + ); + + /*****************/ + /* Function 0x27 */ + WERROR svcctl_QueryServiceConfig2W( + [in,ref] policy_handle *handle, + [in] uint32 info_level, + [out] uint8 buffer[buf_size], + [in] uint32 buf_size, + [out,ref] uint32 *bytes_needed + ); + + /*****************/ + /* Function 0x28 */ + WERROR svcctl_QueryServiceStatusEx( + [in,ref] policy_handle *handle, + [in] uint32 info_level, + [out] uint8 buffer[buf_size], + [in] uint32 buf_size, + [out,ref] uint32 *bytes_needed + ); + + /*****************/ + /* Function 0x29 */ + WERROR EnumServicesStatusExA( + [in,ref] policy_handle *scmanager, + [in] uint32 info_level, + [in] uint32 type, + [in] uint32 state, + [out] uint8 services[buf_size], + [in] uint32 buf_size, + [out,ref] uint32 *bytes_needed, + [out,ref] uint32 *service_returned, + [in,out,unique] uint32 *resume_handle, + [out,ref] [string,charset(UTF16)] uint16 **group_name + ); + + /*****************/ + /* Function 0x2a */ + WERROR EnumServicesStatusExW( + [in,ref] policy_handle *scmanager, + [in] uint32 info_level, + [in] uint32 type, + [in] uint32 state, + [out] uint8 services[buf_size], + [in] uint32 buf_size, + [out,ref] uint32 *bytes_needed, + [out,ref] uint32 *service_returned, + [in,out,unique] uint32 *resume_handle, + [out,ref] [string,charset(UTF16)] uint16 **group_name + ); + + /*****************/ + /* Function 0x2b */ + [todo] WERROR svcctl_SCSendTSMessage( + ); +} diff --git a/librpc/idl/trkwks.idl b/librpc/idl/trkwks.idl new file mode 100644 index 0000000000..7f11af189b --- /dev/null +++ b/librpc/idl/trkwks.idl @@ -0,0 +1,17 @@ +/* + distributed key tracking services +*/ + +[ + uuid("300f3532-38cc-11d0-a3f0-0020af6b0add"), + version(1.2), + pointer_default(unique), + helpstring("Distributed Key Tracking Service") +] +interface trkwks +{ + + /*****************/ + /* Function 0x00 */ + WERROR trkwks_Unknown0(); +} diff --git a/librpc/idl/unixinfo.idl b/librpc/idl/unixinfo.idl new file mode 100644 index 0000000000..6929e86e61 --- /dev/null +++ b/librpc/idl/unixinfo.idl @@ -0,0 +1,56 @@ +#include "idl_types.h" +/* + Unixinfo interface definition +*/ + +import "security.idl"; + +[ uuid("9c54e310-a955-4885-bd31-78787147dfa6"), + version(0.0), + endpoint("ncacn_np:[\\pipe\\unixinfo]", "ncacn_ip_tcp:", "ncalrpc:"), + pointer_default(unique), + helpstring("Unixinfo specific stuff") +] interface unixinfo +{ + /******************/ + /* Function: 0x00 */ + NTSTATUS unixinfo_SidToUid ( + [in] dom_sid sid, + [out] hyper *uid + ); + + /******************/ + /* Function: 0x01 */ + NTSTATUS unixinfo_UidToSid ( + [in] hyper uid, + [out] dom_sid *sid + ); + + /******************/ + /* Function: 0x02 */ + NTSTATUS unixinfo_SidToGid ( + [in] dom_sid sid, + [out] hyper *gid + ); + + /******************/ + /* Function: 0x03 */ + NTSTATUS unixinfo_GidToSid ( + [in] hyper gid, + [out] dom_sid *sid + ); + + typedef struct { + NTSTATUS status; + [charset(UTF8),string] uint8 homedir[]; + [charset(UTF8),string] uint8 shell[]; + } unixinfo_GetPWUidInfo; + + /******************/ + /* Function: 0x04 */ + NTSTATUS unixinfo_GetPWUid ( + [in,out,ref,range(0,1023)] uint32 *count, + [in,size_is(*count)] hyper uids[], + [out,size_is(*count)] unixinfo_GetPWUidInfo infos[*] + ); +} diff --git a/librpc/idl/w32time.idl b/librpc/idl/w32time.idl new file mode 100644 index 0000000000..4839899629 --- /dev/null +++ b/librpc/idl/w32time.idl @@ -0,0 +1,21 @@ +/* + w32time interface definitions +*/ + +[ + uuid("8fb6d884-2388-11d0-8c35-00c04fda2795"), + endpoint("ncacn_np:[\\pipe\\srvsvc]","ncacn_np:[\\pipe\\atsvc]","ncacn_np:[\\pipe\\browser]","ncacn_np:[\\pipe\\keysvc]","ncacn_np:[\\pipe\\wkssvc]"), + version(4.1), + pointer_default(unique), + helpstring("Win32 Time Server") +] +interface w32time +{ + + /*****************/ + /* Function 0x00 */ + [todo] WERROR w32time_SyncTime(); + + [todo] WERROR w32time_GetNetLogonServiceBits(); + [todo] WERROR w32time_QueryProviderStatus(); +} diff --git a/librpc/idl/winreg.cnf b/librpc/idl/winreg.cnf new file mode 100644 index 0000000000..e5a146cd5d --- /dev/null +++ b/librpc/idl/winreg.cnf @@ -0,0 +1,52 @@ +IMPORT security_secinfo offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_winreg_winreg_GetKeySecurity_sec_info, NULL); + +HF_FIELD hf_winreg_access_required "Access Required" "winreg.access_required" FT_UINT32 BASE_HEX NULL 0 "" "" "" + +HF_RENAME hf_winreg_winreg_OpenHKCR_access_required hf_winreg_access_required +HF_RENAME hf_winreg_winreg_OpenHKLM_access_required hf_winreg_access_required +HF_RENAME hf_winreg_winreg_OpenHKU_access_required hf_winreg_access_required +HF_RENAME hf_winreg_winreg_CreateKey_access_required hf_winreg_access_required +HF_RENAME hf_winreg_winreg_OpenHKCC_access_required hf_winreg_access_required +HF_RENAME hf_winreg_winreg_OpenHKDD_access_required hf_winreg_access_required +HF_RENAME hf_winreg_winreg_OpenHKPT_access_required hf_winreg_access_required +HF_RENAME hf_winreg_winreg_OpenHKPN_access_required hf_winreg_access_required + +HF_FIELD hf_winreg_system_name "System Name" "winreg.system_name" FT_UINT16 BASE_DEC NULL 0 "" "" "" + +HF_RENAME hf_winreg_winreg_OpenHKCR_system_name hf_winreg_system_name +HF_RENAME hf_winreg_winreg_OpenHKCU_system_name hf_winreg_system_name +HF_RENAME hf_winreg_winreg_OpenHKLM_system_name hf_winreg_system_name +HF_RENAME hf_winreg_winreg_OpenHKPD_system_name hf_winreg_system_name +HF_RENAME hf_winreg_winreg_OpenHKU_system_name hf_winreg_system_name +HF_RENAME hf_winreg_winreg_OpenHKCC_system_name hf_winreg_system_name +HF_RENAME hf_winreg_winreg_OpenHKDD_system_name hf_winreg_system_name +HF_RENAME hf_winreg_winreg_OpenHKPT_system_name hf_winreg_system_name +HF_RENAME hf_winreg_winreg_OpenHKPN_system_name hf_winreg_system_name + +HF_FIELD hf_winreg_handle "Handle" "winreg.handle" FT_BYTES BASE_NONE NULL 0 "" "" "" + +HF_RENAME hf_winreg_winreg_OpenHKCR_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenHKCU_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenHKLM_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenHKPD_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenHKU_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_CloseKey_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_CreateKey_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_DeleteKey_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_DeleteValue_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_EnumKey_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_EnumValue_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_FlushKey_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_GetKeySecurity_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_LoadKey_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_NotifyChangeKeyValue_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenKey_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_QueryInfoKey_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_QueryValue_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_SetKeySecurity_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_SetValue_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_GetVersion_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenHKCC_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenHKDD_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenHKPT_handle hf_winreg_handle +HF_RENAME hf_winreg_winreg_OpenHKPN_handle hf_winreg_handle diff --git a/librpc/idl/winreg.idl b/librpc/idl/winreg.idl new file mode 100644 index 0000000000..9216f9893b --- /dev/null +++ b/librpc/idl/winreg.idl @@ -0,0 +1,401 @@ +/* + winreg interface definition +*/ + +import "lsa.idl", "security.idl"; + +[ + uuid("338cd001-2244-31f1-aaaa-900038001003"), + version(1.0), + endpoint("ncacn_np:[\\pipe\\winreg]","ncacn_ip_tcp:","ncalrpc:"), + pointer_default(unique), + helpstring("Remote Registry Service") +] interface winreg +{ + typedef bitmap security_secinfo security_secinfo; + + typedef [bitmap32bit] bitmap { + KEY_QUERY_VALUE = 0x00001, + KEY_SET_VALUE = 0x00002, + KEY_CREATE_SUB_KEY = 0x00004, + KEY_ENUMERATE_SUB_KEYS = 0x00008, + KEY_NOTIFY = 0x00010, + KEY_CREATE_LINK = 0x00020, + KEY_WOW64_64KEY = 0x00100, + KEY_WOW64_32KEY = 0x00200 + } winreg_AccessMask; + + typedef [public,v1_enum] enum { + REG_NONE = 0, + REG_SZ = 1, + REG_EXPAND_SZ = 2, + REG_BINARY = 3, + REG_DWORD = 4, + REG_DWORD_BIG_ENDIAN = 5, + REG_LINK = 6, + REG_MULTI_SZ = 7, + REG_RESOURCE_LIST = 8, + REG_FULL_RESOURCE_DESCRIPTOR = 9, + REG_RESOURCE_REQUIREMENTS_LIST = 10, + REG_QWORD = 11 + } winreg_Type; + + typedef [public,noejs] struct { + [value(strlen_m_term(name)*2)] uint16 name_len; + [value(strlen_m_term(name)*2)] uint16 name_size; + [string,charset(UTF16)] uint16 *name; + } winreg_String; + + /******************/ + /* Function: 0x00 */ + WERROR winreg_OpenHKCR( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x01 */ + WERROR winreg_OpenHKCU( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x02 */ + [public] WERROR winreg_OpenHKLM( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x03 */ + WERROR winreg_OpenHKPD( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x04 */ + WERROR winreg_OpenHKU( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x05 */ + [public] WERROR winreg_CloseKey( + [in,out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x06 */ + + typedef struct { + [size_is(size),length_is(len)] uint8 *data; + uint32 size; + uint32 len; + } KeySecurityData; + + typedef struct { + uint32 length; + KeySecurityData sd; + boolean8 inherit; + } winreg_SecBuf; + + typedef [v1_enum] enum { + REG_ACTION_NONE = 0, /* used by caller */ + REG_CREATED_NEW_KEY = 1, + REG_OPENED_EXISTING_KEY = 2 + } winreg_CreateAction; + + [public] WERROR winreg_CreateKey( + [in,ref] policy_handle *handle, + [in] winreg_String name, + [in] winreg_String keyclass, + [in] uint32 options, + [in] winreg_AccessMask access_mask, + [in,unique] winreg_SecBuf *secdesc, + [out,ref] policy_handle *new_handle, + [in,out,unique] winreg_CreateAction *action_taken + ); + + /******************/ + /* Function: 0x07 */ + [public] 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 { + [value(strlen_m_term(name)*2)] uint16 length; + /* size cannot be auto-set by value() as it is the + amount of space the server is allowed to use for this + string in the reply, not its current size */ + uint16 size; + [size_is(size/2),length_is(length/2),charset(UTF16)] uint16 *name; + } winreg_StringBuf; + + /******************/ + /* Function: 0x09 */ + [public] WERROR winreg_EnumKey( + [in,ref] policy_handle *handle, + [in] uint32 enum_index, + [in,out,ref] winreg_StringBuf *name, + [in,out,unique] winreg_StringBuf *keyclass, + [in,out,unique] NTTIME *last_changed_time + ); + + /******************/ + /* Function: 0x0a */ + + [public] WERROR winreg_EnumValue( + [in,ref] policy_handle *handle, + [in] uint32 enum_index, + [in,out,ref] winreg_StringBuf *name, + [in,out,unique] winreg_Type *type, + [in,out,unique,size_is(*size),length_is(*length)] uint8 *value, + [in,out,unique] uint32 *size, + [in,out,unique] uint32 *length + ); + + /******************/ + /* Function: 0x0b */ + [public] WERROR winreg_FlushKey( + [in,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x0c */ + [public] WERROR winreg_GetKeySecurity( + [in,ref] policy_handle *handle, + [in] security_secinfo sec_info, + [in,out,ref] KeySecurityData *sd + ); + + /******************/ + /* Function: 0x0d */ + WERROR winreg_LoadKey( + [in,ref] policy_handle *handle, + [in,unique] winreg_String *keyname, + [in,unique] winreg_String *filename + ); + + /******************/ + /* Function: 0x0e */ + typedef [public,bitmap32bit] bitmap { + REG_NOTIFY_CHANGE_NAME = 0x00000001, + REG_NOTIFY_CHANGE_ATTRIBUTES = 0x00000002, + REG_NOTIFY_CHANGE_LAST_SET = 0x00000004, + REG_NOTIFY_CHANGE_SECURITY = 0x00000008 + } winreg_NotifyChangeType; + + [public] WERROR winreg_NotifyChangeKeyValue( + [in,ref] policy_handle *handle, + [in] boolean8 watch_subtree, + [in] winreg_NotifyChangeType notify_filter, + [in] uint32 unknown, + [in] winreg_String string1, + [in] winreg_String string2, + [in] uint32 unknown2 + ); + + /******************/ + /* Function: 0x0f */ + [public] WERROR winreg_OpenKey( + [in,ref] policy_handle *parent_handle, + [in] winreg_String keyname, + [in] uint32 unknown, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x10 */ + [public] WERROR winreg_QueryInfoKey( + [in,ref] policy_handle *handle, + [in,out,ref] winreg_String *classname, + [out,ref] uint32 *num_subkeys, + [out,ref] uint32 *max_subkeylen, + [out,ref] uint32 *max_classlen, + [out,ref] uint32 *num_values, + [out,ref] uint32 *max_valnamelen, + [out,ref] uint32 *max_valbufsize, + [out,ref] uint32 *secdescsize, + [out,ref] NTTIME *last_changed_time + ); + + /******************/ + /* Function: 0x11 */ + [public] WERROR winreg_QueryValue( + [in,ref] policy_handle *handle, + [in,ref] winreg_String *value_name, + [in,out,unique] winreg_Type *type, + [in,out,unique,size_is(*data_size),length_is(*data_length)] uint8 *data, + [in,out,unique] uint32 *data_size, + [in,out,unique] uint32 *data_length + ); + + /******************/ + /* Function: 0x12 */ + [todo] WERROR winreg_ReplaceKey( + ); + + /******************/ + /* Function: 0x13 */ + WERROR winreg_RestoreKey( + [in,ref] policy_handle *handle, + [in,ref] winreg_String *filename, + [in] uint32 flags + ); + + /******************/ + /* Function: 0x14 */ + + typedef struct { + uint32 data_size; + KeySecurityData sec_data; + uint8 inherit; + } KeySecurityAttribute; + + WERROR winreg_SaveKey( + [in,ref] policy_handle *handle, + [in,ref] winreg_String *filename, + [in,unique] KeySecurityAttribute *sec_attrib + ); + + /******************/ + /* Function: 0x15 */ + WERROR winreg_SetKeySecurity( + [in,ref] policy_handle *handle, + [in] security_secinfo sec_info, + [in,ref] KeySecurityData *sd + ); + + /******************/ + /* Function: 0x16 */ + WERROR winreg_SetValue( + [in,ref] policy_handle *handle, + [in] winreg_String name, + [in] winreg_Type type, + [in,size_is(size),ref] uint8 *data, + [in] uint32 size + ); + + /******************/ + /* Function: 0x17 */ + [todo] WERROR winreg_UnLoadKey( + ); + + /******************/ + /* Function: 0x18 */ + WERROR winreg_InitiateSystemShutdown( + [in,unique] uint16 *hostname, + /* + * Note: lsa_String and winreg_String both result + * in WERR_INVALID_PARAM + */ + [in,unique] lsa_StringLarge *message, + [in] uint32 timeout, + [in] uint8 force_apps, + [in] uint8 do_reboot + ); + + /******************/ + /* Function: 0x19 */ + WERROR winreg_AbortSystemShutdown( + [in,unique] uint16 *server + ); + + /******************/ + /* Function: 0x1a */ + [public] WERROR winreg_GetVersion( + [in,ref] policy_handle *handle, + [out,ref] uint32 *version + ); + + /******************/ + /* Function: 0x1b */ + WERROR winreg_OpenHKCC( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x1c */ + WERROR winreg_OpenHKDD( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + typedef struct { + winreg_String *name; + winreg_Type type; + uint32 offset; + uint32 length; + } QueryMultipleValue; + + /******************/ + /* Function: 0x1d */ + [public] WERROR winreg_QueryMultipleValues( + [in,ref] policy_handle *key_handle, + [in,out,ref,size_is(num_values),length_is(num_values)] QueryMultipleValue *values, + [in] uint32 num_values, + [in,out,unique,size_is(*buffer_size),length_is(*buffer_size)] uint8 *buffer, + [in,out,ref] uint32 *buffer_size + ); + + /******************/ + /* Function: 0x1e */ + WERROR winreg_InitiateSystemShutdownEx( + [in,unique] uint16 *hostname, + /* + * Note: lsa_String and winreg_String both result + * in WERR_INVALID_PARAM + */ + [in,unique] lsa_StringLarge *message, + [in] uint32 timeout, + [in] uint8 force_apps, + [in] uint8 do_reboot, + [in] uint32 reason + ); + + /******************/ + /* Function: 0x1f */ + [todo] WERROR winreg_SaveKeyEx( + ); + + /******************/ + /* Function: 0x20 */ + WERROR winreg_OpenHKPT( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x21 */ + WERROR winreg_OpenHKPN( + [in,unique] uint16 *system_name, + [in] winreg_AccessMask access_mask, + [out,ref] policy_handle *handle + ); + + /******************/ + /* Function: 0x22 */ + [todo] WERROR winreg_QueryMultipleValues2( + ); +} diff --git a/librpc/idl/wkssvc.idl b/librpc/idl/wkssvc.idl new file mode 100644 index 0000000000..9340990e99 --- /dev/null +++ b/librpc/idl/wkssvc.idl @@ -0,0 +1,795 @@ +#include "idl_types.h" + +/* + wkssvc interface definitions +*/ + +import "srvsvc.idl", "lsa.idl"; + +[ uuid("6bffd098-a112-3610-9833-46c3f87e345a"), + version(1.0), + pointer_default(unique), + helpstring("Workstation Service"), + endpoint("ncacn_np:[\\pipe\\wkssvc]","ncacn_ip_tcp:","ncalrpc:") +] interface wkssvc +{ + typedef [v1_enum] enum srvsvc_PlatformId srvsvc_PlatformId; + +#define BOOL uint32 + + /******************/ + /* Function: 0x00 */ + + typedef struct { + srvsvc_PlatformId platform_id; + [string,charset(UTF16)] uint16 *server_name; + [string,charset(UTF16)] uint16 *domain_name; + uint32 version_major; + uint32 version_minor; + } wkssvc_NetWkstaInfo100; + + typedef struct { + srvsvc_PlatformId platform_id; + [string,charset(UTF16)] uint16 *server_name; + [string,charset(UTF16)] uint16 *domain_name; + uint32 version_major; + uint32 version_minor; + [string,charset(UTF16)] uint16 *lan_root; + } wkssvc_NetWkstaInfo101; + + typedef struct { + srvsvc_PlatformId platform_id; + [string,charset(UTF16)] uint16 *server_name; + [string,charset(UTF16)] uint16 *domain_name; + uint32 version_major; + uint32 version_minor; + [string,charset(UTF16)] uint16 *lan_root; + uint32 logged_on_users; + } wkssvc_NetWkstaInfo102; + + /* FIXME: 302, 402 */ + + 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 struct { + uint32 char_wait; + } wkssvc_NetWkstaInfo1010; + + typedef struct { + uint32 collection_time; + } wkssvc_NetWkstaInfo1011; + + typedef struct { + uint32 maximum_collection_count; + } wkssvc_NetWkstaInfo1012; + + typedef struct { + uint32 keep_connection; + } wkssvc_NetWkstaInfo1013; + + typedef struct { + uint32 session_timeout; + } wkssvc_NetWkstaInfo1018; + + typedef struct { + uint32 size_char_buf; + } wkssvc_NetWkstaInfo1023; + + typedef struct { + uint32 errorlog_sz; + } wkssvc_NetWkstaInfo1027; + + /* downlevel */ + typedef struct { + uint32 print_buf_time; + } wkssvc_NetWkstaInfo1028; + + /* downlevel */ + typedef struct { + uint32 wrk_heuristics; + } wkssvc_NetWkstaInfo1032; + + typedef struct { + uint32 max_threads; + } wkssvc_NetWkstaInfo1033; + + typedef struct { + uint32 lock_quota; + } wkssvc_NetWkstaInfo1041; + + typedef struct { + uint32 lock_increment; + } wkssvc_NetWkstaInfo1042; + + typedef struct { + uint32 lock_maximum; + } wkssvc_NetWkstaInfo1043; + + typedef struct { + uint32 pipe_increment; + } wkssvc_NetWkstaInfo1044; + + typedef struct { + uint32 pipe_maximum; + } wkssvc_NetWkstaInfo1045; + + typedef struct { + uint32 dormant_file_limit; + } wkssvc_NetWkstaInfo1046; + + typedef struct { + uint32 cache_file_timeout; + } wkssvc_NetWkstaInfo1047; + + typedef struct { + uint32 use_opportunistic_locking; + } wkssvc_NetWkstaInfo1048; + + typedef struct { + uint32 use_unlock_behind; + } wkssvc_NetWkstaInfo1049; + + typedef struct { + uint32 use_close_behind; + } wkssvc_NetWkstaInfo1050; + + typedef struct { + uint32 buf_named_pipes; + } wkssvc_NetWkstaInfo1051; + + typedef struct { + uint32 use_lock_read_unlock; + } wkssvc_NetWkstaInfo1052; + + typedef struct { + uint32 utilize_nt_caching; + } wkssvc_NetWkstaInfo1053; + + typedef struct { + uint32 use_raw_read; + } wkssvc_NetWkstaInfo1054; + + typedef struct { + uint32 use_raw_write; + } wkssvc_NetWkstaInfo1055; + + typedef struct { + uint32 use_write_raw_data; + } wkssvc_NetWkstaInfo1056; + + typedef struct { + uint32 use_encryption; + } wkssvc_NetWkstaInfo1057; + + typedef struct { + uint32 buf_files_deny_write; + } wkssvc_NetWkstaInfo1058; + + typedef struct { + uint32 buf_read_only_files; + } wkssvc_NetWkstaInfo1059; + + typedef struct { + uint32 force_core_create_mode; + } wkssvc_NetWkstaInfo1060; + + typedef struct { + uint32 use_512_byte_max_transfer; + } wkssvc_NetWkstaInfo1061; + + typedef struct { + uint32 read_ahead_throughput; + } wkssvc_NetWkstaInfo1062; + + typedef union { + [case(100)] wkssvc_NetWkstaInfo100 *info100; + [case(101)] wkssvc_NetWkstaInfo101 *info101; + [case(102)] wkssvc_NetWkstaInfo102 *info102; + [case(502)] wkssvc_NetWkstaInfo502 *info502; + [case(1010)] wkssvc_NetWkstaInfo1010 *info1010; + [case(1011)] wkssvc_NetWkstaInfo1011 *info1011; + [case(1012)] wkssvc_NetWkstaInfo1012 *info1012; + [case(1013)] wkssvc_NetWkstaInfo1013 *info1013; + [case(1018)] wkssvc_NetWkstaInfo1018 *info1018; + [case(1023)] wkssvc_NetWkstaInfo1023 *info1023; + [case(1027)] wkssvc_NetWkstaInfo1027 *info1027; + [case(1028)] wkssvc_NetWkstaInfo1028 *info1028; + [case(1032)] wkssvc_NetWkstaInfo1032 *info1032; + [case(1033)] wkssvc_NetWkstaInfo1033 *info1033; + [case(1041)] wkssvc_NetWkstaInfo1041 *info1041; + [case(1042)] wkssvc_NetWkstaInfo1042 *info1042; + [case(1043)] wkssvc_NetWkstaInfo1043 *info1043; + [case(1044)] wkssvc_NetWkstaInfo1044 *info1044; + [case(1045)] wkssvc_NetWkstaInfo1045 *info1045; + [case(1046)] wkssvc_NetWkstaInfo1046 *info1046; + [case(1047)] wkssvc_NetWkstaInfo1047 *info1047; + [case(1048)] wkssvc_NetWkstaInfo1048 *info1048; + [case(1049)] wkssvc_NetWkstaInfo1049 *info1049; + [case(1050)] wkssvc_NetWkstaInfo1050 *info1050; + [case(1051)] wkssvc_NetWkstaInfo1051 *info1051; + [case(1052)] wkssvc_NetWkstaInfo1052 *info1052; + [case(1053)] wkssvc_NetWkstaInfo1053 *info1053; + [case(1054)] wkssvc_NetWkstaInfo1054 *info1054; + [case(1055)] wkssvc_NetWkstaInfo1055 *info1055; + [case(1056)] wkssvc_NetWkstaInfo1056 *info1056; + [case(1057)] wkssvc_NetWkstaInfo1057 *info1057; + [case(1058)] wkssvc_NetWkstaInfo1058 *info1058; + [case(1059)] wkssvc_NetWkstaInfo1059 *info1059; + [case(1060)] wkssvc_NetWkstaInfo1060 *info1060; + [case(1061)] wkssvc_NetWkstaInfo1061 *info1061; + [case(1062)] wkssvc_NetWkstaInfo1062 *info1062; + [default] ; + } wkssvc_NetWkstaInfo; + + WERROR wkssvc_NetWkstaGetInfo( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in] uint32 level, + [out,switch_is(level),ref] wkssvc_NetWkstaInfo *info + ); + + + /******************/ + /* Function: 0x01 */ + WERROR wkssvc_NetWkstaSetInfo( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in] uint32 level, + [in,switch_is(level),ref] wkssvc_NetWkstaInfo *info, + [in,out,ref] uint32 *parm_error + ); + + + /*****************************/ + /* Function 0x02 */ + typedef struct { + [string,charset(UTF16)] uint16 *user_name; + } wkssvc_NetrWkstaUserInfo0; + + typedef struct { + uint32 entries_read; + [size_is(entries_read)] wkssvc_NetrWkstaUserInfo0 *user0; + } wkssvc_NetWkstaEnumUsersCtr0; + + typedef struct { + [string,charset(UTF16)] uint16 *user_name; + [string,charset(UTF16)] uint16 *logon_domain; + [string,charset(UTF16)] uint16 *other_domains; + [string,charset(UTF16)] uint16 *logon_server; + } wkssvc_NetrWkstaUserInfo1; + + typedef struct { + uint32 entries_read; + [size_is(entries_read)] wkssvc_NetrWkstaUserInfo1 *user1; + } wkssvc_NetWkstaEnumUsersCtr1; + + typedef [switch_type(uint32)] union { + [case(0)] wkssvc_NetWkstaEnumUsersCtr0 *user0; + [case(1)] wkssvc_NetWkstaEnumUsersCtr1 *user1; + } wkssvc_NetWkstaEnumUsersCtr; + + typedef struct { + uint32 level; + [switch_is(level)] wkssvc_NetWkstaEnumUsersCtr ctr; + } wkssvc_NetWkstaEnumUsersInfo; + + WERROR wkssvc_NetWkstaEnumUsers( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,out,ref] wkssvc_NetWkstaEnumUsersInfo *info, + [in] uint32 prefmaxlen, + [out,ref] uint32 *entries_read, + [in,out,unique] uint32 *resume_handle + ); + + /*****************************/ + /* Function 0x03 */ + typedef struct { + [string,charset(UTF16)] uint16 *other_domains; + } wkssvc_NetrWkstaUserInfo1101; + + typedef [switch_type(uint32)] union { + [case(0)] wkssvc_NetrWkstaUserInfo0 *info0; + [case(1)] wkssvc_NetrWkstaUserInfo1 *info1; + [case(1101)] wkssvc_NetrWkstaUserInfo1101 *info1101; + } wkssvc_NetrWkstaUserInfo; + + WERROR wkssvc_NetrWkstaUserGetInfo( + [in,unique] [string,charset(UTF16)] uint16 *unknown, + [in] uint32 level, + [out,ref] [switch_is(level)] wkssvc_NetrWkstaUserInfo *info + ); + + /*****************************/ + /* Function 0x04 */ + WERROR wkssvc_NetrWkstaUserSetInfo( + [in,unique] [string,charset(UTF16)] uint16 *unknown, + [in] uint32 level, + [in,ref] [switch_is(level)] wkssvc_NetrWkstaUserInfo *info, + [in,out,unique] uint32 *parm_err + ); + + /*****************************/ + /* Function 0x05 */ + + typedef struct { + uint32 quality_of_service; + uint32 vc_count; + [string,charset(UTF16)] uint16 *name; + [string,charset(UTF16)] uint16 *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; + } wkssvc_NetWkstaTransportCtr; + + typedef struct { + uint32 level; + [switch_is(level)] wkssvc_NetWkstaTransportCtr ctr; + } wkssvc_NetWkstaTransportInfo; + + WERROR wkssvc_NetWkstaTransportEnum ( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,out,ref] wkssvc_NetWkstaTransportInfo *info, + [in] uint32 max_buffer, + [out,ref] uint32 *total_entries, + [in,out,unique] uint32 *resume_handle + ); + + /*****************************/ + /* Function 0x06 */ + /* only supported on NT */ + WERROR wkssvc_NetrWkstaTransportAdd( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in] uint32 level, /* must be 0 */ + [in,ref] wkssvc_NetWkstaTransportInfo0 *info0, + [in,out,unique] uint32 *parm_err + ); + + /*****************************/ + /* Function 0x07 */ + /* only supported on NT */ + WERROR wkssvc_NetrWkstaTransportDel( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *transport_name, + [in] uint32 unknown3 + ); + + /*****************************/ + /* Function 0x08 */ + typedef struct { + [string,charset(UTF16)] uint16 *unknown1; + [string,charset(UTF16)] uint16 *unknown2; + } wkssvc_NetrUseInfo3; + + typedef struct { + [string,charset(UTF16)] uint16 *local; + [string,charset(UTF16)] uint16 *remote; + [string,charset(UTF16)] uint16 *password; + uint32 status; + uint32 asg_type; + uint32 ref_count; + uint32 use_count; + [string,charset(UTF16)] uint16 *user_name; + [string,charset(UTF16)] uint16 *domain_name; + } wkssvc_NetrUseInfo2; + + typedef struct { + [string,charset(UTF16)] uint16 *local; + [string,charset(UTF16)] uint16 *remote; + [string,charset(UTF16)] uint16 *password; + uint32 status; + uint32 asg_type; + uint32 ref_count; + uint32 use_count; + } wkssvc_NetrUseInfo1; + + typedef struct { + [string,charset(UTF16)] uint16 *local; + [string,charset(UTF16)] uint16 *remote; + } wkssvc_NetrUseInfo0; + + typedef [switch_type(uint32)] union { + [case(0)] wkssvc_NetrUseInfo0 *info0; + [case(1)] wkssvc_NetrUseInfo1 *info1; + [case(2)] wkssvc_NetrUseInfo2 *info2; + [case(3)] wkssvc_NetrUseInfo3 *info3; + } wkssvc_NetrUseGetInfoCtr; + + WERROR wkssvc_NetrUseAdd( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in] uint32 level, + [in,ref] [switch_is(level)] wkssvc_NetrUseGetInfoCtr *ctr, + [in,out,unique] uint32 *parm_err + ); + + /*****************************/ + /* Function 0x09 */ + WERROR wkssvc_NetrUseGetInfo( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *use_name, + [in] uint32 level, + [out,ref] [switch_is(level)] wkssvc_NetrUseGetInfoCtr *ctr + ); + + /*****************************/ + /* Function 0x0a */ + WERROR wkssvc_NetrUseDel( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *use_name, + [in] uint32 force_cond + ); + + /*****************************/ + /* Function 0x0b */ + typedef struct { + uint32 count; + [size_is(count)] wkssvc_NetrUseInfo2 *array; + } wkssvc_NetrUseEnumCtr2; + + typedef struct { + uint32 count; + [size_is(count)] wkssvc_NetrUseInfo1 *array; + } wkssvc_NetrUseEnumCtr1; + + typedef struct { + uint32 count; + [size_is(count)] wkssvc_NetrUseInfo0 *array; + } wkssvc_NetrUseEnumCtr0; + + typedef [switch_type(uint32)] union { + [case(0)] wkssvc_NetrUseEnumCtr0 *ctr0; + [case(1)] wkssvc_NetrUseEnumCtr1 *ctr1; + [case(2)] wkssvc_NetrUseEnumCtr2 *ctr2; + } wkssvc_NetrUseEnumCtr; + + typedef struct { + uint32 level; + [switch_is(level)] wkssvc_NetrUseEnumCtr ctr; + } wkssvc_NetrUseEnumInfo; + + WERROR wkssvc_NetrUseEnum( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,out,ref] wkssvc_NetrUseEnumInfo *info, + [in] uint32 prefmaxlen, + [out,ref] uint32 *entries_read, + [in,out,unique] uint32 *resume_handle + ); + + /*****************************/ + /* Function 0x0c */ + WERROR wkssvc_NetrMessageBufferSend( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *message_name, + [in,unique] [string,charset(UTF16)] uint16 *message_sender_name, + [in,ref] [size_is(message_size)] uint8 *message_buffer, + [in] uint32 message_size + ); + + /*****************************/ + /* Function 0x0d */ + typedef struct { + hyper unknown1; + hyper unknown2; + hyper unknown3; + hyper unknown4; + hyper unknown5; + hyper unknown6; + hyper unknown7; + hyper unknown8; + hyper unknown9; + hyper unknown10; + hyper unknown11; + hyper unknown12; + hyper unknown13; + uint32 unknown14; + uint32 unknown15; + uint32 unknown16; + uint32 unknown17; + uint32 unknown18; + uint32 unknown19; + uint32 unknown20; + uint32 unknown21; + uint32 unknown22; + uint32 unknown23; + uint32 unknown24; + uint32 unknown25; + uint32 unknown26; + uint32 unknown27; + uint32 unknown28; + uint32 unknown29; + uint32 unknown30; + uint32 unknown31; + uint32 unknown32; + uint32 unknown33; + uint32 unknown34; + uint32 unknown35; + uint32 unknown36; + uint32 unknown37; + uint32 unknown38; + uint32 unknown39; + uint32 unknown40; + } wkssvc_NetrWorkstationStatistics; + + WERROR wkssvc_NetrWorkstationStatisticsGet( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *unknown2, + [in] uint32 unknown3, + [in] uint32 unknown4, + [out,ref] wkssvc_NetrWorkstationStatistics **info + ); + + /*****************************/ + /* Function 0x0e */ + WERROR wkssvc_NetrLogonDomainNameAdd( + [in,ref] [string,charset(UTF16)] uint16 *domain_name + ); + + /*****************************/ + /* Function 0x0f */ + WERROR wkssvc_NetrLogonDomainNameDel( + [in,ref] [string,charset(UTF16)] uint16 *domain_name + ); + + /*****************************/ + /* Function 0x10 */ + WERROR wkssvc_NetrJoinDomain( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *domain_name, + [in,unique] [string,charset(UTF16)] uint16 *account_ou, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] [string,charset(UTF16)] uint16 *password, + [in] wkssvc_joinflags join_flags + ); + + /*****************************/ + /* Function 0x11 */ + WERROR wkssvc_NetrUnjoinDomain( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] [string,charset(UTF16)] uint16 *password, + [in] wkssvc_joinflags unjoin_flags + ); + + /*****************************/ + /* Function 0x12 */ + typedef [bitmap32bit] bitmap { + /* TRUE: create the account in the domain */ + WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE = 0x00000002 + } wkssvc_renameflags; + + WERROR wkssvc_NetrRenameMachineInDomain( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *NewMachineName, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] [string,charset(UTF16)] uint16 *password, + [in] wkssvc_renameflags RenameOptions + ); + + /*****************************/ + /* Function 0x13 */ + typedef enum { + NetSetupUnknown = 0, + NetSetupMachine = 1, + NetSetupWorkgroup = 2, + NetSetupDomain = 3, + NetSetupNonExistentDomain = 4, + NetSetupDnsMachine = 5 + } wkssvc_NetValidateNameType; + + WERROR wkssvc_NetrValidateName( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *name, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] [string,charset(UTF16)] uint16 *Password, + [in] wkssvc_NetValidateNameType name_type + ); + + /*****************************/ + /* Function 0x14 */ + typedef enum { + NET_SETUP_UNKNOWN_STATUS = 0, + NET_SETUP_UNJOINED = 1, + NET_SETUP_WORKGROUP_NAME = 2, + NET_SETUP_DOMAIN_NAME = 3 + } wkssvc_NetJoinStatus; + + WERROR wkssvc_NetrGetJoinInformation( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,out,ref] [string,charset(UTF16)] uint16 **name_buffer, + [out,ref] wkssvc_NetJoinStatus *name_type + ); + + /*****************************/ + /* Function 0x15 */ + WERROR wkssvc_NetrGetJoinableOus( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *domain_name, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] [string,charset(UTF16)] uint16 *unknown, + [in,out,ref] uint32 *num_ous, + /* + * this is a [ref] pointer to a [unique] pointer to an + * array of [unique] pointers to a string array + */ + [out,ref] [size_is(,*num_ous)] [string,charset(UTF16)] uint16 ***ous + ); + + typedef [flag(NDR_PAHEX)] struct { + uint8 data[524]; + } wkssvc_PasswordBuffer; + + typedef [bitmap32bit] bitmap { + WKSSVC_JOIN_FLAGS_JOIN_WITH_NEW_NAME = 0x00000400, + WKSSVC_JOIN_FLAGS_JOIN_DC_ACCOUNT = 0x00000200, + /* TRUE: defer setting the SPN and dNSHostName until a rename operation */ + WKSSVC_JOIN_FLAGS_DEFER_SPN = 0x00000100, + + /* TRUE: set the machine password to the provided one after the join completes */ + WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED = 0x00000080, + + /* TRUE: perform an unsecured join */ + WKSSVC_JOIN_FLAGS_JOIN_UNSECURE = 0x00000040, + + /* TRUE: allow the join to complete even if the account already exists */ + WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED = 0x00000020, + + /* TRUE: this join is part of a w9x upgrade */ + WKSSVC_JOIN_FLAGS_WIN9X_UPGRADE = 0x00000010, + + /* TRUE: delete the account when the domain is left */ + WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE = 0x00000004, + + /* TRUE: create the account in the domain */ + WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE = 0x00000002, + + /* TRUE: join domain FALSE: join workgroup */ + WKSSVC_JOIN_FLAGS_JOIN_TYPE = 0x00000001 + + } wkssvc_joinflags; + + /*****************************/ + /* Function 0x16 */ + WERROR wkssvc_NetrJoinDomain2 ( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *domain_name, + [in,unique] [string,charset(UTF16)] uint16 *account_ou, + [in,unique] [string,charset(UTF16)] uint16 *admin_account, + [in,unique] wkssvc_PasswordBuffer *encrypted_password, + [in] wkssvc_joinflags join_flags + ); + + /*****************************/ + /* Function 0x17 */ + WERROR wkssvc_NetrUnjoinDomain2 ( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *account, + [in,unique] wkssvc_PasswordBuffer *encrypted_password, + [in] wkssvc_joinflags unjoin_flags + ); + + /*****************************/ + /* Function 0x18 */ + WERROR wkssvc_NetrRenameMachineInDomain2( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *NewMachineName, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] wkssvc_PasswordBuffer *EncryptedPassword, + [in] wkssvc_renameflags RenameOptions + ); + + /*****************************/ + /* Function 0x19 */ + WERROR wkssvc_NetrValidateName2( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *name, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] wkssvc_PasswordBuffer *EncryptedPassword, + [in] wkssvc_NetValidateNameType name_type + ); + + /*****************************/ + /* Function 0x1a */ + WERROR wkssvc_NetrGetJoinableOus2( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,ref] [string,charset(UTF16)] uint16 *domain_name, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] wkssvc_PasswordBuffer *EncryptedPassword, + [in,out,ref] uint32 *num_ous, + /* + * this is a [ref] pointer to a [unique] pointer to an + * array of [unique] pointers to a string array + */ + [out,ref] [size_is(,*num_ous)] [string,charset(UTF16)] uint16 ***ous + ); + + /*****************************/ + /* Function 0x1b */ + WERROR wkssvc_NetrAddAlternateComputerName( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *NewAlternateMachineName, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] wkssvc_PasswordBuffer *EncryptedPassword, + [in] uint32 Reserved + ); + + /*****************************/ + /* Function 0x1c */ + WERROR wkssvc_NetrRemoveAlternateComputerName( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *AlternateMachineNameToRemove, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] wkssvc_PasswordBuffer *EncryptedPassword, + [in] uint32 Reserved + ); + + /*****************************/ + /* Function 0x1d */ + WERROR wkssvc_NetrSetPrimaryComputername( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *primary_name, + [in,unique] [string,charset(UTF16)] uint16 *Account, + [in,unique] wkssvc_PasswordBuffer *EncryptedPassword, + [in] uint32 Reserved + ); + + /*****************************/ + /* Function 0x1e */ + typedef enum { + NetPrimaryComputerName = 0, + NetAlternateComputerNames = 1, + NetAllComputerNames = 2, + NetComputerNameTypeMax = 3 + } wkssvc_ComputerNameType; + + typedef struct { + uint32 count; + [size_is(count)] lsa_String *computer_name; + } wkssvc_ComputerNamesCtr; + + WERROR wkssvc_NetrEnumerateComputerNames( + [in,unique] [string,charset(UTF16)] uint16 *server_name, + [in] wkssvc_ComputerNameType name_type, + [in] uint32 Reserved, + [out,ref] wkssvc_ComputerNamesCtr **ctr + ); +} diff --git a/librpc/idl/wmi.idl b/librpc/idl/wmi.idl new file mode 100644 index 0000000000..1f7b5ca1cf --- /dev/null +++ b/librpc/idl/wmi.idl @@ -0,0 +1,716 @@ +/* + * WMI IDL. + * See http://en.wikipedia.org/wiki/Windows_Management_Instrumentation for more information. + */ +#include "idl_types.h" + +import "dcom.idl"; +import "misc.idl"; + +[ + helper("librpc/ndr/ndr_wmi.h"), + uuid("8BC3F05E-D86B-11d0-A075-00C04FB68820") +] coclass WbemLevel1Login +{ + interface IWbemLevel1Login; + +}; + +[ + local, + object, + uuid("dc12a681-737f-11cf-884d-00aa004b2e24") +] +interface IWbemClassObject : IUnknown +{ + + typedef [noprint] struct { + [value(0x72657355)] uint32 flags; + [string, charset(UTF16)] uint16 data[]; + } BSTR; + + WERROR Delete( + [in, string, charset(UTF16)] uint16 *wszName + ); + +}; + +[ + uuid(9A653086-174F-11d2-B5F9-00104B703EFD) +] +coclass WbemClassObject +{ + interface IWbemClassObject; +}; + + +[ + uuid("9556dc99-828c-11cf-a37e-00aa003240c7"), + object, + pointer_default(unique) +] interface IWbemServices : IUnknown +{ + typedef [v1_enum] enum + { + RPC_S_CALL_FAILED = 1726, + + WBEM_NO_ERROR = 0, + WBEM_S_NO_ERROR = 0, + WBEM_S_SAME = 0, + WBEM_S_FALSE = 1, + WBEM_S_ALREADY_EXISTS = 0x40001, + WBEM_S_RESET_TO_DEFAULT = 0x40002, + WBEM_S_DIFFERENT = 0x40003, + WBEM_S_TIMEDOUT = 0x40004, + WBEM_S_NO_MORE_DATA = 0x40005, + WBEM_S_OPERATION_CANCELLED = 0x40006, + WBEM_S_PENDING = 0x40007, + WBEM_S_DUPLICATE_OBJECTS = 0x40008, + WBEM_S_ACCESS_DENIED = 0x40009, + WBEM_S_PARTIAL_RESULTS = 0x40010, + WBEM_S_NO_POSTHOOK = 0x40011, + WBEM_S_POSTHOOK_WITH_BOTH = 0x40012, + WBEM_S_POSTHOOK_WITH_NEW = 0x40013, + WBEM_S_POSTHOOK_WITH_STATUS = 0x40014, + WBEM_S_POSTHOOK_WITH_OLD = 0x40015, + WBEM_S_REDO_PREHOOK_WITH_ORIGINAL_OBJECT = 0x40016, + WBEM_S_SOURCE_NOT_AVAILABLE = 0x40017, + WBEM_E_FAILED = 0x80041001, + WBEM_E_NOT_FOUND = 0x80041002, + WBEM_E_ACCESS_DENIED = 0x80041003, + WBEM_E_PROVIDER_FAILURE = 0x80041004, + WBEM_E_TYPE_MISMATCH = 0x80041005, + WBEM_E_OUT_OF_MEMORY = 0x80041006, + WBEM_E_INVALID_CONTEXT = 0x80041007, + WBEM_E_INVALID_PARAMETER = 0x80041008, + WBEM_E_NOT_AVAILABLE = 0x80041009, + WBEM_E_CRITICAL_ERROR = 0x8004100A, + WBEM_E_INVALID_STREAM = 0x8004100B, + WBEM_E_NOT_SUPPORTED = 0x8004100C, + WBEM_E_INVALID_SUPERCLASS = 0x8004100D, + WBEM_E_INVALID_NAMESPACE = 0x8004100E, + WBEM_E_INVALID_OBJECT = 0x8004100F, + WBEM_E_INVALID_CLASS = 0x80041010, + WBEM_E_PROVIDER_NOT_FOUND = 0x80041011, + WBEM_E_INVALID_PROVIDER_REGISTRATION = 0x80041012, + WBEM_E_PROVIDER_LOAD_FAILURE = 0x80041013, + WBEM_E_INITIALIZATION_FAILURE = 0x80041014, + WBEM_E_TRANSPORT_FAILURE = 0x80041015, + WBEM_E_INVALID_OPERATION = 0x80041016, + WBEM_E_INVALID_QUERY = 0x80041017, + WBEM_E_INVALID_QUERY_TYPE = 0x80041018, + WBEM_E_ALREADY_EXISTS = 0x80041019, + WBEM_E_OVERRIDE_NOT_ALLOWED = 0x8004101A, + WBEM_E_PROPAGATED_QUALIFIER = 0x8004101B, + WBEM_E_PROPAGATED_PROPERTY = 0x8004101C, + WBEM_E_UNEXPECTED = 0x8004101D, + WBEM_E_ILLEGAL_OPERATION = 0x8004101E, + WBEM_E_CANNOT_BE_KEY = 0x8004101F, + WBEM_E_INCOMPLETE_CLASS = 0x80041020, + WBEM_E_INVALID_SYNTAX = 0x80041021, + WBEM_E_NONDECORATED_OBJECT = 0x80041022, + WBEM_E_READ_ONLY = 0x80041023, + WBEM_E_PROVIDER_NOT_CAPABLE = 0x80041024, + WBEM_E_CLASS_HAS_CHILDREN = 0x80041025, + WBEM_E_CLASS_HAS_INSTANCES = 0x80041026, + WBEM_E_QUERY_NOT_IMPLEMENTED = 0x80041027, + WBEM_E_ILLEGAL_NULL = 0x80041028, + WBEM_E_INVALID_QUALIFIER_TYPE = 0x80041029, + WBEM_E_INVALID_PROPERTY_TYPE = 0x8004102A, + WBEM_E_VALUE_OUT_OF_RANGE = 0x8004102B, + WBEM_E_CANNOT_BE_SINGLETON = 0x8004102C, + WBEM_E_INVALID_CIM_TYPE = 0x8004102D, + WBEM_E_INVALID_METHOD = 0x8004102E, + WBEM_E_INVALID_METHOD_PARAMETERS = 0x8004102F, + WBEM_E_SYSTEM_PROPERTY = 0x80041030, + WBEM_E_INVALID_PROPERTY = 0x80041031, + WBEM_E_CALL_CANCELLED = 0x80041032, + WBEM_E_SHUTTING_DOWN = 0x80041033, + WBEM_E_PROPAGATED_METHOD = 0x80041034, + WBEM_E_UNSUPPORTED_PARAMETER = 0x80041035, + WBEM_E_MISSING_PARAMETER_ID = 0x80041036, + WBEM_E_INVALID_PARAMETER_ID = 0x80041037, + WBEM_E_NONCONSECUTIVE_PARAMETER_IDS = 0x80041038, + WBEM_E_PARAMETER_ID_ON_RETVAL = 0x80041039, + WBEM_E_INVALID_OBJECT_PATH = 0x8004103A, + WBEM_E_OUT_OF_DISK_SPACE = 0x8004103B, + WBEM_E_BUFFER_TOO_SMALL = 0x8004103C, + WBEM_E_UNSUPPORTED_PUT_EXTENSION = 0x8004103D, + WBEM_E_UNKNOWN_OBJECT_TYPE = 0x8004103E, + WBEM_E_UNKNOWN_PACKET_TYPE = 0x8004103F, + WBEM_E_MARSHAL_VERSION_MISMATCH = 0x80041040, + WBEM_E_MARSHAL_INVALID_SIGNATURE = 0x80041041, + WBEM_E_INVALID_QUALIFIER = 0x80041042, + WBEM_E_INVALID_DUPLICATE_PARAMETER = 0x80041043, + WBEM_E_TOO_MUCH_DATA = 0x80041044, + WBEM_E_SERVER_TOO_BUSY = 0x80041045, + WBEM_E_INVALID_FLAVOR = 0x80041046, + WBEM_E_CIRCULAR_REFERENCE = 0x80041047, + WBEM_E_UNSUPPORTED_CLASS_UPDATE = 0x80041048, + WBEM_E_CANNOT_CHANGE_KEY_INHERITANCE = 0x80041049, + WBEM_E_CANNOT_CHANGE_INDEX_INHERITANCE = 0x80041050, + WBEM_E_TOO_MANY_PROPERTIES = 0x80041051, + WBEM_E_UPDATE_TYPE_MISMATCH = 0x80041052, + WBEM_E_UPDATE_OVERRIDE_NOT_ALLOWED = 0x80041053, + WBEM_E_UPDATE_PROPAGATED_METHOD = 0x80041054, + WBEM_E_METHOD_NOT_IMPLEMENTED = 0x80041055, + WBEM_E_METHOD_DISABLED = 0x80041056, + WBEM_E_REFRESHER_BUSY = 0x80041057, + WBEM_E_UNPARSABLE_QUERY = 0x80041058, + WBEM_E_NOT_EVENT_CLASS = 0x80041059, + WBEM_E_MISSING_GROUP_WITHIN = 0x8004105A, + WBEM_E_MISSING_AGGREGATION_LIST = 0x8004105B, + WBEM_E_PROPERTY_NOT_AN_OBJECT = 0x8004105C, + WBEM_E_AGGREGATING_BY_OBJECT = 0x8004105D, + WBEM_E_UNINTERPRETABLE_PROVIDER_QUERY = 0x8004105F, + WBEM_E_BACKUP_RESTORE_WINMGMT_RUNNING = 0x80041060, + WBEM_E_QUEUE_OVERFLOW = 0x80041061, + WBEM_E_PRIVILEGE_NOT_HELD = 0x80041062, + WBEM_E_INVALID_OPERATOR = 0x80041063, + WBEM_E_LOCAL_CREDENTIALS = 0x80041064, + WBEM_E_CANNOT_BE_ABSTRACT = 0x80041065, + WBEM_E_AMENDED_OBJECT = 0x80041066, + WBEM_E_CLIENT_TOO_SLOW = 0x80041067, + WBEM_E_NULL_SECURITY_DESCRIPTOR = 0x80041068, + WBEM_E_TIMED_OUT = 0x80041069, + WBEM_E_INVALID_ASSOCIATION = 0x8004106A, + WBEM_E_AMBIGUOUS_OPERATION = 0x8004106B, + WBEM_E_QUOTA_VIOLATION = 0x8004106C, + WBEM_E_RESERVED_001 = 0x8004106D, + WBEM_E_RESERVED_002 = 0x8004106E, + WBEM_E_UNSUPPORTED_LOCALE = 0x8004106F, + WBEM_E_HANDLE_OUT_OF_DATE = 0x80041070, + WBEM_E_CONNECTION_FAILED = 0x80041071, + WBEM_E_INVALID_HANDLE_REQUEST = 0x80041072, + WBEM_E_PROPERTY_NAME_TOO_WIDE = 0x80041073, + WBEM_E_CLASS_NAME_TOO_WIDE = 0x80041074, + WBEM_E_METHOD_NAME_TOO_WIDE = 0x80041075, + WBEM_E_QUALIFIER_NAME_TOO_WIDE = 0x80041076, + WBEM_E_RERUN_COMMAND = 0x80041077, + WBEM_E_DATABASE_VER_MISMATCH = 0x80041078, + WBEM_E_VETO_DELETE = 0x80041079, + WBEM_E_VETO_PUT = 0x8004107A, + WBEM_E_INVALID_LOCALE = 0x80041080, + WBEM_E_PROVIDER_SUSPENDED = 0x80041081, + WBEM_E_SYNCHRONIZATION_REQUIRED = 0x80041082, + WBEM_E_NO_SCHEMA = 0x80041083, + WBEM_E_PROVIDER_ALREADY_REGISTERED = 0x80041084, + WBEM_E_PROVIDER_NOT_REGISTERED = 0x80041085, + WBEM_E_FATAL_TRANSPORT_ERROR = 0x80041086, + WBEM_E_ENCRYPTED_CONNECTION_REQUIRED = 0x80041087, + WBEM_E_PROVIDER_TIMED_OUT = 0x80041088, + WBEM_E_NO_KEY = 0x80041089, + WBEM_E_PROVIDER_DISABLED = 0x8004108a + } WBEMSTATUS; + + typedef [public,noprint] enum + { + WBEM_FLAG_RETURN_WBEM_COMPLETE = 0, + WBEM_FLAG_BIDIRECTIONAL = 0, + WBEM_FLAG_RETURN_IMMEDIATELY = 0x000010, + WBEM_FLAG_FORWARD_ONLY = 0x000020, + WBEM_FLAG_NO_ERROR_OBJECT = 0x000040, + WBEM_FLAG_SEND_STATUS = 0x000080, + WBEM_FLAG_ENSURE_LOCATABLE = 0x000100, + WBEM_FLAG_DIRECT_READ = 0x000200, + WBEM_FLAG_USE_AMENDED_QUALIFIERS = 0x020000, + WBEM_FLAG_STRONG_VALIDATION = 0x100000, + WBEM_FLAG_RETURN_ERROR_OBJECT = 0, + WBEM_FLAG_DONT_SEND_STATUS = 0, + WBEM_FLAG_SEND_ONLY_SELECTED = 0, + + WBEM_RETURN_WHEN_COMPLETE = 0, + WBEM_RETURN_IMMEDIATELY = WBEM_FLAG_RETURN_IMMEDIATELY, + + WBEM_MASK_RESERVED_FLAGS = 0x001F000 + } WBEM_GENERIC_FLAG_TYPE; + + typedef [public,noprint,v1_enum] enum tag_WBEM_TIMEOUT_TYPE + { + WBEM_NO_WAIT = 0, + WBEM_INFINITE = 0xFFFFFFFF + } WBEM_TIMEOUT_TYPE; + + typedef [public,v1_enum] enum + { + CIM_EMPTY = 0, + CIM_SINT16 = 2, + CIM_SINT32 = 3, + CIM_REAL32 = 4, + CIM_REAL64 = 5, + CIM_STRING = 8, + + CIM_BOOLEAN = 11, + CIM_OBJECT = 13, + CIM_SINT8 = 16, + CIM_UINT8 = 17, + CIM_UINT16 = 18, + CIM_UINT32 = 19, + CIM_SINT64 = 20, + CIM_UINT64 = 21, + CIM_DATETIME = 101, + CIM_REFERENCE = 102, + CIM_CHAR16 = 103, + + CIM_FLAG_ARRAY = 0x2000, + CIM_ILLEGAL = 0x0fff, + CIM_TYPEMASK = 0x2fff, + + CIM_ARR_SINT8 = CIM_FLAG_ARRAY | CIM_SINT8, + CIM_ARR_UINT8 = CIM_FLAG_ARRAY | CIM_UINT8, + CIM_ARR_SINT16 = CIM_FLAG_ARRAY | CIM_SINT16, + CIM_ARR_UINT16 = CIM_FLAG_ARRAY | CIM_UINT16, + CIM_ARR_SINT32 = CIM_FLAG_ARRAY | CIM_SINT32, + CIM_ARR_UINT32 = CIM_FLAG_ARRAY | CIM_UINT32, + CIM_ARR_SINT64 = CIM_FLAG_ARRAY | CIM_SINT64, + CIM_ARR_UINT64 = CIM_FLAG_ARRAY | CIM_UINT64, + CIM_ARR_REAL32 = CIM_FLAG_ARRAY | CIM_REAL32, + CIM_ARR_REAL64 = CIM_FLAG_ARRAY | CIM_REAL64, + CIM_ARR_BOOLEAN = CIM_FLAG_ARRAY | CIM_BOOLEAN, + CIM_ARR_STRING = CIM_FLAG_ARRAY | CIM_STRING, + CIM_ARR_DATETIME = CIM_FLAG_ARRAY | CIM_DATETIME, + CIM_ARR_REFERENCE = CIM_FLAG_ARRAY | CIM_REFERENCE, + CIM_ARR_CHAR16 = CIM_FLAG_ARRAY | CIM_CHAR16, + CIM_ARR_OBJECT = CIM_FLAG_ARRAY | CIM_OBJECT + + } CIMTYPE_ENUMERATION; + + typedef [public,bitmap8bit] bitmap + { + WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE = 0x1, + WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS = 0x2, +// WBEM_FLAVOR_MASK_PROPAGATION = 0x0F, + + WBEM_FLAVOR_NOT_OVERRIDABLE = 0x10, +// WBEM_FLAVOR_MASK_PERMISSIONS = 0x10, + + WBEM_FLAVOR_ORIGIN_PROPAGATED = 0x20, + WBEM_FLAVOR_ORIGIN_SYSTEM = 0x40, +// WBEM_FLAVOR_MASK_ORIGIN = 0x60, + + WBEM_FLAVOR_AMENDED = 0x80 +// WBEM_FLAVOR_MASK_AMENDED = 0x80 + + } WBEM_FLAVOR_TYPE; + + typedef [public,bitmap8bit] bitmap + { + WCF_DECORATIONS = 1, + WCF_INSTANCE = 2, + WCF_CLASS = 4, + WCF_CLASS_PART_INTERNAL = 8 + // WCF_CLASS_PART_SHARED = 0x104 + } WCO_FLAGS; + + typedef [public,nopull,nopush] struct + { + uint32 count; + [ref,charset(UTF16)] uint16 *item[count]; + } CIMSTRINGS; + + typedef [public,bitmap8bit] bitmap { + DEFAULT_FLAG_EMPTY = 1, + DEFAULT_FLAG_INHERITED = 2 + } DEFAULT_FLAGS; + + WERROR OpenNamespace( + [in] BSTR strNamespace, + [in] long lFlags, + [in] IWbemContext* pCtx, + [out, in, unique] IWbemServices** ppWorkingNamespace, + [out, in, unique] IWbemCallResult** ppResult + ); + + WERROR CancelAsyncCall( + [in] IWbemObjectSink* pSink + ); + + WERROR QueryObjectSink( + [in] long lFlags, + [out] IWbemObjectSink** ppResponseHandler + ); + + WERROR GetObject( + [in] BSTR strObjectPath, + [in] long lFlags, + [in] IWbemContext* pCtx, + [out, in, unique] IWbemClassObject** ppObject, + [out, in, unique] IWbemCallResult** ppCallResult + ); + + + WERROR GetObjectAsync( + [in] BSTR strObjectPath, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + WERROR PutClass( + [in] IWbemClassObject* pObject, + [in] long lFlags, + [in] IWbemContext* pCtx, + [out, in, unique] IWbemCallResult** ppCallResult + ); + + WERROR PutClassAsync( + [in] IWbemClassObject* pObject, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + WERROR DeleteClass( + [in] BSTR strClass, + [in] long lFlags, + [in] IWbemContext* pCtx, + [out, in, unique] IWbemCallResult** ppCallResult + ); + + WERROR DeleteClassAsync( + [in] BSTR strClass, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + WERROR CreateClassEnum( + [in] BSTR strSuperclass, + [in] long lFlags, + [in] IWbemContext* pCtx, + [out] IEnumWbemClassObject** ppEnum + ); + + WERROR CreateClassEnumAsync( + [in] BSTR strSuperclass, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + WERROR PutInstance( + [in] IWbemClassObject* pInst, + [in] long lFlags, + [in] IWbemContext* pCtx, + [out, in, unique] IWbemCallResult** ppCallResult + ); + + WERROR PutInstanceAsync( + [in] IWbemClassObject* pInst, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + + WERROR DeleteInstance( + [in] BSTR strObjectPath, + [in] long lFlags, + [in] IWbemContext* pCtx, + [out, in, unique] IWbemCallResult** ppCallResult + ); + + + WERROR DeleteInstanceAsync( + [in] BSTR strObjectPath, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + + WERROR CreateInstanceEnum( + [in] BSTR strFilter, // allow more things than a class name + [in] long lFlags, + [in,unique] IWbemContext* pCtx, + [out] IEnumWbemClassObject** ppEnum + ); + + WERROR CreateInstanceEnumAsync( + [in] BSTR strSuperClass, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + WERROR ExecQuery( + [in] BSTR strQueryLanguage, + [in] BSTR strQuery, + [in] long lFlags, + [in,unique] IWbemContext* pCtx, + [out] IEnumWbemClassObject** ppEnum + ); + + WERROR ExecQueryAsync( + [in] BSTR strQueryLanguage, + [in] BSTR strQuery, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + WERROR ExecNotificationQuery( + [in] BSTR strQueryLanguage, + [in] BSTR strQuery, + [in] long lFlags, + [in,unique] IWbemContext* pCtx, + [out] IEnumWbemClassObject** ppEnum + ); + + WERROR ExecNotificationQueryAsync( + [in] BSTR strQueryLanguage, + [in] BSTR strQuery, + [in] long lFlags, + [in] IWbemContext* pCtx, + [in] IWbemObjectSink* pResponseHandler + ); + + WERROR ExecMethod( + [in] BSTR strObjectPath, + [in] BSTR strMethodName, + [in] long lFlags, + [in,unique] IWbemContext* pCtx, + [in,unique] IWbemClassObject* pInParams, + [in,out,unique] IWbemClassObject** ppOutParams, + [in,out,unique] IWbemCallResult** ppCallResult + ); + + WERROR ExecMethodAsync( + [in] BSTR strObjectPath, + [in] BSTR strMethodName, + [in] uint32 lFlags, + [in] IWbemContext* pCtx, + [in] IWbemClassObject* pInParams, + [in] IWbemObjectSink* pResponseHandler + ); +} + +[ + object, + uuid(027947e1-d731-11ce-a357-000000000001), + pointer_default(unique) +] interface IEnumWbemClassObject : IUnknown +{ + WERROR Reset(); + + [call_as(Next)] WERROR IEnumWbemClassObject_Next( + [in] int32 lTimeout, + [in] uint32 uCount, + [out, size_is(uCount), length_is(*puReturned)] IWbemClassObject** apObjects, + [out] uint32* puReturned + ); + + WERROR NextAsync( + [in] uint32 uCount, + [in] IWbemObjectSink* pSink + ); + + WERROR IEnumWbemClassObject_Clone( + [out] IEnumWbemClassObject** ppEnum + ); + + WERROR Skip( + [in] int32 lTimeout, + [in] uint32 nCount + ); +}; + +[ + object, + local, + uuid("44aca674-e8fc-11d0-a07c-00c04fb68820"), + pointer_default(unique) +] interface IWbemContext : IUnknown +{ + WERROR Clone([out] IWbemContext** ppNewCopy); + + WERROR GetNames( +// [in] long lFlags, +// [out] SAFEARRAY (BSTR)* pNames + ); + + WERROR BeginEnumeration([in] long lFlags); + + WERROR Next( +// [in] long lFlags, +// [out] BSTR* pstrName, +// [out] VARIANT* pValue + ); + + WERROR EndEnumeration(); + + + WERROR SetValue( +// [in, string] LPCWSTR wszName, +// [in] long lFlags +// [in] VARIANT* pValue + ); + + WERROR GetValue( +// [in, string] LPCWSTR wszName, +// [in] long lFlags, +// [out] VARIANT* pValue + ); + + WERROR DeleteValue( +// [in, string] LPCWSTR wszName, +// [in] long lFlags + ); + + WERROR DeleteAll(); +} + +[ + object, + uuid("F309AD18-D86A-11d0-A075-00C04FB68820"), + pointer_default(unique) +] interface IWbemLevel1Login : IUnknown +{ + WERROR EstablishPosition( + [in, unique, string, charset(UTF16)] uint16* wszLocaleList, + [in] DWORD dwNumLocales, + [out] DWORD* reserved + ); + WERROR RequestChallenge( + [in, unique, string, charset(UTF16)] uint16* wszNetworkResource, + [in, unique, string, charset(UTF16)] uint16* wszUser, + [out, size_is(16), length_is(16)] uint8 * Nonce + ); + WERROR WBEMLogin( + [in, unique, string, charset(UTF16)] uint16* wszPreferredLocale, + [in, size_is(16), length_is(16), unique] uint8 * AccessToken, + [in] long lFlags, + [in] IWbemContext* pCtx, + [out] IWbemServices** ppNamespace + ); + + + WERROR NTLMLogin( + [in,unique,string,charset(UTF16)] uint16 *wszNetworkResource, + [in,unique,string,charset(UTF16)] uint16 *wszPreferredLocale, + [in] long lFlags, + [in,unique] IWbemContext* pCtx, + [out,ref] IWbemServices** ppNamespace + ); + +} + +[ + object, + uuid("423ec01e-2e35-11d2-b604-00104b703efd"), + pointer_default(unique) +] interface IWbemWCOSmartEnum : IUnknown +{ + typedef struct { + uint32 size; + char data[size]; + } WBEMDATA; + + typedef enum { + WTYPE_SCHEMA = 1, + WTYPE_CLASS = 2, + WTYPE_OBJECT = 3 + } WTYPES; + + typedef [relative_base] struct { + // [relative] WBEMDATA4 *data; /* 0x9 */ + uint32 data_size; + uint8 wtype; + } WBEMDATA4; + + typedef [relative_base] struct { + [relative] WBEMDATA4 *data; /* 0x9 */ + uint32 data_size; + uint8 wtype; + } WBEMDATA3; + + typedef [relative_base] struct { + [relative,size_is(obj_num)] WBEMDATA3 *data; /* 0x8 */ + uint32 data_size; + uint32 obj_num; + } WBEMDATA2; + + typedef [relative_base] struct { + [relative] WBEMDATA2 *data; /* 0x8 */ + uint32 data_size; + } WBEMDATA1; + + typedef [relative_base] struct { + uint32 u1_0; /* 0 */ + hyper signature; /* 'WBEMDATA' */ + [relative] WBEMDATA1 *data; /* 0x1A */ + uint32 data_size; + uint32 u2_0; /* 0 */ + uint8 ver_major; /* 1 */ + uint8 ver_minor; /* 0 - Win2000, 1 - WinXP/2003 */ + } WBEMDATA0; + + WERROR IWbemWCOSmartEnum_Next( + [in,ref] GUID *gEWCO, + [in] uint32 lTimeOut, + [in] uint32 uCount, + [in] uint32 unknown, + [in,ref] GUID *gWCO, + [out,ref] uint32 *puReturned, + [out,ref] uint32 *pSize, + [out,ref,noprint,size_is(,*pSize)] uint8 **pData + ); +} + +[ + object, + uuid("1c1c45ee-4395-11d2-b60b-00104b703efd"), + pointer_default(unique) +] interface IWbemFetchSmartEnum : IUnknown +{ + WERROR Fetch([out] IWbemWCOSmartEnum** ppEnum); + WERROR Test([out] IWbemClassObject** ppEnum); +} + +[ + object, + // restricted, + uuid(44aca675-e8fc-11d0-a07c-00c04fb68820) +] interface IWbemCallResult : IUnknown +{ + WERROR GetResultObject( + [in] long lTimeout, + [out] IWbemClassObject** ppResultObject + ); + + WERROR GetResultString( + [in] long lTimeout, + [out] BSTR* pstrResultString + ); + + WERROR GetResultServices( + [in] long lTimeout, + [out] IWbemServices** ppServices + ); + + WERROR GetCallStatus( + [in] long lTimeout, + [out] long* plStatus + ); +} + + +[ + object, + restricted, + uuid(7c857801-7381-11cf-884d-00aa004b2e24) +] +interface IWbemObjectSink : IUnknown +{ + WERROR SetStatus( + [in] long lFlags, + [in] WERROR hResult, + [in] BSTR strParam, + [in] IWbemClassObject* pObjParam + ); + WERROR Indicate( + [in] long lObjectCount, + [in, size_is(lObjectCount)] IWbemClassObject** apObjArray + ); +}; + diff --git a/librpc/idl/wzcsvc.idl b/librpc/idl/wzcsvc.idl new file mode 100644 index 0000000000..b403c0798c --- /dev/null +++ b/librpc/idl/wzcsvc.idl @@ -0,0 +1,31 @@ +/* + wireless configuration service +*/ + +[ + uuid("621dff68-3c39-4c6c-aae3-e68e2c6503ad"), + version(1.0), + helpstring("Wireless Configuration Service") +] +interface wzcsvc +{ + + void wzcsvc_EnumInterfaces(); + void wzcsvc_QueryInterface(); + void wzcsvc_SetInterface(); + void wzcsvc_RefreshInterface(); + void wzcsvc_QueryContext(); + void wzcsvc_SetContext(); + void wzcsvc_EapolUIResponse(); + void wzcsvc_EapolGetCustomAuthData(); + void wzcsvc_EapolSetCustomAuthData(); + void wzcsvc_EapolGetInterfaceParams(); + void wzcsvc_EapolSetInterfaceParams(); + void wzcsvc_EapolReAuthenticateInterface(); + void wzcsvc_EapolQueryInterfaceState(); + void wzcsvc_OpenWZCDbLogSession(); + void wzcsvc_CloseWZCDbLogSession(); + void wzcsvc_EnumWZCDbLogRecords(); + void wzcsvc_FlushWZCdbLog(); + void wzcsvc_GetWZCDbLogRecord(); +} diff --git a/librpc/idl/xattr.idl b/librpc/idl/xattr.idl new file mode 100644 index 0000000000..c1af4791ae --- /dev/null +++ b/librpc/idl/xattr.idl @@ -0,0 +1,140 @@ +#include "idl_types.h" + +/* + IDL structures for xattr file attributes + + this has nothing to do with RPC, we are just using our NDR/IDL + infrastructure as a convenient way to store linearised information + about a file in a architecture independent manner +*/ + +import "security.idl"; + +[ + pointer_default(unique) +] +interface xattr +{ + const char *XATTR_DOSATTRIB_NAME = "user.DosAttrib"; + const int XATTR_DOSATTRIB_ESTIMATED_SIZE = 64; + + /* we store basic dos attributes in a DosAttrib xattr. By + using a union we can cope with new version of this + structure more easily */ + + typedef struct { + uint32 attrib; + uint32 ea_size; + udlong size; + udlong alloc_size; + NTTIME create_time; + NTTIME change_time; + } xattr_DosInfo1; + +/* + We use xattrDosInfo1 again when we store values. + Because the sticky write time is now stored in the opendb + and xattr_DosInfo2Old is only present to parse existing + values from disk. + + const int XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME = 0x1; +*/ + typedef struct { + uint32 flags; + uint32 attrib; + uint32 ea_size; + udlong size; + udlong alloc_size; + NTTIME create_time; + NTTIME change_time; + NTTIME write_time; /* only used when sticky write time is set */ + utf8string name; + } xattr_DosInfo2Old; + + typedef [switch_type(uint16)] union { + [case(1)] xattr_DosInfo1 info1; + [case(2)] xattr_DosInfo2Old oldinfo2; + } xattr_DosInfo; + + typedef [public] struct { + uint16 version; + [switch_is(version)] xattr_DosInfo info; + } xattr_DosAttrib; + + + /* we store DOS style extended attributes in a DosEAs xattr */ + const char *XATTR_DOSEAS_NAME = "user.DosEAs"; + + typedef struct { + utf8string name; + DATA_BLOB value; + } xattr_EA; + + typedef [public] struct { + uint16 num_eas; + [size_is(num_eas)] xattr_EA *eas; + } xattr_DosEAs; + + /* Slightly different version, used by the vfs_xattr_tdb module */ + typedef [public] struct { + uint32 num_eas; + xattr_EA eas[num_eas]; + } tdb_xattrs; + + /* we store stream information in this xattr structure. Then + the streams themselves are stored in + user.DosStream.STREAMNAME or in external files, according + to the flags */ + const char *XATTR_DOSSTREAMS_NAME = "user.DosStreams"; + + const int XATTR_STREAM_FLAG_INTERNAL = 0x00000001; + + /* stream data is stored in attributes with the given prefix */ + const char *XATTR_DOSSTREAM_PREFIX = "user.DosStream."; + + const int XATTR_MAX_STREAM_SIZE = 0x4000; + const int XATTR_MAX_STREAM_SIZE_TDB = 0x100000; + + typedef struct { + uint32 flags; + udlong size; + udlong alloc_size; + utf8string name; + } xattr_DosStream; + + typedef [public] struct { + uint32 num_streams; + [size_is(num_streams)] xattr_DosStream *streams; + } xattr_DosStreams; + + + /* we store the NT ACL a NTACL xattr. It is versioned so we + can later add other acl attribs (such as posix acl mapping) + + we put this xattr in the security namespace to ensure that + only trusted users can write to the ACL + + stored in "security.NTACL" + + Version 1. raw SD stored as Samba4 does it. + Version 2. raw SD + last changed timestamp so we + can discard if this doesn't match the POSIX st_ctime. + */ + + const char *XATTR_NTACL_NAME = "security.NTACL"; + + typedef [public] struct { + security_descriptor *sd; + NTTIME last_changed; + } security_descriptor_timestamp; + + typedef [switch_type(uint16)] union { + [case(1)] security_descriptor *sd; + [case(2)] security_descriptor_timestamp *sd_ts; + } xattr_NTACL_Info; + + typedef [public] struct { + uint16 version; + [switch_is(version)] xattr_NTACL_Info info; + } xattr_NTACL; +} diff --git a/librpc/ndr.pc.in b/librpc/ndr.pc.in new file mode 100644 index 0000000000..2f4d95006f --- /dev/null +++ b/librpc/ndr.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: ndr +Description: Network Data Representation Core Library +Requires: samba-hostconfig talloc +Version: 0.0.1 +Libs: -L${libdir} -lndr +Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h new file mode 100644 index 0000000000..63b89e17f4 --- /dev/null +++ b/librpc/ndr/libndr.h @@ -0,0 +1,521 @@ +/* + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* This is a public header file that is installed as part of Samba. + * If you remove any functions or change their signature, update + * the so version number. */ + +#ifndef __LIBNDR_H__ +#define __LIBNDR_H__ + +#include <talloc.h> +#include <sys/time.h> +#if _SAMBA_BUILD_ == 4 +#include "../lib/util/util.h" /* for discard_const */ +#include "lib/charset/charset.h" +#endif + +/* + this provides definitions for the libcli/rpc/ MSRPC library +*/ + + +/* + this is used by the token store/retrieve code +*/ +struct ndr_token_list { + struct ndr_token_list *next, *prev; + const void *key; + uint32_t value; +}; + +/* 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_t flags; /* LIBNDR_FLAG_* */ + uint8_t *data; + uint32_t data_size; + uint32_t offset; + + struct smb_iconv_convenience *iconv_convenience; + + uint32_t relative_base_offset; + struct ndr_token_list *relative_base_list; + + struct ndr_token_list *relative_list; + struct ndr_token_list *array_size_list; + struct ndr_token_list *array_length_list; + struct ndr_token_list *switch_list; + + TALLOC_CTX *current_mem_ctx; + + /* this is used to ensure we generate unique reference IDs + between request and reply */ + uint32_t ptr_count; +}; + +/* structure passed to functions that generate NDR formatted data */ +struct ndr_push { + uint32_t flags; /* LIBNDR_FLAG_* */ + uint8_t *data; + uint32_t alloc_size; + uint32_t offset; + + uint32_t relative_base_offset; + struct ndr_token_list *relative_base_list; + + struct ndr_token_list *switch_list; + struct ndr_token_list *relative_list; + struct ndr_token_list *nbt_string_list; + struct ndr_token_list *full_ptr_list; + + /* this is used to ensure we generate unique reference IDs */ + uint32_t ptr_count; + + struct smb_iconv_convenience *iconv_convenience; +}; + +/* structure passed to functions that print IDL structures */ +struct ndr_print { + uint32_t flags; /* LIBNDR_FLAG_* */ + uint32_t depth; + struct ndr_token_list *switch_list; + void (*print)(struct ndr_print *, const char *, ...) PRINTF_ATTRIBUTE(2,3); + void *private_data; +}; + +#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_FLAG_STR_BYTESIZE (1<<8) +#define LIBNDR_FLAG_STR_CONFORMANT (1<<10) +#define LIBNDR_FLAG_STR_CHARLEN (1<<11) +#define LIBNDR_FLAG_STR_UTF8 (1<<12) +#define LIBNDR_STRING_FLAGS (0x7FFC) + + +#define LIBNDR_FLAG_REF_ALLOC (1<<20) +#define LIBNDR_FLAG_REMAINING (1<<21) +#define LIBNDR_FLAG_ALIGN2 (1<<22) +#define LIBNDR_FLAG_ALIGN4 (1<<23) +#define LIBNDR_FLAG_ALIGN8 (1<<24) + +#define LIBNDR_ALIGN_FLAGS (LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8) + +#define LIBNDR_PRINT_ARRAY_HEX (1<<25) +#define LIBNDR_PRINT_SET_VALUES (1<<26) + +/* used to force a section of IDL to be little-endian */ +#define LIBNDR_FLAG_LITTLE_ENDIAN (1<<27) + +/* used to check if alignment padding is zero */ +#define LIBNDR_FLAG_PAD_CHECK (1<<28) + +/* set if an object uuid will be present */ +#define LIBNDR_FLAG_OBJECT_PRESENT (1<<30) + +/* set to avoid recursion in ndr_size_*() calculation */ +#define LIBNDR_FLAG_NO_NDR_SIZE (1<<31) + +/* 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_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) + +/* useful macro for debugging in strings */ +#define NDR_PRINT_STRUCT_STRING(ctx, type, p) ndr_print_struct_string(ctx, (ndr_print_fn_t)ndr_print_ ##type, #p, p) +#define NDR_PRINT_UNION_STRING(ctx, type, level, p) ndr_print_union_string(ctx, (ndr_print_fn_t)ndr_print_ ##type, #p, level, p) +#define NDR_PRINT_FUNCTION_STRING(ctx, type, flags, p) ndr_print_function_string(ctx, (ndr_print_function_t)ndr_print_ ##type, #type, flags, p) +#define NDR_PRINT_BOTH_STRING(ctx, type, p) NDR_PRINT_FUNCTION_STRING(ctx, type, NDR_BOTH, p) +#define NDR_PRINT_OUT_STRING(ctx, type, p) NDR_PRINT_FUNCTION_STRING(ctx, type, NDR_OUT, p) +#define NDR_PRINT_IN_STRING(ctx, type, p) NDR_PRINT_FUNCTION_STRING(ctx, type, NDR_IN | NDR_SET_VALUES, p) + +#define NDR_BE(ndr) (((ndr)->flags & (LIBNDR_FLAG_BIGENDIAN|LIBNDR_FLAG_LITTLE_ENDIAN)) == LIBNDR_FLAG_BIGENDIAN) + +enum ndr_err_code { + NDR_ERR_SUCCESS = 0, + 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_COMPRESSION, + NDR_ERR_STRING, + NDR_ERR_VALIDATE, + NDR_ERR_BUFSIZE, + NDR_ERR_ALLOC, + NDR_ERR_RANGE, + NDR_ERR_TOKEN, + NDR_ERR_IPV4ADDRESS, + NDR_ERR_INVALID_POINTER, + NDR_ERR_UNREAD_BYTES +}; + +#define NDR_ERR_CODE_IS_SUCCESS(x) (x == NDR_ERR_SUCCESS) + +#define NDR_ERR_HAVE_NO_MEMORY(x) do { \ + if (NULL == (x)) { \ + return NDR_ERR_ALLOC; \ + } \ +} while (0) + +enum ndr_compression_alg { + NDR_COMPRESSION_MSZIP = 2, + NDR_COMPRESSION_XPRESS = 3 +}; + +/* + 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", (unsigned)n); \ + } \ +} while(0) + +#define NDR_ALIGN(ndr, n) ndr_align_size(ndr->offset, n) + +#define NDR_ROUND(size, n) (((size)+((n)-1)) & ~((n)-1)) + +#define NDR_PULL_ALIGN(ndr, n) do { \ + if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \ + if (ndr->flags & LIBNDR_FLAG_PAD_CHECK) { \ + ndr_check_padding(ndr, n); \ + } \ + 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", (unsigned)n); \ + } \ +} while(0) + +#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, n)) + +#define NDR_PUSH_ALIGN(ndr, n) do { \ + if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \ + uint32_t _pad = ((ndr->offset + (n-1)) & ~(n-1)) - ndr->offset; \ + while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, 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 { \ + enum ndr_err_code _status; \ + _status = call; \ + if (!NDR_ERR_CODE_IS_SUCCESS(_status)) { \ + return _status; \ + } \ +} while (0) + +#define NDR_PULL_GET_MEM_CTX(ndr) (ndr->current_mem_ctx) + +#define NDR_PULL_SET_MEM_CTX(ndr, mem_ctx, flgs) do {\ + if ( !(flgs) || (ndr->flags & flgs) ) {\ + if (!(mem_ctx)) {\ + return ndr_pull_error(ndr, NDR_ERR_ALLOC, "NDR_PULL_SET_MEM_CTX(NULL): %s\n", __location__); \ + }\ + ndr->current_mem_ctx = discard_const(mem_ctx);\ + }\ +} while(0) + +#define _NDR_PULL_FIX_CURRENT_MEM_CTX(ndr) do {\ + if (!ndr->current_mem_ctx) {\ + ndr->current_mem_ctx = talloc_new(ndr);\ + if (!ndr->current_mem_ctx) {\ + return ndr_pull_error(ndr, NDR_ERR_ALLOC, "_NDR_PULL_FIX_CURRENT_MEM_CTX() failed: %s\n", __location__); \ + }\ + }\ +} while(0) + +#define NDR_PULL_ALLOC(ndr, s) do { \ + _NDR_PULL_FIX_CURRENT_MEM_CTX(ndr);\ + (s) = talloc_ptrtype(ndr->current_mem_ctx, (s)); \ + if (!(s)) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Alloc %s failed: %s\n", # s, __location__); \ +} while (0) + +#define NDR_PULL_ALLOC_N(ndr, s, n) do { \ + _NDR_PULL_FIX_CURRENT_MEM_CTX(ndr);\ + (s) = talloc_array_ptrtype(ndr->current_mem_ctx, (s), n); \ + if (!(s)) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Alloc %u * %s failed: %s\n", (unsigned)n, # s, __location__); \ +} while (0) + + +#define NDR_PUSH_ALLOC_SIZE(ndr, s, size) do { \ + (s) = talloc_array(ndr, uint8_t, size); \ + if (!(s)) return ndr_push_error(ndr, NDR_ERR_ALLOC, "push alloc %u failed: %s\n", (unsigned)size, __location__); \ +} while (0) + +#define NDR_PUSH_ALLOC(ndr, s) do { \ + (s) = talloc_ptrtype(ndr, (s)); \ + if (!(s)) return ndr_push_error(ndr, NDR_ERR_ALLOC, "push alloc %s failed: %s\n", # s, __location__); \ +} while (0) + +/* these are used when generic fn pointers are needed for ndr push/pull fns */ +typedef enum ndr_err_code (*ndr_push_flags_fn_t)(struct ndr_push *, int ndr_flags, const void *); +typedef enum ndr_err_code (*ndr_pull_flags_fn_t)(struct ndr_pull *, int ndr_flags, void *); +typedef void (*ndr_print_fn_t)(struct ndr_print *, const char *, const void *); +typedef void (*ndr_print_function_t)(struct ndr_print *, const char *, int, const void *); + +#if _SAMBA_BUILD_ == 4 +#include "libcli/util/error.h" +#endif +#include "librpc/gen_ndr/misc.h" + +extern const struct ndr_syntax_id ndr_transfer_syntax; +extern const struct ndr_syntax_id ndr64_transfer_syntax; + +struct ndr_interface_call { + const char *name; + size_t struct_size; + ndr_push_flags_fn_t ndr_push; + ndr_pull_flags_fn_t ndr_pull; + ndr_print_function_t ndr_print; + bool async; +}; + +struct ndr_interface_string_array { + uint32_t count; + const char * const *names; +}; + +struct ndr_interface_table { + const char *name; + struct ndr_syntax_id syntax_id; + const char *helpstring; + uint32_t num_calls; + const struct ndr_interface_call *calls; + const struct ndr_interface_string_array *endpoints; + const struct ndr_interface_string_array *authservices; +}; + +struct ndr_interface_list { + struct ndr_interface_list *prev, *next; + const struct ndr_interface_table *table; +}; + +/* FIXME: Use represent_as instead */ +struct dom_sid; +enum ndr_err_code ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid); +enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid); +void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid); +enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid); +enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid); +void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid); +size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags); +enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid); +enum ndr_err_code ndr_pull_dom_sid0(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid); +void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid); +size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags); +void ndr_print_ipv4_addr(struct ndr_print *ndr, const char *name, const struct in_addr *_ip); +void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid); +bool ndr_syntax_id_equal(const struct ndr_syntax_id *i1, const struct ndr_syntax_id *i2); +enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const void *p, ndr_push_flags_fn_t fn); +enum ndr_err_code ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, uint32_t level, ndr_push_flags_fn_t fn); +size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t push); +size_t ndr_size_union(const void *p, int flags, uint32_t level, ndr_push_flags_fn_t push); +uint32_t ndr_push_get_relative_base_offset(struct ndr_push *ndr); +void ndr_push_restore_relative_base_offset(struct ndr_push *ndr, uint32_t offset); +enum ndr_err_code ndr_push_setup_relative_base_offset1(struct ndr_push *ndr, const void *p, uint32_t offset); +enum ndr_err_code ndr_push_setup_relative_base_offset2(struct ndr_push *ndr, const void *p); +enum ndr_err_code ndr_push_relative_ptr1(struct ndr_push *ndr, const void *p); +enum ndr_err_code ndr_push_relative_ptr2(struct ndr_push *ndr, const void *p); +uint32_t ndr_pull_get_relative_base_offset(struct ndr_pull *ndr); +void ndr_pull_restore_relative_base_offset(struct ndr_pull *ndr, uint32_t offset); +enum ndr_err_code ndr_pull_setup_relative_base_offset1(struct ndr_pull *ndr, const void *p, uint32_t offset); +enum ndr_err_code ndr_pull_setup_relative_base_offset2(struct ndr_pull *ndr, const void *p); +enum ndr_err_code ndr_pull_relative_ptr1(struct ndr_pull *ndr, const void *p, uint32_t rel_offset); +enum ndr_err_code ndr_pull_relative_ptr2(struct ndr_pull *ndr, const void *p); +size_t ndr_align_size(uint32_t offset, size_t n); +struct ndr_pull *ndr_pull_init_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience); +enum ndr_err_code ndr_pull_advance(struct ndr_pull *ndr, uint32_t size); +struct ndr_push *ndr_push_init_ctx(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience); +DATA_BLOB ndr_push_blob(struct ndr_push *ndr); +enum ndr_err_code ndr_push_expand(struct ndr_push *ndr, uint32_t extra_size); +void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3); +void ndr_print_string_helper(struct ndr_print *ndr, const char *format, ...) PRINTF_ATTRIBUTE(2,3); +void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr); +void ndr_print_union_debug(ndr_print_fn_t fn, const char *name, uint32_t level, void *ptr); +void ndr_print_function_debug(ndr_print_function_t fn, const char *name, int flags, void *ptr); +char *ndr_print_struct_string(TALLOC_CTX *mem_ctx, ndr_print_fn_t fn, const char *name, void *ptr); +char *ndr_print_union_string(TALLOC_CTX *mem_ctx, ndr_print_fn_t fn, const char *name, uint32_t level, void *ptr); +char *ndr_print_function_string(TALLOC_CTX *mem_ctx, + ndr_print_function_t fn, const char *name, + int flags, void *ptr); +void ndr_set_flags(uint32_t *pflags, uint32_t new_flags); +enum ndr_err_code ndr_pull_error(struct ndr_pull *ndr, + enum ndr_err_code ndr_err, + const char *format, ...) PRINTF_ATTRIBUTE(3,4); +enum ndr_err_code ndr_push_error(struct ndr_push *ndr, + enum ndr_err_code ndr_err, + const char *format, ...) PRINTF_ATTRIBUTE(3,4); +enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr, + struct ndr_pull **_subndr, + size_t header_size, + ssize_t size_is); +enum ndr_err_code ndr_pull_subcontext_end(struct ndr_pull *ndr, + struct ndr_pull *subndr, + size_t header_size, + ssize_t size_is); +enum ndr_err_code ndr_push_subcontext_start(struct ndr_push *ndr, + struct ndr_push **_subndr, + size_t header_size, + ssize_t size_is); +enum ndr_err_code ndr_push_subcontext_end(struct ndr_push *ndr, + struct ndr_push *subndr, + size_t header_size, + ssize_t size_is); +enum ndr_err_code ndr_token_store(TALLOC_CTX *mem_ctx, + struct ndr_token_list **list, + const void *key, + uint32_t value); +enum ndr_err_code ndr_token_retrieve_cmp_fn(struct ndr_token_list **list, const void *key, uint32_t *v, comparison_fn_t _cmp_fn, bool _remove_tok); +enum ndr_err_code ndr_token_retrieve(struct ndr_token_list **list, const void *key, uint32_t *v); +uint32_t ndr_token_peek(struct ndr_token_list **list, const void *key); +enum ndr_err_code ndr_pull_array_size(struct ndr_pull *ndr, const void *p); +uint32_t ndr_get_array_size(struct ndr_pull *ndr, const void *p); +enum ndr_err_code ndr_check_array_size(struct ndr_pull *ndr, void *p, uint32_t size); +enum ndr_err_code ndr_pull_array_length(struct ndr_pull *ndr, const void *p); +uint32_t ndr_get_array_length(struct ndr_pull *ndr, const void *p); +enum ndr_err_code ndr_check_array_length(struct ndr_pull *ndr, void *p, uint32_t length); +enum ndr_err_code ndr_push_set_switch_value(struct ndr_push *ndr, const void *p, uint32_t val); +enum ndr_err_code ndr_pull_set_switch_value(struct ndr_pull *ndr, const void *p, uint32_t val); +enum ndr_err_code ndr_print_set_switch_value(struct ndr_print *ndr, const void *p, uint32_t val); +uint32_t ndr_push_get_switch_value(struct ndr_push *ndr, const void *p); +uint32_t ndr_pull_get_switch_value(struct ndr_pull *ndr, const void *p); +uint32_t ndr_print_get_switch_value(struct ndr_print *ndr, const void *p); +enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, ndr_pull_flags_fn_t fn); +enum ndr_err_code ndr_pull_struct_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, ndr_pull_flags_fn_t fn); +enum ndr_err_code ndr_pull_union_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, uint32_t level, ndr_pull_flags_fn_t fn); +enum ndr_err_code ndr_pull_union_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, uint32_t level, ndr_pull_flags_fn_t fn); + +/* from libndr_basic.h */ +#define NDR_SCALAR_PROTO(name, type) \ +enum ndr_err_code ndr_push_ ## name(struct ndr_push *ndr, int ndr_flags, type v); \ +enum ndr_err_code ndr_pull_ ## name(struct ndr_pull *ndr, int ndr_flags, type *v); \ +void ndr_print_ ## name(struct ndr_print *ndr, const char *var_name, type v); + +#define NDR_BUFFER_PROTO(name, type) \ +enum ndr_err_code ndr_push_ ## name(struct ndr_push *ndr, int ndr_flags, const type *v); \ +enum ndr_err_code ndr_pull_ ## name(struct ndr_pull *ndr, int ndr_flags, type *v); \ +void ndr_print_ ## name(struct ndr_print *ndr, const char *var_name, const type *v); + +NDR_SCALAR_PROTO(uint8, uint8_t) +NDR_SCALAR_PROTO(int8, int8_t) +NDR_SCALAR_PROTO(uint16, uint16_t) +NDR_SCALAR_PROTO(int16, int16_t) +NDR_SCALAR_PROTO(uint32, uint32_t) +NDR_SCALAR_PROTO(int32, int32_t) +NDR_SCALAR_PROTO(udlong, uint64_t) +NDR_SCALAR_PROTO(udlongr, uint64_t) +NDR_SCALAR_PROTO(dlong, int64_t) +NDR_SCALAR_PROTO(hyper, uint64_t) +NDR_SCALAR_PROTO(pointer, void *) +NDR_SCALAR_PROTO(time_t, time_t) +NDR_SCALAR_PROTO(NTSTATUS, NTSTATUS) +NDR_SCALAR_PROTO(WERROR, WERROR) +NDR_SCALAR_PROTO(NTTIME, NTTIME) +NDR_SCALAR_PROTO(NTTIME_1sec, NTTIME) +NDR_SCALAR_PROTO(NTTIME_hyper, NTTIME) +NDR_SCALAR_PROTO(DATA_BLOB, DATA_BLOB) +NDR_SCALAR_PROTO(ipv4address, const char *) +NDR_SCALAR_PROTO(string, const char *) + +enum ndr_err_code ndr_pull_policy_handle(struct ndr_pull *ndr, int ndr_flags, struct policy_handle *r); +enum ndr_err_code ndr_push_policy_handle(struct ndr_push *ndr, int ndr_flags, const struct policy_handle *r); +void ndr_print_policy_handle(struct ndr_print *ndr, const char *name, const struct policy_handle *r); +bool policy_handle_empty(struct policy_handle *h); + +void ndr_check_padding(struct ndr_pull *ndr, size_t n); +enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v); +enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v); +enum ndr_err_code ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, uint32_t n); +enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n); +enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size); +enum ndr_err_code ndr_pull_align(struct ndr_pull *ndr, size_t size); +enum ndr_err_code ndr_push_bytes(struct ndr_push *ndr, const uint8_t *data, uint32_t n); +enum ndr_err_code ndr_push_zero(struct ndr_push *ndr, uint32_t n); +enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n); +enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void *p); +enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p); +enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr); +void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type); +void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type, const char *val, uint32_t value); +void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value); +void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value); +void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p); +void ndr_print_union(struct ndr_print *ndr, const char *name, int level, const char *type); +void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level); +void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, const uint8_t *data, uint32_t count); +uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags); + +/* strings */ +uint32_t ndr_charset_length(const void *var, charset_t chset); +size_t ndr_string_array_size(struct ndr_push *ndr, const char *s); +uint32_t ndr_size_string(int ret, const char * const* string, int flags); +enum ndr_err_code ndr_pull_string_array(struct ndr_pull *ndr, int ndr_flags, const char ***_a); +enum ndr_err_code ndr_push_string_array(struct ndr_push *ndr, int ndr_flags, const char **a); +void ndr_print_string_array(struct ndr_print *ndr, const char *name, const char **a); +uint32_t ndr_string_length(const void *_var, uint32_t element_size); +enum ndr_err_code ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size); +enum ndr_err_code ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var, uint32_t length, uint8_t byte_mul, charset_t chset); +enum ndr_err_code ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var, uint32_t length, uint8_t byte_mul, charset_t chset); + +/* GUIDs */ +bool GUID_equal(const struct GUID *u1, const struct GUID *u2); +NTSTATUS GUID_from_string(const char *s, struct GUID *guid); +NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid); +struct GUID GUID_zero(void); +bool GUID_all_zero(const struct GUID *u); +int GUID_compare(const struct GUID *u1, const struct GUID *u2); +char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid); +char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid); +char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid); +struct GUID GUID_random(void); + +#endif /* __LIBNDR_H__ */ diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c new file mode 100644 index 0000000000..2f1daeaeb5 --- /dev/null +++ b/librpc/ndr/ndr.c @@ -0,0 +1,1118 @@ +/* + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* + 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" +#include "librpc/ndr/libndr.h" +#include "../lib/util/dlinklist.h" +#if _SAMBA_BUILD_ == 4 +#include "param/param.h" +#endif + +#define NDR_BASE_MARSHALL_SIZE 1024 + +/* this guid indicates NDR encoding in a protocol tower */ +const struct ndr_syntax_id ndr_transfer_syntax = { + { 0x8a885d04, 0x1ceb, 0x11c9, {0x9f, 0xe8}, {0x08,0x00,0x2b,0x10,0x48,0x60} }, + 2 +}; + +const struct ndr_syntax_id ndr64_transfer_syntax = { + { 0x71710533, 0xbeba, 0x4937, {0x83, 0x19}, {0xb5,0xdb,0xef,0x9c,0xcc,0x36} }, + 1 +}; + +/* + work out the number of bytes needed to align on a n byte boundary +*/ +_PUBLIC_ size_t ndr_align_size(uint32_t 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 +*/ +_PUBLIC_ struct ndr_pull *ndr_pull_init_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience) +{ + struct ndr_pull *ndr; + + ndr = talloc_zero(mem_ctx, struct ndr_pull); + if (!ndr) return NULL; + ndr->current_mem_ctx = mem_ctx; + + ndr->data = blob->data; + ndr->data_size = blob->length; + ndr->iconv_convenience = talloc_reference(ndr, iconv_convenience); + + return ndr; +} + +/* + advance by 'size' bytes +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_advance(struct ndr_pull *ndr, uint32_t 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 NDR_ERR_SUCCESS; +} + +/* + set the parse offset to 'ofs' +*/ +static enum ndr_err_code ndr_pull_set_offset(struct ndr_pull *ndr, uint32_t 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 NDR_ERR_SUCCESS; +} + +/* create a ndr_push structure, ready for some marshalling */ +_PUBLIC_ struct ndr_push *ndr_push_init_ctx(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience) +{ + struct ndr_push *ndr; + + ndr = talloc_zero(mem_ctx, struct ndr_push); + if (!ndr) { + return NULL; + } + + ndr->flags = 0; + ndr->alloc_size = NDR_BASE_MARSHALL_SIZE; + ndr->data = talloc_array(ndr, uint8_t, ndr->alloc_size); + if (!ndr->data) { + return NULL; + } + ndr->iconv_convenience = talloc_reference(ndr, iconv_convenience); + + return ndr; +} + +/* return a DATA_BLOB structure for the current ndr_push marshalled data */ +_PUBLIC_ DATA_BLOB ndr_push_blob(struct ndr_push *ndr) +{ + DATA_BLOB blob; + blob = data_blob_const(ndr->data, ndr->offset); + if (ndr->alloc_size > ndr->offset) { + ndr->data[ndr->offset] = 0; + } + return blob; +} + + +/* + expand the available space in the buffer to ndr->offset + extra_size +*/ +_PUBLIC_ enum ndr_err_code ndr_push_expand(struct ndr_push *ndr, uint32_t extra_size) +{ + uint32_t size = extra_size + ndr->offset; + + if (size < ndr->offset) { + /* extra_size overflowed the offset */ + return ndr_push_error(ndr, NDR_ERR_BUFSIZE, "Overflow in push_expand to %u", + size); + } + + if (ndr->alloc_size > size) { + return NDR_ERR_SUCCESS; + } + + ndr->alloc_size += NDR_BASE_MARSHALL_SIZE; + if (size+1 > ndr->alloc_size) { + ndr->alloc_size = size+1; + } + ndr->data = talloc_realloc(ndr, ndr->data, uint8_t, ndr->alloc_size); + if (!ndr->data) { + return ndr_push_error(ndr, NDR_ERR_ALLOC, "Failed to push_expand to %u", + ndr->alloc_size); + } + + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) +{ + va_list ap; + char *s = NULL; + int i, ret; + + va_start(ap, format); + ret = vasprintf(&s, format, ap); + va_end(ap); + + if (ret == -1) { + return; + } + + for (i=0;i<ndr->depth;i++) { + DEBUGADD(0,(" ")); + } + + DEBUGADD(0,("%s\n", s)); + free(s); +} + +_PUBLIC_ void ndr_print_string_helper(struct ndr_print *ndr, const char *format, ...) +{ + va_list ap; + int i; + + for (i=0;i<ndr->depth;i++) { + ndr->private_data = talloc_asprintf_append_buffer( + (char *)ndr->private_data, " "); + } + + va_start(ap, format); + ndr->private_data = talloc_vasprintf_append_buffer((char *)ndr->private_data, + format, ap); + va_end(ap); + ndr->private_data = talloc_asprintf_append_buffer((char *)ndr->private_data, + "\n"); +} + +/* + a useful helper function for printing idl structures via DEBUG() +*/ +_PUBLIC_ void ndr_print_debug(ndr_print_fn_t fn, const char *name, void *ptr) +{ + struct ndr_print *ndr; + + ndr = talloc_zero(NULL, struct ndr_print); + if (!ndr) return; + ndr->print = ndr_print_debug_helper; + ndr->depth = 1; + ndr->flags = 0; + fn(ndr, name, ptr); + talloc_free(ndr); +} + +/* + a useful helper function for printing idl unions via DEBUG() +*/ +_PUBLIC_ void ndr_print_union_debug(ndr_print_fn_t fn, const char *name, uint32_t level, void *ptr) +{ + struct ndr_print *ndr; + + ndr = talloc_zero(NULL, struct ndr_print); + if (!ndr) return; + ndr->print = ndr_print_debug_helper; + ndr->depth = 1; + ndr->flags = 0; + ndr_print_set_switch_value(ndr, ptr, level); + fn(ndr, name, ptr); + talloc_free(ndr); +} + +/* + a useful helper function for printing idl function calls via DEBUG() +*/ +_PUBLIC_ void ndr_print_function_debug(ndr_print_function_t fn, const char *name, int flags, void *ptr) +{ + struct ndr_print *ndr; + + ndr = talloc_zero(NULL, struct ndr_print); + if (!ndr) return; + ndr->print = ndr_print_debug_helper; + ndr->depth = 1; + ndr->flags = 0; + fn(ndr, name, flags, ptr); + talloc_free(ndr); +} + +/* + a useful helper function for printing idl structures to a string +*/ +_PUBLIC_ char *ndr_print_struct_string(TALLOC_CTX *mem_ctx, ndr_print_fn_t fn, const char *name, void *ptr) +{ + struct ndr_print *ndr; + char *ret = NULL; + + ndr = talloc_zero(mem_ctx, struct ndr_print); + if (!ndr) return NULL; + ndr->private_data = talloc_strdup(ndr, ""); + if (!ndr->private_data) { + goto failed; + } + ndr->print = ndr_print_string_helper; + ndr->depth = 1; + ndr->flags = 0; + fn(ndr, name, ptr); + ret = talloc_steal(mem_ctx, (char *)ndr->private_data); +failed: + talloc_free(ndr); + return ret; +} + +/* + a useful helper function for printing idl unions to a string +*/ +_PUBLIC_ char *ndr_print_union_string(TALLOC_CTX *mem_ctx, ndr_print_fn_t fn, const char *name, uint32_t level, void *ptr) +{ + struct ndr_print *ndr; + char *ret = NULL; + + ndr = talloc_zero(mem_ctx, struct ndr_print); + if (!ndr) return NULL; + ndr->private_data = talloc_strdup(ndr, ""); + if (!ndr->private_data) { + goto failed; + } + ndr->print = ndr_print_string_helper; + ndr->depth = 1; + ndr->flags = 0; + ndr_print_set_switch_value(ndr, ptr, level); + fn(ndr, name, ptr); + ret = talloc_steal(mem_ctx, (char *)ndr->private_data); +failed: + talloc_free(ndr); + return ret; +} + +/* + a useful helper function for printing idl function calls to a string +*/ +_PUBLIC_ char *ndr_print_function_string(TALLOC_CTX *mem_ctx, + ndr_print_function_t fn, const char *name, + int flags, void *ptr) +{ + struct ndr_print *ndr; + char *ret = NULL; + + ndr = talloc_zero(mem_ctx, struct ndr_print); + if (!ndr) return NULL; + ndr->private_data = talloc_strdup(ndr, ""); + if (!ndr->private_data) { + goto failed; + } + ndr->print = ndr_print_string_helper; + ndr->depth = 1; + ndr->flags = 0; + fn(ndr, name, flags, ptr); + ret = talloc_steal(mem_ctx, (char *)ndr->private_data); +failed: + talloc_free(ndr); + return ret; +} + +_PUBLIC_ void ndr_set_flags(uint32_t *pflags, uint32_t new_flags) +{ + /* the big/little endian flags are inter-dependent */ + if (new_flags & LIBNDR_FLAG_LITTLE_ENDIAN) { + (*pflags) &= ~LIBNDR_FLAG_BIGENDIAN; + } + if (new_flags & LIBNDR_FLAG_BIGENDIAN) { + (*pflags) &= ~LIBNDR_FLAG_LITTLE_ENDIAN; + } + if (new_flags & LIBNDR_FLAG_REMAINING) { + (*pflags) &= ~LIBNDR_ALIGN_FLAGS; + } + if (new_flags & LIBNDR_ALIGN_FLAGS) { + (*pflags) &= ~LIBNDR_FLAG_REMAINING; + } + (*pflags) |= new_flags; +} + +/* + return and possibly log an NDR error +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_error(struct ndr_pull *ndr, + enum ndr_err_code ndr_err, + const char *format, ...) +{ + char *s=NULL; + va_list ap; + int ret; + + va_start(ap, format); + ret = vasprintf(&s, format, ap); + va_end(ap); + + if (ret == -1) { + return NDR_ERR_ALLOC; + } + + DEBUG(1,("ndr_pull_error(%u): %s\n", ndr_err, s)); + + free(s); + + return ndr_err; +} + +/* + return and possibly log an NDR error +*/ +_PUBLIC_ enum ndr_err_code ndr_push_error(struct ndr_push *ndr, + enum ndr_err_code ndr_err, + const char *format, ...) +{ + char *s=NULL; + va_list ap; + int ret; + + va_start(ap, format); + ret = vasprintf(&s, format, ap); + va_end(ap); + + if (ret == -1) { + return NDR_ERR_ALLOC; + } + + DEBUG(1,("ndr_push_error(%u): %s\n", ndr_err, s)); + + free(s); + + return ndr_err; +} + +/* + handle subcontext buffers, which in midl land are user-marshalled, but + we use magic in pidl to make them easier to cope with +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr, + struct ndr_pull **_subndr, + size_t header_size, + ssize_t size_is) +{ + struct ndr_pull *subndr; + uint32_t r_content_size; + bool force_le = false; + bool force_be = false; + + switch (header_size) { + case 0: { + uint32_t content_size = ndr->data_size - ndr->offset; + if (size_is >= 0) { + content_size = size_is; + } + r_content_size = content_size; + break; + } + + case 2: { + uint16_t content_size; + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &content_size)); + if (size_is >= 0 && size_is != content_size) { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d", + (int)size_is, (int)content_size); + } + r_content_size = content_size; + break; + } + + case 4: { + uint32_t content_size; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &content_size)); + if (size_is >= 0 && size_is != content_size) { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d", + (int)size_is, (int)content_size); + } + r_content_size = content_size; + break; + } + case 0xFFFFFC01: { + /* + * Common Type Header for the Serialization Stream + * See [MS-RPCE] 2.2.6 Type Serialization Version 1 + */ + uint8_t version; + uint8_t drep; + uint16_t hdrlen; + uint32_t filler; + uint32_t content_size; + uint32_t reserved; + + /* version */ + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &version)); + + if (version != 1) { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, + "Bad subcontext (PULL) Common Type Header version %d != 1", + (int)version); + } + + /* + * 0x10 little endian + * 0x00 big endian + */ + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &drep)); + if (drep == 0x10) { + force_le = true; + } else if (drep == 0x00) { + force_be = true; + } else { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, + "Bad subcontext (PULL) Common Type Header invalid drep 0x%02X", + (unsigned int)drep); + } + + /* length of the "Private Header for Constructed Type" */ + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &hdrlen)); + if (hdrlen != 8) { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, + "Bad subcontext (PULL) Common Type Header length %d != 8", + (int)hdrlen); + } + + /* filler should be ignored */ + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &filler)); + + /* + * Private Header for Constructed Type + */ + /* length - will be updated latter */ + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &content_size)); + if (size_is >= 0 && size_is != content_size) { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d", + (int)size_is, (int)content_size); + } + /* the content size must be a multiple of 8 */ + if ((content_size % 8) != 0) { + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, + "Bad subcontext (PULL) size_is(%d) not padded to 8 content_size %d", + (int)size_is, (int)content_size); + } + r_content_size = content_size; + + /* reserved */ + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &reserved)); + break; + } + default: + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) header_size %d", + (int)header_size); + } + + NDR_PULL_NEED_BYTES(ndr, r_content_size); + + subndr = talloc_zero(ndr, struct ndr_pull); + NDR_ERR_HAVE_NO_MEMORY(subndr); + subndr->flags = ndr->flags; + subndr->current_mem_ctx = ndr->current_mem_ctx; + + subndr->data = ndr->data + ndr->offset; + subndr->offset = 0; + subndr->data_size = r_content_size; + subndr->iconv_convenience = talloc_reference(subndr, ndr->iconv_convenience); + + if (force_le) { + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN); + } else if (force_be) { + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN); + } + + *_subndr = subndr; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_subcontext_end(struct ndr_pull *ndr, + struct ndr_pull *subndr, + size_t header_size, + ssize_t size_is) +{ + uint32_t advance; + if (size_is >= 0) { + advance = size_is; + } else if (header_size > 0) { + advance = subndr->data_size; + } else { + advance = subndr->offset; + } + NDR_CHECK(ndr_pull_advance(ndr, advance)); + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_push_subcontext_start(struct ndr_push *ndr, + struct ndr_push **_subndr, + size_t header_size, + ssize_t size_is) +{ + struct ndr_push *subndr; + + subndr = ndr_push_init_ctx(ndr, ndr->iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(subndr); + subndr->flags = ndr->flags; + + *_subndr = subndr; + return NDR_ERR_SUCCESS; +} + +/* + push a subcontext header +*/ +_PUBLIC_ enum ndr_err_code ndr_push_subcontext_end(struct ndr_push *ndr, + struct ndr_push *subndr, + size_t header_size, + ssize_t size_is) +{ + ssize_t padding_len; + + if (size_is >= 0) { + padding_len = size_is - subndr->offset; + if (padding_len > 0) { + NDR_CHECK(ndr_push_zero(subndr, padding_len)); + } else if (padding_len < 0) { + return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PUSH) content_size %d is larger than size_is(%d)", + (int)subndr->offset, (int)size_is); + } + } + + switch (header_size) { + case 0: + break; + + case 2: + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, subndr->offset)); + break; + + case 4: + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, subndr->offset)); + break; + + case 0xFFFFFC01: + /* + * Common Type Header for the Serialization Stream + * See [MS-RPCE] 2.2.6 Type Serialization Version 1 + */ + padding_len = NDR_ROUND(subndr->offset, 8) - subndr->offset; + if (padding_len > 0) { + NDR_CHECK(ndr_push_zero(subndr, padding_len)); + } + + /* version */ + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, 1)); + + /* + * 0x10 little endian + * 0x00 big endian + */ + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, NDR_BE(ndr)?0x00:0x10)); + + /* length of the "Private Header for Constructed Type" */ + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 8)); + + /* filler */ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xCCCCCCCC)); + + /* + * Private Header for Constructed Type + */ + /* length - will be updated latter */ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, subndr->offset)); + + /* reserved */ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + break; + + default: + return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext header size %d", + (int)header_size); + } + + NDR_CHECK(ndr_push_bytes(ndr, subndr->data, subndr->offset)); + return NDR_ERR_SUCCESS; +} + +/* + store a token in the ndr context, for later retrieval +*/ +_PUBLIC_ enum ndr_err_code ndr_token_store(TALLOC_CTX *mem_ctx, + struct ndr_token_list **list, + const void *key, + uint32_t value) +{ + struct ndr_token_list *tok; + tok = talloc(mem_ctx, struct ndr_token_list); + NDR_ERR_HAVE_NO_MEMORY(tok); + tok->key = key; + tok->value = value; + DLIST_ADD((*list), tok); + return NDR_ERR_SUCCESS; +} + +/* + retrieve a token from a ndr context, using cmp_fn to match the tokens +*/ +_PUBLIC_ enum ndr_err_code ndr_token_retrieve_cmp_fn(struct ndr_token_list **list, const void *key, uint32_t *v, + comparison_fn_t _cmp_fn, bool _remove_tok) +{ + struct ndr_token_list *tok; + for (tok=*list;tok;tok=tok->next) { + if (_cmp_fn && _cmp_fn(tok->key,key)==0) goto found; + else if (!_cmp_fn && tok->key == key) goto found; + } + return NDR_ERR_TOKEN; +found: + *v = tok->value; + if (_remove_tok) { + DLIST_REMOVE((*list), tok); + talloc_free(tok); + } + return NDR_ERR_SUCCESS; +} + +/* + retrieve a token from a ndr context +*/ +_PUBLIC_ enum ndr_err_code ndr_token_retrieve(struct ndr_token_list **list, const void *key, uint32_t *v) +{ + return ndr_token_retrieve_cmp_fn(list, key, v, NULL, true); +} + +/* + peek at but don't removed a token from a ndr context +*/ +_PUBLIC_ uint32_t ndr_token_peek(struct ndr_token_list **list, const void *key) +{ + enum ndr_err_code status; + uint32_t v; + + status = ndr_token_retrieve_cmp_fn(list, key, &v, NULL, false); + if (!NDR_ERR_CODE_IS_SUCCESS(status)) { + return 0; + } + + return v; +} + +/* + pull an array size field and add it to the array_size_list token list +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_array_size(struct ndr_pull *ndr, const void *p) +{ + uint32_t size; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &size)); + return ndr_token_store(ndr, &ndr->array_size_list, p, size); +} + +/* + get the stored array size field +*/ +_PUBLIC_ uint32_t ndr_get_array_size(struct ndr_pull *ndr, const void *p) +{ + return ndr_token_peek(&ndr->array_size_list, p); +} + +/* + check the stored array size field +*/ +_PUBLIC_ enum ndr_err_code ndr_check_array_size(struct ndr_pull *ndr, void *p, uint32_t size) +{ + uint32_t stored; + stored = ndr_token_peek(&ndr->array_size_list, p); + if (stored != size) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, + "Bad array size - got %u expected %u\n", + stored, size); + } + return NDR_ERR_SUCCESS; +} + +/* + pull an array length field and add it to the array_length_list token list +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_array_length(struct ndr_pull *ndr, const void *p) +{ + uint32_t length, offset; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &offset)); + if (offset != 0) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, + "non-zero array offset %u\n", offset); + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length)); + return ndr_token_store(ndr, &ndr->array_length_list, p, length); +} + +/* + get the stored array length field +*/ +_PUBLIC_ uint32_t ndr_get_array_length(struct ndr_pull *ndr, const void *p) +{ + return ndr_token_peek(&ndr->array_length_list, p); +} + +/* + check the stored array length field +*/ +_PUBLIC_ enum ndr_err_code ndr_check_array_length(struct ndr_pull *ndr, void *p, uint32_t length) +{ + uint32_t stored; + stored = ndr_token_peek(&ndr->array_length_list, p); + if (stored != length) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, + "Bad array length - got %u expected %u\n", + stored, length); + } + return NDR_ERR_SUCCESS; +} + +/* + store a switch value + */ +_PUBLIC_ enum ndr_err_code ndr_push_set_switch_value(struct ndr_push *ndr, const void *p, uint32_t val) +{ + return ndr_token_store(ndr, &ndr->switch_list, p, val); +} + +_PUBLIC_ enum ndr_err_code ndr_pull_set_switch_value(struct ndr_pull *ndr, const void *p, uint32_t val) +{ + return ndr_token_store(ndr, &ndr->switch_list, p, val); +} + +_PUBLIC_ enum ndr_err_code ndr_print_set_switch_value(struct ndr_print *ndr, const void *p, uint32_t val) +{ + return ndr_token_store(ndr, &ndr->switch_list, p, val); +} + +/* + retrieve a switch value + */ +_PUBLIC_ uint32_t ndr_push_get_switch_value(struct ndr_push *ndr, const void *p) +{ + return ndr_token_peek(&ndr->switch_list, p); +} + +_PUBLIC_ uint32_t ndr_pull_get_switch_value(struct ndr_pull *ndr, const void *p) +{ + return ndr_token_peek(&ndr->switch_list, p); +} + +_PUBLIC_ uint32_t ndr_print_get_switch_value(struct ndr_print *ndr, const void *p) +{ + return ndr_token_peek(&ndr->switch_list, p); +} + +/* + pull a struct from a blob using NDR +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, + ndr_pull_flags_fn_t fn) +{ + struct ndr_pull *ndr; + ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(ndr); + NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p)); + return NDR_ERR_SUCCESS; +} + +/* + pull a struct from a blob using NDR - failing if all bytes are not consumed +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + void *p, ndr_pull_flags_fn_t fn) +{ + struct ndr_pull *ndr; + ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(ndr); + NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p)); + if (ndr->offset < ndr->data_size) { + return ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES, + "not all bytes consumed ofs[%u] size[%u]", + ndr->offset, ndr->data_size); + } + return NDR_ERR_SUCCESS; +} + +/* + pull a union from a blob using NDR, given the union discriminator +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_union_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, void *p, + uint32_t level, ndr_pull_flags_fn_t fn) +{ + struct ndr_pull *ndr; + ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(ndr); + NDR_CHECK(ndr_pull_set_switch_value(ndr, p, level)); + NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p)); + return NDR_ERR_SUCCESS; +} + +/* + pull a union from a blob using NDR, given the union discriminator, + failing if all bytes are not consumed +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_union_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, void *p, + uint32_t level, ndr_pull_flags_fn_t fn) +{ + struct ndr_pull *ndr; + ndr = ndr_pull_init_blob(blob, mem_ctx, iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(ndr); + NDR_CHECK(ndr_pull_set_switch_value(ndr, p, level)); + NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p)); + if (ndr->offset < ndr->data_size) { + return ndr_pull_error(ndr, NDR_ERR_UNREAD_BYTES, + "not all bytes consumed ofs[%u] size[%u]", + ndr->offset, ndr->data_size); + } + return NDR_ERR_SUCCESS; +} + +/* + push a struct to a blob using NDR +*/ +_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const void *p, ndr_push_flags_fn_t fn) +{ + struct ndr_push *ndr; + ndr = ndr_push_init_ctx(mem_ctx, iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(ndr); + + NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p)); + + *blob = ndr_push_blob(ndr); + talloc_steal(mem_ctx, blob->data); + talloc_free(ndr); + + return NDR_ERR_SUCCESS; +} + +/* + push a union to a blob using NDR +*/ +_PUBLIC_ enum ndr_err_code ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, + uint32_t level, ndr_push_flags_fn_t fn) +{ + struct ndr_push *ndr; + ndr = ndr_push_init_ctx(mem_ctx, iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(ndr); + + NDR_CHECK(ndr_push_set_switch_value(ndr, p, level)); + NDR_CHECK(fn(ndr, NDR_SCALARS|NDR_BUFFERS, p)); + + *blob = ndr_push_blob(ndr); + talloc_steal(mem_ctx, blob->data); + talloc_free(ndr); + + return NDR_ERR_SUCCESS; +} + +/* + generic ndr_size_*() handler for structures +*/ +_PUBLIC_ size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t push) +{ + struct ndr_push *ndr; + enum ndr_err_code status; + size_t ret; + + /* avoid recursion */ + if (flags & LIBNDR_FLAG_NO_NDR_SIZE) return 0; + + ndr = ndr_push_init_ctx(NULL, lp_iconv_convenience(global_loadparm)); + if (!ndr) return 0; + ndr->flags |= flags | LIBNDR_FLAG_NO_NDR_SIZE; + status = push(ndr, NDR_SCALARS|NDR_BUFFERS, discard_const(p)); + if (!NDR_ERR_CODE_IS_SUCCESS(status)) { + talloc_free(ndr); + return 0; + } + ret = ndr->offset; + talloc_free(ndr); + return ret; +} + +/* + generic ndr_size_*() handler for unions +*/ +_PUBLIC_ size_t ndr_size_union(const void *p, int flags, uint32_t level, ndr_push_flags_fn_t push) +{ + struct ndr_push *ndr; + enum ndr_err_code status; + size_t ret; + + /* avoid recursion */ + if (flags & LIBNDR_FLAG_NO_NDR_SIZE) return 0; + + ndr = ndr_push_init_ctx(NULL, lp_iconv_convenience(global_loadparm)); + if (!ndr) return 0; + ndr->flags |= flags | LIBNDR_FLAG_NO_NDR_SIZE; + + status = ndr_push_set_switch_value(ndr, p, level); + if (!NDR_ERR_CODE_IS_SUCCESS(status)) { + talloc_free(ndr); + return 0; + } + status = push(ndr, NDR_SCALARS|NDR_BUFFERS, p); + if (!NDR_ERR_CODE_IS_SUCCESS(status)) { + talloc_free(ndr); + return 0; + } + ret = ndr->offset; + talloc_free(ndr); + return ret; +} + +/* + get the current base for relative pointers for the push +*/ +_PUBLIC_ uint32_t ndr_push_get_relative_base_offset(struct ndr_push *ndr) +{ + return ndr->relative_base_offset; +} + +/* + restore the old base for relative pointers for the push +*/ +_PUBLIC_ void ndr_push_restore_relative_base_offset(struct ndr_push *ndr, uint32_t offset) +{ + ndr->relative_base_offset = offset; +} + +/* + setup the current base for relative pointers for the push + called in the NDR_SCALAR stage +*/ +_PUBLIC_ enum ndr_err_code ndr_push_setup_relative_base_offset1(struct ndr_push *ndr, const void *p, uint32_t offset) +{ + ndr->relative_base_offset = offset; + return ndr_token_store(ndr, &ndr->relative_base_list, p, offset); +} + +/* + setup the current base for relative pointers for the push + called in the NDR_BUFFERS stage +*/ +_PUBLIC_ enum ndr_err_code ndr_push_setup_relative_base_offset2(struct ndr_push *ndr, const void *p) +{ + return ndr_token_retrieve(&ndr->relative_base_list, p, &ndr->relative_base_offset); +} + +/* + push a relative object - stage1 + this is called during SCALARS processing +*/ +_PUBLIC_ enum ndr_err_code ndr_push_relative_ptr1(struct ndr_push *ndr, const void *p) +{ + if (p == NULL) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + return NDR_ERR_SUCCESS; + } + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_token_store(ndr, &ndr->relative_list, p, ndr->offset)); + return ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF); +} + +/* + push a relative object - stage2 + this is called during buffers processing +*/ +_PUBLIC_ enum ndr_err_code ndr_push_relative_ptr2(struct ndr_push *ndr, const void *p) +{ + uint32_t save_offset; + uint32_t ptr_offset = 0xFFFFFFFF; + if (p == NULL) { + return NDR_ERR_SUCCESS; + } + save_offset = ndr->offset; + NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &ptr_offset)); + if (ptr_offset > ndr->offset) { + return ndr_push_error(ndr, NDR_ERR_BUFSIZE, + "ndr_push_relative_ptr2 ptr_offset(%u) > ndr->offset(%u)", + ptr_offset, ndr->offset); + } + ndr->offset = ptr_offset; + if (save_offset < ndr->relative_base_offset) { + return ndr_push_error(ndr, NDR_ERR_BUFSIZE, + "ndr_push_relative_ptr2 save_offset(%u) < ndr->relative_base_offset(%u)", + save_offset, ndr->relative_base_offset); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, save_offset - ndr->relative_base_offset)); + ndr->offset = save_offset; + return NDR_ERR_SUCCESS; +} + +/* + get the current base for relative pointers for the pull +*/ +_PUBLIC_ uint32_t ndr_pull_get_relative_base_offset(struct ndr_pull *ndr) +{ + return ndr->relative_base_offset; +} + +/* + restore the old base for relative pointers for the pull +*/ +_PUBLIC_ void ndr_pull_restore_relative_base_offset(struct ndr_pull *ndr, uint32_t offset) +{ + ndr->relative_base_offset = offset; +} + +/* + setup the current base for relative pointers for the pull + called in the NDR_SCALAR stage +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_setup_relative_base_offset1(struct ndr_pull *ndr, const void *p, uint32_t offset) +{ + ndr->relative_base_offset = offset; + return ndr_token_store(ndr, &ndr->relative_base_list, p, offset); +} + +/* + setup the current base for relative pointers for the pull + called in the NDR_BUFFERS stage +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_setup_relative_base_offset2(struct ndr_pull *ndr, const void *p) +{ + return ndr_token_retrieve(&ndr->relative_base_list, p, &ndr->relative_base_offset); +} + +/* + pull a relative object - stage1 + called during SCALARS processing +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_relative_ptr1(struct ndr_pull *ndr, const void *p, uint32_t rel_offset) +{ + rel_offset += ndr->relative_base_offset; + if (rel_offset > ndr->data_size) { + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, + "ndr_pull_relative_ptr1 rel_offset(%u) > ndr->data_size(%u)", + rel_offset, ndr->data_size); + } + return ndr_token_store(ndr, &ndr->relative_list, p, rel_offset); +} + +/* + pull a relative object - stage2 + called during BUFFERS processing +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_relative_ptr2(struct ndr_pull *ndr, const void *p) +{ + uint32_t rel_offset; + NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, p, &rel_offset)); + return ndr_pull_set_offset(ndr, rel_offset); +} diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c new file mode 100644 index 0000000000..1d2b47c850 --- /dev/null +++ b/librpc/ndr/ndr_basic.c @@ -0,0 +1,833 @@ +/* + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/network.h" +#include "librpc/ndr/libndr.h" + +#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_IVALS(ndr, ofs) (NDR_BE(ndr)?RIVALS(ndr->data,ofs):IVALS(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) +#define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0) + + +/* + check for data leaks from the server by looking for non-zero pad bytes + these could also indicate that real structure elements have been + mistaken for padding in the IDL +*/ +_PUBLIC_ void ndr_check_padding(struct ndr_pull *ndr, size_t n) +{ + size_t ofs2 = (ndr->offset + (n-1)) & ~(n-1); + int i; + for (i=ndr->offset;i<ofs2;i++) { + if (ndr->data[i] != 0) { + break; + } + } + if (i<ofs2) { + DEBUG(0,("WARNING: Non-zero padding to %d: ", (int)n)); + for (i=ndr->offset;i<ofs2;i++) { + DEBUG(0,("%02x ", ndr->data[i])); + } + DEBUG(0,("\n")); + } + +} + +/* + parse a int8_t +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v) +{ + NDR_PULL_NEED_BYTES(ndr, 1); + *v = (int8_t)CVAL(ndr->data, ndr->offset); + ndr->offset += 1; + return NDR_ERR_SUCCESS; +} + +/* + parse a uint8_t +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v) +{ + NDR_PULL_NEED_BYTES(ndr, 1); + *v = CVAL(ndr->data, ndr->offset); + ndr->offset += 1; + return NDR_ERR_SUCCESS; +} + +/* + parse a int16_t +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v) +{ + NDR_PULL_ALIGN(ndr, 2); + NDR_PULL_NEED_BYTES(ndr, 2); + *v = (uint16_t)NDR_SVAL(ndr, ndr->offset); + ndr->offset += 2; + return NDR_ERR_SUCCESS; +} + +/* + parse a uint16_t +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v) +{ + NDR_PULL_ALIGN(ndr, 2); + NDR_PULL_NEED_BYTES(ndr, 2); + *v = NDR_SVAL(ndr, ndr->offset); + ndr->offset += 2; + return NDR_ERR_SUCCESS; +} + +/* + parse a int32_t +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v) +{ + NDR_PULL_ALIGN(ndr, 4); + NDR_PULL_NEED_BYTES(ndr, 4); + *v = NDR_IVALS(ndr, ndr->offset); + ndr->offset += 4; + return NDR_ERR_SUCCESS; +} + +/* + parse a uint32_t +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v) +{ + NDR_PULL_ALIGN(ndr, 4); + NDR_PULL_NEED_BYTES(ndr, 4); + *v = NDR_IVAL(ndr, ndr->offset); + ndr->offset += 4; + return NDR_ERR_SUCCESS; +} + +/* + parse a pointer referent identifier +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v) +{ + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v)); + if (*v != 0) { + ndr->ptr_count++; + } + return NDR_ERR_SUCCESS; +} + +/* + parse a ref pointer referent identifier +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v) +{ + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v)); + /* ref pointers always point to data */ + *v = 1; + return NDR_ERR_SUCCESS; +} + +/* + parse a udlong +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v) +{ + NDR_PULL_ALIGN(ndr, 4); + NDR_PULL_NEED_BYTES(ndr, 8); + *v = NDR_IVAL(ndr, ndr->offset); + *v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32; + ndr->offset += 8; + return NDR_ERR_SUCCESS; +} + +/* + parse a udlongr +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v) +{ + NDR_PULL_ALIGN(ndr, 4); + NDR_PULL_NEED_BYTES(ndr, 8); + *v = ((uint64_t)NDR_IVAL(ndr, ndr->offset)) << 32; + *v |= NDR_IVAL(ndr, ndr->offset+4); + ndr->offset += 8; + return NDR_ERR_SUCCESS; +} + +/* + parse a dlong +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_dlong(struct ndr_pull *ndr, int ndr_flags, int64_t *v) +{ + return ndr_pull_udlong(ndr, ndr_flags, (uint64_t *)v); +} + +/* + parse a hyper +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_hyper(struct ndr_pull *ndr, int ndr_flags, uint64_t *v) +{ + NDR_PULL_ALIGN(ndr, 8); + return ndr_pull_udlong(ndr, ndr_flags, v); +} + +/* + parse a pointer +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags, void* *v) +{ + uintptr_t h; + NDR_PULL_ALIGN(ndr, sizeof(h)); + NDR_PULL_NEED_BYTES(ndr, sizeof(h)); + memcpy(&h, ndr->data+ndr->offset, sizeof(h)); + ndr->offset += sizeof(h); + *v = (void *)h; + return NDR_ERR_SUCCESS; +} + +/* + pull a NTSTATUS +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *status = NT_STATUS(v); + return NDR_ERR_SUCCESS; +} + +/* + push a NTSTATUS +*/ +_PUBLIC_ enum ndr_err_code ndr_push_NTSTATUS(struct ndr_push *ndr, int ndr_flags, NTSTATUS status) +{ + return ndr_push_uint32(ndr, ndr_flags, NT_STATUS_V(status)); +} + +_PUBLIC_ 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 +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *status = W_ERROR(v); + return NDR_ERR_SUCCESS; +} + +/* + push a WERROR +*/ +_PUBLIC_ enum ndr_err_code ndr_push_WERROR(struct ndr_push *ndr, int ndr_flags, WERROR status) +{ + return ndr_push_uint32(ndr, NDR_SCALARS, W_ERROR_V(status)); +} + +_PUBLIC_ 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 +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, uint32_t n) +{ + NDR_PULL_NEED_BYTES(ndr, n); + memcpy(data, ndr->data + ndr->offset, n); + ndr->offset += n; + return NDR_ERR_SUCCESS; +} + +/* + pull an array of uint8 +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n) +{ + if (!(ndr_flags & NDR_SCALARS)) { + return NDR_ERR_SUCCESS; + } + return ndr_pull_bytes(ndr, data, n); +} + +/* + push a int8_t +*/ +_PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v) +{ + NDR_PUSH_NEED_BYTES(ndr, 1); + SCVAL(ndr->data, ndr->offset, (uint8_t)v); + ndr->offset += 1; + return NDR_ERR_SUCCESS; +} + +/* + push a uint8_t +*/ +_PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v) +{ + NDR_PUSH_NEED_BYTES(ndr, 1); + SCVAL(ndr->data, ndr->offset, v); + ndr->offset += 1; + return NDR_ERR_SUCCESS; +} + +/* + push a int16_t +*/ +_PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v) +{ + NDR_PUSH_ALIGN(ndr, 2); + NDR_PUSH_NEED_BYTES(ndr, 2); + NDR_SSVAL(ndr, ndr->offset, (uint16_t)v); + ndr->offset += 2; + return NDR_ERR_SUCCESS; +} + +/* + push a uint16_t +*/ +_PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v) +{ + NDR_PUSH_ALIGN(ndr, 2); + NDR_PUSH_NEED_BYTES(ndr, 2); + NDR_SSVAL(ndr, ndr->offset, v); + ndr->offset += 2; + return NDR_ERR_SUCCESS; +} + +/* + push a int32_t +*/ +_PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v) +{ + NDR_PUSH_ALIGN(ndr, 4); + NDR_PUSH_NEED_BYTES(ndr, 4); + NDR_SIVALS(ndr, ndr->offset, v); + ndr->offset += 4; + return NDR_ERR_SUCCESS; +} + +/* + push a uint32_t +*/ +_PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v) +{ + NDR_PUSH_ALIGN(ndr, 4); + NDR_PUSH_NEED_BYTES(ndr, 4); + NDR_SIVAL(ndr, ndr->offset, v); + ndr->offset += 4; + return NDR_ERR_SUCCESS; +} + +/* + push a udlong +*/ +_PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v) +{ + NDR_PUSH_ALIGN(ndr, 4); + NDR_PUSH_NEED_BYTES(ndr, 8); + NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF)); + NDR_SIVAL(ndr, ndr->offset+4, (v>>32)); + ndr->offset += 8; + return NDR_ERR_SUCCESS; +} + +/* + push a udlongr +*/ +_PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v) +{ + NDR_PUSH_ALIGN(ndr, 4); + NDR_PUSH_NEED_BYTES(ndr, 8); + NDR_SIVAL(ndr, ndr->offset, (v>>32)); + NDR_SIVAL(ndr, ndr->offset+4, (v & 0xFFFFFFFF)); + ndr->offset += 8; + return NDR_ERR_SUCCESS; +} + +/* + push a dlong +*/ +_PUBLIC_ enum ndr_err_code ndr_push_dlong(struct ndr_push *ndr, int ndr_flags, int64_t v) +{ + return ndr_push_udlong(ndr, NDR_SCALARS, (uint64_t)v); +} + +/* + push a hyper +*/ +_PUBLIC_ enum ndr_err_code ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, uint64_t v) +{ + NDR_PUSH_ALIGN(ndr, 8); + return ndr_push_udlong(ndr, NDR_SCALARS, v); +} + +/* + push a pointer +*/ +_PUBLIC_ enum ndr_err_code ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v) +{ + uintptr_t h = (intptr_t)v; + NDR_PUSH_ALIGN(ndr, sizeof(h)); + NDR_PUSH_NEED_BYTES(ndr, sizeof(h)); + memcpy(ndr->data+ndr->offset, &h, sizeof(h)); + ndr->offset += sizeof(h); + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size) +{ + NDR_PUSH_ALIGN(ndr, size); + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_align(struct ndr_pull *ndr, size_t size) +{ + NDR_PULL_ALIGN(ndr, size); + return NDR_ERR_SUCCESS; +} + +/* + push some bytes +*/ +_PUBLIC_ enum ndr_err_code ndr_push_bytes(struct ndr_push *ndr, const uint8_t *data, uint32_t n) +{ + NDR_PUSH_NEED_BYTES(ndr, n); + memcpy(ndr->data + ndr->offset, data, n); + ndr->offset += n; + return NDR_ERR_SUCCESS; +} + +/* + push some zero bytes +*/ +_PUBLIC_ enum ndr_err_code ndr_push_zero(struct ndr_push *ndr, uint32_t n) +{ + NDR_PUSH_NEED_BYTES(ndr, n); + memset(ndr->data + ndr->offset, 0, n); + ndr->offset += n; + return NDR_ERR_SUCCESS; +} + +/* + push an array of uint8 +*/ +_PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n) +{ + if (!(ndr_flags & NDR_SCALARS)) { + return NDR_ERR_SUCCESS; + } + return ndr_push_bytes(ndr, data, n); +} + +/* + push a unique non-zero value if a pointer is non-NULL, otherwise 0 +*/ +_PUBLIC_ enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void *p) +{ + uint32_t ptr = 0; + if (p) { + ptr = ndr->ptr_count * 4; + ptr |= 0x00020000; + ndr->ptr_count++; + } + return ndr_push_uint32(ndr, NDR_SCALARS, ptr); +} + +/* + push a 'simple' full non-zero value if a pointer is non-NULL, otherwise 0 +*/ +_PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p) +{ + uint32_t ptr = 0; + if (p) { + /* Check if the pointer already exists and has an id */ + ptr = ndr_token_peek(&ndr->full_ptr_list, p); + if (ptr == 0) { + ndr->ptr_count++; + ptr = ndr->ptr_count; + ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr); + } + } + return ndr_push_uint32(ndr, NDR_SCALARS, ptr); +} + +/* + push always a 0, if a pointer is NULL it's a fatal error +*/ +_PUBLIC_ enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr) +{ + return ndr_push_uint32(ndr, NDR_SCALARS, 0xAEF1AEF1); +} + + +/* + push a NTTIME +*/ +_PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t) +{ + NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t)); + return NDR_ERR_SUCCESS; +} + +/* + pull a NTTIME +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t) +{ + NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t)); + return NDR_ERR_SUCCESS; +} + +/* + push a NTTIME +*/ +_PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t) +{ + t /= 10000000; + NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t)); + return NDR_ERR_SUCCESS; +} + +/* + pull a NTTIME_1sec +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t) +{ + NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t)); + (*t) *= 10000000; + return NDR_ERR_SUCCESS; +} + +/* + pull a NTTIME_hyper +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t) +{ + NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t)); + return NDR_ERR_SUCCESS; +} + +/* + push a NTTIME_hyper +*/ +_PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t) +{ + NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t)); + return NDR_ERR_SUCCESS; +} + +/* + push a time_t +*/ +_PUBLIC_ enum ndr_err_code ndr_push_time_t(struct ndr_push *ndr, int ndr_flags, time_t t) +{ + return ndr_push_uint32(ndr, ndr_flags, t); +} + +/* + pull a time_t +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_time_t(struct ndr_pull *ndr, int ndr_flags, time_t *t) +{ + uint32_t tt; + NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &tt)); + *t = tt; + return NDR_ERR_SUCCESS; +} + + +/* + pull a ipv4address +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_flags, const char **address) +{ + struct in_addr in; + NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &in.s_addr)); + in.s_addr = htonl(in.s_addr); + *address = talloc_strdup(ndr->current_mem_ctx, inet_ntoa(in)); + NDR_ERR_HAVE_NO_MEMORY(*address); + return NDR_ERR_SUCCESS; +} + +/* + push a ipv4address +*/ +_PUBLIC_ enum ndr_err_code ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address) +{ + uint32_t addr; + if (!is_ipaddress(address)) { + return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS, + "Invalid IPv4 address: '%s'", + address); + } + addr = inet_addr(address); + NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, htonl(addr))); + return NDR_ERR_SUCCESS; +} + +/* + print a ipv4address +*/ +_PUBLIC_ void ndr_print_ipv4address(struct ndr_print *ndr, const char *name, + const char *address) +{ + ndr->print(ndr, "%-25s: %s", name, address); +} + + +_PUBLIC_ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type) +{ + ndr->print(ndr, "%s: struct %s", name, type); +} + +_PUBLIC_ void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type, + const char *val, uint32_t value) +{ + if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) { + ndr->print(ndr, "%-25s: %s (0x%X)", name, val?val:"UNKNOWN_ENUM_VALUE", value); + } else { + ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value); + } +} + +_PUBLIC_ void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value) +{ + /* this is an attempt to support multi-bit bitmap masks */ + value &= flag; + + while (!(flag & 1)) { + flag >>= 1; + value >>= 1; + } + if (flag == 1) { + ndr->print(ndr, " %d: %-25s", value, flag_name); + } else { + ndr->print(ndr, "0x%02x: %-25s (%d)", value, flag_name, value); + } +} + +_PUBLIC_ void ndr_print_int8(struct ndr_print *ndr, const char *name, int8_t v) +{ + ndr->print(ndr, "%-25s: %d", name, v); +} + +_PUBLIC_ void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v) +{ + ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v); +} + +_PUBLIC_ void ndr_print_int16(struct ndr_print *ndr, const char *name, int16_t v) +{ + ndr->print(ndr, "%-25s: %d", name, v); +} + +_PUBLIC_ void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v) +{ + ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v); +} + +_PUBLIC_ void ndr_print_int32(struct ndr_print *ndr, const char *name, int32_t v) +{ + ndr->print(ndr, "%-25s: %d", name, v); +} + +_PUBLIC_ void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v) +{ + ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v); +} + +_PUBLIC_ void ndr_print_udlong(struct ndr_print *ndr, const char *name, uint64_t v) +{ + ndr->print(ndr, "%-25s: 0x%016llx (%llu)", name, (unsigned long long)v, (unsigned long long)v); +} + +_PUBLIC_ void ndr_print_udlongr(struct ndr_print *ndr, const char *name, uint64_t v) +{ + ndr_print_udlong(ndr, name, v); +} + +_PUBLIC_ void ndr_print_dlong(struct ndr_print *ndr, const char *name, int64_t v) +{ + ndr->print(ndr, "%-25s: 0x%016llx (%lld)", name, (unsigned long long)v, (long long)v); +} + +_PUBLIC_ void ndr_print_hyper(struct ndr_print *ndr, const char *name, uint64_t v) +{ + ndr_print_dlong(ndr, name, v); +} + +_PUBLIC_ void ndr_print_pointer(struct ndr_print *ndr, const char *name, void *v) +{ + ndr->print(ndr, "%-25s: %p", name, v); +} + +_PUBLIC_ 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); + } +} + +_PUBLIC_ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t) +{ + ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr, t)); +} + +_PUBLIC_ void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t) +{ + /* this is a standard NTTIME here + * as it's already converted in the pull/push code + */ + ndr_print_NTTIME(ndr, name, t); +} + +_PUBLIC_ void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME t) +{ + ndr_print_NTTIME(ndr, name, t); +} + +_PUBLIC_ 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, timestring(ndr, t)); + } +} + +_PUBLIC_ void ndr_print_union(struct ndr_print *ndr, const char *name, int level, const char *type) +{ + if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) { + ndr->print(ndr, "%-25s: union %s(case 0x%X)", name, type, level); + } else { + ndr->print(ndr, "%-25s: union %s(case %d)", name, type, level); + } +} + +_PUBLIC_ void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level) +{ + ndr->print(ndr, "UNKNOWN LEVEL %u", level); +} + +_PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, + const uint8_t *data, uint32_t count) +{ + int i; + + if (count <= 600 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) { + char s[1202]; + 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--; +} + +_PUBLIC_ void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r) +{ + ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, (unsigned)r.length); + if (r.length) { + dump_data(10, r.data, r.length); + } +} + + +/* + push a DATA_BLOB onto the wire. +*/ +_PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flags, 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, NDR_SCALARS, blob.length)); + } + NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length)); + return NDR_ERR_SUCCESS; +} + +/* + pull a DATA_BLOB from the wire. +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob) +{ + uint32_t length = 0; + + 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, NDR_SCALARS, &length)); + } + NDR_PULL_NEED_BYTES(ndr, length); + *blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length); + ndr->offset += length; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags) +{ + if (!data) return ret; + return ret + data->length; +} diff --git a/librpc/ndr/ndr_compression.c b/librpc/ndr/ndr_compression.c new file mode 100644 index 0000000000..c73c3bb6fa --- /dev/null +++ b/librpc/ndr/ndr_compression.c @@ -0,0 +1,518 @@ +/* + Unix SMB/CIFS implementation. + + libndr compression support + + Copyright (C) Stefan Metzmacher 2005 + Copyright (C) Matthieu Suiche 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "../lib/compression/lzxpress.h" +#include "librpc/ndr/libndr.h" +#include "../librpc/ndr/ndr_compression.h" +#include <zlib.h> + +static voidpf ndr_zlib_alloc(voidpf opaque, uInt items, uInt size) +{ + return talloc_zero_size(opaque, items * size); +} + +static void ndr_zlib_free(voidpf opaque, voidpf address) +{ + talloc_free(address); +} + +static enum ndr_err_code ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpull, + struct ndr_push *ndrpush, + z_stream *z, + bool *last) +{ + DATA_BLOB comp_chunk; + uint32_t comp_chunk_offset; + uint32_t comp_chunk_size; + DATA_BLOB plain_chunk; + uint32_t plain_chunk_offset; + uint32_t plain_chunk_size; + int z_ret; + + NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size)); + if (plain_chunk_size > 0x00008000) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad MSZIP plain chunk size %08X > 0x00008000 (PULL)", + plain_chunk_size); + } + + NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size)); + + DEBUG(9,("MSZIP plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n", + plain_chunk_size, plain_chunk_size, comp_chunk_size, comp_chunk_size)); + + comp_chunk_offset = ndrpull->offset; + NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size)); + comp_chunk.length = comp_chunk_size; + comp_chunk.data = ndrpull->data + comp_chunk_offset; + + plain_chunk_offset = ndrpush->offset; + NDR_CHECK(ndr_push_zero(ndrpush, plain_chunk_size)); + plain_chunk.length = plain_chunk_size; + plain_chunk.data = ndrpush->data + plain_chunk_offset; + + if (comp_chunk.length < 2) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "Bad MSZIP comp chunk size %u < 2 (PULL)", + (unsigned int)comp_chunk.length); + } + /* CK = Chris Kirmse, official Microsoft purloiner */ + if (comp_chunk.data[0] != 'C' || + comp_chunk.data[1] != 'K') { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "Bad MSZIP invalid prefix [%c%c] != [CK]", + comp_chunk.data[0], comp_chunk.data[1]); + } + + z->next_in = comp_chunk.data + 2; + z->avail_in = comp_chunk.length -2; + z->total_in = 0; + + z->next_out = plain_chunk.data; + z->avail_out = plain_chunk.length; + z->total_out = 0; + + if (!z->opaque) { + /* the first time we need to intialize completely */ + z->zalloc = ndr_zlib_alloc; + z->zfree = ndr_zlib_free; + z->opaque = ndrpull; + + z_ret = inflateInit2(z, -15); + if (z_ret != Z_OK) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "Bad inflateInit2 error %s(%d) (PULL)", + zError(z_ret), z_ret); + + } + } + + /* call inflate untill we get Z_STREAM_END or an error */ + while (true) { + z_ret = inflate(z, Z_BLOCK); + if (z_ret != Z_OK) break; + } + + if (z_ret != Z_STREAM_END) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "Bad inflate(Z_BLOCK) error %s(%d) (PULL)", + zError(z_ret), z_ret); + } + + if (z->avail_in) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "MSZIP not all avail_in[%u] bytes consumed (PULL)", + z->avail_in); + } + + if (z->avail_out) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "MSZIP not all avail_out[%u] bytes consumed (PULL)", + z->avail_out); + } + + if ((plain_chunk_size < 0x00008000) || (ndrpull->offset+4 >= ndrpull->data_size)) { + /* this is the last chunk */ + *last = true; + } + + z_ret = inflateReset(z); + if (z_ret != Z_OK) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "Bad inflateReset error %s(%d) (PULL)", + zError(z_ret), z_ret); + } + + z_ret = inflateSetDictionary(z, plain_chunk.data, plain_chunk.length); + if (z_ret != Z_OK) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "Bad inflateSetDictionary error %s(%d) (PULL)", + zError(z_ret), z_ret); + } + + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_push_compression_mszip_chunk(struct ndr_push *ndrpush, + struct ndr_pull *ndrpull, + z_stream *z, + bool *last) +{ + DATA_BLOB comp_chunk; + uint32_t comp_chunk_size; + uint32_t comp_chunk_size_offset; + DATA_BLOB plain_chunk; + uint32_t plain_chunk_size; + uint32_t plain_chunk_offset; + uint32_t max_plain_size = 0x00008000; + uint32_t max_comp_size = 0x00008000 + 2 + 12 /*TODO: what value do we really need here?*/; + uint32_t tmp_offset; + int z_ret; + + plain_chunk_size = MIN(max_plain_size, ndrpull->data_size - ndrpull->offset); + plain_chunk_offset = ndrpull->offset; + NDR_CHECK(ndr_pull_advance(ndrpull, plain_chunk_size)); + + plain_chunk.data = ndrpull->data + plain_chunk_offset; + plain_chunk.length = plain_chunk_size; + + if (plain_chunk_size < max_plain_size) { + *last = true; + } + + NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, plain_chunk_size)); + comp_chunk_size_offset = ndrpush->offset; + NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, 0xFEFEFEFE)); + + NDR_CHECK(ndr_push_expand(ndrpush, max_comp_size)); + + comp_chunk.data = ndrpush->data + ndrpush->offset; + comp_chunk.length = max_comp_size; + + /* CK = Chris Kirmse, official Microsoft purloiner */ + comp_chunk.data[0] = 'C'; + comp_chunk.data[1] = 'K'; + + z->next_in = plain_chunk.data; + z->avail_in = plain_chunk.length; + z->total_in = 0; + + z->next_out = comp_chunk.data + 2; + z->avail_out = comp_chunk.length - 2; + z->total_out = 0; + + if (!z->opaque) { + /* the first time we need to intialize completely */ + z->zalloc = ndr_zlib_alloc; + z->zfree = ndr_zlib_free; + z->opaque = ndrpull; + + /* TODO: find how to trigger the same parameters windows uses */ + z_ret = deflateInit2(z, + Z_DEFAULT_COMPRESSION, + Z_DEFLATED, + -15, + 9, + Z_DEFAULT_STRATEGY); + if (z_ret != Z_OK) { + return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION, + "Bad deflateInit2 error %s(%d) (PUSH)", + zError(z_ret), z_ret); + + } + } + + /* call deflate untill we get Z_STREAM_END or an error */ + while (true) { + z_ret = deflate(z, Z_FINISH); + if (z_ret != Z_OK) break; + } + if (z_ret != Z_STREAM_END) { + return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION, + "Bad delate(Z_BLOCK) error %s(%d) (PUSH)", + zError(z_ret), z_ret); + } + + if (z->avail_in) { + return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION, + "MSZIP not all avail_in[%u] bytes consumed (PUSH)", + z->avail_in); + } + + comp_chunk_size = 2 + z->total_out; + + z_ret = deflateReset(z); + if (z_ret != Z_OK) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "Bad deflateReset error %s(%d) (PULL)", + zError(z_ret), z_ret); + } + + z_ret = deflateSetDictionary(z, plain_chunk.data, plain_chunk.length); + if (z_ret != Z_OK) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "Bad deflateSetDictionary error %s(%d) (PULL)", + zError(z_ret), z_ret); + } + + tmp_offset = ndrpush->offset; + ndrpush->offset = comp_chunk_size_offset; + NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, comp_chunk_size)); + ndrpush->offset = tmp_offset; + + DEBUG(9,("MSZIP comp plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n", + (unsigned int)plain_chunk.length, + (unsigned int)plain_chunk.length, + comp_chunk_size, comp_chunk_size)); + + ndrpush->offset += comp_chunk_size; + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_compression_xpress_chunk(struct ndr_pull *ndrpull, + struct ndr_push *ndrpush, + bool *last) +{ + DATA_BLOB comp_chunk; + DATA_BLOB plain_chunk; + uint32_t comp_chunk_offset; + uint32_t plain_chunk_offset; + uint32_t comp_chunk_size; + uint32_t plain_chunk_size; + ssize_t ret; + + NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size)); + if (plain_chunk_size > 0x00010000) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad XPRESS plain chunk size %08X > 0x00010000 (PULL)", + plain_chunk_size); + } + + NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size)); + + comp_chunk_offset = ndrpull->offset; + NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size)); + comp_chunk.length = comp_chunk_size; + comp_chunk.data = ndrpull->data + comp_chunk_offset; + + plain_chunk_offset = ndrpush->offset; + NDR_CHECK(ndr_push_zero(ndrpush, plain_chunk_size)); + plain_chunk.length = plain_chunk_size; + plain_chunk.data = ndrpush->data + plain_chunk_offset; + + DEBUG(9,("XPRESS plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n", + plain_chunk_size, plain_chunk_size, comp_chunk_size, comp_chunk_size)); + + /* Uncompressing the buffer using LZ Xpress algorithm */ + ret = lzxpress_decompress(comp_chunk.data, + comp_chunk.length, + plain_chunk.data, + plain_chunk.length); + if (ret < 0) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "XPRESS lzxpress_decompress() returned %d\n", + (int)ret); + } + plain_chunk.length = ret; + + if ((plain_chunk_size < 0x00010000) || (ndrpull->offset+4 >= ndrpull->data_size)) { + /* this is the last chunk */ + *last = true; + } + + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_push_compression_xpress_chunk(struct ndr_push *ndrpush, + struct ndr_pull *ndrpull, + bool *last) +{ + DATA_BLOB comp_chunk; + uint32_t comp_chunk_size_offset; + DATA_BLOB plain_chunk; + uint32_t plain_chunk_size; + uint32_t plain_chunk_offset; + uint32_t max_plain_size = 0x00010000; + uint32_t max_comp_size = 0x00020000 + 2; /* TODO: use the correct value here */ + uint32_t tmp_offset; + ssize_t ret; + + plain_chunk_size = MIN(max_plain_size, ndrpull->data_size - ndrpull->offset); + plain_chunk_offset = ndrpull->offset; + NDR_CHECK(ndr_pull_advance(ndrpull, plain_chunk_size)); + + plain_chunk.data = ndrpull->data + plain_chunk_offset; + plain_chunk.length = plain_chunk_size; + + if (plain_chunk_size < max_plain_size) { + *last = true; + } + + NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, plain_chunk_size)); + comp_chunk_size_offset = ndrpush->offset; + NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, 0xFEFEFEFE)); + + NDR_CHECK(ndr_push_expand(ndrpush, max_comp_size)); + + comp_chunk.data = ndrpush->data + ndrpush->offset; + comp_chunk.length = max_comp_size; + + /* Compressing the buffer using LZ Xpress algorithm */ + ret = lzxpress_compress(plain_chunk.data, + plain_chunk.length, + comp_chunk.data, + comp_chunk.length); + if (ret < 0) { + return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, + "XPRESS lzxpress_compress() returned %d\n", + (int)ret); + } + comp_chunk.length = ret; + + tmp_offset = ndrpush->offset; + ndrpush->offset = comp_chunk_size_offset; + NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, comp_chunk.length)); + ndrpush->offset = tmp_offset; + + ndrpush->offset += comp_chunk.length; + return NDR_ERR_SUCCESS; +} + +/* + handle compressed subcontext buffers, which in midl land are user-marshalled, but + we use magic in pidl to make them easier to cope with +*/ +enum ndr_err_code ndr_pull_compression_start(struct ndr_pull *subndr, + struct ndr_pull **_comndr, + enum ndr_compression_alg compression_alg, + ssize_t decompressed_len) +{ + struct ndr_push *ndrpush; + struct ndr_pull *comndr; + DATA_BLOB uncompressed; + bool last = false; + z_stream z; + + ndrpush = ndr_push_init_ctx(subndr, subndr->iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(ndrpush); + + switch (compression_alg) { + case NDR_COMPRESSION_MSZIP: + ZERO_STRUCT(z); + while (!last) { + NDR_CHECK(ndr_pull_compression_mszip_chunk(subndr, ndrpush, &z, &last)); + } + break; + + case NDR_COMPRESSION_XPRESS: + while (!last) { + NDR_CHECK(ndr_pull_compression_xpress_chunk(subndr, ndrpush, &last)); + } + break; + + default: + return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PULL)", + compression_alg); + } + + uncompressed = ndr_push_blob(ndrpush); + if (uncompressed.length != decompressed_len) { + return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, + "Bad uncompressed_len [%u] != [%u](0x%08X) (PULL)", + (int)uncompressed.length, + (int)decompressed_len, + (int)decompressed_len); + } + + comndr = talloc_zero(subndr, struct ndr_pull); + NDR_ERR_HAVE_NO_MEMORY(comndr); + comndr->flags = subndr->flags; + comndr->current_mem_ctx = subndr->current_mem_ctx; + + comndr->data = uncompressed.data; + comndr->data_size = uncompressed.length; + comndr->offset = 0; + + comndr->iconv_convenience = talloc_reference(comndr, subndr->iconv_convenience); + + *_comndr = comndr; + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_compression_end(struct ndr_pull *subndr, + struct ndr_pull *comndr, + enum ndr_compression_alg compression_alg, + ssize_t decompressed_len) +{ + return NDR_ERR_SUCCESS; +} + +/* + push a compressed subcontext +*/ +enum ndr_err_code ndr_push_compression_start(struct ndr_push *subndr, + struct ndr_push **_uncomndr, + enum ndr_compression_alg compression_alg, + ssize_t decompressed_len) +{ + struct ndr_push *uncomndr; + + switch (compression_alg) { + case NDR_COMPRESSION_MSZIP: + case NDR_COMPRESSION_XPRESS: + break; + default: + return ndr_push_error(subndr, NDR_ERR_COMPRESSION, + "Bad compression algorithm %d (PUSH)", + compression_alg); + } + + uncomndr = ndr_push_init_ctx(subndr, subndr->iconv_convenience); + NDR_ERR_HAVE_NO_MEMORY(uncomndr); + uncomndr->flags = subndr->flags; + + *_uncomndr = uncomndr; + return NDR_ERR_SUCCESS; +} + +/* + push a compressed subcontext +*/ +enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr, + struct ndr_push *uncomndr, + enum ndr_compression_alg compression_alg, + ssize_t decompressed_len) +{ + struct ndr_pull *ndrpull; + bool last = false; + z_stream z; + + ndrpull = talloc_zero(uncomndr, struct ndr_pull); + NDR_ERR_HAVE_NO_MEMORY(ndrpull); + ndrpull->flags = uncomndr->flags; + ndrpull->data = uncomndr->data; + ndrpull->data_size = uncomndr->offset; + ndrpull->offset = 0; + + ndrpull->iconv_convenience = talloc_reference(ndrpull, subndr->iconv_convenience); + + switch (compression_alg) { + case NDR_COMPRESSION_MSZIP: + ZERO_STRUCT(z); + while (!last) { + NDR_CHECK(ndr_push_compression_mszip_chunk(subndr, ndrpull, &z, &last)); + } + break; + + case NDR_COMPRESSION_XPRESS: + while (!last) { + NDR_CHECK(ndr_push_compression_xpress_chunk(subndr, ndrpull, &last)); + } + break; + + default: + return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PUSH)", + compression_alg); + } + + talloc_free(uncomndr); + return NDR_ERR_SUCCESS; +} diff --git a/librpc/ndr/ndr_compression.h b/librpc/ndr/ndr_compression.h new file mode 100644 index 0000000000..b939f6a42b --- /dev/null +++ b/librpc/ndr/ndr_compression.h @@ -0,0 +1,35 @@ +#ifndef __LIBRPC_NDR_NDR_COMPRESSION_H__ +#define __LIBRPC_NDR_NDR_COMPRESSION_H__ + +#undef _PRINTF_ATTRIBUTE +#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) +/* This file was automatically generated by mkproto.pl. DO NOT EDIT */ + +/* this file contains prototypes for functions that are private + * to this subsystem or library. These functions should not be + * used outside this particular subsystem! */ + + +/* The following definitions come from librpc/ndr/ndr_compression.c */ + +enum ndr_err_code ndr_pull_compression_start(struct ndr_pull *subndr, + struct ndr_pull **_comndr, + enum ndr_compression_alg compression_alg, + ssize_t decompressed_len); +enum ndr_err_code ndr_pull_compression_end(struct ndr_pull *subndr, + struct ndr_pull *comndr, + enum ndr_compression_alg compression_alg, + ssize_t decompressed_len); +enum ndr_err_code ndr_push_compression_start(struct ndr_push *subndr, + struct ndr_push **_uncomndr, + enum ndr_compression_alg compression_alg, + ssize_t decompressed_len); +enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr, + struct ndr_push *uncomndr, + enum ndr_compression_alg compression_alg, + ssize_t decompressed_len); +#undef _PRINTF_ATTRIBUTE +#define _PRINTF_ATTRIBUTE(a1, a2) + +#endif /* __LIBRPC_NDR_NDR_COMPRESSION_H__ */ + diff --git a/librpc/ndr/ndr_drsblobs.c b/librpc/ndr/ndr_drsblobs.c new file mode 100644 index 0000000000..aecb0c3b16 --- /dev/null +++ b/librpc/ndr/ndr_drsblobs.c @@ -0,0 +1,213 @@ +/* + Unix SMB/CIFS implementation. + + Manually parsed structures found in the DRS protocol + + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "librpc/gen_ndr/ndr_drsblobs.h" + +/* parser auto-generated by pidl, then hand-modified by abartlet */ + +/* Modified to have 'count' specified */ +static enum ndr_err_code ndr_push_AuthenticationInformationArray_with_count(struct ndr_push *ndr, int ndr_flags, int count, + const struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); + } + } + return NDR_ERR_SUCCESS; +} + +/* Modified to have 'count' specified, and to allocate the array */ +static enum ndr_err_code ndr_pull_AuthenticationInformationArray_with_count(struct ndr_pull *ndr, int ndr_flags, int count, struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + TALLOC_CTX *_mem_save_array_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_PULL_ALLOC_N(ndr, r->array, count); + _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); + } + } + return NDR_ERR_SUCCESS; +} + +/* Modified to have 'count' specified */ +_PUBLIC_ void ndr_print_AuthenticationInformationArray_with_count(struct ndr_print *ndr, const char *name, int count, const struct AuthenticationInformationArray *r) +{ + uint32_t cntr_array_0; + ndr_print_struct(ndr, name, "AuthenticationInformationArray"); + ndr->depth++; + ndr->print(ndr, "%s: ARRAY(%d)", "array", (int)1); + ndr->depth++; + for (cntr_array_0=0;cntr_array_0<count;cntr_array_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_array_0) != -1) { + ndr_print_AuthenticationInformation(ndr, "array", &r->array[cntr_array_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +/* Modified to call AuthenticationInformationArray with 'count' specified */ +_PUBLIC_ enum ndr_err_code ndr_push_trustAuthInOutBlob(struct ndr_push *ndr, int ndr_flags, const struct trustAuthInOutBlob *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->current)); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->current) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->current)); + NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); + } + if (r->previous) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->previous)); + NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_trustAuthInOutBlob(struct ndr_pull *ndr, int ndr_flags, struct trustAuthInOutBlob *r) +{ + uint32_t _ptr_current; + TALLOC_CTX *_mem_save_current_0; + uint32_t _ptr_previous; + TALLOC_CTX *_mem_save_previous_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_current)); + if (_ptr_current) { + NDR_PULL_ALLOC(ndr, r->current); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->current, _ptr_current)); + } else { + r->current = NULL; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_previous)); + if (_ptr_previous) { + NDR_PULL_ALLOC(ndr, r->previous); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->previous, _ptr_previous)); + } else { + r->previous = NULL; + } + } + if (ndr_flags & NDR_BUFFERS) { + if (r->current) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->current)); + _mem_save_current_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->current, 0); + NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_current_0, 0); + ndr->offset = _relative_save_offset; + } + if (r->previous) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->previous)); + _mem_save_previous_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->previous, 0); + NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_previous_0, 0); + ndr->offset = _relative_save_offset; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_trustAuthInOutBlob(struct ndr_print *ndr, const char *name, const struct trustAuthInOutBlob *r) +{ + ndr_print_struct(ndr, name, "trustAuthInOutBlob"); + ndr->depth++; + ndr_print_uint32(ndr, "count", r->count); + ndr_print_ptr(ndr, "current", r->current); + ndr->depth++; + if (r->current) { + ndr_print_AuthenticationInformationArray_with_count(ndr, "current", r->count, r->current); + } + ndr->depth--; + ndr_print_ptr(ndr, "previous", r->previous); + ndr->depth++; + if (r->previous) { + ndr_print_AuthenticationInformationArray_with_count(ndr, "previous", r->count, r->previous); + } + ndr->depth--; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_trustDomainPasswords(struct ndr_pull *ndr, int ndr_flags, struct trustDomainPasswords *r) +{ + if (ndr_flags & NDR_SCALARS) { + uint32_t offset; + NDR_PULL_ALIGN(ndr, 4); + NDR_PULL_NEED_BYTES(ndr, 8); + + offset = ndr->offset; + ndr->offset = ndr->data_size - 8; + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->outgoing_size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->incoming_size)); + + ndr->offset = offset; + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->confounder, 512)); + { + struct ndr_pull *_ndr_outgoing; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_outgoing, 0, r->outgoing_size)); + NDR_CHECK(ndr_pull_trustCurrentPasswords(_ndr_outgoing, NDR_SCALARS|NDR_BUFFERS, &r->outgoing)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_outgoing, 0, r->outgoing_size)); + } + { + struct ndr_pull *_ndr_incoming; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_incoming, 0, r->incoming_size)); + NDR_CHECK(ndr_pull_trustCurrentPasswords(_ndr_incoming, NDR_SCALARS|NDR_BUFFERS, &r->incoming)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_incoming, 0, r->incoming_size)); + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->outgoing_size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->incoming_size)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + diff --git a/librpc/ndr/ndr_drsuapi.c b/librpc/ndr/ndr_drsuapi.c new file mode 100644 index 0000000000..4d1ae8b163 --- /dev/null +++ b/librpc/ndr/ndr_drsuapi.c @@ -0,0 +1,352 @@ +/* + Unix SMB/CIFS implementation. + + routines for printing some linked list structs in DRSUAPI + + Copyright (C) Stefan (metze) Metzmacher 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +#include "includes.h" +#include "librpc/gen_ndr/ndr_drsuapi.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "../lib/util/asn1.h" +#include "librpc/ndr/ndr_compression.h" +/* We don't need multibyte if we're just comparing to 'ff' */ +#undef strncasecmp + +void ndr_print_drsuapi_DsReplicaObjectListItem(struct ndr_print *ndr, const char *name, + const struct drsuapi_DsReplicaObjectListItem *r) +{ + ndr_print_struct(ndr, name, "drsuapi_DsReplicaObjectListItem"); + ndr->depth++; + ndr_print_ptr(ndr, "next_object", r->next_object); + ndr_print_drsuapi_DsReplicaObject(ndr, "object", &r->object); + ndr->depth--; + if (r->next_object) { + ndr_print_drsuapi_DsReplicaObjectListItem(ndr, "next_object", r->next_object); + } +} + +void ndr_print_drsuapi_DsReplicaObjectListItemEx(struct ndr_print *ndr, const char *name, const struct drsuapi_DsReplicaObjectListItemEx *r) +{ + ndr_print_struct(ndr, name, "drsuapi_DsReplicaObjectListItemEx"); + ndr->depth++; + ndr_print_ptr(ndr, "next_object", r->next_object); + ndr_print_drsuapi_DsReplicaObject(ndr, "object", &r->object); + ndr_print_uint32(ndr, "is_nc_prefix", r->is_nc_prefix); + ndr_print_ptr(ndr, "parent_object_guid", r->parent_object_guid); + ndr->depth++; + if (r->parent_object_guid) { + ndr_print_GUID(ndr, "parent_object_guid", r->parent_object_guid); + } + ndr->depth--; + ndr_print_ptr(ndr, "meta_data_ctr", r->meta_data_ctr); + ndr->depth++; + if (r->meta_data_ctr) { + ndr_print_drsuapi_DsReplicaMetaDataCtr(ndr, "meta_data_ctr", r->meta_data_ctr); + } + ndr->depth--; + ndr->depth--; + if (r->next_object) { + ndr_print_drsuapi_DsReplicaObjectListItemEx(ndr, "next_object", r->next_object); + } +} + +#define _OID_PUSH_CHECK(call) do { \ + bool _status; \ + _status = call; \ + if (_status != true) { \ + return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "OID Conversion Error: %s\n", __location__); \ + } \ +} while (0) + +#define _OID_PULL_CHECK(call) do { \ + bool _status; \ + _status = call; \ + if (_status != true) { \ + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "OID Conversion Error: %s\n", __location__); \ + } \ +} while (0) + +enum ndr_err_code ndr_push_drsuapi_DsReplicaOID(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsReplicaOID *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_drsuapi_DsReplicaOID_oid(r->oid, 0))); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->oid)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->oid) { + DATA_BLOB blob; + + if (strncasecmp("ff", r->oid, 2) == 0) { + blob = strhex_to_data_blob(ndr, r->oid); + if (!blob.data) { + return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, + "HEX String Conversion Error: %s\n", + __location__); + } + } else { + _OID_PUSH_CHECK(ber_write_OID_String(&blob, r->oid)); + } + + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, blob.length)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, blob.data, blob.length)); + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_drsuapi_DsReplicaOID(struct ndr_pull *ndr, int ndr_flags, struct drsuapi_DsReplicaOID *r) +{ + uint32_t _ptr_oid; + TALLOC_CTX *_mem_save_oid_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->__ndr_size)); + if (r->__ndr_size < 0 || r->__ndr_size > 10000) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_oid)); + if (_ptr_oid) { + NDR_PULL_ALLOC(ndr, r->oid); + } else { + r->oid = NULL; + } + } + if (ndr_flags & NDR_BUFFERS) { + if (r->oid) { + DATA_BLOB _oid_array; + const char *_oid; + + _mem_save_oid_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, ndr, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->oid)); + _oid_array.length = ndr_get_array_size(ndr, &r->oid); + NDR_PULL_ALLOC_N(ndr, _oid_array.data, _oid_array.length); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, _oid_array.data, _oid_array.length)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_oid_0, 0); + + if (_oid_array.length && _oid_array.data[0] == 0xFF) { + _oid = data_blob_hex_string(ndr, &_oid_array); + NDR_ERR_HAVE_NO_MEMORY(_oid); + } else { + _OID_PULL_CHECK(ber_read_OID_String(ndr, _oid_array, &_oid)); + } + data_blob_free(&_oid_array); + talloc_steal(r->oid, _oid); + r->oid = _oid; + } + if (r->oid) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->oid, r->__ndr_size)); + } + } + return NDR_ERR_SUCCESS; +} + +size_t ndr_size_drsuapi_DsReplicaOID_oid(const char *oid, int flags) +{ + DATA_BLOB _blob; + size_t ret = 0; + + if (!oid) return 0; + + if (strncasecmp("ff", oid, 2) == 0) { + _blob = strhex_to_data_blob(NULL, oid); + if (_blob.data) { + ret = _blob.length; + } + } else { + if (ber_write_OID_String(&_blob, oid)) { + ret = _blob.length; + } + } + data_blob_free(&_blob); + return ret; +} + +enum ndr_err_code ndr_push_drsuapi_DsGetNCChangesMSZIPCtr1(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsGetNCChangesMSZIPCtr1 *r) +{ + if (ndr_flags & NDR_SCALARS) { + uint32_t decompressed_length = 0; + uint32_t compressed_length = 0; + if (r->ts) { + { + struct ndr_push *_ndr_ts; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1)); + { + struct ndr_push *_ndr_ts_compressed; + NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1)); + NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr1TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts)); + decompressed_length = _ndr_ts_compressed->offset; + NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1)); + } + compressed_length = _ndr_ts->offset; + talloc_free(_ndr_ts); + } + } + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, decompressed_length)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, compressed_length)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->ts)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->ts) { + { + struct ndr_push *_ndr_ts; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1)); + { + struct ndr_push *_ndr_ts_compressed; + NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1)); + NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr1TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts)); + NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1)); + } + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_ts, 4, -1)); + } + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_drsuapi_DsGetNCChangesMSZIPCtr6(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsGetNCChangesMSZIPCtr6 *r) +{ + if (ndr_flags & NDR_SCALARS) { + uint32_t decompressed_length = 0; + uint32_t compressed_length = 0; + if (r->ts) { + { + struct ndr_push *_ndr_ts; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1)); + { + struct ndr_push *_ndr_ts_compressed; + NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1)); + NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr6TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts)); + decompressed_length = _ndr_ts_compressed->offset; + NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1)); + } + compressed_length = _ndr_ts->offset; + talloc_free(_ndr_ts); + } + } + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, decompressed_length)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, compressed_length)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->ts)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->ts) { + { + struct ndr_push *_ndr_ts; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1)); + { + struct ndr_push *_ndr_ts_compressed; + NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1)); + NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr6TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts)); + NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1)); + } + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_ts, 4, -1)); + } + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_drsuapi_DsGetNCChangesXPRESSCtr1(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsGetNCChangesXPRESSCtr1 *r) +{ + if (ndr_flags & NDR_SCALARS) { + uint32_t decompressed_length = 0; + uint32_t compressed_length = 0; + if (r->ts) { + { + struct ndr_push *_ndr_ts; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1)); + { + struct ndr_push *_ndr_ts_compressed; + NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1)); + NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr1TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts)); + decompressed_length = _ndr_ts_compressed->offset; + NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1)); + } + compressed_length = _ndr_ts->offset; + talloc_free(_ndr_ts); + } + } + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, decompressed_length)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, compressed_length)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->ts)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->ts) { + { + struct ndr_push *_ndr_ts; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1)); + { + struct ndr_push *_ndr_ts_compressed; + NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1)); + NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr1TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts)); + NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1)); + } + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_ts, 4, -1)); + } + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_drsuapi_DsGetNCChangesXPRESSCtr6(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsGetNCChangesXPRESSCtr6 *r) +{ + if (ndr_flags & NDR_SCALARS) { + uint32_t decompressed_length = 0; + uint32_t compressed_length = 0; + if (r->ts) { + { + struct ndr_push *_ndr_ts; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1)); + { + struct ndr_push *_ndr_ts_compressed; + NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1)); + NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr6TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts)); + decompressed_length = _ndr_ts_compressed->offset; + NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1)); + } + compressed_length = _ndr_ts->offset; + talloc_free(_ndr_ts); + } + } + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, decompressed_length)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, compressed_length)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->ts)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->ts) { + { + struct ndr_push *_ndr_ts; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1)); + { + struct ndr_push *_ndr_ts_compressed; + NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1)); + NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr6TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts)); + NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1)); + } + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_ts, 4, -1)); + } + } + } + return NDR_ERR_SUCCESS; +} diff --git a/librpc/ndr/ndr_drsuapi.h b/librpc/ndr/ndr_drsuapi.h new file mode 100644 index 0000000000..12c2c78bde --- /dev/null +++ b/librpc/ndr/ndr_drsuapi.h @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + + routines for printing some linked list structs in DRSUAPI + + Copyright (C) Stefan (metze) Metzmacher 2005-2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _LIBRPC_NDR_NDR_DRSUAPI_H +#define _LIBRPC_NDR_NDR_DRSUAPI_H + +void ndr_print_drsuapi_DsReplicaObjectListItem(struct ndr_print *ndr, const char *name, + const struct drsuapi_DsReplicaObjectListItem *r); + +void ndr_print_drsuapi_DsReplicaObjectListItemEx(struct ndr_print *ndr, const char *name, + const struct drsuapi_DsReplicaObjectListItemEx *r); + +enum ndr_err_code ndr_push_drsuapi_DsReplicaOID(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsReplicaOID *r); +enum ndr_err_code ndr_pull_drsuapi_DsReplicaOID(struct ndr_pull *ndr, int ndr_flags, struct drsuapi_DsReplicaOID *r); +size_t ndr_size_drsuapi_DsReplicaOID_oid(const char *oid, int flags); + +#endif /* _LIBRPC_NDR_NDR_DRSUAPI_H */ diff --git a/librpc/ndr/ndr_krb5pac.c b/librpc/ndr/ndr_krb5pac.c new file mode 100644 index 0000000000..1b32df4c62 --- /dev/null +++ b/librpc/ndr/ndr_krb5pac.c @@ -0,0 +1,140 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling spoolss subcontext buffer structures + + Copyright (C) Stefan Metzmacher 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +#include "includes.h" +#include "librpc/gen_ndr/ndr_krb5pac.h" + +static size_t _ndr_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) +{ + size_t s = ndr_size_PAC_INFO(r, level, flags); + switch (level) { + case PAC_TYPE_LOGON_INFO: + return NDR_ROUND(s,8); + default: + return s; + } +} + +static size_t _subcontext_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) +{ + size_t s = ndr_size_PAC_INFO(r, level, flags); + return NDR_ROUND(s,8); +} + +enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,0))); + { + uint32_t _flags_save_PAC_INFO = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->info)); + ndr->flags = _flags_save_PAC_INFO; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_PAC_INFO = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + if (r->info) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->info)); + { + struct ndr_push *_ndr_info; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0))); + NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type)); + NDR_CHECK(ndr_push_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0))); + } + } + ndr->flags = _flags_save_PAC_INFO; + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_PAC_BUFFER(struct ndr_pull *ndr, int ndr_flags, struct PAC_BUFFER *r) +{ + uint32_t _ptr_info; + TALLOC_CTX *_mem_save_info_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_PAC_TYPE(ndr, NDR_SCALARS, &r->type)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); + { + uint32_t _flags_save_PAC_INFO = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); + if (_ptr_info) { + NDR_PULL_ALLOC(ndr, r->info); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->info, _ptr_info)); + } else { + r->info = NULL; + } + ndr->flags = _flags_save_PAC_INFO; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_PAC_INFO = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + if (r->info) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->info)); + _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info, 0); + { + struct ndr_pull *_ndr_info; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 0, r->_ndr_size)); + NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->info, r->type)); + NDR_CHECK(ndr_pull_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 0, r->_ndr_size)); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_PAC_INFO; + } + } + return NDR_ERR_SUCCESS; +} + +void ndr_print_PAC_BUFFER(struct ndr_print *ndr, const char *name, const struct PAC_BUFFER *r) +{ + ndr_print_struct(ndr, name, "PAC_BUFFER"); + ndr->depth++; + ndr_print_PAC_TYPE(ndr, "type", r->type); + ndr_print_uint32(ndr, "_ndr_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?_ndr_size_PAC_INFO(r->info,r->type,0):r->_ndr_size); + ndr_print_ptr(ndr, "info", r->info); + ndr->depth++; + if (r->info) { + ndr_print_set_switch_value(ndr, r->info, r->type); + ndr_print_PAC_INFO(ndr, "info", r->info); + } + ndr->depth--; + ndr_print_uint32(ndr, "_pad", r->_pad); + ndr->depth--; +} diff --git a/librpc/ndr/ndr_misc.c b/librpc/ndr/ndr_misc.c new file mode 100644 index 0000000000..c4a1adb3ea --- /dev/null +++ b/librpc/ndr/ndr_misc.c @@ -0,0 +1,37 @@ +/* + Unix SMB/CIFS implementation. + + UUID/GUID/policy_handle functions + + Copyright (C) Andrew Tridgell 2003. + Copyright (C) Stefan (metze) Metzmacher 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/network.h" +#include "librpc/ndr/libndr.h" + +_PUBLIC_ void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid) +{ + ndr->print(ndr, "%-25s: %s", name, GUID_string(ndr, guid)); +} + +bool ndr_syntax_id_equal(const struct ndr_syntax_id *i1, + const struct ndr_syntax_id *i2) +{ + return GUID_equal(&i1->uuid, &i2->uuid) + && (i1->if_version == i2->if_version); +} diff --git a/librpc/ndr/ndr_orpc.c b/librpc/ndr/ndr_orpc.c new file mode 100644 index 0000000000..6a55048e43 --- /dev/null +++ b/librpc/ndr/ndr_orpc.c @@ -0,0 +1,173 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling DCOM string arrays + + Copyright (C) Jelmer Vernooij 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +#include "includes.h" +#include "librpc/gen_ndr/ndr_orpc.h" + +enum ndr_err_code ndr_pull_DUALSTRINGARRAY(struct ndr_pull *ndr, int ndr_flags, struct DUALSTRINGARRAY *ar) +{ + uint16_t num_entries, security_offset; + uint16_t towerid; + uint32_t towernum = 0, conformant_size; + + if (!(ndr_flags & NDR_SCALARS)) { + return NDR_ERR_SUCCESS; + } + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &conformant_size)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &num_entries)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &security_offset)); + + ar->stringbindings = talloc_array(ndr, struct STRINGBINDING *, num_entries); + ar->stringbindings[0] = NULL; + + do { + /* 'Peek' */ + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &towerid)); + + if (towerid > 0) { + ndr->offset -= 2; + ar->stringbindings = talloc_realloc(ndr, ar->stringbindings, struct STRINGBINDING *, towernum+2); + ar->stringbindings[towernum] = talloc(ndr, struct STRINGBINDING); + NDR_CHECK(ndr_pull_STRINGBINDING(ndr, ndr_flags, ar->stringbindings[towernum])); + towernum++; + } + } while (towerid != 0); + + ar->stringbindings[towernum] = NULL; + towernum = 0; + + ar->securitybindings = talloc_array(ndr, struct SECURITYBINDING *, num_entries); + ar->securitybindings[0] = NULL; + + do { + /* 'Peek' */ + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &towerid)); + + if (towerid > 0) { + ndr->offset -= 2; + ar->securitybindings = talloc_realloc(ndr, ar->securitybindings, struct SECURITYBINDING *, towernum+2); + ar->securitybindings[towernum] = talloc(ndr, struct SECURITYBINDING); + NDR_CHECK(ndr_pull_SECURITYBINDING(ndr, ndr_flags, ar->securitybindings[towernum])); + towernum++; + } + } while (towerid != 0); + + ar->securitybindings[towernum] = NULL; + + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_DUALSTRINGARRAY(struct ndr_push *ndr, int ndr_flags, const struct DUALSTRINGARRAY *ar) +{ + return ndr_push_error(ndr, NDR_ERR_STRING, "ndr_push_DUALSTRINGARRAY not implemented"); +} + +/* + print a dom_sid +*/ +void ndr_print_DUALSTRINGARRAY(struct ndr_print *ndr, const char *name, const struct DUALSTRINGARRAY *ar) +{ + int i; + ndr->print(ndr, "%-25s: DUALSTRINGARRAY", name); + ndr->depth++; + ndr->print(ndr, "STRING BINDINGS"); + ndr->depth++; + for (i=0;ar->stringbindings[i];i++) { + char *idx = NULL; + asprintf(&idx, "[%d]", i); + if (idx) { + ndr_print_STRINGBINDING(ndr, idx, ar->stringbindings[i]); + free(idx); + } + } + ndr->depth--; + ndr->print(ndr, "SECURITY BINDINGS"); + ndr->depth++; + for (i=0;ar->securitybindings[i];i++) { + char *idx = NULL; + asprintf(&idx, "[%d]", i); + if (idx) { + ndr_print_SECURITYBINDING(ndr, idx, ar->securitybindings[i]); + free(idx); + } + } + ndr->depth--; +} + +enum ndr_err_code ndr_pull_STRINGARRAY(struct ndr_pull *ndr, int ndr_flags, struct STRINGARRAY *ar) +{ + uint16_t towerid; + uint32_t towernum = 0; + uint16_t num_entries; + + if (!(ndr_flags & NDR_SCALARS)) { + return NDR_ERR_SUCCESS; + } + + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &num_entries)); + + ar->stringbindings = talloc_array(ndr, struct STRINGBINDING *, 1); + ar->stringbindings[0] = NULL; + + do { + /* 'Peek' */ + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &towerid)); + + if (towerid > 0) { + ndr->offset -= 2; + ar->stringbindings = talloc_realloc(ndr, ar->stringbindings, struct STRINGBINDING *, towernum+2); + ar->stringbindings[towernum] = talloc(ndr, struct STRINGBINDING); + NDR_CHECK(ndr_pull_STRINGBINDING(ndr, ndr_flags, ar->stringbindings[towernum])); + towernum++; + } + } while (towerid != 0); + + ar->stringbindings[towernum] = NULL; + towernum = 0; + + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_push_STRINGARRAY(struct ndr_push *ndr, int ndr_flags, const struct STRINGARRAY *ar) +{ + return ndr_push_error(ndr, NDR_ERR_STRING, "ndr_push_STRINGARRAY not implemented"); +} + +/* + print a dom_sid +*/ +void ndr_print_STRINGARRAY(struct ndr_print *ndr, const char *name, const struct STRINGARRAY *ar) +{ + int i; + ndr->print(ndr, "%-25s: STRINGARRAY", name); + ndr->depth++; + for (i=0;ar->stringbindings[i];i++) { + char *idx = NULL; + asprintf(&idx, "[%d]", i); + if (idx) { + ndr_print_STRINGBINDING(ndr, idx, ar->stringbindings[i]); + free(idx); + } + } + ndr->depth--; +} diff --git a/librpc/ndr/ndr_table.c b/librpc/ndr/ndr_table.c new file mode 100644 index 0000000000..7ca04173f7 --- /dev/null +++ b/librpc/ndr/ndr_table.c @@ -0,0 +1,133 @@ +/* + Unix SMB/CIFS implementation. + + dcerpc utility functions + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Jelmer Vernooij 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "../lib/util/dlinklist.h" +#include "librpc/ndr/libndr.h" +#include "librpc/ndr/ndr_table.h" +#undef strcasecmp + +static struct ndr_interface_list *ndr_interfaces; + +/* + register a ndr interface table +*/ +NTSTATUS ndr_table_register(const struct ndr_interface_table *table) +{ + struct ndr_interface_list *l; + + for (l = ndr_interfaces; l; l = l->next) { + if (GUID_equal(&table->syntax_id.uuid, &l->table->syntax_id.uuid)) { + DEBUG(0, ("Attempt to register interface %s which has the " + "same UUID as already registered interface %s\n", + table->name, l->table->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + } + + l = talloc(talloc_autofree_context(), struct ndr_interface_list); + l->table = table; + + DLIST_ADD(ndr_interfaces, l); + + return NT_STATUS_OK; +} + +/* + find the pipe name for a local IDL interface +*/ +const char *ndr_interface_name(const struct GUID *uuid, uint32_t if_version) +{ + const struct ndr_interface_list *l; + for (l=ndr_table_list();l;l=l->next) { + if (GUID_equal(&l->table->syntax_id.uuid, uuid) && + l->table->syntax_id.if_version == if_version) { + return l->table->name; + } + } + return "UNKNOWN"; +} + +/* + find the number of calls defined by local IDL +*/ +int ndr_interface_num_calls(const struct GUID *uuid, uint32_t if_version) +{ + const struct ndr_interface_list *l; + for (l=ndr_interfaces;l;l=l->next){ + if (GUID_equal(&l->table->syntax_id.uuid, uuid) && + l->table->syntax_id.if_version == if_version) { + return l->table->num_calls; + } + } + return -1; +} + + +/* + find a dcerpc interface by name +*/ +const struct ndr_interface_table *ndr_table_by_name(const char *name) +{ + const struct ndr_interface_list *l; + for (l=ndr_interfaces;l;l=l->next) { + if (strcasecmp(l->table->name, name) == 0) { + return l->table; + } + } + return NULL; +} + +/* + find a dcerpc interface by uuid +*/ +const struct ndr_interface_table *ndr_table_by_uuid(const struct GUID *uuid) +{ + const struct ndr_interface_list *l; + for (l=ndr_interfaces;l;l=l->next) { + if (GUID_equal(&l->table->syntax_id.uuid, uuid)) { + return l->table; + } + } + return NULL; +} + +/* + return the list of registered dcerpc_pipes +*/ +const struct ndr_interface_list *ndr_table_list(void) +{ + return ndr_interfaces; +} + + +NTSTATUS ndr_table_init(void) +{ + static bool initialized = false; + + if (initialized) return NT_STATUS_OK; + initialized = true; + + ndr_table_register_builtin_tables(); + + return NT_STATUS_OK; +} diff --git a/librpc/ndr/ndr_table.h b/librpc/ndr/ndr_table.h new file mode 100644 index 0000000000..9e8fea1db6 --- /dev/null +++ b/librpc/ndr/ndr_table.h @@ -0,0 +1,14 @@ +#ifndef _NDR_TABLE_PROTO_H_ +#define _NDR_TABLE_PROTO_H_ + +NTSTATUS ndr_table_register(const struct ndr_interface_table *table); +const char *ndr_interface_name(const struct GUID *uuid, uint32_t if_version); +int ndr_interface_num_calls(const struct GUID *uuid, uint32_t if_version); +const struct ndr_interface_table *ndr_table_by_name(const char *name); +const struct ndr_interface_table *ndr_table_by_uuid(const struct GUID *uuid); +const struct ndr_interface_list *ndr_table_list(void); +NTSTATUS ndr_table_init(void); +NTSTATUS ndr_table_register_builtin_tables(void); + +#endif /* _NDR_TABLE_PROTO_H_ */ + diff --git a/librpc/ndr/ndr_wmi.c b/librpc/ndr/ndr_wmi.c new file mode 100644 index 0000000000..2c122decf4 --- /dev/null +++ b/librpc/ndr/ndr_wmi.c @@ -0,0 +1,60 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling DCOM string arrays + + Copyright (C) Jelmer Vernooij 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. +*/ +//#define NDR_CHECK_DEBUG +#include "includes.h" +#include "librpc/gen_ndr/ndr_dcom.h" +#include "librpc/gen_ndr/ndr_wmi.h" +#include "librpc/ndr/ndr_wmi.h" + +// Just for debugging +int NDR_CHECK_depth = 0; +int NDR_CHECK_shift = 0x18; + +enum ndr_err_code ndr_push_BSTR(struct ndr_push *ndr, int ndr_flags, const struct BSTR *r) +{ + uint32_t len; + uint32_t flags; + enum ndr_err_code status; + len = strlen(r->data); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0x72657355)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, len)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 2*len)); + flags = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NOTERM | LIBNDR_FLAG_STR_SIZE4); + status = ndr_push_string(ndr, NDR_SCALARS, r->data); + ndr->flags = flags; + return status; + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_BSTR(struct ndr_pull *ndr, int ndr_flags, struct BSTR *r) +{ + return NDR_ERR_BAD_SWITCH; +} + +void ndr_print_BSTR(struct ndr_print *ndr, const char *name, const struct BSTR *r) +{ + ndr->print(ndr, "%-25s: BSTR(\"%s\")", name, r->data); +} diff --git a/librpc/ndr/ndr_wmi.h b/librpc/ndr/ndr_wmi.h new file mode 100644 index 0000000000..539b9e882b --- /dev/null +++ b/librpc/ndr/ndr_wmi.h @@ -0,0 +1,3 @@ +typedef const char *CIMSTRING; +enum ndr_err_code ndr_pull_CIMSTRING(struct ndr_pull *ndr, int ndr_flags, CIMSTRING *r); +enum ndr_err_code ndr_push_CIMSTRING(struct ndr_push *ndr, int ndr_flags, const CIMSTRING *r); diff --git a/librpc/ndr/uuid.c b/librpc/ndr/uuid.c new file mode 100644 index 0000000000..1e6ee0a3db --- /dev/null +++ b/librpc/ndr/uuid.c @@ -0,0 +1,227 @@ +/* + Unix SMB/CIFS implementation. + + UUID/GUID functions + + Copyright (C) Theodore Ts'o 1996, 1997, + Copyright (C) Jim McDonough 2002. + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "librpc/ndr/libndr.h" + +/** + build a GUID from a string +*/ +_PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid) +{ + NTSTATUS status = NT_STATUS_INVALID_PARAMETER; + uint32_t time_low; + uint32_t time_mid, time_hi_and_version; + uint32_t clock_seq[2]; + uint32_t node[6]; + int i; + + if (s == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + 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])) { + status = NT_STATUS_OK; + } else 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])) { + status = NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + 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; +} + +/** + build a GUID from a string +*/ +_PUBLIC_ NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid) +{ + NTSTATUS status = NT_STATUS_INVALID_PARAMETER; + uint32_t time_low; + uint32_t time_mid, time_hi_and_version; + uint32_t clock_seq[2]; + uint32_t node[6]; + int i; + + if (s == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + 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])) { + status = NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + 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; +} + +/** + * generate a random GUID + */ +_PUBLIC_ struct GUID GUID_random(void) +{ + struct GUID guid; + + generate_random_buffer((uint8_t *)&guid, sizeof(guid)); + guid.clock_seq[0] = (guid.clock_seq[0] & 0x3F) | 0x80; + guid.time_hi_and_version = (guid.time_hi_and_version & 0x0FFF) | 0x4000; + + return guid; +} + +/** + * generate an empty GUID + */ +_PUBLIC_ struct GUID GUID_zero(void) +{ + struct GUID guid; + + ZERO_STRUCT(guid); + + return guid; +} + +_PUBLIC_ bool GUID_all_zero(const struct GUID *u) +{ + if (u->time_low != 0 || + u->time_mid != 0 || + u->time_hi_and_version != 0 || + u->clock_seq[0] != 0 || + u->clock_seq[1] != 0 || + !all_zero(u->node, 6)) { + return false; + } + return true; +} + +_PUBLIC_ bool GUID_equal(const struct GUID *u1, const struct GUID *u2) +{ + if (u1->time_low != u2->time_low || + u1->time_mid != u2->time_mid || + u1->time_hi_and_version != u2->time_hi_and_version || + u1->clock_seq[0] != u2->clock_seq[0] || + u1->clock_seq[1] != u2->clock_seq[1] || + memcmp(u1->node, u2->node, 6) != 0) { + return false; + } + return true; +} + +_PUBLIC_ int GUID_compare(const struct GUID *u1, const struct GUID *u2) +{ + if (u1->time_low != u2->time_low) { + return u1->time_low - u2->time_low; + } + + if (u1->time_mid != u2->time_mid) { + return u1->time_mid - u2->time_mid; + } + + if (u1->time_hi_and_version != u2->time_hi_and_version) { + return u1->time_hi_and_version - u2->time_hi_and_version; + } + + if (u1->clock_seq[0] != u2->clock_seq[0]) { + return u1->clock_seq[0] - u2->clock_seq[0]; + } + + if (u1->clock_seq[1] != u2->clock_seq[1]) { + return u1->clock_seq[1] - u2->clock_seq[1]; + } + + return memcmp(u1->node, u2->node, 6); +} + +/** + its useful to be able to display these in debugging messages +*/ +_PUBLIC_ 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]); +} + +_PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid) +{ + char *ret, *s = GUID_string(mem_ctx, guid); + ret = talloc_asprintf(mem_ctx, "{%s}", s); + talloc_free(s); + return ret; +} + +_PUBLIC_ char *NS_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]); +} + +_PUBLIC_ bool policy_handle_empty(struct policy_handle *h) +{ + return (h->handle_type == 0 && GUID_all_zero(&h->uuid)); +} diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c new file mode 100644 index 0000000000..b755431034 --- /dev/null +++ b/librpc/rpc/binding.c @@ -0,0 +1,725 @@ +/* + Unix SMB/CIFS implementation. + + dcerpc utility functions + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Jelmer Vernooij 2004 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 + Copyright (C) Rafal Szczesniak 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "librpc/gen_ndr/ndr_epmapper.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "librpc/rpc/dcerpc.h" +#undef strcasecmp + +#define MAX_PROTSEQ 10 + +static const struct { + const char *name; + enum dcerpc_transport_t transport; + int num_protocols; + enum epm_protocol protseq[MAX_PROTSEQ]; +} transports[] = { + { "ncacn_np", NCACN_NP, 3, + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_SMB, EPM_PROTOCOL_NETBIOS }}, + { "ncacn_ip_tcp", NCACN_IP_TCP, 3, + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP, EPM_PROTOCOL_IP } }, + { "ncacn_http", NCACN_HTTP, 3, + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP, EPM_PROTOCOL_IP } }, + { "ncadg_ip_udp", NCACN_IP_UDP, 3, + { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_UDP, EPM_PROTOCOL_IP } }, + { "ncalrpc", NCALRPC, 2, + { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE } }, + { "ncacn_unix_stream", NCACN_UNIX_STREAM, 2, + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_UNIX_DS } }, + { "ncadg_unix_dgram", NCADG_UNIX_DGRAM, 2, + { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_UNIX_DS } }, + { "ncacn_at_dsp", NCACN_AT_DSP, 3, + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_APPLETALK, EPM_PROTOCOL_DSP } }, + { "ncadg_at_ddp", NCADG_AT_DDP, 3, + { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_APPLETALK, EPM_PROTOCOL_DDP } }, + { "ncacn_vns_ssp", NCACN_VNS_SPP, 3, + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_STREETTALK, EPM_PROTOCOL_VINES_SPP } }, + { "ncacn_vns_ipc", NCACN_VNS_IPC, 3, + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_STREETTALK, EPM_PROTOCOL_VINES_IPC }, }, + { "ncadg_ipx", NCADG_IPX, 2, + { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_IPX }, + }, + { "ncacn_spx", NCACN_SPX, 3, + /* I guess some MS programmer confused the identifier for + * EPM_PROTOCOL_UUID (0x0D or 13) with the one for + * EPM_PROTOCOL_SPX (0x13) here. -- jelmer*/ + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_UUID }, + }, +}; + +static const struct { + const char *name; + uint32_t flag; +} ncacn_options[] = { + {"sign", DCERPC_SIGN}, + {"seal", DCERPC_SEAL}, + {"connect", DCERPC_CONNECT}, + {"spnego", DCERPC_AUTH_SPNEGO}, + {"ntlm", DCERPC_AUTH_NTLM}, + {"krb5", DCERPC_AUTH_KRB5}, + {"validate", DCERPC_DEBUG_VALIDATE_BOTH}, + {"print", DCERPC_DEBUG_PRINT_BOTH}, + {"padcheck", DCERPC_DEBUG_PAD_CHECK}, + {"bigendian", DCERPC_PUSH_BIGENDIAN}, + {"smb2", DCERPC_SMB2}, + {"hdrsign", DCERPC_HEADER_SIGNING} +}; + +const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) +{ + struct ndr_syntax_id syntax; + NTSTATUS status; + + switch(epm_floor->lhs.protocol) { + case EPM_PROTOCOL_UUID: + status = dcerpc_floor_get_lhs_data(epm_floor, &syntax); + if (NT_STATUS_IS_OK(status)) { + /* lhs is used: UUID */ + char *uuidstr; + + if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax.uuid)) { + return "NDR"; + } + + if (GUID_equal(&syntax.uuid, &ndr64_transfer_syntax.uuid)) { + return "NDR64"; + } + + uuidstr = GUID_string(mem_ctx, &syntax.uuid); + + return talloc_asprintf(mem_ctx, " uuid %s/0x%02x", uuidstr, syntax.if_version); + } else { /* IPX */ + return talloc_asprintf(mem_ctx, "IPX:%s", + data_blob_hex_string(mem_ctx, &epm_floor->rhs.uuid.unknown)); + } + + case EPM_PROTOCOL_NCACN: + return "RPC-C"; + + case EPM_PROTOCOL_NCADG: + return "RPC"; + + case EPM_PROTOCOL_NCALRPC: + return "NCALRPC"; + + case EPM_PROTOCOL_DNET_NSP: + return "DNET/NSP"; + + case EPM_PROTOCOL_IP: + return talloc_asprintf(mem_ctx, "IP:%s", epm_floor->rhs.ip.ipaddr); + + case EPM_PROTOCOL_PIPE: + return talloc_asprintf(mem_ctx, "PIPE:%s", epm_floor->rhs.pipe.path); + + case EPM_PROTOCOL_SMB: + return talloc_asprintf(mem_ctx, "SMB:%s", epm_floor->rhs.smb.unc); + + case EPM_PROTOCOL_UNIX_DS: + return talloc_asprintf(mem_ctx, "Unix:%s", epm_floor->rhs.unix_ds.path); + + case EPM_PROTOCOL_NETBIOS: + return talloc_asprintf(mem_ctx, "NetBIOS:%s", epm_floor->rhs.netbios.name); + + case EPM_PROTOCOL_NETBEUI: + return "NETBeui"; + + case EPM_PROTOCOL_SPX: + return "SPX"; + + case EPM_PROTOCOL_NB_IPX: + return "NB_IPX"; + + case EPM_PROTOCOL_HTTP: + return talloc_asprintf(mem_ctx, "HTTP:%d", epm_floor->rhs.http.port); + + case EPM_PROTOCOL_TCP: + return talloc_asprintf(mem_ctx, "TCP:%d", epm_floor->rhs.tcp.port); + + case EPM_PROTOCOL_UDP: + return talloc_asprintf(mem_ctx, "UDP:%d", epm_floor->rhs.udp.port); + + default: + return talloc_asprintf(mem_ctx, "UNK(%02x):", epm_floor->lhs.protocol); + } +} + + +/* + form a binding string from a binding structure +*/ +_PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b) +{ + char *s = talloc_strdup(mem_ctx, ""); + int i; + const char *t_name = NULL; + + if (b->transport != NCA_UNKNOWN) { + for (i=0;i<ARRAY_SIZE(transports);i++) { + if (transports[i].transport == b->transport) { + t_name = transports[i].name; + } + } + if (!t_name) { + return NULL; + } + } + + if (!GUID_all_zero(&b->object.uuid)) { + s = talloc_asprintf(s, "%s@", + GUID_string(mem_ctx, &b->object.uuid)); + } + + if (t_name != NULL) { + s = talloc_asprintf_append_buffer(s, "%s:", t_name); + if (s == NULL) { + return NULL; + } + } + + if (b->host) { + s = talloc_asprintf_append_buffer(s, "%s", b->host); + } + + if (!b->endpoint && !b->options && !b->flags) { + return s; + } + + s = talloc_asprintf_append_buffer(s, "["); + + if (b->endpoint) { + s = talloc_asprintf_append_buffer(s, "%s", b->endpoint); + } + + /* 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_append_buffer(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_append_buffer(s, ",%s", ncacn_options[i].name); + if (!s) return NULL; + } + } + + s = talloc_asprintf_append_buffer(s, "]"); + + return s; +} + +/* + parse a binding string into a dcerpc_binding structure +*/ +_PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out) +{ + struct dcerpc_binding *b; + char *options; + char *p; + int i, j, comma_count; + + b = talloc(mem_ctx, struct dcerpc_binding); + if (!b) { + return NT_STATUS_NO_MEMORY; + } + + p = strchr(s, '@'); + + if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ + NTSTATUS status; + + status = GUID_from_string(s, &b->object.uuid); + + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Failed parsing UUID\n")); + return status; + } + + s = p + 1; + } else { + ZERO_STRUCT(b->object); + } + + b->object.if_version = 0; + + p = strchr(s, ':'); + + if (p == NULL) { + b->transport = NCA_UNKNOWN; + } else { + char *type = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); + if (!type) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0;i<ARRAY_SIZE(transports);i++) { + if (strcasecmp(type, transports[i].name) == 0) { + b->transport = transports[i].transport; + break; + } + } + + if (i==ARRAY_SIZE(transports)) { + DEBUG(0,("Unknown dcerpc transport '%s'\n", type)); + return NT_STATUS_INVALID_PARAMETER; + } + + talloc_free(type); + + s = p+1; + } + + p = strchr(s, '['); + if (p) { + b->host = talloc_strndup(b, s, PTR_DIFF(p, s)); + options = talloc_strdup(mem_ctx, p+1); + if (options[strlen(options)-1] != ']') { + return NT_STATUS_INVALID_PARAMETER; + } + options[strlen(options)-1] = 0; + } else { + b->host = talloc_strdup(b, s); + options = NULL; + } + if (!b->host) { + return NT_STATUS_NO_MEMORY; + } + + b->target_hostname = b->host; + + b->options = NULL; + b->flags = 0; + b->assoc_group_id = 0; + b->endpoint = NULL; + + if (!options) { + *b_out = b; + return NT_STATUS_OK; + } + + comma_count = count_chars(options, ','); + + b->options = talloc_array(b, const char *, comma_count+2); + if (!b->options) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; (p = strchr(options, ',')); i++) { + b->options[i] = talloc_strndup(b, options, PTR_DIFF(p, options)); + if (!b->options[i]) { + return NT_STATUS_NO_MEMORY; + } + options = p+1; + } + b->options[i] = options; + 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; + } + } + } + + if (b->options[0]) { + /* Endpoint is first option */ + b->endpoint = b->options[0]; + if (strlen(b->endpoint) == 0) b->endpoint = NULL; + + for (i=0;b->options[i];i++) { + b->options[i] = b->options[i+1]; + } + } + + if (b->options[0] == NULL) + b->options = NULL; + + *b_out = b; + return NT_STATUS_OK; +} + +_PUBLIC_ NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct ndr_syntax_id *syntax) +{ + TALLOC_CTX *mem_ctx = talloc_init("floor_get_lhs_data"); + struct ndr_pull *ndr = ndr_pull_init_blob(&epm_floor->lhs.lhs_data, mem_ctx, NULL); + enum ndr_err_code ndr_err; + uint16_t if_version=0; + + ndr->flags |= LIBNDR_FLAG_NOALIGN; + + ndr_err = ndr_pull_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(mem_ctx); + return ndr_map_error2ntstatus(ndr_err); + } + + ndr_err = ndr_pull_uint16(ndr, NDR_SCALARS, &if_version); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(mem_ctx); + return ndr_map_error2ntstatus(ndr_err); + } + + syntax->if_version = if_version; + + talloc_free(mem_ctx); + + return NT_STATUS_OK; +} + +static DATA_BLOB dcerpc_floor_pack_lhs_data(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax) +{ + struct ndr_push *ndr = ndr_push_init_ctx(mem_ctx, NULL); + + ndr->flags |= LIBNDR_FLAG_NOALIGN; + + ndr_push_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); + ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version); + + return ndr_push_blob(ndr); +} + +const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) +{ + switch (epm_floor->lhs.protocol) { + case EPM_PROTOCOL_TCP: + if (epm_floor->rhs.tcp.port == 0) return NULL; + return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.tcp.port); + + case EPM_PROTOCOL_UDP: + if (epm_floor->rhs.udp.port == 0) return NULL; + return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.udp.port); + + case EPM_PROTOCOL_HTTP: + if (epm_floor->rhs.http.port == 0) return NULL; + return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.http.port); + + case EPM_PROTOCOL_IP: + return talloc_strdup(mem_ctx, epm_floor->rhs.ip.ipaddr); + + case EPM_PROTOCOL_NCACN: + return NULL; + + case EPM_PROTOCOL_NCADG: + return NULL; + + case EPM_PROTOCOL_SMB: + if (strlen(epm_floor->rhs.smb.unc) == 0) return NULL; + return talloc_strdup(mem_ctx, epm_floor->rhs.smb.unc); + + case EPM_PROTOCOL_PIPE: + if (strlen(epm_floor->rhs.pipe.path) == 0) return NULL; + return talloc_strdup(mem_ctx, epm_floor->rhs.pipe.path); + + case EPM_PROTOCOL_NETBIOS: + if (strlen(epm_floor->rhs.netbios.name) == 0) return NULL; + return talloc_strdup(mem_ctx, epm_floor->rhs.netbios.name); + + case EPM_PROTOCOL_NCALRPC: + return NULL; + + case EPM_PROTOCOL_VINES_SPP: + return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_spp.port); + + case EPM_PROTOCOL_VINES_IPC: + return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_ipc.port); + + case EPM_PROTOCOL_STREETTALK: + return talloc_strdup(mem_ctx, epm_floor->rhs.streettalk.streettalk); + + case EPM_PROTOCOL_UNIX_DS: + if (strlen(epm_floor->rhs.unix_ds.path) == 0) return NULL; + return talloc_strdup(mem_ctx, epm_floor->rhs.unix_ds.path); + + case EPM_PROTOCOL_NULL: + return NULL; + + default: + DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol)); + break; + } + + return NULL; +} + +static NTSTATUS dcerpc_floor_set_rhs_data(TALLOC_CTX *mem_ctx, + struct epm_floor *epm_floor, + const char *data) +{ + switch (epm_floor->lhs.protocol) { + case EPM_PROTOCOL_TCP: + epm_floor->rhs.tcp.port = atoi(data); + return NT_STATUS_OK; + + case EPM_PROTOCOL_UDP: + epm_floor->rhs.udp.port = atoi(data); + return NT_STATUS_OK; + + case EPM_PROTOCOL_HTTP: + epm_floor->rhs.http.port = atoi(data); + return NT_STATUS_OK; + + case EPM_PROTOCOL_IP: + epm_floor->rhs.ip.ipaddr = talloc_strdup(mem_ctx, data); + NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.ip.ipaddr); + return NT_STATUS_OK; + + case EPM_PROTOCOL_NCACN: + epm_floor->rhs.ncacn.minor_version = 0; + return NT_STATUS_OK; + + case EPM_PROTOCOL_NCADG: + epm_floor->rhs.ncadg.minor_version = 0; + return NT_STATUS_OK; + + case EPM_PROTOCOL_SMB: + epm_floor->rhs.smb.unc = talloc_strdup(mem_ctx, data); + NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.smb.unc); + return NT_STATUS_OK; + + case EPM_PROTOCOL_PIPE: + epm_floor->rhs.pipe.path = talloc_strdup(mem_ctx, data); + NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.pipe.path); + return NT_STATUS_OK; + + case EPM_PROTOCOL_NETBIOS: + epm_floor->rhs.netbios.name = talloc_strdup(mem_ctx, data); + NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.netbios.name); + return NT_STATUS_OK; + + case EPM_PROTOCOL_NCALRPC: + return NT_STATUS_OK; + + case EPM_PROTOCOL_VINES_SPP: + epm_floor->rhs.vines_spp.port = atoi(data); + return NT_STATUS_OK; + + case EPM_PROTOCOL_VINES_IPC: + epm_floor->rhs.vines_ipc.port = atoi(data); + return NT_STATUS_OK; + + case EPM_PROTOCOL_STREETTALK: + epm_floor->rhs.streettalk.streettalk = talloc_strdup(mem_ctx, data); + NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.streettalk.streettalk); + return NT_STATUS_OK; + + case EPM_PROTOCOL_UNIX_DS: + epm_floor->rhs.unix_ds.path = talloc_strdup(mem_ctx, data); + NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.unix_ds.path); + return NT_STATUS_OK; + + case EPM_PROTOCOL_NULL: + return NT_STATUS_OK; + + default: + DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol)); + break; + } + + return NT_STATUS_NOT_SUPPORTED; +} + +enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot) +{ + int i; + + /* Find a transport that has 'prot' as 4th protocol */ + for (i=0;i<ARRAY_SIZE(transports);i++) { + if (transports[i].num_protocols >= 2 && + transports[i].protseq[1] == prot) { + return transports[i].transport; + } + } + + /* Unknown transport */ + return (unsigned int)-1; +} + +_PUBLIC_ enum dcerpc_transport_t dcerpc_transport_by_tower(struct epm_tower *tower) +{ + int i; + + /* Find a transport that matches this tower */ + for (i=0;i<ARRAY_SIZE(transports);i++) { + int j; + if (transports[i].num_protocols != tower->num_floors - 2) { + continue; + } + + for (j = 0; j < transports[i].num_protocols; j++) { + if (transports[i].protseq[j] != tower->floors[j+2].lhs.protocol) { + break; + } + } + + if (j == transports[i].num_protocols) { + return transports[i].transport; + } + } + + /* Unknown transport */ + return (unsigned int)-1; +} + +_PUBLIC_ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, + struct epm_tower *tower, + struct dcerpc_binding **b_out) +{ + NTSTATUS status; + struct dcerpc_binding *binding; + + binding = talloc(mem_ctx, struct dcerpc_binding); + NT_STATUS_HAVE_NO_MEMORY(binding); + + ZERO_STRUCT(binding->object); + binding->options = NULL; + binding->host = NULL; + binding->target_hostname = NULL; + binding->flags = 0; + binding->assoc_group_id = 0; + + binding->transport = dcerpc_transport_by_tower(tower); + + if (binding->transport == (unsigned int)-1) { + return NT_STATUS_NOT_SUPPORTED; + } + + if (tower->num_floors < 1) { + return NT_STATUS_OK; + } + + /* Set object uuid */ + status = dcerpc_floor_get_lhs_data(&tower->floors[0], &binding->object); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Error pulling object uuid and version: %s", nt_errstr(status))); + return status; + } + + /* Ignore floor 1, it contains the NDR version info */ + + binding->options = NULL; + + /* Set endpoint */ + if (tower->num_floors >= 4) { + binding->endpoint = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[3]); + } else { + binding->endpoint = NULL; + } + + /* Set network address */ + if (tower->num_floors >= 5) { + binding->host = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[4]); + NT_STATUS_HAVE_NO_MEMORY(binding->host); + binding->target_hostname = binding->host; + } + *b_out = binding; + return NT_STATUS_OK; +} + +_PUBLIC_ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, struct epm_tower *tower) +{ + const enum epm_protocol *protseq = NULL; + int num_protocols = -1, i; + NTSTATUS status; + + /* Find transport */ + for (i=0;i<ARRAY_SIZE(transports);i++) { + if (transports[i].transport == binding->transport) { + protseq = transports[i].protseq; + num_protocols = transports[i].num_protocols; + break; + } + } + + if (num_protocols == -1) { + DEBUG(0, ("Unable to find transport with id '%d'\n", binding->transport)); + return NT_STATUS_UNSUCCESSFUL; + } + + tower->num_floors = 2 + num_protocols; + tower->floors = talloc_array(mem_ctx, struct epm_floor, tower->num_floors); + + /* Floor 0 */ + tower->floors[0].lhs.protocol = EPM_PROTOCOL_UUID; + + tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, &binding->object); + + tower->floors[0].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2); + + /* Floor 1 */ + tower->floors[1].lhs.protocol = EPM_PROTOCOL_UUID; + + tower->floors[1].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, + &ndr_transfer_syntax); + + tower->floors[1].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2); + + /* Floor 2 to num_protocols */ + for (i = 0; i < num_protocols; i++) { + tower->floors[2 + i].lhs.protocol = protseq[i]; + tower->floors[2 + i].lhs.lhs_data = data_blob_talloc(mem_ctx, NULL, 0); + ZERO_STRUCT(tower->floors[2 + i].rhs); + dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[2 + i], ""); + } + + /* The 4th floor contains the endpoint */ + if (num_protocols >= 2 && binding->endpoint) { + status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[3], binding->endpoint); + if (NT_STATUS_IS_ERR(status)) { + return status; + } + } + + /* The 5th contains the network address */ + if (num_protocols >= 3 && binding->host) { + if (is_ipaddress(binding->host)) { + status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[4], + binding->host); + } else { + /* note that we don't attempt to resolve the + name here - when we get a hostname here we + are in the client code, and want to put in + a wildcard all-zeros IP for the server to + fill in */ + status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[4], + "0.0.0.0"); + } + if (NT_STATUS_IS_ERR(status)) { + return status; + } + } + + return NT_STATUS_OK; +} diff --git a/librpc/tables.pl b/librpc/tables.pl new file mode 100644 index 0000000000..04764f5fa0 --- /dev/null +++ b/librpc/tables.pl @@ -0,0 +1,89 @@ +#!/usr/bin/perl -w + +################################################### +# package to produce a table of all idl parsers +# Copyright tridge@samba.org 2003 +# Copyright jelmer@samba.org 2005 +# released under the GNU GPL + +use strict; + +use Getopt::Long; +use File::Basename; + +my $opt_output = 'librpc/gen_ndr/tables.c'; +my $opt_help = 0; + + +######################################### +# display help text +sub ShowHelp() +{ + print " + perl NDR interface table generator + Copyright (C) tridge\@samba.org + + Usage: tables.pl [options] <idlfile> + + \n"; + exit(0); +} + +# main program +GetOptions ( + 'help|h|?' => \$opt_help, + 'output=s' => \$opt_output, + ); + +if ($opt_help) { + ShowHelp(); + exit(0); +} + +my $init_fns = ""; + +################################### +# extract table entries from 1 file +sub process_file($) +{ + my $filename = shift; + open(FILE, $filename) || die "unable to open $filename\n"; + my $found = 0; + + while (my $line = <FILE>) { + if ($line =~ /extern const struct ndr_interface_table (\w+);/) { + $found = 1; + $init_fns.="\tstatus = ndr_table_register(&$1);\n"; + $init_fns.="\tif (NT_STATUS_IS_ERR(status)) return status;\n\n"; + } + } + + if ($found) { + print "#include \"$filename\"\n"; + } + + close(FILE); +} + +print <<EOF; + +/* Automatically generated by tables.pl. DO NOT EDIT */ + +#include "includes.h" +#include "librpc/ndr/libndr.h" +#include "librpc/ndr/ndr_table.h" +EOF + +process_file($_) foreach (@ARGV); + +print <<EOF; + +NTSTATUS ndr_table_register_builtin_tables(void) +{ + NTSTATUS status; + +$init_fns + + return NT_STATUS_OK; +} +EOF diff --git a/librpc/tools/ndrdump.1.xml b/librpc/tools/ndrdump.1.xml new file mode 100644 index 0000000000..9d66102682 --- /dev/null +++ b/librpc/tools/ndrdump.1.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc"> +<refentry id="ndrdump.1"> + +<refmeta> + <refentrytitle>ndrdump</refentrytitle> + <manvolnum>1</manvolnum> +</refmeta> + + +<refnamediv> + <refname>ndrdump</refname> + <refpurpose>DCE/RPC Packet Parser and Dumper</refpurpose> +</refnamediv> + +<refsynopsisdiv> + <cmdsynopsis> + <command>ndrdump</command> + <arg choice="opt">-c context</arg> + <arg choice="req">pipe</arg> + <arg choice="req">function</arg> + <arg choice="req">in|out</arg> + <arg choice="req">filename</arg> + </cmdsynopsis> + <cmdsynopsis> + <command>ndrdump</command> + <arg choice="opt">pipe</arg> + </cmdsynopsis> + <cmdsynopsis> + <command>ndrdump</command> + </cmdsynopsis> +</refsynopsisdiv> + +<refsect1> + <title>DESCRIPTION</title> + + <para>ndrdump tries to parse the specified <replaceable>filename</replaceable> + using Samba's parser for the specified pipe and function. The + third argument should be + either <emphasis>in</emphasis> or <emphasis>out</emphasis>, depending + on whether the data should be parsed as a request or a reply.</para> + + <para>Running ndrdump without arguments will list the pipes for which + parsers are available.</para> + + <para>Running ndrdump with one argument will list the functions that + Samba can parse for the specified pipe.</para> + + <para>The primary function of ndrdump is debugging Samba's internal + DCE/RPC parsing functions. The file being parsed is usually + one exported by wiresharks <quote>Export selected packet bytes</quote> + function.</para> + + <para>The context argument can be used to load context data from the request + packet when parsing reply packets (such as array lengths).</para> + +</refsect1> + +<refsect1> + <title>VERSION</title> + + <para>This man page is correct for version 4.0 of the Samba suite.</para> +</refsect1> + +<refsect1> + <title>SEE ALSO</title> + + <para>wireshark, pidl</para> + +</refsect1> + +<refsect1> + <title>AUTHOR</title> + + <para>This utility is part of the <ulink url="http://www.samba.org/">Samba</ulink> suite, which is developed by the global <ulink url="http://www.samba.org/samba/team/">Samba Team</ulink>.</para> + + <para>ndrdump was written by Andrew Tridgell. </para> + + <para>This manpage was written by Jelmer Vernooij. </para> + +</refsect1> + +</refentry> diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c new file mode 100644 index 0000000000..69b304dc9c --- /dev/null +++ b/librpc/tools/ndrdump.c @@ -0,0 +1,444 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Jelmer Vernooij 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "system/locale.h" +#include "librpc/ndr/libndr.h" +#include "librpc/ndr/ndr_table.h" +#if (_SAMBA_BUILD_ >= 4) +#include "lib/cmdline/popt_common.h" +#include "param/param.h" +#endif + +static const struct ndr_interface_call *find_function( + const struct ndr_interface_table *p, + const char *function) +{ + int i; + if (isdigit(function[0])) { + i = strtol(function, NULL, 0); + return &p->calls[i]; + } + for (i=0;i<p->num_calls;i++) { + if (strcmp(p->calls[i].name, function) == 0) { + break; + } + } + if (i == p->num_calls) { + printf("Function '%s' not found\n", function); + exit(1); + } + return &p->calls[i]; +} + +_NORETURN_ static void show_pipes(void) +{ + const struct ndr_interface_list *l; + printf("\nYou must specify a pipe\n"); + printf("known pipes are:\n"); + for (l=ndr_table_list();l;l=l->next) { + if(l->table->helpstring) { + printf("\t%s - %s\n", l->table->name, l->table->helpstring); + } else { + printf("\t%s\n", l->table->name); + } + } + exit(1); +} + +_NORETURN_ static void show_functions(const struct ndr_interface_table *p) +{ + int i; + printf("\nYou must specify a function\n"); + printf("known functions on '%s' are:\n", p->name); + for (i=0;i<p->num_calls;i++) { + printf("\t0x%02x (%2d) %s\n", i, i, p->calls[i].name); + } + exit(1); +} + +static char *stdin_load(TALLOC_CTX *mem_ctx, size_t *size) +{ + int num_read, total_len = 0; + char buf[255]; + char *result = NULL; + + while((num_read = read(STDIN_FILENO, buf, 255)) > 0) { + + if (result) { + result = talloc_realloc( + mem_ctx, result, char, total_len + num_read); + } else { + result = talloc_array(mem_ctx, char, num_read); + } + + memcpy(result + total_len, buf, num_read); + + total_len += num_read; + } + + if (size) + *size = total_len; + + return result; +} + +static const struct ndr_interface_table *load_iface_from_plugin(const char *plugin, const char *pipe_name) +{ + const struct ndr_interface_table *p; + void *handle; + char *symbol; + + handle = dlopen(plugin, RTLD_NOW); + if (handle == NULL) { + printf("%s: Unable to open: %s\n", plugin, dlerror()); + return NULL; + } + + symbol = talloc_asprintf(NULL, "ndr_table_%s", pipe_name); + p = (const struct ndr_interface_table *)dlsym(handle, symbol); + + if (!p) { + printf("%s: Unable to find DCE/RPC interface table for '%s': %s\n", plugin, pipe_name, dlerror()); + talloc_free(symbol); + return NULL; + } + + talloc_free(symbol); + + return p; +} + +static void ndrdump_data(uint8_t *d, uint32_t l, bool force) +{ + if (force) { + dump_data(0, d, l); + } else { + dump_data_skip_zeros(0, d, l); + } +} + + int main(int argc, const char *argv[]) +{ + const struct ndr_interface_table *p = NULL; + const struct ndr_interface_call *f; + const char *pipe_name, *function, *inout, *filename; + uint8_t *data; + size_t size; + DATA_BLOB blob; + struct ndr_pull *ndr_pull; + struct ndr_print *ndr_print; + TALLOC_CTX *mem_ctx; + int flags; + poptContext pc; + NTSTATUS status; + enum ndr_err_code ndr_err; + void *st; + void *v_st; + const char *ctx_filename = NULL; + const char *plugin = NULL; + bool validate = false; + bool dumpdata = false; + int opt; + enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO}; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"context-file", 'c', POPT_ARG_STRING, NULL, OPT_CONTEXT_FILE, "In-filename to parse first", "CTX-FILE" }, + {"validate", 0, POPT_ARG_NONE, NULL, OPT_VALIDATE, "try to validate the data", NULL }, + {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMP_DATA, "dump the hex data", NULL }, + {"load-dso", 'l', POPT_ARG_STRING, NULL, OPT_LOAD_DSO, "load from shared object file", NULL }, + POPT_COMMON_SAMBA + POPT_COMMON_VERSION + { NULL } + }; + + ndr_table_init(); + + /* Initialise samba stuff */ + load_case_tables(); + + setlinebuf(stdout); + + dbf = x_stderr; + + setup_logging(argv[0], true); + + pc = poptGetContext("ndrdump", argc, argv, long_options, 0); + + poptSetOtherOptionHelp( + pc, "<pipe|uuid> <function> <inout> [<filename>]"); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case OPT_CONTEXT_FILE: + ctx_filename = poptGetOptArg(pc); + break; + case OPT_VALIDATE: + validate = true; + break; + case OPT_DUMP_DATA: + dumpdata = true; + break; + case OPT_LOAD_DSO: + plugin = poptGetOptArg(pc); + break; + } + } + + pipe_name = poptGetArg(pc); + + if (!pipe_name) { + poptPrintUsage(pc, stderr, 0); + show_pipes(); + exit(1); + } + + if (plugin != NULL) { + p = load_iface_from_plugin(plugin, pipe_name); + } + if (!p) { + p = ndr_table_by_name(pipe_name); + } + + if (!p) { + struct GUID uuid; + + status = GUID_from_string(pipe_name, &uuid); + + if (NT_STATUS_IS_OK(status)) { + p = ndr_table_by_uuid(&uuid); + } + } + + if (!p) { + printf("Unknown pipe or UUID '%s'\n", pipe_name); + exit(1); + } + + function = poptGetArg(pc); + inout = poptGetArg(pc); + filename = poptGetArg(pc); + + if (!function || !inout) { + poptPrintUsage(pc, stderr, 0); + show_functions(p); + exit(1); + } + + if (strcmp(inout, "in") == 0 || + strcmp(inout, "request") == 0) { + flags = NDR_IN; + } else if (strcmp(inout, "out") == 0 || + strcmp(inout, "response") == 0) { + flags = NDR_OUT; + } else { + printf("Bad inout value '%s'\n", inout); + exit(1); + } + + f = find_function(p, function); + + mem_ctx = talloc_init("ndrdump"); + + st = talloc_zero_size(mem_ctx, f->struct_size); + if (!st) { + printf("Unable to allocate %d bytes\n", (int)f->struct_size); + exit(1); + } + + v_st = talloc_zero_size(mem_ctx, f->struct_size); + if (!v_st) { + printf("Unable to allocate %d bytes\n", (int)f->struct_size); + exit(1); + } + + if (ctx_filename) { + if (flags == NDR_IN) { + printf("Context file can only be used for \"out\" packages\n"); + exit(1); + } + + data = (uint8_t *)file_load(ctx_filename, &size, 0, mem_ctx); + if (!data) { + perror(ctx_filename); + exit(1); + } + + blob.data = data; + blob.length = size; + + ndr_pull = ndr_pull_init_blob(&blob, mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); + ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; + + ndr_err = f->ndr_pull(ndr_pull, NDR_IN, st); + + if (ndr_pull->offset != ndr_pull->data_size) { + printf("WARNING! %d unread bytes while parsing context file\n", ndr_pull->data_size - ndr_pull->offset); + } + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + printf("pull for context file returned %s\n", nt_errstr(status)); + exit(1); + } + memcpy(v_st, st, f->struct_size); + } + + if (filename) + data = (uint8_t *)file_load(filename, &size, 0, mem_ctx); + else + data = (uint8_t *)stdin_load(mem_ctx, &size); + + if (!data) { + if (filename) + perror(filename); + else + perror("stdin"); + exit(1); + } + + blob.data = data; + blob.length = size; + + ndr_pull = ndr_pull_init_blob(&blob, mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); + ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; + + ndr_err = f->ndr_pull(ndr_pull, flags, st); + status = ndr_map_error2ntstatus(ndr_err); + + printf("pull returned %s\n", nt_errstr(status)); + + if (ndr_pull->offset != ndr_pull->data_size) { + printf("WARNING! %d unread bytes\n", ndr_pull->data_size - ndr_pull->offset); + ndrdump_data(ndr_pull->data+ndr_pull->offset, + ndr_pull->data_size - ndr_pull->offset, + dumpdata); + } + + if (dumpdata) { + printf("%d bytes consumed\n", ndr_pull->offset); + ndrdump_data(blob.data, blob.length, dumpdata); + } + + ndr_print = talloc_zero(mem_ctx, struct ndr_print); + ndr_print->print = ndr_print_debug_helper; + ndr_print->depth = 1; + f->ndr_print(ndr_print, function, flags, st); + + if (!NT_STATUS_IS_OK(status)) { + printf("dump FAILED\n"); + exit(1); + } + + if (validate) { + DATA_BLOB v_blob; + struct ndr_push *ndr_v_push; + struct ndr_pull *ndr_v_pull; + struct ndr_print *ndr_v_print; + uint32_t i; + uint8_t byte_a, byte_b; + bool differ; + + ndr_v_push = ndr_push_init_ctx(mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); + + ndr_err = f->ndr_push(ndr_v_push, flags, st); + status = ndr_map_error2ntstatus(ndr_err); + printf("push returned %s\n", nt_errstr(status)); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + printf("validate push FAILED\n"); + exit(1); + } + + v_blob = ndr_push_blob(ndr_v_push); + + if (dumpdata) { + printf("%ld bytes generated (validate)\n", (long)v_blob.length); + ndrdump_data(v_blob.data, v_blob.length, dumpdata); + } + + ndr_v_pull = ndr_pull_init_blob(&v_blob, mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); + ndr_v_pull->flags |= LIBNDR_FLAG_REF_ALLOC; + + ndr_err = f->ndr_pull(ndr_v_pull, flags, v_st); + status = ndr_map_error2ntstatus(ndr_err); + printf("pull returned %s\n", nt_errstr(status)); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + printf("validate pull FAILED\n"); + exit(1); + } + + + if (ndr_v_pull->offset != ndr_v_pull->data_size) { + printf("WARNING! %d unread bytes in validation\n", ndr_v_pull->data_size - ndr_v_pull->offset); + ndrdump_data(ndr_v_pull->data+ndr_v_pull->offset, + ndr_v_pull->data_size - ndr_v_pull->offset, + dumpdata); + } + + ndr_v_print = talloc_zero(mem_ctx, struct ndr_print); + ndr_v_print->print = ndr_print_debug_helper; + ndr_v_print->depth = 1; + f->ndr_print(ndr_v_print, function, flags, v_st); + + if (blob.length != v_blob.length) { + printf("WARNING! orig bytes:%llu validated pushed bytes:%llu\n", + (unsigned long long)blob.length, (unsigned long long)v_blob.length); + } + + if (ndr_pull->offset != ndr_v_pull->offset) { + printf("WARNING! orig pulled bytes:%llu validated pulled bytes:%llu\n", + (unsigned long long)ndr_pull->offset, (unsigned long long)ndr_v_pull->offset); + } + + differ = false; + byte_a = 0x00; + byte_b = 0x00; + for (i=0; i < blob.length; i++) { + byte_a = blob.data[i]; + + if (i == v_blob.length) { + byte_b = 0x00; + differ = true; + break; + } + + byte_b = v_blob.data[i]; + + if (byte_a != byte_b) { + differ = true; + break; + } + } + if (differ) { + printf("WARNING! orig and validated differ at byte 0x%02X (%u)\n", i, i); + printf("WARNING! orig byte[0x%02X] = 0x%02X validated byte[0x%02X] = 0x%02X\n", + i, byte_a, i, byte_b); + } + } + + printf("dump OK\n"); + + talloc_free(mem_ctx); + + poptFreeContext(pc); + + return 0; +} |