Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/source4/librpc
Files:
5 added
6 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/librpc/dcerpc.pc.in

    r740 r988  
    88Requires: ndr
    99Version: @PACKAGE_VERSION@
    10 Libs: @LIB_RPATH@ -L${libdir} -ldcerpc
     10Libs: @LIB_RPATH@ -L${libdir} -ldcerpc -ldcerpc-binding
    1111Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1
  • vendor/current/source4/librpc/idl/irpc.idl

    r740 r988  
    11#include "idl_types.h"
    22
    3 import "misc.idl", "security.idl", "nbt.idl", "netlogon.idl";
     3import "misc.idl", "security.idl", "nbt.idl", "netlogon.idl", "server_id.idl";
    44
    55/*
     
    3030        } irpc_header;
    3131
     32        typedef [public] struct {
     33                utf8string name;
     34                uint32 count;
     35                [size_is(count)] server_id ids[*];
     36        } irpc_name_record;
     37
     38        typedef [public] struct {
     39                [size_is(num_records)] irpc_name_record *names[*];
     40                uint32 num_records;
     41        } irpc_name_records;
     42
    3243        /******************************************************
    3344         uptime call - supported by all messaging servers
     
    197208                [in,out,ref] NL_DNS_NAME_INFO_ARRAY *dns_names
    198209                );
     210
     211        /******************************************************
     212         * Management calls for the dns server
     213         ******************************************************/
     214        /**
     215         * Force internal DNS server to reload the DNS zones.
     216         *
     217         * Called when zones are added or deleted through RPC
     218         * or replicated by DRS.
     219         */
     220        NTSTATUS dnssrv_reload_dns_zones();
    199221}
  • vendor/current/source4/librpc/idl/opendb.idl

    r740 r988  
    88*/
    99
    10 import "server_id4.idl";
     10import "server_id.idl";
    1111
    1212[
  • vendor/current/source4/librpc/idl/sasl_helpers.idl

    r414 r988  
    22
    33[
     4  uuid("7512b2f4-5f4f-11e4-bbe6-3c970e8d8226"),
     5  version(1.0),
    46  pointer_default(unique),
    57  helpstring("SASL helpers")
  • vendor/current/source4/librpc/idl/winbind.idl

    r740 r988  
    55#include "idl_types.h"
    66
    7 import "netlogon.idl", "lsa.idl", "security.idl", "idmap.idl";
     7import "netlogon.idl";
    88
    99[
    10   uuid("245f3e6b-3c5d-6e21-3a2d-2a3d645b7221"),
     10  uuid("b875118e-47a3-4210-b5f7-c240cce656b2"),
    1111  version(1.0),
    1212  pointer_default(unique)
     
    1616        typedef [switch_type(uint16)] union netr_LogonLevel netr_LogonLevel;
    1717        typedef [switch_type(uint16)] union netr_Validation netr_Validation;
    18 
    19         /* a call to get runtime informations */
    20         void winbind_information(/* TODO */);
    21 
    22         /*
    23          * a call to trigger some internal events,
    24          * for use in torture tests...
    25          */
    26         NTSTATUS winbind_remote_control(/* TODO */);
    2718
    2819        /*
     
    3728        );
    3829
    39         typedef [v1_enum] enum {
    40                 WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS        = 1,
    41                 WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS        = 2
    42         } winbind_get_idmap_level;
    43 
    44         NTSTATUS winbind_get_idmap(
    45                 [in]     winbind_get_idmap_level level,
    46                 [in]     uint32 count,
    47                 [in,out] [size_is(count)] id_map ids[]
    48         );
    49 
    5030        NTSTATUS winbind_DsrUpdateReadOnlyServerDnsRecords(
    5131                [in,unique] [string,charset(UTF16)] uint16 *site_name,
  • vendor/current/source4/librpc/idl/winsif.idl

    r414 r988  
    77        version(1.0),
    88        helpstring("WINS Administration Interface1"),
     9        helper("../libcli/nbt/libnbt.h"),
    910        pointer_default(unique)
    1011] interface winsif
     
    237238                /*
    238239                 * TODO: fix pidl to handles this completly correct...
    239                  *       currently it gives a warning about a missing pointer
    240                  *       and completely ignores the size_is(80).
     240                 *       currently it gives a warning about a missing pointer.
    241241                 */
    242242                [out,ref,string,charset(DOS),size_is(80)] uint8 *unc_name
  • vendor/current/source4/librpc/idl/winsrepl.idl

    r740 r988  
    1414[
    1515        uuid("915f5653-bac1-431c-97ee-9ffb34526921"),
    16         helpstring("WINS Replication PDUs")
     16        helpstring("WINS Replication PDUs"),
     17        helper("../libcli/nbt/libnbt.h")
    1718] interface wrepl
    1819{
  • vendor/current/source4/librpc/idl/wscript_build

    r740 r988  
    66
    77bld.SAMBA_PIDL_LIST('PIDL',
    8                     source='''irpc.idl nfs4acl.idl s4_notify.idl ntp_signd.idl
    9                               opendb.idl sasl_helpers.idl server_id4.idl winbind.idl
     8                    source='''irpc.idl ntp_signd.idl
     9                              opendb.idl sasl_helpers.idl
    1010                              winsif.idl winsrepl.idl winstation.idl''',
    1111                    options="--includedir=%s --header --ndr-parser --client --python --server" % topinclude,
  • vendor/current/source4/librpc/ndr/py_misc.c

    r740 r988  
    22   Unix SMB/CIFS implementation.
    33   Samba utility functions
     4
    45   Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
    56   
     
    2021#include "librpc/gen_ndr/misc.h"
    2122
    22 #ifndef Py_RETURN_NONE
    23 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    24 #endif
    25 
    2623static int py_GUID_cmp(PyObject *py_self, PyObject *py_other)
    2724{
    2825        int ret;
    29         struct GUID *self = py_talloc_get_ptr(py_self), *other;
    30         other = py_talloc_get_ptr(py_other);
     26        struct GUID *self = pytalloc_get_ptr(py_self), *other;
     27        other = pytalloc_get_ptr(py_other);
    3128        if (other == NULL)
    3229                return -1;
     
    4441static PyObject *py_GUID_str(PyObject *py_self)
    4542{
    46         struct GUID *self = py_talloc_get_ptr(py_self);
     43        struct GUID *self = pytalloc_get_ptr(py_self);
    4744        char *str = GUID_string(NULL, self);
    4845        PyObject *ret = PyString_FromString(str);
     
    5350static PyObject *py_GUID_repr(PyObject *py_self)
    5451{
    55         struct GUID *self = py_talloc_get_ptr(py_self);
     52        struct GUID *self = pytalloc_get_ptr(py_self);
    5653        char *str = GUID_string(NULL, self);
    5754        PyObject *ret = PyString_FromFormat("GUID('%s')", str);
     
    6461        PyObject *str = NULL;
    6562        NTSTATUS status;
    66         struct GUID *guid = py_talloc_get_ptr(self);
     63        struct GUID *guid = pytalloc_get_ptr(self);
    6764        const char *kwnames[] = { "str", NULL };
    6865
     
    103100        char *str = NULL;
    104101        NTSTATUS status;
    105         struct policy_handle *handle = py_talloc_get_ptr(self);
     102        struct policy_handle *handle = pytalloc_get_ptr(self);
    106103        const char *kwnames[] = { "uuid", "type", NULL };
    107104
     
    122119static PyObject *py_policy_handle_repr(PyObject *py_self)
    123120{
    124         struct policy_handle *self = py_talloc_get_ptr(py_self);
     121        struct policy_handle *self = pytalloc_get_ptr(py_self);
    125122        char *uuid_str = GUID_string(NULL, &self->uuid);
    126123        PyObject *ret = PyString_FromFormat("policy_handle(%d, '%s')", self->handle_type, uuid_str);
     
    131128static PyObject *py_policy_handle_str(PyObject *py_self)
    132129{
    133         struct policy_handle *self = py_talloc_get_ptr(py_self);
     130        struct policy_handle *self = pytalloc_get_ptr(py_self);
    134131        char *uuid_str = GUID_string(NULL, &self->uuid);
    135132        PyObject *ret = PyString_FromFormat("%d, %s", self->handle_type, uuid_str);
  • vendor/current/source4/librpc/ndr/py_security.c

    r740 r988  
    22   Unix SMB/CIFS implementation.
    33   Samba utility functions
    4    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
     4
     5   Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010
    56   
    67   This program is free software; you can redistribute it and/or modify
     
    2021#include "libcli/security/security.h"
    2122
    22 #ifndef Py_RETURN_NONE
    23 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    24 #endif
    25 
    2623static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
    2724{
     
    4441static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args)
    4542{
    46         struct dom_sid *self = py_talloc_get_ptr(py_self);
     43        struct dom_sid *self = pytalloc_get_ptr(py_self);
    4744        struct dom_sid *domain_sid;
    4845        TALLOC_CTX *mem_ctx;
     
    6461        }
    6562
    66         py_domain_sid = py_talloc_steal(&dom_sid_Type, domain_sid);
     63        py_domain_sid = pytalloc_steal(&dom_sid_Type, domain_sid);
    6764        talloc_free(mem_ctx);
    6865        return Py_BuildValue("(OI)", py_domain_sid, rid);
     
    7168static int py_dom_sid_cmp(PyObject *py_self, PyObject *py_other)
    7269{
    73         struct dom_sid *self = py_talloc_get_ptr(py_self), *other;
    74         other = py_talloc_get_ptr(py_other);
     70        struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
     71        int val;
     72
     73        other = pytalloc_get_ptr(py_other);
    7574        if (other == NULL)
    7675                return -1;
    7776
    78         return dom_sid_compare(self, other);
     77        val =  dom_sid_compare(self, other);
     78        if (val > 0) {
     79                return 1;
     80        } else if (val < 0) {
     81                return -1;
     82        }
     83        return 0;
    7984}
    8085
    8186static PyObject *py_dom_sid_str(PyObject *py_self)
    8287{
    83         struct dom_sid *self = py_talloc_get_ptr(py_self);
     88        struct dom_sid *self = pytalloc_get_ptr(py_self);
    8489        char *str = dom_sid_string(NULL, self);
    8590        PyObject *ret = PyString_FromString(str);
     
    9095static PyObject *py_dom_sid_repr(PyObject *py_self)
    9196{
    92         struct dom_sid *self = py_talloc_get_ptr(py_self);
     97        struct dom_sid *self = pytalloc_get_ptr(py_self);
    9398        char *str = dom_sid_string(NULL, self);
    9499        PyObject *ret = PyString_FromFormat("dom_sid('%s')", str);
     
    100105{
    101106        char *str = NULL;
    102         struct dom_sid *sid = py_talloc_get_ptr(self);
     107        struct dom_sid *sid = pytalloc_get_ptr(self);
    103108        const char *kwnames[] = { "str", NULL };
    104109
     
    135140static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
    136141{
    137         struct security_descriptor *desc = py_talloc_get_ptr(self);
     142        struct security_descriptor *desc = pytalloc_get_ptr(self);
    138143        NTSTATUS status;
    139144        struct security_ace *ace;
     
    143148                return NULL;
    144149
    145         ace = py_talloc_get_ptr(py_ace);
     150        ace = pytalloc_get_ptr(py_ace);
    146151        status = security_descriptor_sacl_add(desc, ace);
    147152        PyErr_NTSTATUS_IS_ERR_RAISE(status);
     
    151156static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
    152157{
    153         struct security_descriptor *desc = py_talloc_get_ptr(self);
     158        struct security_descriptor *desc = pytalloc_get_ptr(self);
    154159        NTSTATUS status;
    155160        struct security_ace *ace;
     
    159164                return NULL;
    160165
    161         ace = py_talloc_get_ptr(py_ace);
     166        ace = pytalloc_get_ptr(py_ace);
    162167
    163168        status = security_descriptor_dacl_add(desc, ace);
     
    168173static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
    169174{
    170         struct security_descriptor *desc = py_talloc_get_ptr(self);
     175        struct security_descriptor *desc = pytalloc_get_ptr(self);
    171176        NTSTATUS status;
    172177        struct dom_sid *sid;
     
    176181                return NULL;
    177182
    178         sid = py_talloc_get_ptr(py_sid);
     183        sid = pytalloc_get_ptr(py_sid);
    179184        status = security_descriptor_dacl_del(desc, sid);
    180185        PyErr_NTSTATUS_IS_ERR_RAISE(status);
     
    184189static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
    185190{
    186         struct security_descriptor *desc = py_talloc_get_ptr(self);
     191        struct security_descriptor *desc = pytalloc_get_ptr(self);
    187192        NTSTATUS status;
    188193        struct dom_sid *sid;
     
    192197                return NULL;
    193198
    194         sid = py_talloc_get_ptr(py_sid);
     199        sid = pytalloc_get_ptr(py_sid);
    195200        status = security_descriptor_sacl_del(desc, sid);
    196201        PyErr_NTSTATUS_IS_ERR_RAISE(status);
     
    200205static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
    201206{
    202         return py_talloc_steal(self, security_descriptor_initialise(NULL));
     207        return pytalloc_steal(self, security_descriptor_initialise(NULL));
    203208}
    204209
     
    213218                return NULL;
    214219
    215         sid = py_talloc_get_ptr(py_sid);
     220        sid = pytalloc_get_ptr(py_sid);
    216221
    217222        secdesc = sddl_decode(NULL, sddl, sid);
     
    221226        }
    222227
    223         return py_talloc_steal((PyTypeObject *)self, secdesc);
     228        return pytalloc_steal((PyTypeObject *)self, secdesc);
    224229}
    225230
     
    228233        struct dom_sid *sid;
    229234        PyObject *py_sid = Py_None;
    230         struct security_descriptor *desc = py_talloc_get_ptr(self);
     235        struct security_descriptor *desc = pytalloc_get_ptr(self);
    231236        char *text;
    232237        PyObject *ret;
     
    236241
    237242        if (py_sid != Py_None)
    238                 sid = py_talloc_get_ptr(py_sid);
     243                sid = pytalloc_get_ptr(py_sid);
    239244        else
    240245                sid = NULL;
     
    278283        PyObject *py_sid;
    279284        struct dom_sid *sid;
    280         struct security_token *token = py_talloc_get_ptr(self);
     285        struct security_token *token = pytalloc_get_ptr(self);
    281286        if (!PyArg_ParseTuple(args, "O", &py_sid))
    282287                return NULL;
    283288
    284         sid = py_talloc_get_ptr(py_sid);
     289        sid = pytalloc_get_ptr(py_sid);
    285290
    286291        return PyBool_FromLong(security_token_is_sid(token, sid));
     
    291296        PyObject *py_sid;
    292297        struct dom_sid *sid;
    293         struct security_token *token = py_talloc_get_ptr(self);
     298        struct security_token *token = pytalloc_get_ptr(self);
    294299        if (!PyArg_ParseTuple(args, "O", &py_sid))
    295300                return NULL;
    296301
    297         sid = py_talloc_get_ptr(py_sid);
     302        sid = pytalloc_get_ptr(py_sid);
    298303
    299304        return PyBool_FromLong(security_token_has_sid(token, sid));
     
    302307static PyObject *py_token_is_anonymous(PyObject *self)
    303308{
    304         struct security_token *token = py_talloc_get_ptr(self);
     309        struct security_token *token = pytalloc_get_ptr(self);
    305310       
    306311        return PyBool_FromLong(security_token_is_anonymous(token));
     
    309314static PyObject *py_token_is_system(PyObject *self)
    310315{
    311         struct security_token *token = py_talloc_get_ptr(self);
     316        struct security_token *token = pytalloc_get_ptr(self);
    312317       
    313318        return PyBool_FromLong(security_token_is_system(token));
     
    316321static PyObject *py_token_has_builtin_administrators(PyObject *self)
    317322{
    318         struct security_token *token = py_talloc_get_ptr(self);
     323        struct security_token *token = pytalloc_get_ptr(self);
    319324       
    320325        return PyBool_FromLong(security_token_has_builtin_administrators(token));
     
    323328static PyObject *py_token_has_nt_authenticated_users(PyObject *self)
    324329{
    325         struct security_token *token = py_talloc_get_ptr(self);
     330        struct security_token *token = pytalloc_get_ptr(self);
    326331       
    327332        return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
     
    331336{
    332337        int priv;
    333         struct security_token *token = py_talloc_get_ptr(self);
     338        struct security_token *token = pytalloc_get_ptr(self);
    334339
    335340        if (!PyArg_ParseTuple(args, "i", &priv))
     
    342347{
    343348        int priv;
    344         struct security_token *token = py_talloc_get_ptr(self);
     349        struct security_token *token = pytalloc_get_ptr(self);
    345350
    346351        if (!PyArg_ParseTuple(args, "i", &priv))
     
    353358static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
    354359{
    355         return py_talloc_steal(self, security_token_initialise(NULL));
     360        return pytalloc_steal(self, security_token_initialise(NULL));
    356361}       
    357362
     
    415420        sid = dom_sid_parse_talloc(NULL, str);
    416421        talloc_free(str);
    417         ret = py_talloc_steal(&dom_sid_Type, sid);
     422        ret = pytalloc_steal(&dom_sid_Type, sid);
    418423        return ret;
    419424}
  • vendor/current/source4/librpc/ndr/py_xattr.c

    r740 r988  
    1919
    2020#include <Python.h>
    21 
    22 #ifndef Py_RETURN_NONE
    23 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    24 #endif
    2521
    2622static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
     
    6460static PyObject *py_ntacl_print(PyObject *self, PyObject *args)
    6561{
    66         struct xattr_NTACL *ntacl = py_talloc_get_ptr(self);
     62        struct xattr_NTACL *ntacl = pytalloc_get_ptr(self);
    6763        struct ndr_print *pr;
    6864        TALLOC_CTX *mem_ctx;
  • vendor/current/source4/librpc/rpc/dcerpc.c

    r919 r988  
    2222
    2323#include "includes.h"
     24#include "system/filesys.h"
    2425#include "../lib/util/dlinklist.h"
    2526#include "lib/events/events.h"
     
    2829#include "librpc/gen_ndr/ndr_misc.h"
    2930#include "librpc/gen_ndr/ndr_dcerpc.h"
    30 #include "libcli/composite/composite.h"
    3131#include "auth/gensec/gensec.h"
    3232#include "param/param.h"
    3333#include "lib/util/tevent_ntstatus.h"
    3434#include "librpc/rpc/rpc_common.h"
     35#include "lib/tsocket/tsocket.h"
     36#include "libcli/smb/tstream_smbXcli_np.h"
     37
    3538
    3639enum rpc_request_state {
     
    6265        DATA_BLOB request_data;
    6366        bool ignore_timeout;
    64 
    65         /* use by the ndr level async recv call */
    66         struct {
    67                 const struct ndr_interface_table *table;
    68                 uint32_t opnum;
    69                 void *struct_ptr;
    70                 TALLOC_CTX *mem_ctx;
    71         } ndr;
     67        bool wait_for_sync;
     68        bool verify_bitmask1;
     69        bool verify_pcontext;
    7270
    7371        struct {
     
    7775};
    7876
    79 _PUBLIC_ NTSTATUS dcerpc_init(struct loadparm_context *lp_ctx)
    80 {
    81         return gensec_init(lp_ctx);
     77_PUBLIC_ NTSTATUS dcerpc_init(void)
     78{
     79        return gensec_init();
    8280}
    8381
    8482static void dcerpc_connection_dead(struct dcecli_connection *conn, NTSTATUS status);
    85 static void dcerpc_ship_next_request(struct dcecli_connection *c);
    86 
    87 static struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
     83static void dcerpc_schedule_io_trigger(struct dcecli_connection *c);
     84
     85static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx,
     86                                               struct dcerpc_pipe *p,
    8887                                               const struct GUID *object,
    8988                                               uint16_t opnum,
     
    105104                                        ndr_pull_flags_fn_t ndr_pull,
    106105                                        ndr_print_function_t ndr_print);
     106static NTSTATUS dcerpc_shutdown_pipe(struct dcecli_connection *p, NTSTATUS status);
     107static NTSTATUS dcerpc_send_request(struct dcecli_connection *p, DATA_BLOB *data,
     108                             bool trigger_read);
     109static NTSTATUS dcerpc_send_read(struct dcecli_connection *p);
    107110
    108111/* destroy a dcerpc connection */
     
    139142
    140143        c->call_id = 1;
    141         c->security_state.auth_info = NULL;
     144        c->security_state.auth_type = DCERPC_AUTH_TYPE_NONE;
     145        c->security_state.auth_level = DCERPC_AUTH_LEVEL_NONE;
     146        c->security_state.auth_context_id = 0;
    142147        c->security_state.session_key = dcerpc_generic_session_key;
    143148        c->security_state.generic_state = NULL;
    144         c->binding_string = NULL;
    145149        c->flags = 0;
    146         c->srv_max_xmit_frag = 0;
    147         c->srv_max_recv_frag = 0;
     150        /*
     151         * Windows uses 5840 for ncacn_ip_tcp,
     152         * so we also use it (for every transport)
     153         * by default. But we give the transport
     154         * the chance to overwrite it.
     155         */
     156        c->srv_max_xmit_frag = 5840;
     157        c->srv_max_recv_frag = 5840;
    148158        c->pending = NULL;
     159
     160        c->io_trigger = tevent_create_immediate(c);
     161        if (c->io_trigger == NULL) {
     162                talloc_free(c);
     163                return NULL;
     164        }
    149165
    150166        talloc_set_destructor(c, dcerpc_connection_destructor);
     
    166182        }
    167183
     184        if (!hs->p->conn) {
     185                return false;
     186        }
     187
     188        if (hs->p->conn->dead) {
     189                return false;
     190        }
     191
    168192        return true;
    169193}
     
    186210}
    187211
     212static void dcerpc_bh_auth_info(struct dcerpc_binding_handle *h,
     213                                enum dcerpc_AuthType *auth_type,
     214                                enum dcerpc_AuthLevel *auth_level)
     215{
     216        struct dcerpc_bh_state *hs = dcerpc_binding_handle_data(h,
     217                                     struct dcerpc_bh_state);
     218
     219        if (hs->p == NULL) {
     220                return;
     221        }
     222
     223        if (hs->p->conn == NULL) {
     224                return;
     225        }
     226
     227        *auth_type = hs->p->conn->security_state.auth_type;
     228        *auth_level = hs->p->conn->security_state.auth_level;
     229}
     230
    188231struct dcerpc_bh_raw_call_state {
     232        struct tevent_context *ev;
    189233        struct dcerpc_binding_handle *h;
    190234        DATA_BLOB in_data;
     
    216260                return NULL;
    217261        }
     262        state->ev = ev;
    218263        state->h = h;
    219264        state->in_data.data = discard_const_p(uint8_t, in_data);
     
    222267        ok = dcerpc_bh_is_connected(h);
    223268        if (!ok) {
    224                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     269                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    225270                return tevent_req_post(req, ev);
    226271        }
    227272
    228         subreq = dcerpc_request_send(hs->p,
     273        subreq = dcerpc_request_send(state,
     274                                     hs->p,
    229275                                     object,
    230276                                     opnum,
     
    261307                status = dcerpc_fault_to_nt_status(fault_code);
    262308        }
     309
     310        /*
     311         * We trigger the callback in the next event run
     312         * because the code in this file might trigger
     313         * multiple request callbacks from within a single
     314         * while loop.
     315         *
     316         * In order to avoid segfaults from within
     317         * dcerpc_connection_dead() we call
     318         * tevent_req_defer_callback().
     319         */
     320        tevent_req_defer_callback(req, state->ev);
     321
    263322        if (!NT_STATUS_IS_OK(status)) {
    264323                tevent_req_nterror(req, status);
     
    314373        ok = dcerpc_bh_is_connected(h);
    315374        if (!ok) {
    316                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     375                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    317376                return tevent_req_post(req, ev);
    318377        }
     
    427486        for (i=0;i<num_examples;i++) {
    428487                char *name=NULL;
    429                 asprintf(&name, "%s/rpclog/%s-out.%d",
    430                          hs->p->conn->packet_log_dir,
    431                          call->name, i);
    432                 if (name == NULL) {
     488                int ret;
     489
     490                ret = asprintf(&name, "%s/rpclog/%s-out.%d",
     491                               hs->p->conn->packet_log_dir,
     492                               call->name, i);
     493                if (ret == -1) {
    433494                        return;
    434495                }
     
    522583        .is_connected           = dcerpc_bh_is_connected,
    523584        .set_timeout            = dcerpc_bh_set_timeout,
     585        .auth_info              = dcerpc_bh_auth_info,
    524586        .raw_call_send          = dcerpc_bh_raw_call_send,
    525587        .raw_call_recv          = dcerpc_bh_raw_call_recv,
     
    645707        enum ndr_err_code ndr_err;
    646708
    647         ndr = ndr_pull_init_flags(c, blob, mem_ctx);
     709        ndr = ndr_pull_init_blob(blob, mem_ctx);
    648710        if (!ndr) {
    649711                return NT_STATUS_NO_MEMORY;
     
    654716        }
    655717
     718        if (CVAL(blob->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) {
     719                ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
     720        }
     721
    656722        ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
     723        TALLOC_FREE(ndr);
    657724        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    658725                return ndr_map_error2ntstatus(ndr_err);
     
    677744        uint32_t auth_length;
    678745
    679         if (!c->security_state.auth_info ||
    680             !c->security_state.generic_state) {
    681                 return NT_STATUS_OK;
    682         }
    683 
    684         switch (c->security_state.auth_info->auth_level) {
     746        status = dcerpc_verify_ncacn_packet_header(pkt, DCERPC_PKT_RESPONSE,
     747                                        pkt->u.response.stub_and_verifier.length,
     748                                        0, /* required_flags */
     749                                        DCERPC_PFC_FLAG_FIRST |
     750                                        DCERPC_PFC_FLAG_LAST);
     751        if (!NT_STATUS_IS_OK(status)) {
     752                return status;
     753        }
     754
     755        switch (c->security_state.auth_level) {
    685756        case DCERPC_AUTH_LEVEL_PRIVACY:
    686757        case DCERPC_AUTH_LEVEL_INTEGRITY:
     
    717788        pkt->u.response.stub_and_verifier.length -= auth_length;
    718789
     790        if (auth.auth_type != c->security_state.auth_type) {
     791                return NT_STATUS_RPC_PROTOCOL_ERROR;
     792        }
     793
     794        if (auth.auth_level != c->security_state.auth_level) {
     795                return NT_STATUS_RPC_PROTOCOL_ERROR;
     796        }
     797
     798        if (auth.auth_context_id != c->security_state.auth_context_id) {
     799                return NT_STATUS_RPC_PROTOCOL_ERROR;
     800        }
     801
    719802        /* check signature or unseal the packet */
    720         switch (c->security_state.auth_info->auth_level) {
     803        switch (c->security_state.auth_level) {
    721804        case DCERPC_AUTH_LEVEL_PRIVACY:
    722805                status = gensec_unseal_packet(c->security_state.generic_state,
    723                                               mem_ctx,
    724806                                              raw_packet->data + DCERPC_REQUEST_LENGTH,
    725807                                              pkt->u.response.stub_and_verifier.length,
     
    734816        case DCERPC_AUTH_LEVEL_INTEGRITY:
    735817                status = gensec_check_packet(c->security_state.generic_state,
    736                                              mem_ctx,
    737818                                             pkt->u.response.stub_and_verifier.data,
    738819                                             pkt->u.response.stub_and_verifier.length,
     
    776857        enum ndr_err_code ndr_err;
    777858        size_t hdr_size = DCERPC_REQUEST_LENGTH;
    778 
    779         /* non-signed packets are simpler */
    780         if (sig_size == 0) {
    781                 return ncacn_push_auth(blob, mem_ctx, pkt, NULL);
    782         }
    783 
    784         switch (c->security_state.auth_info->auth_level) {
     859        struct dcerpc_auth auth_info = {
     860                .auth_type = c->security_state.auth_type,
     861                .auth_level = c->security_state.auth_level,
     862                .auth_context_id = c->security_state.auth_context_id,
     863        };
     864
     865        switch (c->security_state.auth_level) {
    785866        case DCERPC_AUTH_LEVEL_PRIVACY:
    786867        case DCERPC_AUTH_LEVEL_INTEGRITY:
     868                if (sig_size == 0) {
     869                        return NT_STATUS_INTERNAL_ERROR;
     870                }
    787871                break;
    788872
     
    826910           whole packet, whereas w2k8 wants it relative to the start
    827911           of the stub */
    828         c->security_state.auth_info->auth_pad_length =
    829                 (16 - (pkt->u.request.stub_and_verifier.length & 15)) & 15;
    830         ndr_err = ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length);
     912        auth_info.auth_pad_length =
     913                DCERPC_AUTH_PAD_LENGTH(pkt->u.request.stub_and_verifier.length);
     914        ndr_err = ndr_push_zero(ndr, auth_info.auth_pad_length);
    831915        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    832916                return ndr_map_error2ntstatus(ndr_err);
     
    834918
    835919        payload_length = pkt->u.request.stub_and_verifier.length +
    836                 c->security_state.auth_info->auth_pad_length;
    837 
    838         /* we start without signature, it will appended later */
    839         c->security_state.auth_info->credentials = data_blob(NULL,0);
     920                auth_info.auth_pad_length;
    840921
    841922        /* add the auth verifier */
    842         ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info);
     923        ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, &auth_info);
    843924        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    844925                return ndr_map_error2ntstatus(ndr_err);
     
    858939
    859940        /* sign or seal the packet */
    860         switch (c->security_state.auth_info->auth_level) {
     941        switch (c->security_state.auth_level) {
    861942        case DCERPC_AUTH_LEVEL_PRIVACY:
    862943                status = gensec_seal_packet(c->security_state.generic_state,
     
    898979                        (unsigned) creds2.length,
    899980                        (unsigned) sig_size,
    900                         (unsigned) c->security_state.auth_info->auth_pad_length,
     981                        (unsigned) auth_info.auth_pad_length,
    901982                        (unsigned) pkt->u.request.stub_and_verifier.length));
    902983                dcerpc_set_frag_length(blob, blob->length + creds2.length);
     
    9321013  map a bind nak reason to a NTSTATUS
    9331014*/
    934 static NTSTATUS dcerpc_map_reason(uint16_t reason)
     1015static NTSTATUS dcerpc_map_nak_reason(enum dcerpc_bind_nak_reason reason)
    9351016{
    9361017        switch (reason) {
    937         case DCERPC_BIND_REASON_ASYNTAX:
     1018        case DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED:
     1019                return NT_STATUS_REVISION_MISMATCH;
     1020        case DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE:
     1021                return NT_STATUS_INVALID_PARAMETER;
     1022        default:
     1023                break;
     1024        }
     1025        return NT_STATUS_UNSUCCESSFUL;
     1026}
     1027
     1028static NTSTATUS dcerpc_map_ack_reason(const struct dcerpc_ack_ctx *ack)
     1029{
     1030        if (ack == NULL) {
     1031                return NT_STATUS_RPC_PROTOCOL_ERROR;
     1032        }
     1033
     1034        switch (ack->result) {
     1035        case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
     1036                /*
     1037                 * We have not asked for this...
     1038                 */
     1039                return NT_STATUS_RPC_PROTOCOL_ERROR;
     1040        default:
     1041                break;
     1042        }
     1043
     1044        switch (ack->reason.value) {
     1045        case DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED:
    9381046                return NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX;
    939         case DCERPC_BIND_REASON_INVALID_AUTH_TYPE:
    940                 return NT_STATUS_INVALID_PARAMETER;
     1047        case DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED:
     1048                return NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX;
     1049        default:
     1050                break;
    9411051        }
    9421052        return NT_STATUS_UNSUCCESSFUL;
    943 }
    944 
    945 /*
    946   a bind or alter context has failed
    947 */
    948 static void dcerpc_composite_fail(struct rpc_request *req)
    949 {
    950         struct composite_context *c = talloc_get_type(req->async.private_data,
    951                                                       struct composite_context);
    952         composite_error(c, req->status);
    9531053}
    9541054
     
    9811081        conn->dead = true;
    9821082
    983         if (conn->transport.shutdown_pipe) {
    984                 conn->transport.shutdown_pipe(conn, status);
    985         }
     1083        TALLOC_FREE(conn->io_trigger);
     1084        conn->io_trigger_pending = false;
     1085
     1086        dcerpc_shutdown_pipe(conn, status);
    9861087
    9871088        /* all pending requests get the error */
     
    9961097        }       
    9971098
     1099        /* all requests, which are not shipped */
     1100        while (conn->request_queue) {
     1101                struct rpc_request *req = conn->request_queue;
     1102                dcerpc_req_dequeue(req);
     1103                req->state = RPC_REQUEST_DONE;
     1104                req->status = status;
     1105                if (req->async.callback) {
     1106                        req->async.callback(req);
     1107                }
     1108        }
     1109
    9981110        talloc_set_destructor(conn, NULL);
    9991111        if (conn->free_skipped) {
     
    10181130        struct ncacn_packet pkt;
    10191131
     1132        if (conn->dead) {
     1133                return;
     1134        }
     1135
    10201136        if (NT_STATUS_IS_OK(status) && blob->length == 0) {
    10211137                status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
     
    10351151                data_blob_free(blob);
    10361152                dcerpc_connection_dead(conn, status);
     1153                return;
    10371154        }
    10381155
    10391156        dcerpc_request_recv_data(conn, blob, &pkt);
    1040 }
    1041 
    1042 /*
    1043   Receive a bind reply from the transport
    1044 */
    1045 static void dcerpc_bind_recv_handler(struct rpc_request *req,
    1046                                      DATA_BLOB *raw_packet, struct ncacn_packet *pkt)
    1047 {
    1048         struct composite_context *c;
    1049         struct dcecli_connection *conn;
    1050 
    1051         c = talloc_get_type(req->async.private_data, struct composite_context);
    1052 
    1053         if (pkt->ptype == DCERPC_PKT_BIND_NAK) {
    1054                 DEBUG(2,("dcerpc: bind_nak reason %d\n",
    1055                          pkt->u.bind_nak.reject_reason));
    1056                 composite_error(c, dcerpc_map_reason(pkt->u.bind_nak.
    1057                                                      reject_reason));
    1058                 return;
    1059         }
    1060 
    1061         if ((pkt->ptype != DCERPC_PKT_BIND_ACK) ||
    1062             (pkt->u.bind_ack.num_results == 0) ||
    1063             (pkt->u.bind_ack.ctx_list[0].result != 0)) {
    1064                 req->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
    1065                 composite_error(c, NT_STATUS_NET_WRITE_FAULT);
    1066                 return;
    1067         }
    1068 
    1069         conn = req->p->conn;
    1070 
    1071         conn->srv_max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
    1072         conn->srv_max_recv_frag = pkt->u.bind_ack.max_recv_frag;
    1073 
    1074         if ((req->p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) &&
    1075             (pkt->pfc_flags & DCERPC_PFC_FLAG_CONC_MPX)) {
    1076                 conn->flags |= DCERPC_CONCURRENT_MULTIPLEX;
    1077         }
    1078 
    1079         if ((req->p->binding->flags & DCERPC_HEADER_SIGNING) &&
    1080             (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) {
    1081                 conn->flags |= DCERPC_HEADER_SIGNING;
    1082         }
    1083 
    1084         /* the bind_ack might contain a reply set of credentials */
    1085         if (conn->security_state.auth_info && pkt->auth_length) {
    1086                 NTSTATUS status;
    1087                 uint32_t auth_length;
    1088                 status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.bind_ack.auth_info,
    1089                                                   conn->security_state.auth_info, &auth_length, true);
    1090                 if (!NT_STATUS_IS_OK(status)) {
    1091                         composite_error(c, status);
    1092                         return;
    1093                 }
    1094         }
    1095 
    1096         req->p->assoc_group_id = pkt->u.bind_ack.assoc_group_id;
    1097 
    1098         composite_done(c);
    10991157}
    11001158
     
    11201178}
    11211179
    1122 /*
    1123   send a async dcerpc bind request
    1124 */
    1125 struct composite_context *dcerpc_bind_send(struct dcerpc_pipe *p,
    1126                                            TALLOC_CTX *mem_ctx,
    1127                                            const struct ndr_syntax_id *syntax,
    1128                                            const struct ndr_syntax_id *transfer_syntax)
    1129 {
    1130         struct composite_context *c;
     1180struct dcerpc_bind_state {
     1181        struct tevent_context *ev;
     1182        struct dcerpc_pipe *p;
     1183};
     1184
     1185static void dcerpc_bind_fail_handler(struct rpc_request *subreq);
     1186static void dcerpc_bind_recv_handler(struct rpc_request *subreq,
     1187                                     DATA_BLOB *raw_packet,
     1188                                     struct ncacn_packet *pkt);
     1189
     1190struct tevent_req *dcerpc_bind_send(TALLOC_CTX *mem_ctx,
     1191                                    struct tevent_context *ev,
     1192                                    struct dcerpc_pipe *p,
     1193                                    const struct ndr_syntax_id *syntax,
     1194                                    const struct ndr_syntax_id *transfer_syntax)
     1195{
     1196        struct tevent_req *req;
     1197        struct dcerpc_bind_state *state;
    11311198        struct ncacn_packet pkt;
    11321199        DATA_BLOB blob;
    1133         struct rpc_request *req;
    1134 
    1135         c = composite_create(mem_ctx,p->conn->event_ctx);
    1136         if (c == NULL) return NULL;
    1137 
    1138         c->private_data = p;
     1200        NTSTATUS status;
     1201        struct rpc_request *subreq;
     1202        uint32_t flags;
     1203
     1204        req = tevent_req_create(mem_ctx, &state,
     1205                                struct dcerpc_bind_state);
     1206        if (req == NULL) {
     1207                return NULL;
     1208        }
     1209
     1210        state->ev = ev;
     1211        state->p = p;
    11391212
    11401213        p->syntax = *syntax;
    11411214        p->transfer_syntax = *transfer_syntax;
     1215
     1216        flags = dcerpc_binding_get_flags(p->binding);
    11421217
    11431218        init_ncacn_hdr(p->conn, &pkt);
     
    11481223        pkt.auth_length = 0;
    11491224
    1150         if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) {
     1225        if (flags & DCERPC_CONCURRENT_MULTIPLEX) {
    11511226                pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
    11521227        }
    11531228
    1154         if (p->binding->flags & DCERPC_HEADER_SIGNING) {
     1229        if (p->conn->flags & DCERPC_PROPOSE_HEADER_SIGNING) {
    11551230                pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
    11561231        }
    11571232
    1158         pkt.u.bind.max_xmit_frag = 5840;
    1159         pkt.u.bind.max_recv_frag = 5840;
    1160         pkt.u.bind.assoc_group_id = p->binding->assoc_group_id;
     1233        pkt.u.bind.max_xmit_frag = p->conn->srv_max_xmit_frag;
     1234        pkt.u.bind.max_recv_frag = p->conn->srv_max_recv_frag;
     1235        pkt.u.bind.assoc_group_id = dcerpc_binding_get_assoc_group_id(p->binding);
    11611236        pkt.u.bind.num_contexts = 1;
    11621237        pkt.u.bind.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
    1163         if (composite_nomem(pkt.u.bind.ctx_list, c)) return c;
     1238        if (tevent_req_nomem(pkt.u.bind.ctx_list, req)) {
     1239                return tevent_req_post(req, ev);
     1240        }
    11641241        pkt.u.bind.ctx_list[0].context_id = p->context_id;
    11651242        pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1;
     
    11691246
    11701247        /* construct the NDR form of the packet */
    1171         c->status = ncacn_push_auth(&blob, c, &pkt,
    1172                                     p->conn->security_state.auth_info);
    1173         if (!composite_is_ok(c)) return c;
    1174 
    1175         p->conn->transport.recv_data = dcerpc_recv_data;
     1248        status = ncacn_push_auth(&blob, state, &pkt,
     1249                                 p->conn->security_state.tmp_auth_info.out);
     1250        if (tevent_req_nterror(req, status)) {
     1251                return tevent_req_post(req, ev);
     1252        }
    11761253
    11771254        /*
     
    11791256         * request queue as normal requests
    11801257         */
    1181         req = talloc_zero(c, struct rpc_request);
    1182         if (composite_nomem(req, c)) return c;
    1183 
    1184         req->state = RPC_REQUEST_PENDING;
    1185         req->call_id = pkt.call_id;
    1186         req->async.private_data = c;
    1187         req->async.callback = dcerpc_composite_fail;
    1188         req->p = p;
    1189         req->recv_handler = dcerpc_bind_recv_handler;
    1190         DLIST_ADD_END(p->conn->pending, req, struct rpc_request *);
    1191         talloc_set_destructor(req, dcerpc_req_dequeue);
    1192 
    1193         c->status = p->conn->transport.send_request(p->conn, &blob,
    1194                                                     true);
    1195         if (!composite_is_ok(c)) return c;
    1196 
    1197         event_add_timed(c->event_ctx, req,
    1198                         timeval_current_ofs(DCERPC_REQUEST_TIMEOUT, 0),
    1199                         dcerpc_timeout_handler, req);
    1200 
    1201         return c;
    1202 }
    1203 
    1204 /*
    1205   recv side of async dcerpc bind request
    1206 */
    1207 NTSTATUS dcerpc_bind_recv(struct composite_context *ctx)
    1208 {
    1209         NTSTATUS result = composite_wait(ctx);
    1210         talloc_free(ctx);
    1211         return result;
     1258        subreq = talloc_zero(state, struct rpc_request);
     1259        if (tevent_req_nomem(subreq, req)) {
     1260                return tevent_req_post(req, ev);
     1261        }
     1262
     1263        subreq->state = RPC_REQUEST_PENDING;
     1264        subreq->call_id = pkt.call_id;
     1265        subreq->async.private_data = req;
     1266        subreq->async.callback = dcerpc_bind_fail_handler;
     1267        subreq->p = p;
     1268        subreq->recv_handler = dcerpc_bind_recv_handler;
     1269        DLIST_ADD_END(p->conn->pending, subreq);
     1270        talloc_set_destructor(subreq, dcerpc_req_dequeue);
     1271
     1272        status = dcerpc_send_request(p->conn, &blob, true);
     1273        if (tevent_req_nterror(req, status)) {
     1274                return tevent_req_post(req, ev);
     1275        }
     1276
     1277        tevent_add_timer(ev, subreq,
     1278                         timeval_current_ofs(DCERPC_REQUEST_TIMEOUT, 0),
     1279                         dcerpc_timeout_handler, subreq);
     1280
     1281        return req;
     1282}
     1283
     1284static void dcerpc_bind_fail_handler(struct rpc_request *subreq)
     1285{
     1286        struct tevent_req *req =
     1287                talloc_get_type_abort(subreq->async.private_data,
     1288                struct tevent_req);
     1289        struct dcerpc_bind_state *state =
     1290                tevent_req_data(req,
     1291                struct dcerpc_bind_state);
     1292        NTSTATUS status = subreq->status;
     1293
     1294        TALLOC_FREE(subreq);
     1295
     1296        /*
     1297         * We trigger the callback in the next event run
     1298         * because the code in this file might trigger
     1299         * multiple request callbacks from within a single
     1300         * while loop.
     1301         *
     1302         * In order to avoid segfaults from within
     1303         * dcerpc_connection_dead() we call
     1304         * tevent_req_defer_callback().
     1305         */
     1306        tevent_req_defer_callback(req, state->ev);
     1307
     1308        tevent_req_nterror(req, status);
     1309}
     1310
     1311static void dcerpc_bind_recv_handler(struct rpc_request *subreq,
     1312                                     DATA_BLOB *raw_packet,
     1313                                     struct ncacn_packet *pkt)
     1314{
     1315        struct tevent_req *req =
     1316                talloc_get_type_abort(subreq->async.private_data,
     1317                struct tevent_req);
     1318        struct dcerpc_bind_state *state =
     1319                tevent_req_data(req,
     1320                struct dcerpc_bind_state);
     1321        struct dcecli_connection *conn = state->p->conn;
     1322        struct dcecli_security *sec = &conn->security_state;
     1323        struct dcerpc_binding *b = NULL;
     1324        NTSTATUS status;
     1325        uint32_t flags;
     1326
     1327        /*
     1328         * Note that pkt is allocated under raw_packet->data,
     1329         * while raw_packet->data is a child of subreq.
     1330         */
     1331        talloc_steal(state, raw_packet->data);
     1332        TALLOC_FREE(subreq);
     1333
     1334        /*
     1335         * We trigger the callback in the next event run
     1336         * because the code in this file might trigger
     1337         * multiple request callbacks from within a single
     1338         * while loop.
     1339         *
     1340         * In order to avoid segfaults from within
     1341         * dcerpc_connection_dead() we call
     1342         * tevent_req_defer_callback().
     1343         */
     1344        tevent_req_defer_callback(req, state->ev);
     1345
     1346        if (pkt->ptype == DCERPC_PKT_BIND_NAK) {
     1347                status = dcerpc_map_nak_reason(pkt->u.bind_nak.reject_reason);
     1348
     1349                DEBUG(2,("dcerpc: bind_nak reason %d - %s\n",
     1350                         pkt->u.bind_nak.reject_reason, nt_errstr(status)));
     1351
     1352                tevent_req_nterror(req, status);
     1353                return;
     1354        }
     1355
     1356        status = dcerpc_verify_ncacn_packet_header(pkt,
     1357                                        DCERPC_PKT_BIND_ACK,
     1358                                        pkt->u.bind_ack.auth_info.length,
     1359                                        DCERPC_PFC_FLAG_FIRST |
     1360                                        DCERPC_PFC_FLAG_LAST,
     1361                                        DCERPC_PFC_FLAG_CONC_MPX |
     1362                                        DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
     1363        if (!NT_STATUS_IS_OK(status)) {
     1364                state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
     1365                tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
     1366                return;
     1367        }
     1368
     1369        if (pkt->u.bind_ack.num_results != 1) {
     1370                state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
     1371                tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
     1372                return;
     1373        }
     1374
     1375        if (pkt->u.bind_ack.ctx_list[0].result != 0) {
     1376                status = dcerpc_map_ack_reason(&pkt->u.bind_ack.ctx_list[0]);
     1377                DEBUG(2,("dcerpc: bind_ack failed - reason %d - %s\n",
     1378                         pkt->u.bind_ack.ctx_list[0].reason.value,
     1379                         nt_errstr(status)));
     1380                tevent_req_nterror(req, status);
     1381                return;
     1382        }
     1383
     1384        /*
     1385         * DCE-RPC 1.1 (c706) specifies
     1386         * CONST_MUST_RCV_FRAG_SIZE as 1432
     1387         */
     1388        if (pkt->u.bind_ack.max_xmit_frag < 1432) {
     1389                state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
     1390                tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
     1391                return;
     1392        }
     1393        if (pkt->u.bind_ack.max_recv_frag < 1432) {
     1394                state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
     1395                tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
     1396                return;
     1397        }
     1398        conn->srv_max_xmit_frag = MIN(conn->srv_max_xmit_frag,
     1399                                      pkt->u.bind_ack.max_xmit_frag);
     1400        conn->srv_max_recv_frag = MIN(conn->srv_max_recv_frag,
     1401                                      pkt->u.bind_ack.max_recv_frag);
     1402
     1403        flags = dcerpc_binding_get_flags(state->p->binding);
     1404
     1405        if ((flags & DCERPC_CONCURRENT_MULTIPLEX) &&
     1406            (pkt->pfc_flags & DCERPC_PFC_FLAG_CONC_MPX)) {
     1407                conn->flags |= DCERPC_CONCURRENT_MULTIPLEX;
     1408        }
     1409
     1410        if ((conn->flags & DCERPC_PROPOSE_HEADER_SIGNING) &&
     1411            (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) {
     1412                conn->flags |= DCERPC_HEADER_SIGNING;
     1413        }
     1414
     1415        /* the bind_ack might contain a reply set of credentials */
     1416        if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) {
     1417                uint32_t auth_length;
     1418
     1419                status = dcerpc_pull_auth_trailer(pkt, sec->tmp_auth_info.mem,
     1420                                                  &pkt->u.bind_ack.auth_info,
     1421                                                  sec->tmp_auth_info.in,
     1422                                                  &auth_length, true);
     1423                if (tevent_req_nterror(req, status)) {
     1424                        return;
     1425                }
     1426        }
     1427
     1428        /*
     1429         * We're the owner of the binding, so we're allowed to modify it.
     1430         */
     1431        b = discard_const_p(struct dcerpc_binding, state->p->binding);
     1432        status = dcerpc_binding_set_assoc_group_id(b,
     1433                                                   pkt->u.bind_ack.assoc_group_id);
     1434        if (tevent_req_nterror(req, status)) {
     1435                return;
     1436        }
     1437
     1438        tevent_req_done(req);
     1439}
     1440
     1441NTSTATUS dcerpc_bind_recv(struct tevent_req *req)
     1442{
     1443        return tevent_req_simple_recv_ntstatus(req);
    12121444}
    12131445
     
    12211453        NTSTATUS status;
    12221454        DATA_BLOB blob;
     1455        uint32_t flags;
     1456
     1457        flags = dcerpc_binding_get_flags(p->binding);
    12231458
    12241459        init_ncacn_hdr(p->conn, &pkt);
     
    12301465        pkt.u.auth3.auth_info = data_blob(NULL, 0);
    12311466
    1232         if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) {
     1467        if (flags & DCERPC_CONCURRENT_MULTIPLEX) {
    12331468                pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
    12341469        }
    12351470
    1236         if (p->binding->flags & DCERPC_HEADER_SIGNING) {
    1237                 pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
    1238         }
    1239 
    12401471        /* construct the NDR form of the packet */
    1241         status = ncacn_push_auth(&blob, mem_ctx,
    1242                                  &pkt,
    1243                                  p->conn->security_state.auth_info);
     1472        status = ncacn_push_auth(&blob, mem_ctx, &pkt,
     1473                                 p->conn->security_state.tmp_auth_info.out);
    12441474        if (!NT_STATUS_IS_OK(status)) {
    12451475                return status;
     
    12471477
    12481478        /* send it on its way */
    1249         status = p->conn->transport.send_request(p->conn, &blob, false);
     1479        status = dcerpc_send_request(p->conn, &blob, false);
    12501480        if (!NT_STATUS_IS_OK(status)) {
    12511481                return status;
     
    12771507          info out of step with the server
    12781508        */
    1279         if (c->security_state.auth_info && c->security_state.generic_state &&
    1280             pkt->ptype == DCERPC_PKT_RESPONSE) {
     1509        if (pkt->ptype == DCERPC_PKT_RESPONSE) {
    12811510                status = ncacn_pull_request_auth(c, raw_packet->data, raw_packet, pkt);
    12821511        }
     
    13061535                dcerpc_req_dequeue(req);
    13071536                req->state = RPC_REQUEST_DONE;
     1537
     1538                /*
     1539                 * We have to look at shipping further requests before calling
     1540                 * the async function, that one might close the pipe
     1541                 */
     1542                dcerpc_schedule_io_trigger(c);
     1543
    13081544                req->recv_handler(req, raw_packet, pkt);
    13091545                return;
     
    13111547
    13121548        if (pkt->ptype == DCERPC_PKT_FAULT) {
     1549                status = dcerpc_fault_to_nt_status(pkt->u.fault.status);
    13131550                DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt->u.fault.status)));
     1551                if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
     1552                        dcerpc_connection_dead(c, status);
     1553                        return;
     1554                }
     1555                if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
     1556                        dcerpc_connection_dead(c, status);
     1557                        return;
     1558                }
    13141559                req->fault_code = pkt->u.fault.status;
    13151560                req->status = NT_STATUS_NET_WRITE_FAULT;
     
    13201565                DEBUG(2,("Unexpected packet type %d in dcerpc response\n",
    13211566                         (int)pkt->ptype));
    1322                 req->fault_code = DCERPC_FAULT_OTHER;
    1323                 req->status = NT_STATUS_NET_WRITE_FAULT;
    1324                 goto req_done;
     1567                dcerpc_connection_dead(c, NT_STATUS_RPC_PROTOCOL_ERROR);
     1568                return;
    13251569        }
    13261570
     
    13281572           this request accordingly */
    13291573        if (!NT_STATUS_IS_OK(status)) {
    1330                 req->status = status;
    1331                 goto req_done;
     1574                dcerpc_connection_dead(c, status);
     1575                return;
    13321576        }
    13331577
    13341578        length = pkt->u.response.stub_and_verifier.length;
     1579
     1580        if (req->payload.length + length > DCERPC_NCACN_PAYLOAD_MAX_SIZE) {
     1581                DEBUG(2,("Unexpected total payload 0x%X > 0x%X dcerpc response\n",
     1582                         (unsigned)req->payload.length + length,
     1583                         DCERPC_NCACN_PAYLOAD_MAX_SIZE));
     1584                dcerpc_connection_dead(c, NT_STATUS_RPC_PROTOCOL_ERROR);
     1585                return;
     1586        }
    13351587
    13361588        if (length > 0) {
     
    13491601
    13501602        if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
    1351                 c->transport.send_read(c);
    1352                 return;
     1603                data_blob_free(raw_packet);
     1604                dcerpc_send_read(c);
     1605                return;
     1606        }
     1607
     1608        if (req->verify_bitmask1) {
     1609                req->p->conn->security_state.verified_bitmask1 = true;
     1610        }
     1611        if (req->verify_pcontext) {
     1612                req->p->verified_pcontext = true;
    13531613        }
    13541614
     
    13591619        }
    13601620
    1361 
    13621621req_done:
     1622        data_blob_free(raw_packet);
     1623
    13631624        /* we've got the full payload */
     1625        dcerpc_req_dequeue(req);
    13641626        req->state = RPC_REQUEST_DONE;
    1365         DLIST_REMOVE(c->pending, req);
    1366 
    1367         if (c->request_queue != NULL) {
    1368                 /* We have to look at shipping further requests before calling
    1369                  * the async function, that one might close the pipe */
    1370                 dcerpc_ship_next_request(c);
    1371         }
     1627
     1628        /*
     1629         * We have to look at shipping further requests before calling
     1630         * the async function, that one might close the pipe
     1631         */
     1632        dcerpc_schedule_io_trigger(c);
    13721633
    13731634        if (req->async.callback) {
     
    13751636        }
    13761637}
     1638
     1639static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req);
    13771640
    13781641/*
    13791642  perform the send side of a async dcerpc request
    13801643*/
    1381 static struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
     1644static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx,
     1645                                               struct dcerpc_pipe *p,
    13821646                                               const struct GUID *object,
    13831647                                               uint16_t opnum,
     
    13851649{
    13861650        struct rpc_request *req;
    1387 
    1388         p->conn->transport.recv_data = dcerpc_recv_data;
    1389 
    1390         req = talloc(p, struct rpc_request);
     1651        NTSTATUS status;
     1652
     1653        req = talloc_zero(mem_ctx, struct rpc_request);
    13911654        if (req == NULL) {
    13921655                return NULL;
     
    13951658        req->p = p;
    13961659        req->call_id = next_call_id(p->conn);
    1397         req->status = NT_STATUS_OK;
    13981660        req->state = RPC_REQUEST_QUEUED;
    1399         req->payload = data_blob(NULL, 0);
    1400         req->flags = 0;
    1401         req->fault_code = 0;
    1402         req->ignore_timeout = false;
    1403         req->async.callback = NULL;
    1404         req->async.private_data = NULL;
    1405         req->recv_handler = NULL;
    14061661
    14071662        if (object != NULL) {
     
    14111666                        return NULL;
    14121667                }
    1413         } else {
    1414                 req->object = NULL;
    14151668        }
    14161669
    14171670        req->opnum = opnum;
    14181671        req->request_data.length = stub_data->length;
    1419         req->request_data.data = talloc_reference(req, stub_data->data);
    1420         if (req->request_data.length && req->request_data.data == NULL) {
     1672        req->request_data.data = stub_data->data;
     1673
     1674        status = dcerpc_request_prepare_vt(req);
     1675        if (!NT_STATUS_IS_OK(status)) {
     1676                talloc_free(req);
    14211677                return NULL;
    14221678        }
    14231679
    1424         DLIST_ADD_END(p->conn->request_queue, req, struct rpc_request *);
     1680        DLIST_ADD_END(p->conn->request_queue, req);
    14251681        talloc_set_destructor(req, dcerpc_req_dequeue);
    14261682
    1427         dcerpc_ship_next_request(p->conn);
     1683        dcerpc_schedule_io_trigger(p->conn);
    14281684
    14291685        if (p->request_timeout) {
    1430                 event_add_timed(dcerpc_event_context(p), req,
     1686                tevent_add_timer(p->conn->event_ctx, req,
    14311687                                timeval_current_ofs(p->request_timeout, 0),
    14321688                                dcerpc_timeout_handler, req);
     
    14341690
    14351691        return req;
     1692}
     1693
     1694static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req)
     1695{
     1696        struct dcecli_security *sec = &req->p->conn->security_state;
     1697        struct dcerpc_sec_verification_trailer *t;
     1698        struct dcerpc_sec_vt *c = NULL;
     1699        struct ndr_push *ndr = NULL;
     1700        enum ndr_err_code ndr_err;
     1701
     1702        if (sec->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
     1703                return NT_STATUS_OK;
     1704        }
     1705
     1706        t = talloc_zero(req, struct dcerpc_sec_verification_trailer);
     1707        if (t == NULL) {
     1708                return NT_STATUS_NO_MEMORY;
     1709        }
     1710
     1711        if (!sec->verified_bitmask1) {
     1712                t->commands = talloc_realloc(t, t->commands,
     1713                                             struct dcerpc_sec_vt,
     1714                                             t->count.count + 1);
     1715                if (t->commands == NULL) {
     1716                        return NT_STATUS_NO_MEMORY;
     1717                }
     1718                c = &t->commands[t->count.count++];
     1719                ZERO_STRUCTP(c);
     1720
     1721                c->command = DCERPC_SEC_VT_COMMAND_BITMASK1;
     1722                if (req->p->conn->flags & DCERPC_PROPOSE_HEADER_SIGNING) {
     1723                        c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING;
     1724                }
     1725                req->verify_bitmask1 = true;
     1726        }
     1727
     1728        if (!req->p->verified_pcontext) {
     1729                t->commands = talloc_realloc(t, t->commands,
     1730                                             struct dcerpc_sec_vt,
     1731                                             t->count.count + 1);
     1732                if (t->commands == NULL) {
     1733                        return NT_STATUS_NO_MEMORY;
     1734                }
     1735                c = &t->commands[t->count.count++];
     1736                ZERO_STRUCTP(c);
     1737
     1738                c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT;
     1739                c->u.pcontext.abstract_syntax = req->p->syntax;
     1740                c->u.pcontext.transfer_syntax = req->p->transfer_syntax;
     1741
     1742                req->verify_pcontext = true;
     1743        }
     1744
     1745        if (!(req->p->conn->flags & DCERPC_HEADER_SIGNING)) {
     1746                t->commands = talloc_realloc(t, t->commands,
     1747                                             struct dcerpc_sec_vt,
     1748                                             t->count.count + 1);
     1749                if (t->commands == NULL) {
     1750                        return NT_STATUS_NO_MEMORY;
     1751                }
     1752                c = &t->commands[t->count.count++];
     1753                ZERO_STRUCTP(c);
     1754
     1755                c->command = DCERPC_SEC_VT_COMMAND_HEADER2;
     1756                c->u.header2.ptype = DCERPC_PKT_REQUEST;
     1757                if (req->p->conn->flags & DCERPC_PUSH_BIGENDIAN) {
     1758                        c->u.header2.drep[0] = 0;
     1759                } else {
     1760                        c->u.header2.drep[0] = DCERPC_DREP_LE;
     1761                }
     1762                c->u.header2.drep[1] = 0;
     1763                c->u.header2.drep[2] = 0;
     1764                c->u.header2.drep[3] = 0;
     1765                c->u.header2.call_id = req->call_id;
     1766                c->u.header2.context_id = req->p->context_id;
     1767                c->u.header2.opnum = req->opnum;
     1768        }
     1769
     1770        if (t->count.count == 0) {
     1771                TALLOC_FREE(t);
     1772                return NT_STATUS_OK;
     1773        }
     1774
     1775        c = &t->commands[t->count.count - 1];
     1776        c->command |= DCERPC_SEC_VT_COMMAND_END;
     1777
     1778        if (DEBUGLEVEL >= 10) {
     1779                NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
     1780        }
     1781
     1782        ndr = ndr_push_init_ctx(req);
     1783        if (ndr == NULL) {
     1784                return NT_STATUS_NO_MEMORY;
     1785        }
     1786
     1787        /*
     1788         * for now we just copy and append
     1789         */
     1790
     1791        ndr_err = ndr_push_bytes(ndr, req->request_data.data,
     1792                                 req->request_data.length);
     1793        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1794                return ndr_map_error2ntstatus(ndr_err);
     1795        }
     1796
     1797        ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
     1798                                                NDR_SCALARS | NDR_BUFFERS,
     1799                                                t);
     1800        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1801                return ndr_map_error2ntstatus(ndr_err);
     1802        }
     1803        req->request_data = ndr_push_blob(ndr);
     1804
     1805        return NT_STATUS_OK;
    14361806}
    14371807
     
    14511821        size_t sig_size = 0;
    14521822        bool need_async = false;
     1823        bool can_async = true;
    14531824
    14541825        req = c->request_queue;
     
    14621833        if (c->pending) {
    14631834                need_async = true;
     1835        }
     1836
     1837        if (c->security_state.auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
     1838                can_async = gensec_have_feature(c->security_state.generic_state,
     1839                                                GENSEC_FEATURE_ASYNC_REPLIES);
     1840        }
     1841
     1842        if (need_async && !can_async) {
     1843                req->wait_for_sync = true;
     1844                return;
    14641845        }
    14651846
     
    14761857        chunk_size = p->conn->srv_max_recv_frag;
    14771858        chunk_size -= DCERPC_REQUEST_LENGTH;
    1478         if (c->security_state.auth_info &&
    1479             c->security_state.generic_state) {
     1859        if (c->security_state.auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
     1860                size_t max_payload = chunk_size;
     1861
     1862                max_payload -= DCERPC_AUTH_TRAILER_LENGTH;
     1863                max_payload -= (max_payload % DCERPC_AUTH_PAD_ALIGNMENT);
     1864
    14801865                sig_size = gensec_sig_size(c->security_state.generic_state,
    1481                                            p->conn->srv_max_recv_frag);
     1866                                           max_payload);
    14821867                if (sig_size) {
    14831868                        chunk_size -= DCERPC_AUTH_TRAILER_LENGTH;
     
    14851870                }
    14861871        }
    1487         chunk_size -= (chunk_size % 16);
     1872        chunk_size -= (chunk_size % DCERPC_AUTH_PAD_ALIGNMENT);
    14881873
    14891874        pkt.ptype = DCERPC_PKT_REQUEST;
     
    14911876        pkt.auth_length = 0;
    14921877        pkt.pfc_flags = 0;
    1493         pkt.u.request.alloc_hint = remaining;
    14941878        pkt.u.request.context_id = p->context_id;
    14951879        pkt.u.request.opnum = req->opnum;
     
    15181902                }
    15191903
     1904                pkt.u.request.alloc_hint = remaining;
    15201905                pkt.u.request.stub_and_verifier.data = stub_data->data +
    15211906                        (stub_data->length - remaining);
     
    15331918                }
    15341919
    1535                 req->status = p->conn->transport.send_request(p->conn, &blob, do_trans);
     1920                req->status = dcerpc_send_request(p->conn, &blob, do_trans);
    15361921                if (!NT_STATUS_IS_OK(req->status)) {
    15371922                        req->state = RPC_REQUEST_DONE;
     
    15411926
    15421927                if (last_frag && !do_trans) {
    1543                         req->status = p->conn->transport.send_read(p->conn);
     1928                        req->status = dcerpc_send_read(p->conn);
    15441929                        if (!NT_STATUS_IS_OK(req->status)) {
    15451930                                req->state = RPC_REQUEST_DONE;
     
    15531938}
    15541939
    1555 /*
    1556   return the event context for a dcerpc pipe
    1557   used by callers who wish to operate asynchronously
    1558 */
    1559 _PUBLIC_ struct tevent_context *dcerpc_event_context(struct dcerpc_pipe *p)
    1560 {
    1561         return p->conn->event_ctx;
    1562 }
    1563 
    1564 
     1940static void dcerpc_io_trigger(struct tevent_context *ctx,
     1941                              struct tevent_immediate *im,
     1942                              void *private_data)
     1943{
     1944        struct dcecli_connection *c =
     1945                talloc_get_type_abort(private_data,
     1946                struct dcecli_connection);
     1947
     1948        c->io_trigger_pending = false;
     1949
     1950        dcerpc_schedule_io_trigger(c);
     1951
     1952        dcerpc_ship_next_request(c);
     1953}
     1954
     1955static void dcerpc_schedule_io_trigger(struct dcecli_connection *c)
     1956{
     1957        if (c->dead) {
     1958                return;
     1959        }
     1960
     1961        if (c->request_queue == NULL) {
     1962                return;
     1963        }
     1964
     1965        if (c->request_queue->wait_for_sync && c->pending) {
     1966                return;
     1967        }
     1968
     1969        if (c->io_trigger_pending) {
     1970                return;
     1971        }
     1972
     1973        c->io_trigger_pending = true;
     1974
     1975        tevent_schedule_immediate(c->io_trigger,
     1976                                  c->event_ctx,
     1977                                  dcerpc_io_trigger,
     1978                                  c);
     1979}
    15651980
    15661981/*
     
    15741989
    15751990        while (req->state != RPC_REQUEST_DONE) {
    1576                 struct tevent_context *ctx = dcerpc_event_context(req->p);
    1577                 if (event_loop_once(ctx) != 0) {
     1991                struct tevent_context *ctx = req->p->conn->event_ctx;
     1992                if (tevent_loop_once(ctx) != 0) {
    15781993                        return NT_STATUS_CONNECTION_DISCONNECTED;
    15791994                }
     
    17902205_PUBLIC_ const char *dcerpc_server_name(struct dcerpc_pipe *p)
    17912206{
    1792         if (!p->conn->transport.target_hostname) {
    1793                 if (!p->conn->transport.peer_name) {
    1794                         return "";
    1795                 }
    1796                 return p->conn->transport.peer_name(p->conn);
    1797         }
    1798         return p->conn->transport.target_hostname(p->conn);
     2207        return p->conn ? p->conn->server_name : NULL;
    17992208}
    18002209
     
    18192228}
    18202229
    1821 /*
    1822   Receive an alter reply from the transport
    1823 */
    1824 static void dcerpc_alter_recv_handler(struct rpc_request *req,
    1825                                       DATA_BLOB *raw_packet, struct ncacn_packet *pkt)
    1826 {
    1827         struct composite_context *c;
    1828         struct dcerpc_pipe *recv_pipe;
    1829 
    1830         c = talloc_get_type(req->async.private_data, struct composite_context);
    1831         recv_pipe = talloc_get_type(c->private_data, struct dcerpc_pipe);
    1832 
    1833         if (pkt->ptype == DCERPC_PKT_ALTER_RESP &&
    1834             pkt->u.alter_resp.num_results == 1 &&
    1835             pkt->u.alter_resp.ctx_list[0].result != 0) {
    1836                 DEBUG(2,("dcerpc: alter_resp failed - reason %d\n",
    1837                          pkt->u.alter_resp.ctx_list[0].reason));
    1838                 composite_error(c, dcerpc_map_reason(pkt->u.alter_resp.ctx_list[0].reason));
    1839                 return;
    1840         }
    1841 
    1842         if (pkt->ptype == DCERPC_PKT_FAULT) {
    1843                 DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt->u.fault.status)));
    1844                 recv_pipe->last_fault_code = pkt->u.fault.status;
    1845                 composite_error(c, NT_STATUS_NET_WRITE_FAULT);
    1846                 return;
    1847         }
    1848 
    1849         if (pkt->ptype != DCERPC_PKT_ALTER_RESP ||
    1850             pkt->u.alter_resp.num_results == 0 ||
    1851             pkt->u.alter_resp.ctx_list[0].result != 0) {
    1852                 recv_pipe->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
    1853                 composite_error(c, NT_STATUS_NET_WRITE_FAULT);
    1854                 return;
    1855         }
    1856 
    1857         /* the alter_resp might contain a reply set of credentials */
    1858         if (recv_pipe->conn->security_state.auth_info && pkt->auth_length) {
    1859                 struct dcecli_connection *conn = recv_pipe->conn;
    1860                 NTSTATUS status;
    1861                 uint32_t auth_length;
    1862                 status = dcerpc_pull_auth_trailer(pkt, conn, &pkt->u.alter_resp.auth_info,
    1863                                                   conn->security_state.auth_info, &auth_length, true);
    1864                 if (!NT_STATUS_IS_OK(status)) {
    1865                         composite_error(c, status);
    1866                         return;
    1867                 }
    1868         }
    1869 
    1870         composite_done(c);
    1871 }
    1872 
    1873 /*
    1874    send a dcerpc alter_context request
    1875 */
    1876 struct composite_context *dcerpc_alter_context_send(struct dcerpc_pipe *p,
    1877                                                     TALLOC_CTX *mem_ctx,
    1878                                                     const struct ndr_syntax_id *syntax,
    1879                                                     const struct ndr_syntax_id *transfer_syntax)
    1880 {
    1881         struct composite_context *c;
     2230struct dcerpc_alter_context_state {
     2231        struct tevent_context *ev;
     2232        struct dcerpc_pipe *p;
     2233};
     2234
     2235static void dcerpc_alter_context_fail_handler(struct rpc_request *subreq);
     2236static void dcerpc_alter_context_recv_handler(struct rpc_request *req,
     2237                                              DATA_BLOB *raw_packet,
     2238                                              struct ncacn_packet *pkt);
     2239
     2240struct tevent_req *dcerpc_alter_context_send(TALLOC_CTX *mem_ctx,
     2241                                             struct tevent_context *ev,
     2242                                             struct dcerpc_pipe *p,
     2243                                             const struct ndr_syntax_id *syntax,
     2244                                             const struct ndr_syntax_id *transfer_syntax)
     2245{
     2246        struct tevent_req *req;
     2247        struct dcerpc_alter_context_state *state;
    18822248        struct ncacn_packet pkt;
    18832249        DATA_BLOB blob;
    1884         struct rpc_request *req;
    1885 
    1886         c = composite_create(mem_ctx, p->conn->event_ctx);
    1887         if (c == NULL) return NULL;
    1888 
    1889         c->private_data = p;
     2250        NTSTATUS status;
     2251        struct rpc_request *subreq;
     2252        uint32_t flags;
     2253
     2254        req = tevent_req_create(mem_ctx, &state,
     2255                                struct dcerpc_alter_context_state);
     2256        if (req == NULL) {
     2257                return NULL;
     2258        }
     2259
     2260        state->ev = ev;
     2261        state->p = p;
    18902262
    18912263        p->syntax = *syntax;
    18922264        p->transfer_syntax = *transfer_syntax;
     2265
     2266        flags = dcerpc_binding_get_flags(p->binding);
    18932267
    18942268        init_ncacn_hdr(p->conn, &pkt);
     
    18992273        pkt.auth_length = 0;
    19002274
    1901         if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) {
     2275        if (flags & DCERPC_CONCURRENT_MULTIPLEX) {
    19022276                pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX;
    19032277        }
    19042278
    1905         if (p->binding->flags & DCERPC_HEADER_SIGNING) {
    1906                 pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
    1907         }
    1908 
    1909         pkt.u.alter.max_xmit_frag = 5840;
    1910         pkt.u.alter.max_recv_frag = 5840;
    1911         pkt.u.alter.assoc_group_id = p->binding->assoc_group_id;
     2279        pkt.u.alter.max_xmit_frag = p->conn->srv_max_xmit_frag;
     2280        pkt.u.alter.max_recv_frag = p->conn->srv_max_recv_frag;
     2281        pkt.u.alter.assoc_group_id = dcerpc_binding_get_assoc_group_id(p->binding);
    19122282        pkt.u.alter.num_contexts = 1;
    1913         pkt.u.alter.ctx_list = talloc_array(c, struct dcerpc_ctx_list, 1);
    1914         if (composite_nomem(pkt.u.alter.ctx_list, c)) return c;
     2283        pkt.u.alter.ctx_list = talloc_array(state, struct dcerpc_ctx_list, 1);
     2284        if (tevent_req_nomem(pkt.u.alter.ctx_list, req)) {
     2285                return tevent_req_post(req, ev);
     2286        }
    19152287        pkt.u.alter.ctx_list[0].context_id = p->context_id;
    19162288        pkt.u.alter.ctx_list[0].num_transfer_syntaxes = 1;
     
    19202292
    19212293        /* construct the NDR form of the packet */
    1922         c->status = ncacn_push_auth(&blob, mem_ctx, &pkt,
    1923                                     p->conn->security_state.auth_info);
    1924         if (!composite_is_ok(c)) return c;
    1925 
    1926         p->conn->transport.recv_data = dcerpc_recv_data;
     2294        status = ncacn_push_auth(&blob, state, &pkt,
     2295                                 p->conn->security_state.tmp_auth_info.out);
     2296        if (tevent_req_nterror(req, status)) {
     2297                return tevent_req_post(req, ev);
     2298        }
    19272299
    19282300        /*
     
    19302302         * request queue as normal requests
    19312303         */
    1932         req = talloc_zero(c, struct rpc_request);
    1933         if (composite_nomem(req, c)) return c;
    1934 
    1935         req->state = RPC_REQUEST_PENDING;
    1936         req->call_id = pkt.call_id;
    1937         req->async.private_data = c;
    1938         req->async.callback = dcerpc_composite_fail;
    1939         req->p = p;
    1940         req->recv_handler = dcerpc_alter_recv_handler;
    1941         DLIST_ADD_END(p->conn->pending, req, struct rpc_request *);
    1942         talloc_set_destructor(req, dcerpc_req_dequeue);
    1943 
    1944         c->status = p->conn->transport.send_request(p->conn, &blob, true);
    1945         if (!composite_is_ok(c)) return c;
    1946 
    1947         event_add_timed(c->event_ctx, req,
    1948                         timeval_current_ofs(DCERPC_REQUEST_TIMEOUT, 0),
    1949                         dcerpc_timeout_handler, req);
    1950 
    1951         return c;
    1952 }
    1953 
    1954 NTSTATUS dcerpc_alter_context_recv(struct composite_context *ctx)
    1955 {
    1956         NTSTATUS result = composite_wait(ctx);
    1957         talloc_free(ctx);
    1958         return result;
     2304        subreq = talloc_zero(state, struct rpc_request);
     2305        if (tevent_req_nomem(subreq, req)) {
     2306                return tevent_req_post(req, ev);
     2307        }
     2308
     2309        subreq->state = RPC_REQUEST_PENDING;
     2310        subreq->call_id = pkt.call_id;
     2311        subreq->async.private_data = req;
     2312        subreq->async.callback = dcerpc_alter_context_fail_handler;
     2313        subreq->p = p;
     2314        subreq->recv_handler = dcerpc_alter_context_recv_handler;
     2315        DLIST_ADD_END(p->conn->pending, subreq);
     2316        talloc_set_destructor(subreq, dcerpc_req_dequeue);
     2317
     2318        status = dcerpc_send_request(p->conn, &blob, true);
     2319        if (tevent_req_nterror(req, status)) {
     2320                return tevent_req_post(req, ev);
     2321        }
     2322
     2323        tevent_add_timer(ev, subreq,
     2324                         timeval_current_ofs(DCERPC_REQUEST_TIMEOUT, 0),
     2325                         dcerpc_timeout_handler, subreq);
     2326
     2327        return req;
     2328}
     2329
     2330static void dcerpc_alter_context_fail_handler(struct rpc_request *subreq)
     2331{
     2332        struct tevent_req *req =
     2333                talloc_get_type_abort(subreq->async.private_data,
     2334                struct tevent_req);
     2335        struct dcerpc_alter_context_state *state =
     2336                tevent_req_data(req,
     2337                struct dcerpc_alter_context_state);
     2338        NTSTATUS status = subreq->status;
     2339
     2340        TALLOC_FREE(subreq);
     2341
     2342        /*
     2343         * We trigger the callback in the next event run
     2344         * because the code in this file might trigger
     2345         * multiple request callbacks from within a single
     2346         * while loop.
     2347         *
     2348         * In order to avoid segfaults from within
     2349         * dcerpc_connection_dead() we call
     2350         * tevent_req_defer_callback().
     2351         */
     2352        tevent_req_defer_callback(req, state->ev);
     2353
     2354        tevent_req_nterror(req, status);
     2355}
     2356
     2357static void dcerpc_alter_context_recv_handler(struct rpc_request *subreq,
     2358                                              DATA_BLOB *raw_packet,
     2359                                              struct ncacn_packet *pkt)
     2360{
     2361        struct tevent_req *req =
     2362                talloc_get_type_abort(subreq->async.private_data,
     2363                struct tevent_req);
     2364        struct dcerpc_alter_context_state *state =
     2365                tevent_req_data(req,
     2366                struct dcerpc_alter_context_state);
     2367        struct dcecli_connection *conn = state->p->conn;
     2368        struct dcecli_security *sec = &conn->security_state;
     2369        NTSTATUS status;
     2370
     2371        /*
     2372         * Note that pkt is allocated under raw_packet->data,
     2373         * while raw_packet->data is a child of subreq.
     2374         */
     2375        talloc_steal(state, raw_packet->data);
     2376        TALLOC_FREE(subreq);
     2377
     2378        /*
     2379         * We trigger the callback in the next event run
     2380         * because the code in this file might trigger
     2381         * multiple request callbacks from within a single
     2382         * while loop.
     2383         *
     2384         * In order to avoid segfaults from within
     2385         * dcerpc_connection_dead() we call
     2386         * tevent_req_defer_callback().
     2387         */
     2388        tevent_req_defer_callback(req, state->ev);
     2389
     2390        if (pkt->ptype == DCERPC_PKT_FAULT) {
     2391                DEBUG(5,("dcerpc: alter_resp - rpc fault: %s\n",
     2392                         dcerpc_errstr(state, pkt->u.fault.status)));
     2393                if (pkt->u.fault.status == DCERPC_FAULT_ACCESS_DENIED) {
     2394                        state->p->last_fault_code = pkt->u.fault.status;
     2395                        tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE);
     2396                } else if (pkt->u.fault.status == DCERPC_FAULT_SEC_PKG_ERROR) {
     2397                        state->p->last_fault_code = pkt->u.fault.status;
     2398                        tevent_req_nterror(req, NT_STATUS_LOGON_FAILURE);
     2399                } else {
     2400                        state->p->last_fault_code = pkt->u.fault.status;
     2401                        status = dcerpc_fault_to_nt_status(pkt->u.fault.status);
     2402                        tevent_req_nterror(req, status);
     2403                }
     2404                return;
     2405        }
     2406
     2407        status = dcerpc_verify_ncacn_packet_header(pkt,
     2408                                        DCERPC_PKT_ALTER_RESP,
     2409                                        pkt->u.alter_resp.auth_info.length,
     2410                                        DCERPC_PFC_FLAG_FIRST |
     2411                                        DCERPC_PFC_FLAG_LAST,
     2412                                        DCERPC_PFC_FLAG_CONC_MPX |
     2413                                        DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
     2414        if (!NT_STATUS_IS_OK(status)) {
     2415                state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
     2416                tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
     2417                return;
     2418        }
     2419
     2420        if (pkt->u.alter_resp.num_results != 1) {
     2421                state->p->last_fault_code = DCERPC_NCA_S_PROTO_ERROR;
     2422                tevent_req_nterror(req, NT_STATUS_NET_WRITE_FAULT);
     2423                return;
     2424        }
     2425
     2426        if (pkt->u.alter_resp.ctx_list[0].result != 0) {
     2427                status = dcerpc_map_ack_reason(&pkt->u.alter_resp.ctx_list[0]);
     2428                DEBUG(2,("dcerpc: alter_resp failed - reason %d - %s\n",
     2429                         pkt->u.alter_resp.ctx_list[0].reason.value,
     2430                         nt_errstr(status)));
     2431                tevent_req_nterror(req, status);
     2432                return;
     2433        }
     2434
     2435        /* the alter_resp might contain a reply set of credentials */
     2436        if (pkt->auth_length != 0 && sec->tmp_auth_info.in != NULL) {
     2437                uint32_t auth_length;
     2438
     2439                status = dcerpc_pull_auth_trailer(pkt, sec->tmp_auth_info.mem,
     2440                                                  &pkt->u.alter_resp.auth_info,
     2441                                                  sec->tmp_auth_info.in,
     2442                                                  &auth_length, true);
     2443                if (tevent_req_nterror(req, status)) {
     2444                        return;
     2445                }
     2446        }
     2447
     2448        tevent_req_done(req);
     2449}
     2450
     2451NTSTATUS dcerpc_alter_context_recv(struct tevent_req *req)
     2452{
     2453        return tevent_req_simple_recv_ntstatus(req);
    19592454}
    19602455
     
    19672462                              const struct ndr_syntax_id *transfer_syntax)
    19682463{
    1969         struct composite_context *creq;
    1970         creq = dcerpc_alter_context_send(p, mem_ctx, syntax, transfer_syntax);
    1971         return dcerpc_alter_context_recv(creq);
    1972 }
    1973 
     2464        struct tevent_req *subreq;
     2465        struct tevent_context *ev = p->conn->event_ctx;
     2466        bool ok;
     2467
     2468        /* TODO: create a new event context here */
     2469
     2470        subreq = dcerpc_alter_context_send(mem_ctx, ev,
     2471                                           p, syntax, transfer_syntax);
     2472        if (subreq == NULL) {
     2473                return NT_STATUS_NO_MEMORY;
     2474        }
     2475
     2476        ok = tevent_req_poll(subreq, ev);
     2477        if (!ok) {
     2478                NTSTATUS status;
     2479                status = map_nt_error_from_unix_common(errno);
     2480                return status;
     2481        }
     2482
     2483        return dcerpc_alter_context_recv(subreq);
     2484}
     2485
     2486static void dcerpc_transport_dead(struct dcecli_connection *c, NTSTATUS status)
     2487{
     2488        if (c->transport.stream == NULL) {
     2489                return;
     2490        }
     2491
     2492        tevent_queue_stop(c->transport.write_queue);
     2493        TALLOC_FREE(c->transport.read_subreq);
     2494        TALLOC_FREE(c->transport.stream);
     2495
     2496        if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
     2497                status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
     2498        }
     2499
     2500        if (NT_STATUS_EQUAL(NT_STATUS_OK, status)) {
     2501                status = NT_STATUS_END_OF_FILE;
     2502        }
     2503
     2504        dcerpc_recv_data(c, NULL, status);
     2505}
     2506
     2507
     2508/*
     2509   shutdown SMB pipe connection
     2510*/
     2511struct dcerpc_shutdown_pipe_state {
     2512        struct dcecli_connection *c;
     2513        NTSTATUS status;
     2514};
     2515
     2516static void dcerpc_shutdown_pipe_done(struct tevent_req *subreq);
     2517
     2518static NTSTATUS dcerpc_shutdown_pipe(struct dcecli_connection *c, NTSTATUS status)
     2519{
     2520        struct dcerpc_shutdown_pipe_state *state;
     2521        struct tevent_req *subreq;
     2522
     2523        if (c->transport.stream == NULL) {
     2524                return NT_STATUS_OK;
     2525        }
     2526
     2527        state = talloc_zero(c, struct dcerpc_shutdown_pipe_state);
     2528        if (state == NULL) {
     2529                return NT_STATUS_NO_MEMORY;
     2530        }
     2531        state->c = c;
     2532        state->status = status;
     2533
     2534        subreq = tstream_disconnect_send(state, c->event_ctx, c->transport.stream);
     2535        if (subreq == NULL) {
     2536                return NT_STATUS_NO_MEMORY;
     2537        }
     2538        tevent_req_set_callback(subreq, dcerpc_shutdown_pipe_done, state);
     2539
     2540        return status;
     2541}
     2542
     2543static void dcerpc_shutdown_pipe_done(struct tevent_req *subreq)
     2544{
     2545        struct dcerpc_shutdown_pipe_state *state =
     2546                tevent_req_callback_data(subreq, struct dcerpc_shutdown_pipe_state);
     2547        struct dcecli_connection *c = state->c;
     2548        NTSTATUS status = state->status;
     2549        int error;
     2550
     2551        /*
     2552         * here we ignore the return values...
     2553         */
     2554        tstream_disconnect_recv(subreq, &error);
     2555        TALLOC_FREE(subreq);
     2556
     2557        TALLOC_FREE(state);
     2558
     2559        dcerpc_transport_dead(c, status);
     2560}
     2561
     2562
     2563
     2564struct dcerpc_send_read_state {
     2565        struct dcecli_connection *p;
     2566};
     2567
     2568static int dcerpc_send_read_state_destructor(struct dcerpc_send_read_state *state)
     2569{
     2570        struct dcecli_connection *p = state->p;
     2571
     2572        p->transport.read_subreq = NULL;
     2573
     2574        return 0;
     2575}
     2576
     2577static void dcerpc_send_read_done(struct tevent_req *subreq);
     2578
     2579static NTSTATUS dcerpc_send_read(struct dcecli_connection *p)
     2580{
     2581        struct dcerpc_send_read_state *state;
     2582
     2583        if (p->transport.read_subreq != NULL) {
     2584                p->transport.pending_reads++;
     2585                return NT_STATUS_OK;
     2586        }
     2587
     2588        state = talloc_zero(p, struct dcerpc_send_read_state);
     2589        if (state == NULL) {
     2590                return NT_STATUS_NO_MEMORY;
     2591        }
     2592        state->p = p;
     2593
     2594        talloc_set_destructor(state, dcerpc_send_read_state_destructor);
     2595
     2596        p->transport.read_subreq = dcerpc_read_ncacn_packet_send(state,
     2597                                                          p->event_ctx,
     2598                                                          p->transport.stream);
     2599        if (p->transport.read_subreq == NULL) {
     2600                return NT_STATUS_NO_MEMORY;
     2601        }
     2602        tevent_req_set_callback(p->transport.read_subreq, dcerpc_send_read_done, state);
     2603
     2604        return NT_STATUS_OK;
     2605}
     2606
     2607static void dcerpc_send_read_done(struct tevent_req *subreq)
     2608{
     2609        struct dcerpc_send_read_state *state =
     2610                tevent_req_callback_data(subreq,
     2611                                         struct dcerpc_send_read_state);
     2612        struct dcecli_connection *p = state->p;
     2613        NTSTATUS status;
     2614        struct ncacn_packet *pkt;
     2615        DATA_BLOB blob;
     2616
     2617        status = dcerpc_read_ncacn_packet_recv(subreq, state,
     2618                                               &pkt, &blob);
     2619        TALLOC_FREE(subreq);
     2620        if (!NT_STATUS_IS_OK(status)) {
     2621                TALLOC_FREE(state);
     2622                dcerpc_transport_dead(p, status);
     2623                return;
     2624        }
     2625
     2626        /*
     2627         * here we steal into thet connection context,
     2628         * but p->transport.recv_data() will steal or free it again
     2629         */
     2630        talloc_steal(p, blob.data);
     2631        TALLOC_FREE(state);
     2632
     2633        if (p->transport.pending_reads > 0) {
     2634                p->transport.pending_reads--;
     2635
     2636                status = dcerpc_send_read(p);
     2637                if (!NT_STATUS_IS_OK(status)) {
     2638                        dcerpc_transport_dead(p, status);
     2639                        return;
     2640                }
     2641        }
     2642
     2643        dcerpc_recv_data(p, &blob, NT_STATUS_OK);
     2644}
     2645
     2646struct dcerpc_send_request_state {
     2647        struct dcecli_connection *p;
     2648        DATA_BLOB blob;
     2649        struct iovec iov;
     2650};
     2651
     2652static int dcerpc_send_request_state_destructor(struct dcerpc_send_request_state *state)
     2653{
     2654        struct dcecli_connection *p = state->p;
     2655
     2656        p->transport.read_subreq = NULL;
     2657
     2658        return 0;
     2659}
     2660
     2661static void dcerpc_send_request_wait_done(struct tevent_req *subreq);
     2662static void dcerpc_send_request_done(struct tevent_req *subreq);
     2663
     2664static NTSTATUS dcerpc_send_request(struct dcecli_connection *p, DATA_BLOB *data,
     2665                                    bool trigger_read)
     2666{
     2667        struct dcerpc_send_request_state *state;
     2668        struct tevent_req *subreq;
     2669        bool use_trans = trigger_read;
     2670
     2671        if (p->transport.stream == NULL) {
     2672                return NT_STATUS_CONNECTION_DISCONNECTED;
     2673        }
     2674
     2675        state = talloc_zero(p, struct dcerpc_send_request_state);
     2676        if (state == NULL) {
     2677                return NT_STATUS_NO_MEMORY;
     2678        }
     2679        state->p = p;
     2680
     2681        state->blob = data_blob_talloc(state, data->data, data->length);
     2682        if (state->blob.data == NULL) {
     2683                TALLOC_FREE(state);
     2684                return NT_STATUS_NO_MEMORY;
     2685        }
     2686        state->iov.iov_base = (void *)state->blob.data;
     2687        state->iov.iov_len = state->blob.length;
     2688
     2689        if (p->transport.read_subreq != NULL) {
     2690                use_trans = false;
     2691        }
     2692
     2693        if (!tstream_is_smbXcli_np(p->transport.stream)) {
     2694                use_trans = false;
     2695        }
     2696
     2697        if (use_trans) {
     2698                /*
     2699                 * we need to block reads until our write is
     2700                 * the next in the write queue.
     2701                 */
     2702                p->transport.read_subreq = tevent_queue_wait_send(state, p->event_ctx,
     2703                                                             p->transport.write_queue);
     2704                if (p->transport.read_subreq == NULL) {
     2705                        TALLOC_FREE(state);
     2706                        return NT_STATUS_NO_MEMORY;
     2707                }
     2708                tevent_req_set_callback(p->transport.read_subreq,
     2709                                        dcerpc_send_request_wait_done,
     2710                                        state);
     2711
     2712                talloc_set_destructor(state, dcerpc_send_request_state_destructor);
     2713
     2714                trigger_read = false;
     2715        }
     2716
     2717        subreq = tstream_writev_queue_send(state, p->event_ctx,
     2718                                           p->transport.stream,
     2719                                           p->transport.write_queue,
     2720                                           &state->iov, 1);
     2721        if (subreq == NULL) {
     2722                TALLOC_FREE(state);
     2723                return NT_STATUS_NO_MEMORY;
     2724        }
     2725        tevent_req_set_callback(subreq, dcerpc_send_request_done, state);
     2726
     2727        if (trigger_read) {
     2728                dcerpc_send_read(p);
     2729        }
     2730
     2731        return NT_STATUS_OK;
     2732}
     2733
     2734static void dcerpc_send_request_wait_done(struct tevent_req *subreq)
     2735{
     2736        struct dcerpc_send_request_state *state =
     2737                tevent_req_callback_data(subreq,
     2738                struct dcerpc_send_request_state);
     2739        struct dcecli_connection *p = state->p;
     2740        NTSTATUS status;
     2741        bool ok;
     2742
     2743        p->transport.read_subreq = NULL;
     2744        talloc_set_destructor(state, NULL);
     2745
     2746        ok = tevent_queue_wait_recv(subreq);
     2747        if (!ok) {
     2748                TALLOC_FREE(state);
     2749                dcerpc_transport_dead(p, NT_STATUS_NO_MEMORY);
     2750                return;
     2751        }
     2752
     2753        if (tevent_queue_length(p->transport.write_queue) <= 2) {
     2754                status = tstream_smbXcli_np_use_trans(p->transport.stream);
     2755                if (!NT_STATUS_IS_OK(status)) {
     2756                        TALLOC_FREE(state);
     2757                        dcerpc_transport_dead(p, status);
     2758                        return;
     2759                }
     2760        }
     2761
     2762        /* we free subreq after tstream_cli_np_use_trans */
     2763        TALLOC_FREE(subreq);
     2764
     2765        dcerpc_send_read(p);
     2766}
     2767
     2768static void dcerpc_send_request_done(struct tevent_req *subreq)
     2769{
     2770        struct dcerpc_send_request_state *state =
     2771                tevent_req_callback_data(subreq,
     2772                struct dcerpc_send_request_state);
     2773        int ret;
     2774        int error;
     2775
     2776        ret = tstream_writev_queue_recv(subreq, &error);
     2777        TALLOC_FREE(subreq);
     2778        if (ret == -1) {
     2779                struct dcecli_connection *p = state->p;
     2780                NTSTATUS status = map_nt_error_from_unix_common(error);
     2781
     2782                TALLOC_FREE(state);
     2783                dcerpc_transport_dead(p, status);
     2784                return;
     2785        }
     2786
     2787        TALLOC_FREE(state);
     2788}
  • vendor/current/source4/librpc/rpc/dcerpc.h

    r740 r988  
    3737struct dcerpc_binding_handle;
    3838struct tstream_context;
     39struct ndr_interface_table;
     40struct resolve_context;
    3941
    4042/*
     
    4345struct dcecli_connection;
    4446struct gensec_settings;
     47struct cli_credentials;
    4548struct dcecli_security {
    46         struct dcerpc_auth *auth_info;
     49        enum dcerpc_AuthType auth_type;
     50        enum dcerpc_AuthLevel auth_level;
     51        uint32_t auth_context_id;
     52        struct {
     53                struct dcerpc_auth *out;
     54                struct dcerpc_auth *in;
     55                TALLOC_CTX *mem;
     56        } tmp_auth_info;
    4757        struct gensec_security *generic_state;
    4858
    4959        /* get the session key */
    5060        NTSTATUS (*session_key)(struct dcecli_connection *, DATA_BLOB *);
     61
     62        bool verified_bitmask1;
     63
    5164};
    5265
     
    6174        uint32_t flags;
    6275        struct dcecli_security security_state;
    63         const char *binding_string;
    6476        struct tevent_context *event_ctx;
     77
     78        struct tevent_immediate *io_trigger;
     79        bool io_trigger_pending;
    6580
    6681        /** Directory in which to save ndrdump-parseable files */
     
    7489                void *private_data;
    7590
    76                 NTSTATUS (*shutdown_pipe)(struct dcecli_connection *, NTSTATUS status);
    77 
    78                 const char *(*peer_name)(struct dcecli_connection *);
    79 
    80                 const char *(*target_hostname)(struct dcecli_connection *);
    81 
    82                 /* send a request to the server */
    83                 NTSTATUS (*send_request)(struct dcecli_connection *, DATA_BLOB *, bool trigger_read);
    84 
    85                 /* send a read request to the server */
    86                 NTSTATUS (*send_read)(struct dcecli_connection *);
    87 
    88                 /* a callback to the dcerpc code when a full fragment
    89                    has been received */
    90                 void (*recv_data)(struct dcecli_connection *, DATA_BLOB *, NTSTATUS status);
     91                struct tstream_context *stream;
     92                /** to serialize write events */
     93                struct tevent_queue *write_queue;
     94                /** the current active read request if any */
     95                struct tevent_req *read_subreq;
     96                /** number of read requests other than the current active */
     97                uint32_t pending_reads;
    9198        } transport;
     99
     100        const char *server_name;
    92101
    93102        /* Requests that have been sent, waiting for a reply */
     
    109118        uint32_t context_id;
    110119
    111         uint32_t assoc_group_id;
    112 
    113120        struct ndr_syntax_id syntax;
    114121        struct ndr_syntax_id transfer_syntax;
    115122
    116123        struct dcecli_connection *conn;
    117         struct dcerpc_binding *binding;
     124        const struct dcerpc_binding *binding;
    118125
    119126        /** the last fault code from a DCERPC fault */
     
    122129        /** timeout for individual rpc requests, in seconds */
    123130        uint32_t request_timeout;
     131
     132        /*
     133         * Set for the timeout in dcerpc_pipe_connect_b_send(), to
     134         * allow the timeout not to destory the stack during a nested
     135         * event loop caused by gensec_update()
     136         */
     137        bool inhibit_timeout_processing;
     138        bool timed_out;
     139
     140        bool verified_pcontext;
    124141};
    125142
     
    127144#define DCERPC_REQUEST_TIMEOUT 60
    128145
    129 
    130 struct dcerpc_pipe_connect {
    131         struct dcerpc_pipe *pipe;
    132         struct dcerpc_binding *binding;
    133         const char *pipe_name;
    134         const struct ndr_interface_table *interface;
    135         struct cli_credentials *creds;
    136         struct resolve_context *resolve_ctx;
    137 };
    138 
    139 
    140146struct epm_tower;
    141147struct epm_floor;
     
    143149struct smbcli_tree;
    144150struct smb2_tree;
     151struct smbXcli_conn;
     152struct smbXcli_session;
     153struct smbXcli_tcon;
     154struct roh_connection;
     155struct tstream_tls_params;
    145156struct socket_address;
    146157
     
    157168                              struct smbcli_tree *tree,
    158169                              const char *pipe_name);
     170NTSTATUS dcerpc_pipe_open_smb2(struct dcerpc_pipe *p,
     171                               struct smb2_tree *tree,
     172                               const char *pipe_name);
    159173NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
    160174                               const struct ndr_interface_table *table);
     
    166180
    167181struct composite_context* dcerpc_pipe_connect_b_send(TALLOC_CTX *parent_ctx,
    168                                                      struct dcerpc_binding *binding,
     182                                                     const struct dcerpc_binding *binding,
    169183                                                     const struct ndr_interface_table *table,
    170184                                                     struct cli_credentials *credentials,
     
    177191NTSTATUS dcerpc_pipe_connect_b(TALLOC_CTX *parent_ctx,
    178192                               struct dcerpc_pipe **pp,
    179                                struct dcerpc_binding *binding,
     193                               const struct dcerpc_binding *binding,
    180194                               const struct ndr_interface_table *table,
    181195                               struct cli_credentials *credentials,
     
    185199NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx,
    186200                          struct dcerpc_pipe **p,
    187                           struct dcerpc_binding *binding,
     201                          const struct dcerpc_binding *binding,
    188202                          const struct ndr_interface_table *table,
    189203                          struct cli_credentials *credentials,
     
    191205NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p,
    192206                                     struct dcerpc_pipe **p2,
    193                                      struct dcerpc_binding *b);
     207                                     const struct dcerpc_binding *b);
    194208NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx,
    195209                                   struct dcerpc_pipe *p,
     
    198212                                   struct loadparm_context *lp_ctx,
    199213                                   uint8_t auth_level);
    200 struct tevent_context *dcerpc_event_context(struct dcerpc_pipe *p);
    201 NTSTATUS dcerpc_init(struct loadparm_context *lp_ctx);
    202 struct smbcli_tree *dcerpc_smb_tree(struct dcecli_connection *c);
    203 uint16_t dcerpc_smb_fnum(struct dcecli_connection *c);
     214NTSTATUS dcerpc_init(void);
     215struct composite_context *dcerpc_secondary_smb_send(struct dcecli_connection *c1,
     216                                                    struct dcecli_connection *c2,
     217                                                    const char *pipe_name);
     218NTSTATUS dcerpc_secondary_smb_recv(struct composite_context *c);
    204219NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p,
    205220                                  struct dcerpc_pipe **pp2,
     
    229244                                struct loadparm_context *lp_ctx);
    230245struct composite_context* dcerpc_secondary_auth_connection_send(struct dcerpc_pipe *p,
    231                                                                 struct dcerpc_binding *binding,
     246                                                                const struct dcerpc_binding *binding,
    232247                                                                const struct ndr_interface_table *table,
    233248                                                                struct cli_credentials *credentials,
     
    236251                                               TALLOC_CTX *mem_ctx,
    237252                                               struct dcerpc_pipe **p);
     253NTSTATUS dcerpc_secondary_auth_connection(struct dcerpc_pipe *p,
     254                                        const struct dcerpc_binding *binding,
     255                                        const struct ndr_interface_table *table,
     256                                        struct cli_credentials *credentials,
     257                                        struct loadparm_context *lp_ctx,
     258                                        TALLOC_CTX *mem_ctx,
     259                                        struct dcerpc_pipe **p2);
    238260
    239261struct composite_context* dcerpc_secondary_connection_send(struct dcerpc_pipe *p,
    240                                                            struct dcerpc_binding *b);
     262                                                           const struct dcerpc_binding *b);
    241263void dcerpc_log_packet(const char *lockdir,
    242264                       const struct ndr_interface_table *ndr,
     
    244266                       const DATA_BLOB *pkt);
    245267
    246 
    247 enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot);
    248 
    249 const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor);
    250 
    251268#endif /* __S4_DCERPC_H__ */
  • vendor/current/source4/librpc/rpc/dcerpc.py

    r740 r988  
    1 #!/usr/bin/env python
    2 
    31# Unix SMB/CIFS implementation.
    42# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
    5 #   
     3#
    64# This program is free software; you can redistribute it and/or modify
    75# it under the terms of the GNU General Public License as published by
    86# the Free Software Foundation; either version 3 of the License, or
    97# (at your option) any later version.
    10 #   
     8#
    119# This program is distributed in the hope that it will be useful,
    1210# but WITHOUT ANY WARRANTY; without even the implied warranty of
    1311# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1412# GNU General Public License for more details.
    15 #   
     13#
    1614# You should have received a copy of the GNU General Public License
    1715# along with this program.  If not, see <http://www.gnu.org/licenses/>.
  • vendor/current/source4/librpc/rpc/dcerpc_auth.c

    r740 r988  
    2323
    2424#include "includes.h"
     25#include <tevent.h>
    2526#include "libcli/composite/composite.h"
    2627#include "auth/gensec/gensec.h"
     
    4142
    4243        if (pipe_flags & DCERPC_NDR64) {
    43                 *transfer_syntax = ndr64_transfer_syntax;
     44                *transfer_syntax = ndr_transfer_syntax_ndr64;
    4445        } else {
    45                 *transfer_syntax = ndr_transfer_syntax;
     46                *transfer_syntax = ndr_transfer_syntax_ndr;
    4647        }
    4748
     
    5354  Send request to do a non-authenticated dcerpc bind
    5455*/
     56static void dcerpc_bind_auth_none_done(struct tevent_req *subreq);
     57
    5558struct composite_context *dcerpc_bind_auth_none_send(TALLOC_CTX *mem_ctx,
    5659                                                     struct dcerpc_pipe *p,
     
    6164
    6265        struct composite_context *c;
     66        struct tevent_req *subreq;
    6367
    6468        c = composite_create(mem_ctx, p->conn->event_ctx);
     
    7478        }
    7579
    76         /* c was only allocated as a container for a possible error */
    77         talloc_free(c);
    78 
    79         return dcerpc_bind_send(p, mem_ctx, &syntax, &transfer_syntax);
    80 }
    81 
     80        subreq = dcerpc_bind_send(mem_ctx, p->conn->event_ctx, p,
     81                                  &syntax, &transfer_syntax);
     82        if (composite_nomem(subreq, c)) return c;
     83        tevent_req_set_callback(subreq, dcerpc_bind_auth_none_done, c);
     84
     85        return c;
     86}
     87
     88static void dcerpc_bind_auth_none_done(struct tevent_req *subreq)
     89{
     90        struct composite_context *ctx =
     91                tevent_req_callback_data(subreq,
     92                struct composite_context);
     93
     94        ctx->status = dcerpc_bind_recv(subreq);
     95        TALLOC_FREE(subreq);
     96        if (!composite_is_ok(ctx)) return;
     97
     98        composite_done(ctx);
     99}
    82100
    83101/*
     
    86104NTSTATUS dcerpc_bind_auth_none_recv(struct composite_context *ctx)
    87105{
    88         return dcerpc_bind_recv(ctx);
     106        NTSTATUS result = composite_wait(ctx);
     107        TALLOC_FREE(ctx);
     108        return result;
    89109}
    90110
     
    105125struct bind_auth_state {
    106126        struct dcerpc_pipe *pipe;
    107         DATA_BLOB credentials;
     127        struct dcerpc_auth out_auth_info;
     128        struct dcerpc_auth in_auth_info;
    108129        bool more_processing;   /* Is there anything more to do after the
    109130                                 * first bind itself received? */
    110131};
    111132
    112 static void bind_auth_recv_alter(struct composite_context *creq);
     133static void bind_auth_recv_alter(struct tevent_req *subreq);
    113134
    114135static void bind_auth_next_step(struct composite_context *c)
     
    116137        struct bind_auth_state *state;
    117138        struct dcecli_security *sec;
    118         struct composite_context *creq;
     139        struct tevent_req *subreq;
    119140        bool more_processing = false;
    120141
    121142        state = talloc_get_type(c->private_data, struct bind_auth_state);
    122143        sec = &state->pipe->conn->security_state;
     144
     145        if (state->in_auth_info.auth_type != sec->auth_type) {
     146                composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR);
     147                return;
     148        }
     149
     150        if (state->in_auth_info.auth_level != sec->auth_level) {
     151                composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR);
     152                return;
     153        }
     154
     155        if (state->in_auth_info.auth_context_id != sec->auth_context_id) {
     156                composite_error(c, NT_STATUS_RPC_PROTOCOL_ERROR);
     157                return;
     158        }
     159
     160        state->out_auth_info = (struct dcerpc_auth) {
     161                .auth_type = sec->auth_type,
     162                .auth_level = sec->auth_level,
     163                .auth_context_id = sec->auth_context_id,
     164        };
    123165
    124166        /* The status value here, from GENSEC is vital to the security
     
    132174         */
    133175
    134         c->status = gensec_update(sec->generic_state, state,
    135                                   sec->auth_info->credentials,
    136                                   &state->credentials);
    137         data_blob_free(&sec->auth_info->credentials);
     176        state->pipe->inhibit_timeout_processing = true;
     177        state->pipe->timed_out = false;
     178
     179        c->status = gensec_update_ev(sec->generic_state, state,
     180                                  state->pipe->conn->event_ctx,
     181                                  state->in_auth_info.credentials,
     182                                  &state->out_auth_info.credentials);
     183        if (state->pipe->timed_out) {
     184                composite_error(c, NT_STATUS_IO_TIMEOUT);
     185                return;
     186        }
     187        state->pipe->inhibit_timeout_processing = false;
    138188
    139189        if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     
    144194        if (!composite_is_ok(c)) return;
    145195
    146         if (state->pipe->conn->flags & DCERPC_HEADER_SIGNING) {
    147                 gensec_want_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER);
    148         }
    149 
    150         if (state->credentials.length == 0) {
     196        if (state->out_auth_info.credentials.length == 0) {
    151197                composite_done(c);
    152198                return;
    153199        }
    154200
    155         sec->auth_info->credentials = state->credentials;
     201        state->in_auth_info = (struct dcerpc_auth) {
     202                .auth_type = DCERPC_AUTH_TYPE_NONE,
     203        };
     204        sec->tmp_auth_info.in = &state->in_auth_info;
     205        sec->tmp_auth_info.mem = state;
     206        sec->tmp_auth_info.out = &state->out_auth_info;
    156207
    157208        if (!more_processing) {
    158209                /* NO reply expected, so just send it */
    159210                c->status = dcerpc_auth3(state->pipe, state);
    160                 data_blob_free(&state->credentials);
    161                 sec->auth_info->credentials = data_blob(NULL, 0);
    162211                if (!composite_is_ok(c)) return;
    163212
     
    168217        /* We are demanding a reply, so use a request that will get us one */
    169218
    170         creq = dcerpc_alter_context_send(state->pipe, state,
    171                                          &state->pipe->syntax,
    172                                          &state->pipe->transfer_syntax);
    173         data_blob_free(&state->credentials);
    174         sec->auth_info->credentials = data_blob(NULL, 0);
    175         if (composite_nomem(creq, c)) return;
    176 
    177         composite_continue(c, creq, bind_auth_recv_alter, c);
    178 }
    179 
    180 
    181 static void bind_auth_recv_alter(struct composite_context *creq)
    182 {
    183         struct composite_context *c = talloc_get_type(creq->async.private_data,
    184                                                       struct composite_context);
    185 
    186         c->status = dcerpc_alter_context_recv(creq);
    187         if (!composite_is_ok(c)) return;
    188 
    189         bind_auth_next_step(c);
    190 }
    191 
    192 
    193 static void bind_auth_recv_bindreply(struct composite_context *creq)
    194 {
    195         struct composite_context *c = talloc_get_type(creq->async.private_data,
    196                                                       struct composite_context);
     219        subreq = dcerpc_alter_context_send(state, state->pipe->conn->event_ctx,
     220                                           state->pipe,
     221                                           &state->pipe->syntax,
     222                                           &state->pipe->transfer_syntax);
     223        if (composite_nomem(subreq, c)) return;
     224        tevent_req_set_callback(subreq, bind_auth_recv_alter, c);
     225}
     226
     227
     228static void bind_auth_recv_alter(struct tevent_req *subreq)
     229{
     230        struct composite_context *c =
     231                tevent_req_callback_data(subreq,
     232                struct composite_context);
    197233        struct bind_auth_state *state = talloc_get_type(c->private_data,
    198234                                                        struct bind_auth_state);
    199 
    200         c->status = dcerpc_bind_recv(creq);
     235        struct dcecli_security *sec = &state->pipe->conn->security_state;
     236
     237        ZERO_STRUCT(sec->tmp_auth_info);
     238
     239        c->status = dcerpc_alter_context_recv(subreq);
     240        TALLOC_FREE(subreq);
    201241        if (!composite_is_ok(c)) return;
     242
     243        bind_auth_next_step(c);
     244}
     245
     246
     247static void bind_auth_recv_bindreply(struct tevent_req *subreq)
     248{
     249        struct composite_context *c =
     250                tevent_req_callback_data(subreq,
     251                struct composite_context);
     252        struct bind_auth_state *state = talloc_get_type(c->private_data,
     253                                                        struct bind_auth_state);
     254        struct dcecli_security *sec = &state->pipe->conn->security_state;
     255
     256        ZERO_STRUCT(sec->tmp_auth_info);
     257
     258        c->status = dcerpc_bind_recv(subreq);
     259        TALLOC_FREE(subreq);
     260        if (!composite_is_ok(c)) return;
     261
     262        if (state->pipe->conn->flags & DCERPC_HEADER_SIGNING) {
     263                gensec_want_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER);
     264        }
    202265
    203266        if (!state->more_processing) {
     
    232295                                                const char *service)
    233296{
    234         struct composite_context *c, *creq;
     297        struct composite_context *c;
    235298        struct bind_auth_state *state;
    236299        struct dcecli_security *sec;
    237 
     300        struct tevent_req *subreq;
    238301        struct ndr_syntax_id syntax, transfer_syntax;
     302        const char *target_principal = NULL;
    239303
    240304        /* composite context allocation and setup */
     
    256320
    257321        c->status = gensec_client_start(p, &sec->generic_state,
    258                                         p->conn->event_ctx,
    259322                                        gensec_settings);
    260323        if (!NT_STATUS_IS_OK(c->status)) {
     
    274337
    275338        c->status = gensec_set_target_hostname(sec->generic_state,
    276                                                p->conn->transport.target_hostname(p->conn));
     339                                               dcerpc_server_name(p));
    277340        if (!NT_STATUS_IS_OK(c->status)) {
    278341                DEBUG(1, ("Failed to set GENSEC target hostname: %s\n",
     
    293356        }
    294357
    295         if (p->binding && p->binding->target_principal) {
     358        if (p->binding != NULL) {
     359                target_principal = dcerpc_binding_get_string_option(p->binding,
     360                                                        "target_principal");
     361        }
     362        if (target_principal != NULL) {
    296363                c->status = gensec_set_target_principal(sec->generic_state,
    297                                                         p->binding->target_principal);
     364                                                        target_principal);
    298365                if (!NT_STATUS_IS_OK(c->status)) {
    299366                        DEBUG(1, ("Failed to set GENSEC target principal to %s: %s\n",
    300                                   p->binding->target_principal, nt_errstr(c->status)));
     367                                  target_principal, nt_errstr(c->status)));
    301368                        composite_error(c, c->status);
    302369                        return c;
     
    314381        }
    315382
    316         sec->auth_info = talloc(p, struct dcerpc_auth);
    317         if (composite_nomem(sec->auth_info, c)) return c;
    318 
    319         sec->auth_info->auth_type = auth_type;
    320         sec->auth_info->auth_level = auth_level,
    321         sec->auth_info->auth_pad_length = 0;
    322         sec->auth_info->auth_reserved = 0;
    323         sec->auth_info->auth_context_id = random();
    324         sec->auth_info->credentials = data_blob(NULL, 0);
     383        sec->auth_type = auth_type;
     384        sec->auth_level = auth_level,
     385        /*
     386         * We use auth_context_id = 1 as some older
     387         * Samba versions (<= 4.2.3) use that value hardcoded
     388         * in a response.
     389         */
     390        sec->auth_context_id = 1;
     391
     392        state->out_auth_info = (struct dcerpc_auth) {
     393                .auth_type = sec->auth_type,
     394                .auth_level = sec->auth_level,
     395                .auth_context_id = sec->auth_context_id,
     396        };
    325397
    326398        /* The status value here, from GENSEC is vital to the security
     
    334406         */
    335407
    336         c->status = gensec_update(sec->generic_state, state,
    337                                   sec->auth_info->credentials,
    338                                   &state->credentials);
     408        state->pipe->inhibit_timeout_processing = true;
     409        state->pipe->timed_out = false;
     410        c->status = gensec_update_ev(sec->generic_state, state,
     411                                  p->conn->event_ctx,
     412                                  data_blob_null,
     413                                  &state->out_auth_info.credentials);
     414        if (state->pipe->timed_out) {
     415                composite_error(c, NT_STATUS_IO_TIMEOUT);
     416                return c;
     417        }
     418        state->pipe->inhibit_timeout_processing = false;
     419
    339420        if (!NT_STATUS_IS_OK(c->status) &&
    340421            !NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     
    346427                                                 NT_STATUS_MORE_PROCESSING_REQUIRED);
    347428
    348         if (state->credentials.length == 0) {
     429        if (state->out_auth_info.credentials.length == 0) {
    349430                composite_done(c);
    350431                return c;
    351432        }
    352433
    353         sec->auth_info->credentials = state->credentials;
     434        if (gensec_have_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER)) {
     435                if (sec->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
     436                        state->pipe->conn->flags |= DCERPC_PROPOSE_HEADER_SIGNING;
     437                }
     438        }
     439
     440        state->in_auth_info = (struct dcerpc_auth) {
     441                .auth_type = DCERPC_AUTH_TYPE_NONE,
     442        };
     443        sec->tmp_auth_info.in = &state->in_auth_info;
     444        sec->tmp_auth_info.mem = state;
     445        sec->tmp_auth_info.out = &state->out_auth_info;
    354446
    355447        /* The first request always is a dcerpc_bind. The subsequent ones
    356448         * depend on gensec results */
    357         creq = dcerpc_bind_send(p, state, &syntax, &transfer_syntax);
    358         data_blob_free(&state->credentials);
    359         sec->auth_info->credentials = data_blob(NULL, 0);
    360         if (composite_nomem(creq, c)) return c;
    361 
    362         composite_continue(c, creq, bind_auth_recv_bindreply, c);
     449        subreq = dcerpc_bind_send(state, p->conn->event_ctx, p,
     450                                  &syntax, &transfer_syntax);
     451        if (composite_nomem(subreq, c)) return c;
     452        tevent_req_set_callback(subreq, bind_auth_recv_bindreply, c);
     453
    363454        return c;
    364455}
  • vendor/current/source4/librpc/rpc/dcerpc_connect.c

    r740 r988  
    3030#include "libcli/smb2/smb2.h"
    3131#include "libcli/smb2/smb2_calls.h"
     32#include "libcli/smb/smbXcli_base.h"
    3233#include "librpc/rpc/dcerpc.h"
    3334#include "librpc/rpc/dcerpc_proto.h"
     
    3637#include "libcli/resolve/resolve.h"
    3738
     39struct dcerpc_pipe_connect {
     40        struct dcecli_connection *conn;
     41        struct dcerpc_binding *binding;
     42        const struct ndr_interface_table *interface;
     43        struct cli_credentials *creds;
     44        struct resolve_context *resolve_ctx;
     45        struct {
     46                const char *dir;
     47        } ncalrpc;
     48        struct {
     49                struct smbXcli_conn *conn;
     50                struct smbXcli_session *session;
     51                struct smbXcli_tcon *tcon;
     52                const char *pipe_name;
     53        } smb;
     54};
    3855
    3956struct pipe_np_smb_state {
    4057        struct smb_composite_connect conn;
    41         struct smbcli_tree *tree;
    4258        struct dcerpc_pipe_connect io;
    4359};
     
    5975}
    6076
     77static void continue_smb_open(struct composite_context *c);
    6178
    6279/*
     
    6582static void continue_smb_connect(struct composite_context *ctx)
    6683{
    67         struct composite_context *open_ctx;
    6884        struct composite_context *c = talloc_get_type(ctx->async.private_data,
    6985                                                      struct composite_context);
    7086        struct pipe_np_smb_state *s = talloc_get_type(c->private_data,
    7187                                                      struct pipe_np_smb_state);
    72        
     88        struct smbcli_tree *t;
     89
    7390        /* receive result of smb connect request */
    74         c->status = smb_composite_connect_recv(ctx, c);
    75         if (!composite_is_ok(c)) return;
     91        c->status = smb_composite_connect_recv(ctx, s->io.conn);
     92        if (!composite_is_ok(c)) return;
     93
     94        t = s->conn.out.tree;
    7695
    7796        /* prepare named pipe open parameters */
    78         s->tree         = s->conn.out.tree;
    79         s->io.pipe_name = s->io.binding->endpoint;
     97        s->io.smb.conn = t->session->transport->conn;
     98        s->io.smb.session = t->session->smbXcli;
     99        s->io.smb.tcon = t->smbXcli;
     100        smb1cli_tcon_set_id(s->io.smb.tcon, t->tid);
     101        s->io.smb.pipe_name = dcerpc_binding_get_string_option(s->io.binding,
     102                                                               "endpoint");
     103
     104        continue_smb_open(c);
     105}
     106
     107static void continue_smb_open(struct composite_context *c)
     108{
     109        struct pipe_np_smb_state *s = talloc_get_type(c->private_data,
     110                                                      struct pipe_np_smb_state);
     111        struct composite_context *open_ctx;
    80112
    81113        /* send named pipe open request */
    82         open_ctx = dcerpc_pipe_open_smb_send(s->io.pipe, s->tree, s->io.pipe_name);
     114        open_ctx = dcerpc_pipe_open_smb_send(s->io.conn,
     115                                             s->io.smb.conn,
     116                                             s->io.smb.session,
     117                                             s->io.smb.tcon,
     118                                             DCERPC_REQUEST_TIMEOUT * 1000,
     119                                             s->io.smb.pipe_name);
    83120        if (composite_nomem(open_ctx, c)) return;
    84121
     
    97134        struct composite_context *conn_req;
    98135        struct smb_composite_connect *conn;
     136        uint32_t flags;
    99137
    100138        /* composite context allocation and setup */
    101         c = composite_create(mem_ctx, io->pipe->conn->event_ctx);
     139        c = composite_create(mem_ctx, io->conn->event_ctx);
    102140        if (c == NULL) return NULL;
    103141
     
    109147        conn   = &s->conn;
    110148
     149        if (smbXcli_conn_is_connected(s->io.smb.conn)) {
     150                continue_smb_open(c);
     151                return c;
     152        }
     153
    111154        /* prepare smb connection parameters: we're connecting to IPC$ share on
    112155           remote rpc server */
    113         conn->in.dest_host              = s->io.binding->host;
    114         conn->in.dest_ports                  = lpcfg_smb_ports(lp_ctx);
    115         if (s->io.binding->target_hostname == NULL)
    116                 conn->in.called_name = "*SMBSERVER"; /* FIXME: This is invalid */
    117         else
    118                 conn->in.called_name            = s->io.binding->target_hostname;
     156        conn->in.dest_host = dcerpc_binding_get_string_option(s->io.binding, "host");
     157        conn->in.dest_ports = lpcfg_smb_ports(lp_ctx);
     158        conn->in.called_name =
     159                dcerpc_binding_get_string_option(s->io.binding, "target_hostname");
     160        if (conn->in.called_name == NULL) {
     161                conn->in.called_name = "*SMBSERVER";
     162        }
    119163        conn->in.socket_options         = lpcfg_socket_options(lp_ctx);
    120164        conn->in.service                = "IPC$";
     
    133177         */
    134178        s->conn.in.credentials = s->io.creds;
    135         if (s->io.binding->flags & (DCERPC_SCHANNEL|DCERPC_ANON_FALLBACK)) {
     179        flags = dcerpc_binding_get_flags(s->io.binding);
     180        if (flags & (DCERPC_SCHANNEL|DCERPC_ANON_FALLBACK)) {
    136181                conn->in.fallback_to_anonymous  = true;
    137182        } else {
     
    139184        }
    140185
     186        conn->in.options.min_protocol = PROTOCOL_NT1;
     187        conn->in.options.max_protocol = PROTOCOL_NT1;
     188
     189        conn->in.options.signing = lpcfg_client_ipc_signing(lp_ctx);
     190
    141191        /* send smb connect request */
    142         conn_req = smb_composite_connect_send(conn, s->io.pipe->conn,
     192        conn_req = smb_composite_connect_send(conn, s->io.conn,
    143193                                              s->io.resolve_ctx,
    144                                               s->io.pipe->conn->event_ctx);
     194                                              c->event_ctx);
    145195        if (composite_nomem(conn_req, c)) return c;
    146196
     
    161211}
    162212
    163 
    164 struct pipe_np_smb2_state {
    165         struct smb2_tree *tree;
    166         struct dcerpc_pipe_connect io;
    167 };
    168 
    169 
    170 /*
    171   Stage 3 of ncacn_np_smb: Named pipe opened (or not)
    172 */
    173 static void continue_pipe_open_smb2(struct composite_context *ctx)
    174 {
    175         struct composite_context *c = talloc_get_type(ctx->async.private_data,
    176                                                       struct composite_context);
    177 
    178         /* receive result of named pipe open request on smb2 */
    179         c->status = dcerpc_pipe_open_smb2_recv(ctx);
    180         if (!composite_is_ok(c)) return;
    181 
    182         composite_done(c);
    183 }
    184 
    185 
    186213/*
    187214  Stage 2 of ncacn_np_smb2: Open a named pipe after successful smb2 connection
    188215*/
    189 static void continue_smb2_connect(struct composite_context *ctx)
    190 {
    191         struct composite_context *open_req;
    192         struct composite_context *c = talloc_get_type(ctx->async.private_data,
    193                                                       struct composite_context);
    194         struct pipe_np_smb2_state *s = talloc_get_type(c->private_data,
    195                                                        struct pipe_np_smb2_state);
     216static void continue_smb2_connect(struct tevent_req *subreq)
     217{
     218        struct composite_context *c =
     219                tevent_req_callback_data(subreq,
     220                struct composite_context);
     221        struct pipe_np_smb_state *s = talloc_get_type(c->private_data,
     222                                                      struct pipe_np_smb_state);
     223        struct smb2_tree *t;
    196224
    197225        /* receive result of smb2 connect request */
    198         c->status = smb2_connect_recv(ctx, c, &s->tree);
    199         if (!composite_is_ok(c)) return;
    200 
    201         /* prepare named pipe open parameters */
    202         s->io.pipe_name = s->io.binding->endpoint;
    203 
    204         /* send named pipe open request */
    205         open_req = dcerpc_pipe_open_smb2_send(s->io.pipe, s->tree, s->io.pipe_name);
    206         if (composite_nomem(open_req, c)) return;
    207 
    208         composite_continue(c, open_req, continue_pipe_open_smb2, c);
     226        c->status = smb2_connect_recv(subreq, s->io.conn, &t);
     227        TALLOC_FREE(subreq);
     228        if (!composite_is_ok(c)) return;
     229
     230        s->io.smb.conn = t->session->transport->conn;
     231        s->io.smb.session = t->session->smbXcli;
     232        s->io.smb.tcon = t->smbXcli;
     233        s->io.smb.pipe_name = dcerpc_binding_get_string_option(s->io.binding,
     234                                                               "endpoint");
     235
     236        continue_smb_open(c);
    209237}
    210238
     
    220248{
    221249        struct composite_context *c;
    222         struct pipe_np_smb2_state *s;
    223         struct composite_context *conn_req;
     250        struct pipe_np_smb_state *s;
     251        struct tevent_req *subreq;
    224252        struct smbcli_options options;
     253        const char *host;
     254        uint32_t flags;
    225255
    226256        /* composite context allocation and setup */
    227         c = composite_create(mem_ctx, io->pipe->conn->event_ctx);
     257        c = composite_create(mem_ctx, io->conn->event_ctx);
    228258        if (c == NULL) return NULL;
    229259
    230         s = talloc_zero(c, struct pipe_np_smb2_state);
     260        s = talloc_zero(c, struct pipe_np_smb_state);
    231261        if (composite_nomem(s, c)) return c;
    232262        c->private_data = s;
    233263
    234264        s->io = *io;
     265
     266        if (smbXcli_conn_is_connected(s->io.smb.conn)) {
     267                continue_smb_open(c);
     268                return c;
     269        }
     270
     271        host = dcerpc_binding_get_string_option(s->io.binding, "host");
     272        flags = dcerpc_binding_get_flags(s->io.binding);
    235273
    236274        /*
     
    238276         * schannel connection
    239277         */
    240         if (s->io.binding->flags & DCERPC_SCHANNEL) {
    241                 s->io.creds = cli_credentials_init(mem_ctx);
     278        if (flags & DCERPC_SCHANNEL) {
     279                s->io.creds = cli_credentials_init_anon(mem_ctx);
    242280                if (composite_nomem(s->io.creds, c)) return c;
    243 
    244                 cli_credentials_guess(s->io.creds, lp_ctx);
    245281        }
    246282
    247283        lpcfg_smbcli_options(lp_ctx, &options);
    248284
     285        options.min_protocol = lpcfg_client_ipc_min_protocol(lp_ctx);
     286        if (options.min_protocol < PROTOCOL_SMB2_02) {
     287                options.min_protocol = PROTOCOL_SMB2_02;
     288        }
     289        options.max_protocol = lpcfg_client_ipc_max_protocol(lp_ctx);
     290        if (options.max_protocol < PROTOCOL_SMB2_02) {
     291                options.max_protocol = PROTOCOL_SMB2_02;
     292        }
     293
     294        options.signing = lpcfg_client_ipc_signing(lp_ctx);
     295
    249296        /* send smb2 connect request */
    250         conn_req = smb2_connect_send(mem_ctx, s->io.binding->host,
     297        subreq = smb2_connect_send(s, c->event_ctx,
     298                        host,
    251299                        lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "smb2", "ports", NULL),
    252                                         "IPC$",
    253                                      s->io.resolve_ctx,
    254                                      s->io.creds,
    255                                      c->event_ctx,
    256                                      &options,
    257                                          lpcfg_socket_options(lp_ctx),
    258                                          lpcfg_gensec_settings(mem_ctx, lp_ctx)
    259                                          );
    260         composite_continue(c, conn_req, continue_smb2_connect, c);
     300                        "IPC$",
     301                        s->io.resolve_ctx,
     302                        s->io.creds,
     303                        0, /* previous_session_id */
     304                        &options,
     305                        lpcfg_socket_options(lp_ctx),
     306                        lpcfg_gensec_settings(mem_ctx, lp_ctx));
     307        if (composite_nomem(subreq, c)) return c;
     308        tevent_req_set_callback(subreq, continue_smb2_connect, c);
    261309        return c;
    262310}
     
    291339        struct composite_context *c = talloc_get_type(ctx->async.private_data,
    292340                                                      struct composite_context);
     341        struct pipe_ip_tcp_state *s = talloc_get_type(c->private_data,
     342                                                      struct pipe_ip_tcp_state);
     343        char *localaddr = NULL;
     344        char *remoteaddr = NULL;
    293345
    294346        /* receive result of named pipe open request on tcp/ip */
    295         c->status = dcerpc_pipe_open_tcp_recv(ctx);
     347        c->status = dcerpc_pipe_open_tcp_recv(ctx, s, &localaddr, &remoteaddr);
     348        if (!composite_is_ok(c)) return;
     349
     350        c->status = dcerpc_binding_set_string_option(s->io.binding,
     351                                                     "localaddress",
     352                                                     localaddr);
     353        if (!composite_is_ok(c)) return;
     354
     355        c->status = dcerpc_binding_set_string_option(s->io.binding,
     356                                                     "host",
     357                                                     remoteaddr);
    296358        if (!composite_is_ok(c)) return;
    297359
     
    310372        struct pipe_ip_tcp_state *s;
    311373        struct composite_context *pipe_req;
     374        const char *endpoint;
    312375
    313376        /* composite context allocation and setup */
    314         c = composite_create(mem_ctx, io->pipe->conn->event_ctx);
     377        c = composite_create(mem_ctx, io->conn->event_ctx);
    315378        if (c == NULL) return NULL;
    316379
     
    320383
    321384        /* store input parameters in state structure */
    322         s->io               = *io;
    323         s->localaddr        = talloc_reference(c, io->binding->localaddress);
    324         s->host             = talloc_reference(c, io->binding->host);
    325         s->target_hostname  = talloc_reference(c, io->binding->target_hostname);
    326                              /* port number is a binding endpoint here */
    327         s->port             = atoi(io->binding->endpoint);   
     385        s->io = *io;
     386        s->localaddr = dcerpc_binding_get_string_option(io->binding,
     387                                                        "localaddress");
     388        s->host = dcerpc_binding_get_string_option(io->binding, "host");
     389        s->target_hostname = dcerpc_binding_get_string_option(io->binding,
     390                                                              "target_hostname");
     391        endpoint = dcerpc_binding_get_string_option(io->binding, "endpoint");
     392        /* port number is a binding endpoint here */
     393        if (endpoint != NULL) {
     394                s->port = atoi(endpoint);
     395        }
     396
     397        if (s->port == 0) {
     398                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     399                return c;
     400        }
    328401
    329402        /* send pipe open request on tcp/ip */
    330         pipe_req = dcerpc_pipe_open_tcp_send(s->io.pipe->conn, s->localaddr, s->host, s->target_hostname,
     403        pipe_req = dcerpc_pipe_open_tcp_send(s->io.conn, s->localaddr, s->host, s->target_hostname,
    331404                                             s->port, io->resolve_ctx);
    332405        composite_continue(c, pipe_req, continue_pipe_open_ncacn_ip_tcp, c);
     
    347420
    348421
     422struct pipe_http_state {
     423        struct dcerpc_pipe_connect io;
     424        const char *localaddr;
     425        const char *rpc_server;
     426        uint32_t rpc_server_port;
     427        char *rpc_proxy;
     428        uint32_t rpc_proxy_port;
     429        char *http_proxy;
     430        uint32_t http_proxy_port;
     431        bool use_tls;
     432        bool use_proxy;
     433        bool use_ntlm;
     434        struct loadparm_context *lp_ctx;
     435};
     436
     437/*
     438  Stage 2 of ncacn_http: rpc pipe opened (or not)
     439 */
     440static void continue_pipe_open_ncacn_http(struct tevent_req *subreq)
     441{
     442        struct composite_context *c = NULL;
     443        struct pipe_http_state *s = NULL;
     444        struct tstream_context *stream = NULL;
     445        struct tevent_queue *queue = NULL;
     446
     447        c = tevent_req_callback_data(subreq, struct composite_context);
     448        s = talloc_get_type(c->private_data, struct pipe_http_state);
     449
     450        /* receive result of RoH connect request */
     451        c->status = dcerpc_pipe_open_roh_recv(subreq, s->io.conn,
     452                                              &stream, &queue);
     453        TALLOC_FREE(subreq);
     454        if (!composite_is_ok(c)) return;
     455
     456        s->io.conn->transport.transport = NCACN_HTTP;
     457        s->io.conn->transport.stream = stream;
     458        s->io.conn->transport.write_queue = queue;
     459        s->io.conn->transport.pending_reads = 0;
     460
     461        composite_done(c);
     462}
     463
     464/*
     465  Initiate async open of a rpc connection to a rpc pipe using HTTP transport,
     466  and using the binding structure to determine the endpoint and options
     467*/
     468static struct composite_context* dcerpc_pipe_connect_ncacn_http_send(
     469                TALLOC_CTX *mem_ctx, struct dcerpc_pipe_connect *io,
     470                struct loadparm_context *lp_ctx)
     471{
     472        struct composite_context *c;
     473        struct pipe_http_state *s;
     474        struct tevent_req *subreq;
     475        const char *endpoint;
     476        const char *use_proxy;
     477        char *proxy;
     478        char *port;
     479        const char *opt;
     480
     481        /* composite context allocation and setup */
     482        c = composite_create(mem_ctx, io->conn->event_ctx);
     483        if (c == NULL) return NULL;
     484
     485        s = talloc_zero(c, struct pipe_http_state);
     486        if (composite_nomem(s, c)) return c;
     487        c->private_data = s;
     488
     489        /* store input parameters in state structure */
     490        s->lp_ctx       = lp_ctx;
     491        s->io           = *io;
     492        s->localaddr    = dcerpc_binding_get_string_option(io->binding,
     493                                                        "localaddress");
     494        /* RPC server and port (the endpoint) */
     495        s->rpc_server = dcerpc_binding_get_string_option(io->binding, "host");
     496        endpoint = dcerpc_binding_get_string_option(io->binding, "endpoint");
     497        if (endpoint == NULL) {
     498                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     499                return c;
     500        }
     501        s->rpc_server_port = atoi(endpoint);
     502        if (s->rpc_server_port == 0) {
     503                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     504                return c;
     505        }
     506
     507        /* Use TLS */
     508        opt = dcerpc_binding_get_string_option(io->binding, "HttpUseTls");
     509        if (opt) {
     510                if (strcasecmp(opt, "true") == 0) {
     511                        s->use_tls = true;
     512                } else if (strcasecmp(opt, "false") == 0) {
     513                        s->use_tls = false;
     514                } else {
     515                        composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     516                        return c;
     517                }
     518        } else {
     519                s->use_tls = true;
     520        }
     521
     522        /* RPC Proxy */
     523        proxy = port = talloc_strdup(s, dcerpc_binding_get_string_option(
     524                        io->binding, "RpcProxy"));
     525        s->rpc_proxy  = strsep(&port, ":");
     526        if (proxy && port) {
     527                s->rpc_proxy_port = atoi(port);
     528        } else {
     529                s->rpc_proxy_port = s->use_tls ? 443 : 80;
     530        }
     531        if (s->rpc_proxy == NULL) {
     532                s->rpc_proxy = talloc_strdup(s, s->rpc_server);
     533                if (composite_nomem(s->rpc_proxy, c)) return c;
     534        }
     535
     536        /* HTTP Proxy */
     537        proxy = port = talloc_strdup(s, dcerpc_binding_get_string_option(
     538                        io->binding, "HttpProxy"));
     539        s->http_proxy = strsep(&port, ":");
     540        if (proxy && port) {
     541                s->http_proxy_port = atoi(port);
     542        } else {
     543                s->http_proxy_port = s->use_tls ? 443 : 80;
     544        }
     545
     546        /* Use local proxy */
     547        use_proxy = dcerpc_binding_get_string_option(io->binding,
     548                                                 "HttpConnectOption");
     549        if (use_proxy && strcasecmp(use_proxy, "UseHttpProxy")) {
     550                s->use_proxy = true;
     551        }
     552
     553        /* If use local proxy set, the http proxy should be provided */
     554        if (s->use_proxy && !s->http_proxy) {
     555                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     556                return c;
     557        }
     558
     559        /* Check which HTTP authentication method to use */
     560        opt = dcerpc_binding_get_string_option(io->binding, "HttpAuthOption");
     561        if (opt) {
     562                if (strcasecmp(opt, "basic") == 0) {
     563                        s->use_ntlm = false;
     564                } else if (strcasecmp(opt, "ntlm") == 0) {
     565                        s->use_ntlm = true;
     566                } else {
     567                        composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     568                        return c;
     569                }
     570        } else {
     571                s->use_ntlm = true;
     572        }
     573
     574        subreq = dcerpc_pipe_open_roh_send(s->io.conn, s->localaddr,
     575                                           s->rpc_server, s->rpc_server_port,
     576                                           s->rpc_proxy, s->rpc_proxy_port,
     577                                           s->http_proxy, s->http_proxy_port,
     578                                           s->use_tls, s->use_proxy,
     579                                           s->io.creds, io->resolve_ctx,
     580                                           s->lp_ctx, s->use_ntlm);
     581        if (composite_nomem(subreq, c)) return c;
     582
     583        tevent_req_set_callback(subreq, continue_pipe_open_ncacn_http, c);
     584        return c;
     585}
     586
     587static NTSTATUS dcerpc_pipe_connect_ncacn_http_recv(struct composite_context *c)
     588{
     589        return composite_wait_free(c);
     590}
     591
     592
    349593struct pipe_unix_state {
    350594        struct dcerpc_pipe_connect io;
     
    381625
    382626        /* composite context allocation and setup */
    383         c = composite_create(mem_ctx, io->pipe->conn->event_ctx);
     627        c = composite_create(mem_ctx, io->conn->event_ctx);
    384628        if (c == NULL) return NULL;
    385629
     
    391635           also, verify whether biding endpoint is not null */
    392636        s->io = *io;
    393        
    394         if (!io->binding->endpoint) {
    395                 DEBUG(0, ("Path to unix socket not specified\n"));
    396                 composite_error(c, NT_STATUS_INVALID_PARAMETER);
     637
     638        s->path = dcerpc_binding_get_string_option(io->binding, "endpoint");
     639        if (s->path == NULL) {
     640                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
    397641                return c;
    398642        }
    399643
    400         s->path  = talloc_strdup(c, io->binding->endpoint);  /* path is a binding endpoint here */
    401         if (composite_nomem(s->path, c)) return c;
    402 
    403644        /* send pipe open request on unix socket */
    404         pipe_req = dcerpc_pipe_open_unix_stream_send(s->io.pipe->conn, s->path);
     645        pipe_req = dcerpc_pipe_open_unix_stream_send(s->io.conn, s->path);
    405646        composite_continue(c, pipe_req, continue_pipe_open_ncacn_unix_stream, c);
    406647        return c;
     
    447688*/
    448689static struct composite_context* dcerpc_pipe_connect_ncalrpc_send(TALLOC_CTX *mem_ctx,
    449                                                                   struct dcerpc_pipe_connect *io, struct loadparm_context *lp_ctx)
     690                                                                  struct dcerpc_pipe_connect *io)
    450691{
    451692        struct composite_context *c;
    452693        struct pipe_ncalrpc_state *s;
    453694        struct composite_context *pipe_req;
     695        const char *endpoint;
    454696
    455697        /* composite context allocation and setup */
    456         c = composite_create(mem_ctx, io->pipe->conn->event_ctx);
     698        c = composite_create(mem_ctx, io->conn->event_ctx);
    457699        if (c == NULL) return NULL;
    458700
     
    464706        s->io  = *io;
    465707
     708        endpoint = dcerpc_binding_get_string_option(io->binding, "endpoint");
     709        if (endpoint == NULL) {
     710                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     711                return c;
     712        }
     713
    466714        /* send pipe open request */
    467         pipe_req = dcerpc_pipe_open_pipe_send(s->io.pipe->conn, lpcfg_ncalrpc_dir(lp_ctx),
    468                                               s->io.binding->endpoint);
     715        pipe_req = dcerpc_pipe_open_pipe_send(s->io.conn,
     716                                              s->io.ncalrpc.dir,
     717                                              endpoint);
    469718        composite_continue(c, pipe_req, continue_pipe_open_ncalrpc, c);
    470719        return c;
     
    498747static void continue_pipe_connect_ncacn_np_smb(struct composite_context *ctx);
    499748static void continue_pipe_connect_ncacn_ip_tcp(struct composite_context *ctx);
     749static void continue_pipe_connect_ncacn_http(struct composite_context *ctx);
    500750static void continue_pipe_connect_ncacn_unix(struct composite_context *ctx);
    501751static void continue_pipe_connect_ncalrpc(struct composite_context *ctx);
     
    513763        struct pipe_connect_state *s = talloc_get_type(c->private_data,
    514764                                                       struct pipe_connect_state);
    515        
     765        const char *endpoint;
     766
    516767        c->status = dcerpc_epm_map_binding_recv(ctx);
    517768        if (!composite_is_ok(c)) return;
    518769
    519         DEBUG(4,("Mapped to DCERPC endpoint %s\n", s->binding->endpoint));
    520        
     770        endpoint = dcerpc_binding_get_string_option(s->binding, "endpoint");
     771        DEBUG(4,("Mapped to DCERPC endpoint %s\n", endpoint));
     772
    521773        continue_connect(c, s);
    522774}
     
    534786        struct composite_context *ncacn_np_smb_req;
    535787        struct composite_context *ncacn_ip_tcp_req;
     788        struct composite_context *ncacn_http_req;
    536789        struct composite_context *ncacn_unix_req;
    537790        struct composite_context *ncalrpc_req;
     791        enum dcerpc_transport_t transport;
     792        enum protocol_types min_ipc_protocol;
     793        uint32_t flags;
    538794
    539795        /* dcerpc pipe connect input parameters */
    540         pc.pipe         = s->pipe;
     796        ZERO_STRUCT(pc);
     797        pc.conn         = s->pipe->conn;
    541798        pc.binding      = s->binding;
    542         pc.pipe_name    = NULL;
    543799        pc.interface    = s->table;
    544800        pc.creds        = s->credentials;
    545801        pc.resolve_ctx  = lpcfg_resolve_context(s->lp_ctx);
    546802
     803        transport = dcerpc_binding_get_transport(s->binding);
     804        flags = dcerpc_binding_get_flags(s->binding);
     805
     806        min_ipc_protocol = lpcfg_client_ipc_min_protocol(s->lp_ctx);
     807        if (min_ipc_protocol >= PROTOCOL_SMB2_02) {
     808                flags |= DCERPC_SMB2;
     809        }
     810
    547811        /* connect dcerpc pipe depending on required transport */
    548         switch (s->binding->transport) {
     812        switch (transport) {
    549813        case NCACN_NP:
    550                 if (pc.binding->flags & DCERPC_SMB2) {
     814                if (flags & DCERPC_SMB2) {
    551815                        /* new varient of SMB a.k.a. SMB2 */
    552816                        ncacn_np_smb2_req = dcerpc_pipe_connect_ncacn_np_smb2_send(c, &pc, s->lp_ctx);
     
    567831                return;
    568832
     833        case NCACN_HTTP:
     834                ncacn_http_req = dcerpc_pipe_connect_ncacn_http_send(c, &pc, s->lp_ctx);
     835                composite_continue(c, ncacn_http_req, continue_pipe_connect_ncacn_http, c);
     836                return;
     837
    569838        case NCACN_UNIX_STREAM:
    570839                ncacn_unix_req = dcerpc_pipe_connect_ncacn_unix_stream_send(c, &pc);
     
    573842
    574843        case NCALRPC:
    575                 ncalrpc_req = dcerpc_pipe_connect_ncalrpc_send(c, &pc, s->lp_ctx);
     844                pc.ncalrpc.dir = lpcfg_ncalrpc_dir(s->lp_ctx);
     845                c->status = dcerpc_binding_set_string_option(s->binding, "ncalrpc_dir",
     846                                                             pc.ncalrpc.dir);
     847                if (!composite_is_ok(c)) return;
     848                ncalrpc_req = dcerpc_pipe_connect_ncalrpc_send(c, &pc);
    576849                composite_continue(c, ncalrpc_req, continue_pipe_connect_ncalrpc, c);
    577850                return;
     
    631904
    632905        c->status = dcerpc_pipe_connect_ncacn_ip_tcp_recv(ctx);
     906        if (!composite_is_ok(c)) return;
     907
     908        continue_pipe_connect(c, s);
     909}
     910
     911
     912/*
     913  Stage 3 of pipe_connect_b: Receive result of pipe connect request on http
     914*/
     915static void continue_pipe_connect_ncacn_http(struct composite_context *ctx)
     916{
     917        struct composite_context *c = talloc_get_type(ctx->async.private_data,
     918                                                      struct composite_context);
     919        struct pipe_connect_state *s = talloc_get_type(c->private_data,
     920                                                       struct pipe_connect_state);
     921
     922        c->status = dcerpc_pipe_connect_ncacn_http_recv(ctx);
    633923        if (!composite_is_ok(c)) return;
    634924
     
    679969        struct composite_context *auth_bind_req;
    680970
    681         s->pipe->binding = s->binding;
    682         if (!talloc_reference(s->pipe, s->binding)) {
    683                 composite_error(c, NT_STATUS_NO_MEMORY);
     971        s->pipe->binding = dcerpc_binding_dup(s->pipe, s->binding);
     972        if (composite_nomem(s->pipe->binding, c)) {
    684973                return;
    685974        }
     
    7141003                                           struct timeval t, void *private_data)
    7151004{
    716         struct composite_context *c = talloc_get_type(private_data, struct composite_context);
    717         composite_error(c, NT_STATUS_IO_TIMEOUT);
     1005        struct composite_context *c = talloc_get_type_abort(private_data,
     1006                                                      struct composite_context);
     1007        struct pipe_connect_state *s = talloc_get_type_abort(c->private_data, struct pipe_connect_state);
     1008        if (!s->pipe->inhibit_timeout_processing) {
     1009                composite_error(c, NT_STATUS_IO_TIMEOUT);
     1010        } else {
     1011                s->pipe->timed_out = true;
     1012        }
    7181013}
    7191014
     
    7231018*/
    7241019_PUBLIC_ struct composite_context* dcerpc_pipe_connect_b_send(TALLOC_CTX *parent_ctx,
    725                                                      struct dcerpc_binding *binding,
     1020                                                     const struct dcerpc_binding *binding,
    7261021                                                     const struct ndr_interface_table *table,
    7271022                                                     struct cli_credentials *credentials,
     
    7311026        struct composite_context *c;
    7321027        struct pipe_connect_state *s;
    733         struct tevent_context *new_ev = NULL;
     1028        enum dcerpc_transport_t transport;
     1029        const char *endpoint = NULL;
     1030        struct cli_credentials *epm_creds = NULL;
    7341031
    7351032        /* composite context allocation and setup */
    7361033        c = composite_create(parent_ctx, ev);
    7371034        if (c == NULL) {
    738                 talloc_free(new_ev);
    7391035                return NULL;
    7401036        }
    741         talloc_steal(c, new_ev);
    7421037
    7431038        s = talloc_zero(c, struct pipe_connect_state);
     
    7501045
    7511046        if (DEBUGLEVEL >= 10)
    752                 s->pipe->conn->packet_log_dir = lpcfg_lockdir(lp_ctx);
     1047                s->pipe->conn->packet_log_dir = lpcfg_lock_directory(lp_ctx);
    7531048
    7541049        /* store parameters in state structure */
    755         s->binding      = binding;
     1050        s->binding      = dcerpc_binding_dup(s, binding);
     1051        if (composite_nomem(s->binding, c)) return c;
    7561052        s->table        = table;
    7571053        s->credentials  = credentials;
    7581054        s->lp_ctx       = lp_ctx;
    7591055
    760         event_add_timed(c->event_ctx, c,
    761                         timeval_current_ofs(DCERPC_REQUEST_TIMEOUT, 0),
    762                         dcerpc_connect_timeout_handler, c);
    763        
    764         switch (s->binding->transport) {
    765         case NCA_UNKNOWN: {
     1056        s->pipe->timed_out = false;
     1057        s->pipe->inhibit_timeout_processing = false;
     1058
     1059        tevent_add_timer(c->event_ctx, c,
     1060                         timeval_current_ofs(DCERPC_REQUEST_TIMEOUT, 0),
     1061                         dcerpc_connect_timeout_handler, c);
     1062
     1063        transport = dcerpc_binding_get_transport(s->binding);
     1064
     1065        switch (transport) {
     1066        case NCACN_NP:
     1067        case NCACN_IP_TCP:
     1068        case NCALRPC:
     1069                endpoint = dcerpc_binding_get_string_option(s->binding, "endpoint");
     1070
     1071                /* anonymous credentials for rpc connection used to get endpoint mapping */
     1072                epm_creds = cli_credentials_init_anon(s);
     1073                if (composite_nomem(epm_creds, c)) return c;
     1074
     1075                break;
     1076        case NCACN_HTTP:
     1077                endpoint = dcerpc_binding_get_string_option(s->binding, "endpoint");
     1078                epm_creds = credentials;
     1079                break;
     1080        default:
     1081                break;
     1082        }
     1083
     1084        if (endpoint == NULL) {
    7661085                struct composite_context *binding_req;
     1086
    7671087                binding_req = dcerpc_epm_map_binding_send(c, s->binding, s->table,
     1088                                                          epm_creds,
    7681089                                                          s->pipe->conn->event_ctx,
    7691090                                                          s->lp_ctx);
    7701091                composite_continue(c, binding_req, continue_map_binding, c);
    7711092                return c;
    772                 }
    773 
    774         case NCACN_NP:
    775         case NCACN_IP_TCP:
    776         case NCALRPC:
    777                 if (!s->binding->endpoint) {
    778                         struct composite_context *binding_req;
    779                         binding_req = dcerpc_epm_map_binding_send(c, s->binding, s->table,
    780                                                                   s->pipe->conn->event_ctx,
    781                                                                   s->lp_ctx);
    782                         composite_continue(c, binding_req, continue_map_binding, c);
    783                         return c;
    784                 }
    785 
    786         default:
    787                 break;
    7881093        }
    7891094
     
    8201125_PUBLIC_ NTSTATUS dcerpc_pipe_connect_b(TALLOC_CTX *parent_ctx,
    8211126                               struct dcerpc_pipe **pp,
    822                                struct dcerpc_binding *binding,
     1127                               const struct dcerpc_binding *binding,
    8231128                               const struct ndr_interface_table *table,
    8241129                               struct cli_credentials *credentials,
  • vendor/current/source4/librpc/rpc/dcerpc_schannel.c

    r740 r988  
    3737        struct dcerpc_pipe *pipe2;
    3838        struct dcerpc_binding *binding;
     39        bool dcerpc_schannel_auto;
    3940        struct cli_credentials *credentials;
    4041        struct netlogon_creds_CredentialState *creds;
    41         uint32_t negotiate_flags;
     42        uint32_t local_negotiate_flags;
     43        uint32_t remote_negotiate_flags;
    4244        struct netr_Credential credentials1;
    4345        struct netr_Credential credentials2;
     
    5355static void continue_srv_challenge(struct tevent_req *subreq);
    5456static void continue_srv_auth2(struct tevent_req *subreq);
     57static void continue_get_capabilities(struct tevent_req *subreq);
    5558
    5659
     
    177180                cli_credentials_get_secure_channel_type(s->credentials);
    178181        s->a.in.computer_name    = cli_credentials_get_workstation(s->credentials);
    179         s->a.in.negotiate_flags  = &s->negotiate_flags;
     182        s->a.in.negotiate_flags  = &s->local_negotiate_flags;
    180183        s->a.in.credentials      = &s->credentials3;
    181         s->a.out.negotiate_flags = &s->negotiate_flags;
     184        s->a.out.negotiate_flags = &s->remote_negotiate_flags;
    182185        s->a.out.return_credentials     = &s->credentials3;
    183186
     
    185188                                              s->a.in.account_name,
    186189                                              s->a.in.computer_name,
     190                                              s->a.in.secure_channel_type,
    187191                                              &s->credentials1, &s->credentials2,
    188                                               s->mach_pwd, &s->credentials3, s->negotiate_flags);
     192                                              s->mach_pwd, &s->credentials3,
     193                                              s->local_negotiate_flags);
    189194        if (composite_nomem(s->creds, c)) {
    190195                return;
     
    219224        if (!composite_is_ok(c)) return;
    220225
     226        if (!NT_STATUS_EQUAL(s->a.out.result, NT_STATUS_ACCESS_DENIED) &&
     227            !NT_STATUS_IS_OK(s->a.out.result)) {
     228                composite_error(c, s->a.out.result);
     229                return;
     230        }
     231
     232        /*
     233         * Strong keys could be unsupported (NT4) or disables. So retry with the
     234         * flags returned by the server. - asn
     235         */
     236        if (NT_STATUS_EQUAL(s->a.out.result, NT_STATUS_ACCESS_DENIED)) {
     237                uint32_t lf = s->local_negotiate_flags;
     238                const char *ln = NULL;
     239                uint32_t rf = s->remote_negotiate_flags;
     240                const char *rn = NULL;
     241
     242                if (!s->dcerpc_schannel_auto) {
     243                        composite_error(c, s->a.out.result);
     244                        return;
     245                }
     246                s->dcerpc_schannel_auto = false;
     247
     248                if (lf & NETLOGON_NEG_SUPPORTS_AES)  {
     249                        ln = "aes";
     250                        if (rf & NETLOGON_NEG_SUPPORTS_AES) {
     251                                composite_error(c, s->a.out.result);
     252                                return;
     253                        }
     254                } else if (lf & NETLOGON_NEG_STRONG_KEYS) {
     255                        ln = "strong";
     256                        if (rf & NETLOGON_NEG_STRONG_KEYS) {
     257                                composite_error(c, s->a.out.result);
     258                                return;
     259                        }
     260                } else {
     261                        ln = "des";
     262                }
     263
     264                if (rf & NETLOGON_NEG_SUPPORTS_AES)  {
     265                        rn = "aes";
     266                } else if (rf & NETLOGON_NEG_STRONG_KEYS) {
     267                        rn = "strong";
     268                } else {
     269                        rn = "des";
     270                }
     271
     272                DEBUG(3, ("Server doesn't support %s keys, downgrade to %s"
     273                          "and retry! local[0x%08X] remote[0x%08X]\n",
     274                          ln, rn, lf, rf));
     275
     276                s->local_negotiate_flags = s->remote_negotiate_flags;
     277
     278                generate_random_buffer(s->credentials1.data,
     279                                       sizeof(s->credentials1.data));
     280
     281                subreq = dcerpc_netr_ServerReqChallenge_r_send(s,
     282                                                               c->event_ctx,
     283                                                               s->pipe2->binding_handle,
     284                                                               &s->r);
     285                if (composite_nomem(subreq, c)) return;
     286
     287                tevent_req_set_callback(subreq, continue_srv_challenge, c);
     288                return;
     289        }
     290
     291        s->creds->negotiate_flags = s->remote_negotiate_flags;
     292
    221293        /* verify credentials */
    222294        if (!netlogon_creds_client_check(s->creds, s->a.out.return_credentials)) {
     
    225297        }
    226298
    227         /* setup current netlogon credentials */
    228         cli_credentials_set_netlogon_creds(s->credentials, s->creds);
    229 
    230299        composite_done(c);
    231300}
    232 
    233301
    234302/*
     
    236304  on a secondary pipe
    237305*/
    238 struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
     306static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
    239307                                                   struct dcerpc_pipe *p,
    240308                                                   struct cli_credentials *credentials,
     
    245313        struct composite_context *epm_map_req;
    246314        enum netr_SchannelType schannel_type = cli_credentials_get_secure_channel_type(credentials);
    247        
     315        struct cli_credentials *epm_creds = NULL;
     316
    248317        /* composite context allocation and setup */
    249318        c = composite_create(mem_ctx, p->conn->event_ctx);
     
    257326        s->pipe        = p;
    258327        s->credentials = credentials;
     328        s->local_negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
    259329
    260330        /* allocate credentials */
     331        if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
     332                s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
     333        }
     334        if (s->pipe->conn->flags & DCERPC_SCHANNEL_AES) {
     335                s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
     336                s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
     337        }
     338        if (s->pipe->conn->flags & DCERPC_SCHANNEL_AUTO) {
     339                s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
     340                s->local_negotiate_flags |= NETLOGON_NEG_SUPPORTS_AES;
     341                s->dcerpc_schannel_auto = true;
     342        }
     343
    261344        /* type of authentication depends on schannel type */
    262345        if (schannel_type == SEC_CHAN_RODC) {
    263                 s->negotiate_flags = NETLOGON_NEG_AUTH2_RODC_FLAGS;
    264         } else if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
    265                 s->negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
    266         } else {
    267                 s->negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
    268         }
     346                s->local_negotiate_flags |= NETLOGON_NEG_RODC_PASSTHROUGH;
     347        }
     348
     349        epm_creds = cli_credentials_init_anon(s);
     350        if (composite_nomem(epm_creds, c)) return c;
    269351
    270352        /* allocate binding structure */
    271         s->binding = talloc_zero(c, struct dcerpc_binding);
     353        s->binding = dcerpc_binding_dup(s, s->pipe->binding);
    272354        if (composite_nomem(s->binding, c)) return c;
    273 
    274         *s->binding = *s->pipe->binding;
    275355
    276356        /* request the netlogon endpoint mapping */
    277357        epm_map_req = dcerpc_epm_map_binding_send(c, s->binding,
    278358                                                  &ndr_table_netlogon,
     359                                                  epm_creds,
    279360                                                  s->pipe->conn->event_ctx,
    280361                                                  lp_ctx);
     
    289370  Receive result of schannel key request
    290371 */
    291 NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c)
     372static NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c,
     373                                TALLOC_CTX *mem_ctx,
     374                                struct netlogon_creds_CredentialState **creds)
    292375{
    293376        NTSTATUS status = composite_wait(c);
    294        
     377
     378        if (NT_STATUS_IS_OK(status)) {
     379                struct schannel_key_state *s =
     380                        talloc_get_type_abort(c->private_data,
     381                        struct schannel_key_state);
     382                *creds = talloc_move(mem_ctx, &s->creds);
     383        }
     384
    295385        talloc_free(c);
    296386        return status;
     
    304394        struct loadparm_context *lp_ctx;
    305395        uint8_t auth_level;
     396        struct netlogon_creds_CredentialState *creds_state;
     397        struct netlogon_creds_CredentialState save_creds_state;
     398        struct netr_Authenticator auth;
     399        struct netr_Authenticator return_auth;
     400        union netr_Capabilities capabilities;
     401        struct netr_LogonGetCapabilities c;
    306402};
    307403
     
    324420
    325421        /* receive schannel key */
    326         status = c->status = dcerpc_schannel_key_recv(ctx);
     422        status = c->status = dcerpc_schannel_key_recv(ctx, s, &s->creds_state);
    327423        if (!composite_is_ok(c)) {
    328424                DEBUG(1, ("Failed to setup credentials: %s\n", nt_errstr(status)));
     
    331427
    332428        /* send bind auth request with received creds */
     429        cli_credentials_set_netlogon_creds(s->credentials, s->creds_state);
     430
    333431        auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, s->credentials,
    334432                                         lpcfg_gensec_settings(c, s->lp_ctx),
     
    349447        struct composite_context *c = talloc_get_type(ctx->async.private_data,
    350448                                                      struct composite_context);
     449        struct auth_schannel_state *s = talloc_get_type(c->private_data,
     450                                                        struct auth_schannel_state);
     451        struct tevent_req *subreq;
    351452
    352453        c->status = dcerpc_bind_auth_recv(ctx);
    353454        if (!composite_is_ok(c)) return;
     455
     456        /* if we have a AES encrypted connection, verify the capabilities */
     457        if (ndr_syntax_id_equal(&s->table->syntax_id,
     458                                &ndr_table_netlogon.syntax_id)) {
     459                ZERO_STRUCT(s->return_auth);
     460
     461                s->save_creds_state = *s->creds_state;
     462                netlogon_creds_client_authenticator(&s->save_creds_state, &s->auth);
     463
     464                s->c.in.server_name = talloc_asprintf(c,
     465                                                      "\\\\%s",
     466                                                      dcerpc_server_name(s->pipe));
     467                if (composite_nomem(s->c.in.server_name, c)) return;
     468                s->c.in.computer_name         = cli_credentials_get_workstation(s->credentials);
     469                s->c.in.credential            = &s->auth;
     470                s->c.in.return_authenticator  = &s->return_auth;
     471                s->c.in.query_level           = 1;
     472
     473                s->c.out.capabilities         = &s->capabilities;
     474                s->c.out.return_authenticator = &s->return_auth;
     475
     476                DEBUG(5, ("We established a AES connection, verifying logon "
     477                          "capabilities\n"));
     478
     479                subreq = dcerpc_netr_LogonGetCapabilities_r_send(s,
     480                                                                 c->event_ctx,
     481                                                                 s->pipe->binding_handle,
     482                                                                 &s->c);
     483                if (composite_nomem(subreq, c)) return;
     484
     485                tevent_req_set_callback(subreq, continue_get_capabilities, c);
     486                return;
     487        }
     488
     489        composite_done(c);
     490}
     491
     492/*
     493  Stage 4 of auth_schannel: Get the Logon Capablities and verify them.
     494*/
     495static void continue_get_capabilities(struct tevent_req *subreq)
     496{
     497        struct composite_context *c;
     498        struct auth_schannel_state *s;
     499
     500        c = tevent_req_callback_data(subreq, struct composite_context);
     501        s = talloc_get_type(c->private_data, struct auth_schannel_state);
     502
     503        /* receive rpc request result */
     504        c->status = dcerpc_netr_LogonGetCapabilities_r_recv(subreq, s);
     505        TALLOC_FREE(subreq);
     506        if (NT_STATUS_EQUAL(c->status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
     507                if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     508                        composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
     509                        return;
     510                } else {
     511                        /* This is probably NT */
     512                        composite_done(c);
     513                        return;
     514                }
     515        } else if (!composite_is_ok(c)) {
     516                return;
     517        }
     518
     519        if (NT_STATUS_EQUAL(s->c.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
     520                if (s->creds_state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
     521                        /* This means AES isn't supported. */
     522                        composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
     523                        return;
     524                }
     525
     526                /* This is probably an old Samba version */
     527                composite_done(c);
     528                return;
     529        }
     530
     531        /* verify credentials */
     532        if (!netlogon_creds_client_check(&s->save_creds_state,
     533                                         &s->c.out.return_authenticator->cred)) {
     534                composite_error(c, NT_STATUS_UNSUCCESSFUL);
     535                return;
     536        }
     537
     538        *s->creds_state = s->save_creds_state;
     539        cli_credentials_set_netlogon_creds(s->credentials, s->creds_state);
     540
     541        if (!NT_STATUS_IS_OK(s->c.out.result)) {
     542                composite_error(c, s->c.out.result);
     543                return;
     544        }
     545
     546        /* compare capabilities */
     547        if (s->creds_state->negotiate_flags != s->capabilities.server_capabilities) {
     548                DEBUG(2, ("The client capabilities don't match the server "
     549                          "capabilities: local[0x%08X] remote[0x%08X]\n",
     550                          s->creds_state->negotiate_flags,
     551                          s->capabilities.server_capabilities));
     552                composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
     553                return;
     554        }
     555
     556        /* TODO: Add downgrade dectection. */
    354557
    355558        composite_done(c);
  • vendor/current/source4/librpc/rpc/dcerpc_secondary.c

    r740 r988  
    3232#include "param/param.h"
    3333#include "libcli/resolve/resolve.h"
    34 #include "lib/socket/socket.h"
     34#include "lib/util/util_net.h"
    3535
    3636struct sec_conn_state {
     
    3838        struct dcerpc_pipe *pipe2;
    3939        struct dcerpc_binding *binding;
    40         struct smbcli_tree *tree;
    41         struct socket_address *peer_addr;
    4240};
    4341
     
    4543static void continue_open_smb(struct composite_context *ctx);
    4644static void continue_open_tcp(struct composite_context *ctx);
    47 static void continue_open_pipe(struct composite_context *ctx);
     45static void continue_open_ncalrpc(struct composite_context *ctx);
     46static void continue_open_ncacn_unix(struct composite_context *ctx);
    4847static void continue_pipe_open(struct composite_context *c);
    4948
     
    5453*/
    5554_PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerpc_pipe *p,
    56                                                           struct dcerpc_binding *b)
     55                                                        const struct dcerpc_binding *b)
    5756{
    5857        struct composite_context *c;
     
    6059        struct composite_context *pipe_smb_req;
    6160        struct composite_context *pipe_tcp_req;
     61        const char *localaddress = NULL;
    6262        struct composite_context *pipe_ncalrpc_req;
    63        
     63        const char *ncalrpc_dir = NULL;
     64        struct composite_context *pipe_unix_req;
     65        const char *host;
     66        const char *target_hostname;
     67        const char *endpoint;
     68
    6469        /* composite context allocation and setup */
    6570        c = composite_create(p, p->conn->event_ctx);
     
    7176
    7277        s->pipe     = p;
    73         s->binding  = b;
     78        s->binding  = dcerpc_binding_dup(s, b);
     79        if (composite_nomem(s->binding, c)) return c;
    7480
    7581        /* initialise second dcerpc pipe based on primary pipe's event context */
     
    8086                s->pipe2->conn->packet_log_dir = s->pipe->conn->packet_log_dir;
    8187
     88        host = dcerpc_binding_get_string_option(s->binding, "host");
     89        if (host == NULL) {
     90                /*
     91                 * We may fallback to the host of the given connection
     92                 */
     93                host = dcerpc_binding_get_string_option(s->pipe->binding,
     94                                                        "host");
     95        }
     96        target_hostname = dcerpc_binding_get_string_option(s->binding, "target_hostname");
     97        if (target_hostname == NULL) {
     98                /*
     99                 * We may fallback to the target_hostname of the given connection
     100                 */
     101                target_hostname = dcerpc_binding_get_string_option(s->pipe->binding,
     102                                                                   "target_hostname");
     103        }
     104        endpoint = dcerpc_binding_get_string_option(s->binding, "endpoint");
     105        if (endpoint == NULL) {
     106                /*
     107                 * We may fallback to the endpoint of the given connection
     108                 */
     109                endpoint = dcerpc_binding_get_string_option(s->pipe->binding, "endpoint");
     110        }
     111        if (endpoint == NULL) {
     112                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     113                return c;
     114        }
     115
    82116        /* open second dcerpc pipe using the same transport as for primary pipe */
    83117        switch (s->pipe->conn->transport.transport) {
    84118        case NCACN_NP:
    85                 /* get smb tree of primary dcerpc pipe opened on smb */
    86                 s->tree = dcerpc_smb_tree(s->pipe->conn);
    87                 if (!s->tree) {
    88                         composite_error(c, NT_STATUS_INVALID_PARAMETER);
     119                pipe_smb_req = dcerpc_secondary_smb_send(s->pipe->conn,
     120                                                         s->pipe2->conn,
     121                                                         endpoint);
     122                composite_continue(c, pipe_smb_req, continue_open_smb, c);
     123                return c;
     124
     125        case NCACN_IP_TCP:
     126                if (host == NULL) {
     127                        composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
    89128                        return c;
    90129                }
    91130
    92                 pipe_smb_req = dcerpc_pipe_open_smb_send(s->pipe2, s->tree,
    93                                                          s->binding->endpoint);
    94                 composite_continue(c, pipe_smb_req, continue_open_smb, c);
    95                 return c;
    96 
    97         case NCACN_IP_TCP:
    98                 s->peer_addr = dcerpc_socket_peer_addr(s->pipe->conn, s);
    99                 if (!s->peer_addr) {
    100                         composite_error(c, NT_STATUS_INVALID_PARAMETER);
    101                         return c;
     131                if (!is_ipaddress(host)) {
     132                        /*
     133                         * We may fallback to the host of the given connection
     134                         */
     135                        host = dcerpc_binding_get_string_option(s->pipe->binding,
     136                                                                "host");
     137                        if (host == NULL) {
     138                                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     139                                return c;
     140                        }
     141                        if (!is_ipaddress(host)) {
     142                                composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     143                                return c;
     144                        }
    102145                }
    103146
     147                localaddress = dcerpc_binding_get_string_option(s->binding,
     148                                                                "localaddress");
     149                if (localaddress == NULL) {
     150                        /*
     151                         * We may fallback to the localaddress of the given connection
     152                         */
     153                        localaddress = dcerpc_binding_get_string_option(s->pipe->binding,
     154                                                                        "localaddress");
     155                }
     156
    104157                pipe_tcp_req = dcerpc_pipe_open_tcp_send(s->pipe2->conn,
    105                                                          s->binding->localaddress,
    106                                                          s->peer_addr->addr,
    107                                                          s->binding->target_hostname,
    108                                                          atoi(s->binding->endpoint),
     158                                                         localaddress,
     159                                                         host,
     160                                                         target_hostname,
     161                                                         atoi(endpoint),
    109162                                                         resolve_context_init(s));
    110163                composite_continue(c, pipe_tcp_req, continue_open_tcp, c);
     
    112165
    113166        case NCALRPC:
     167                ncalrpc_dir = dcerpc_binding_get_string_option(s->binding,
     168                                                               "ncalrpc_dir");
     169                if (ncalrpc_dir == NULL) {
     170                        ncalrpc_dir = dcerpc_binding_get_string_option(s->pipe->binding,
     171                                                                "ncalrpc_dir");
     172                }
     173                if (ncalrpc_dir == NULL) {
     174                        composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
     175                        return c;
     176                }
     177
     178                pipe_ncalrpc_req = dcerpc_pipe_open_pipe_send(s->pipe2->conn,
     179                                                              ncalrpc_dir,
     180                                                              endpoint);
     181                composite_continue(c, pipe_ncalrpc_req, continue_open_ncalrpc, c);
     182                return c;
     183
    114184        case NCACN_UNIX_STREAM:
    115                 pipe_ncalrpc_req = dcerpc_pipe_open_unix_stream_send(s->pipe2->conn,
    116                                                               dcerpc_unix_socket_path(s->pipe->conn));
    117                 composite_continue(c, pipe_ncalrpc_req, continue_open_pipe, c);
     185                pipe_unix_req = dcerpc_pipe_open_unix_stream_send(s->pipe2->conn,
     186                                                                  endpoint);
     187                composite_continue(c, pipe_unix_req, continue_open_ncacn_unix, c);
    118188                return c;
    119189
     
    135205                                                      struct composite_context);
    136206       
    137         c->status = dcerpc_pipe_open_smb_recv(ctx);
     207        c->status = dcerpc_secondary_smb_recv(ctx);
    138208        if (!composite_is_ok(c)) return;
    139209
     
    149219        struct composite_context *c = talloc_get_type(ctx->async.private_data,
    150220                                                      struct composite_context);
    151        
    152         c->status = dcerpc_pipe_open_tcp_recv(ctx);
     221        struct sec_conn_state *s = talloc_get_type_abort(c->private_data,
     222                                                         struct sec_conn_state);
     223        char *localaddr = NULL;
     224        char *remoteaddr = NULL;
     225
     226        c->status = dcerpc_pipe_open_tcp_recv(ctx, s, &localaddr, &remoteaddr);
     227        if (!composite_is_ok(c)) return;
     228
     229        c->status = dcerpc_binding_set_string_option(s->binding,
     230                                                     "localaddress",
     231                                                     localaddr);
     232        if (!composite_is_ok(c)) return;
     233
     234        c->status = dcerpc_binding_set_string_option(s->binding,
     235                                                     "host",
     236                                                     remoteaddr);
    153237        if (!composite_is_ok(c)) return;
    154238
     
    156240}
    157241
    158 
    159242/*
    160243  Stage 2 of secondary_connection: Receive result of pipe open request on ncalrpc
    161244*/
    162 static void continue_open_pipe(struct composite_context *ctx)
     245static void continue_open_ncalrpc(struct composite_context *ctx)
    163246{
    164247        struct composite_context *c = talloc_get_type(ctx->async.private_data,
     
    171254}
    172255
     256/*
     257  Stage 2 of secondary_connection: Receive result of pipe open request on ncacn_unix
     258*/
     259static void continue_open_ncacn_unix(struct composite_context *ctx)
     260{
     261        struct composite_context *c = talloc_get_type(ctx->async.private_data,
     262                                                      struct composite_context);
     263
     264        c->status = dcerpc_pipe_open_unix_stream_recv(ctx);
     265        if (!composite_is_ok(c)) return;
     266
     267        continue_pipe_open(c);
     268}
     269
    173270
    174271/*
     
    183280
    184281        s->pipe2->conn->flags = s->pipe->conn->flags;
    185         s->pipe2->binding     = s->binding;
    186         if (!talloc_reference(s->pipe2, s->binding)) {
    187                 composite_error(c, NT_STATUS_NO_MEMORY);
     282        s->pipe2->binding     = dcerpc_binding_dup(s->pipe2, s->binding);
     283        if (composite_nomem(s->pipe2->binding, c)) {
    188284                return;
    189285        }
     
    222318_PUBLIC_ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p,
    223319                                     struct dcerpc_pipe **p2,
    224                                      struct dcerpc_binding *b)
     320                                     const struct dcerpc_binding *b)
    225321{
    226322        struct composite_context *c;
     
    238334struct sec_auth_conn_state {
    239335        struct dcerpc_pipe *pipe2;
    240         struct dcerpc_binding *binding;
     336        const struct dcerpc_binding *binding;
    241337        const struct ndr_interface_table *table;
    242338        struct cli_credentials *credentials;
     
    249345
    250346_PUBLIC_ struct composite_context* dcerpc_secondary_auth_connection_send(struct dcerpc_pipe *p,
    251                                                                 struct dcerpc_binding *binding,
     347                                                                const struct dcerpc_binding *binding,
    252348                                                                const struct ndr_interface_table *table,
    253349                                                                struct cli_credentials *credentials,
     
    336432        return status;
    337433}
     434
     435_PUBLIC_ NTSTATUS dcerpc_secondary_auth_connection(struct dcerpc_pipe *p,
     436                                        const struct dcerpc_binding *binding,
     437                                        const struct ndr_interface_table *table,
     438                                        struct cli_credentials *credentials,
     439                                        struct loadparm_context *lp_ctx,
     440                                        TALLOC_CTX *mem_ctx,
     441                                        struct dcerpc_pipe **p2)
     442{
     443        struct composite_context *c;
     444
     445        c = dcerpc_secondary_auth_connection_send(p, binding, table,
     446                                                  credentials, lp_ctx);
     447        return dcerpc_secondary_auth_connection_recv(c, mem_ctx, p2);
     448}
  • vendor/current/source4/librpc/rpc/dcerpc_smb.c

    r860 r988  
    2222
    2323#include "includes.h"
     24#include "system/filesys.h"
     25#include <tevent.h>
     26#include "lib/tsocket/tsocket.h"
     27#include "libcli/smb/smb_constants.h"
     28#include "libcli/smb/smbXcli_base.h"
     29#include "libcli/smb/tstream_smbXcli_np.h"
    2430#include "libcli/raw/libcliraw.h"
    25 #include "libcli/composite/composite.h"
     31#include "libcli/smb2/smb2.h"
    2632#include "librpc/rpc/dcerpc.h"
    2733#include "librpc/rpc/dcerpc_proto.h"
    28 #include "librpc/rpc/rpc_common.h"
     34#include "libcli/composite/composite.h"
    2935
    3036/* transport private information used by SMB pipe transport */
    3137struct smb_private {
    32         uint16_t fnum;
    33         struct smbcli_tree *tree;
    34         const char *server_name;
    35         bool dead;
     38        DATA_BLOB session_key;
     39
     40        /*
     41         * these are needed to open a secondary connection
     42         */
     43        struct smbXcli_conn *conn;
     44        struct smbXcli_session *session;
     45        struct smbXcli_tcon *tcon;
     46        uint32_t timeout_msec;
    3647};
    37 
    38 
    39 /*
    40   tell the dcerpc layer that the transport is dead
    41 */
    42 static void pipe_dead(struct dcecli_connection *c, NTSTATUS status)
    43 {
    44         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
    45 
    46         if (smb->dead) {
    47                 return;
    48         }
    49 
    50         smb->dead = true;
    51 
    52         if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
    53                 status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
    54         }
    55 
    56         if (NT_STATUS_EQUAL(NT_STATUS_OK, status)) {
    57                 status = NT_STATUS_END_OF_FILE;
    58         }
    59 
    60         if (c->transport.recv_data) {
    61                 c->transport.recv_data(c, NULL, status);
    62         }
    63 }
    64 
    65 
    66 /*
    67    this holds the state of an in-flight call
    68 */
    69 struct smb_read_state {
    70         struct dcecli_connection *c;
    71         struct smbcli_request *req;
    72         size_t received;
    73         DATA_BLOB data;
    74         union smb_read *io;
    75 };
    76 
    77 /*
    78   called when a read request has completed
    79 */
    80 static void smb_read_callback(struct smbcli_request *req)
    81 {
    82         struct smb_private *smb;
    83         struct smb_read_state *state;
    84         union smb_read *io;
    85         uint16_t frag_length;
    86         NTSTATUS status;
    87 
    88         state = talloc_get_type(req->async.private_data, struct smb_read_state);
    89         smb = talloc_get_type(state->c->transport.private_data, struct smb_private);
    90         io = state->io;
    91 
    92         status = smb_raw_read_recv(state->req, io);
    93         if (NT_STATUS_IS_ERR(status)) {
    94                 pipe_dead(state->c, status);
    95                 talloc_free(state);
    96                 return;
    97         }
    98 
    99         state->received += io->readx.out.nread;
    100 
    101         if (state->received < 16) {
    102                 DEBUG(0,("dcerpc_smb: short packet (length %d) in read callback!\n",
    103                          (int)state->received));
    104                 pipe_dead(state->c, NT_STATUS_INFO_LENGTH_MISMATCH);
    105                 talloc_free(state);
    106                 return;
    107         }
    108 
    109         frag_length = dcerpc_get_frag_length(&state->data);
    110 
    111         if (frag_length <= state->received) {
    112                 DATA_BLOB data = state->data;
    113                 struct dcecli_connection *c = state->c;
    114                 data.length = state->received;
    115                 talloc_steal(state->c, data.data);
    116                 talloc_free(state);
    117                 c->transport.recv_data(c, &data, NT_STATUS_OK);
    118                 return;
    119         }
    120 
    121         /* initiate another read request, as we only got part of a fragment */
    122         state->data.data = talloc_realloc(state, state->data.data, uint8_t, frag_length);
    123 
    124         io->readx.in.mincnt = MIN(state->c->srv_max_xmit_frag,
    125                                   frag_length - state->received);
    126         io->readx.in.maxcnt = io->readx.in.mincnt;
    127         io->readx.out.data = state->data.data + state->received;
    128 
    129         state->req = smb_raw_read_send(smb->tree, io);
    130         if (state->req == NULL) {
    131                 pipe_dead(state->c, NT_STATUS_NO_MEMORY);
    132                 talloc_free(state);
    133                 return;
    134         }
    135 
    136         state->req->async.fn = smb_read_callback;
    137         state->req->async.private_data = state;
    138 }
    139 
    140 /*
    141   trigger a read request from the server, possibly with some initial
    142   data in the read buffer
    143 */
    144 static NTSTATUS send_read_request_continue(struct dcecli_connection *c, DATA_BLOB *blob)
    145 {
    146         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
    147         union smb_read *io;
    148         struct smb_read_state *state;
    149         struct smbcli_request *req;
    150 
    151         state = talloc(smb, struct smb_read_state);
    152         if (state == NULL) {
    153                 return NT_STATUS_NO_MEMORY;
    154         }
    155 
    156         state->c = c;
    157         if (blob == NULL) {
    158                 state->received = 0;
    159                 state->data = data_blob_talloc(state, NULL, 0x2000);
    160         } else {
    161                 uint32_t frag_length = blob->length>=16?
    162                         dcerpc_get_frag_length(blob):0x2000;
    163 
    164                 if (frag_length < state->data.length) {
    165                         talloc_free(state);
    166                         return NT_STATUS_RPC_PROTOCOL_ERROR;
    167                 }
    168 
    169                 state->received = blob->length;
    170                 state->data = data_blob_talloc(state, NULL, frag_length);
    171                 if (!state->data.data) {
    172                         talloc_free(state);
    173                         return NT_STATUS_NO_MEMORY;
    174                 }
    175                 memcpy(state->data.data, blob->data, blob->length);
    176         }
    177 
    178         state->io = talloc(state, union smb_read);
    179 
    180         io = state->io;
    181         io->generic.level = RAW_READ_READX;
    182         io->readx.in.file.fnum = smb->fnum;
    183         io->readx.in.mincnt = state->data.length - state->received;
    184         io->readx.in.maxcnt = io->readx.in.mincnt;
    185         io->readx.in.offset = 0;
    186         io->readx.in.remaining = 0;
    187         io->readx.in.read_for_execute = false;
    188         io->readx.out.data = state->data.data + state->received;
    189         req = smb_raw_read_send(smb->tree, io);
    190         if (req == NULL) {
    191                 return NT_STATUS_NO_MEMORY;
    192         }
    193 
    194         req->async.fn = smb_read_callback;
    195         req->async.private_data = state;
    196 
    197         state->req = req;
    198 
    199         return NT_STATUS_OK;
    200 }
    201 
    202 
    203 /*
    204   trigger a read request from the server
    205 */
    206 static NTSTATUS send_read_request(struct dcecli_connection *c)
    207 {
    208         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
    209 
    210         if (smb->dead) {
    211                 return NT_STATUS_CONNECTION_DISCONNECTED;
    212         }
    213 
    214         return send_read_request_continue(c, NULL);
    215 }
    216 
    217 /*
    218    this holds the state of an in-flight trans call
    219 */
    220 struct smb_trans_state {
    221         struct dcecli_connection *c;
    222         struct smbcli_request *req;
    223         struct smb_trans2 *trans;
    224 };
    225 
    226 /*
    227   called when a trans request has completed
    228 */
    229 static void smb_trans_callback(struct smbcli_request *req)
    230 {
    231         struct smb_trans_state *state = (struct smb_trans_state *)req->async.private_data;
    232         struct dcecli_connection *c = state->c;
    233         NTSTATUS status;
    234 
    235         status = smb_raw_trans_recv(req, state, state->trans);
    236 
    237         if (NT_STATUS_IS_ERR(status)) {
    238                 pipe_dead(c, status);
    239                 return;
    240         }
    241 
    242         if (!NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
    243                 DATA_BLOB data = state->trans->out.data;
    244                 talloc_steal(c, data.data);
    245                 talloc_free(state);
    246                 c->transport.recv_data(c, &data, NT_STATUS_OK);
    247                 return;
    248         }
    249 
    250         /* there is more to receive - setup a readx */
    251         send_read_request_continue(c, &state->trans->out.data);
    252         talloc_free(state);
    253 }
    254 
    255 /*
    256   send a SMBtrans style request
    257 */
    258 static NTSTATUS smb_send_trans_request(struct dcecli_connection *c, DATA_BLOB *blob)
    259 {
    260         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
    261         struct smb_trans2 *trans;
    262         uint16_t setup[2];
    263         struct smb_trans_state *state;
    264         uint16_t max_data;
    265 
    266         state = talloc(smb, struct smb_trans_state);
    267         if (state == NULL) {
    268                 return NT_STATUS_NO_MEMORY;
    269         }
    270 
    271         state->c = c;
    272         state->trans = talloc(state, struct smb_trans2);
    273         trans = state->trans;
    274 
    275         trans->in.data = *blob;
    276         trans->in.params = data_blob(NULL, 0);
    277        
    278         setup[0] = TRANSACT_DCERPCCMD;
    279         setup[1] = smb->fnum;
    280 
    281         if (c->srv_max_xmit_frag > 0) {
    282                 max_data = MIN(UINT16_MAX, c->srv_max_xmit_frag);
    283         } else {
    284                 max_data = UINT16_MAX;
    285         }
    286 
    287         trans->in.max_param = 0;
    288         trans->in.max_data = max_data;
    289         trans->in.max_setup = 0;
    290         trans->in.setup_count = 2;
    291         trans->in.flags = 0;
    292         trans->in.timeout = 0;
    293         trans->in.setup = setup;
    294         trans->in.trans_name = "\\PIPE\\";
    295 
    296         state->req = smb_raw_trans_send(smb->tree, trans);
    297         if (state->req == NULL) {
    298                 talloc_free(state);
    299                 return NT_STATUS_NO_MEMORY;
    300         }
    301 
    302         state->req->async.fn = smb_trans_callback;
    303         state->req->async.private_data = state;
    304 
    305         talloc_steal(state, state->req);
    306 
    307         return NT_STATUS_OK;
    308 }
    309 
    310 /*
    311   called when a write request has completed
    312 */
    313 static void smb_write_callback(struct smbcli_request *req)
    314 {
    315         struct dcecli_connection *c = (struct dcecli_connection *)req->async.private_data;
    316 
    317         if (!NT_STATUS_IS_OK(req->status)) {
    318                 DEBUG(0,("dcerpc_smb: write callback error\n"));
    319                 pipe_dead(c, req->status);
    320         }
    321 
    322         smbcli_request_destroy(req);
    323 }
    324 
    325 /*
    326    send a packet to the server
    327 */
    328 static NTSTATUS smb_send_request(struct dcecli_connection *c, DATA_BLOB *blob,
    329                                  bool trigger_read)
    330 {
    331         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
    332         union smb_write io;
    333         struct smbcli_request *req;
    334 
    335         if (!smb || smb->dead) {
    336                 return NT_STATUS_CONNECTION_DISCONNECTED;
    337         }
    338 
    339         if (trigger_read) {
    340                 return smb_send_trans_request(c, blob);
    341         }
    342 
    343         io.generic.level = RAW_WRITE_WRITEX;
    344         io.writex.in.file.fnum = smb->fnum;
    345         io.writex.in.offset = 0;
    346         io.writex.in.wmode = PIPE_START_MESSAGE;
    347         io.writex.in.remaining = blob->length;
    348         io.writex.in.count = blob->length;
    349         io.writex.in.data = blob->data;
    350 
    351         /* we must not timeout at the smb level for rpc requests, as otherwise
    352            signing/sealing can be messed up */
    353         smb->tree->session->transport->options.request_timeout = 0;
    354 
    355         req = smb_raw_write_send(smb->tree, &io);
    356         if (req == NULL) {
    357                 return NT_STATUS_NO_MEMORY;
    358         }
    359 
    360         req->async.fn = smb_write_callback;
    361         req->async.private_data = c;
    362 
    363         if (trigger_read) {
    364                 send_read_request(c);
    365         }
    366 
    367         return NT_STATUS_OK;
    368 }
    369 
    370 
    371 static void free_request(struct smbcli_request *req)
    372 {
    373         talloc_free(req);
    374 }
    375 
    376 /*
    377    shutdown SMB pipe connection
    378 */
    379 static NTSTATUS smb_shutdown_pipe(struct dcecli_connection *c, NTSTATUS status)
    380 {
    381         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
    382         union smb_close io;
    383         struct smbcli_request *req;
    384 
    385         /* maybe we're still starting up */
    386         if (!smb) return status;
    387 
    388         io.close.level = RAW_CLOSE_CLOSE;
    389         io.close.in.file.fnum = smb->fnum;
    390         io.close.in.write_time = 0;
    391         req = smb_raw_close_send(smb->tree, &io);
    392         if (req != NULL) {
    393                 /* we don't care if this fails, so just free it if it succeeds */
    394                 req->async.fn = free_request;
    395         }
    396 
    397         talloc_free(smb);
    398         c->transport.private_data = NULL;
    399 
    400         return status;
    401 }
    402 
    403 /*
    404   return SMB server name (called name)
    405 */
    406 static const char *smb_peer_name(struct dcecli_connection *c)
    407 {
    408         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
    409         if (smb == NULL) return "";
    410         return smb->server_name;
    411 }
    412 
    413 /*
    414   return remote name we make the actual connection (good for kerberos)
    415 */
    416 static const char *smb_target_hostname(struct dcecli_connection *c)
    417 {
    418         struct smb_private *smb = talloc_get_type(c->transport.private_data, struct smb_private);
    419         if (smb == NULL) return "";
    420         return smb->tree->session->transport->socket->hostname;
    421 }
    42248
    42349/*
     
    42652static NTSTATUS smb_session_key(struct dcecli_connection *c, DATA_BLOB *session_key)
    42753{
    428         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
     54        struct smb_private *smb = talloc_get_type_abort(
     55                c->transport.private_data, struct smb_private);
    42956
    43057        if (smb == NULL) return NT_STATUS_CONNECTION_DISCONNECTED;
    431         if (smb->tree->session->user_session_key.data) {
    432                 *session_key = smb->tree->session->user_session_key;
    433                 return NT_STATUS_OK;
    434         }
    435         return NT_STATUS_NO_USER_SESSION_KEY;
    436 }
    437 
    438 struct pipe_open_smb_state {
    439         union smb_open *open;
     58
     59        if (smb->session_key.length == 0) {
     60                return NT_STATUS_NO_USER_SESSION_KEY;
     61        }
     62
     63        *session_key = smb->session_key;
     64        return NT_STATUS_OK;
     65}
     66
     67struct dcerpc_pipe_open_smb_state {
    44068        struct dcecli_connection *c;
    441         struct smbcli_tree *tree;
    442         struct composite_context *ctx;
     69        struct composite_context *ctx;
     70
     71        const char *fname;
     72
     73        struct smb_private *smb;
    44374};
    44475
    445 static void pipe_open_recv(struct smbcli_request *req);
    446 
    447 struct composite_context *dcerpc_pipe_open_smb_send(struct dcerpc_pipe *p,
    448                                                     struct smbcli_tree *tree,
    449                                                     const char *pipe_name)
    450 {
    451         struct composite_context *ctx;
    452         struct pipe_open_smb_state *state;
    453         struct smbcli_request *req;
    454         struct dcecli_connection *c = p->conn;
    455 
    456         /* if we don't have a binding on this pipe yet, then create one */
    457         if (p->binding == NULL) {
    458                 NTSTATUS status;
    459                 char *s;
    460                 SMB_ASSERT(tree->session->transport->socket->hostname != NULL);
    461                 s = talloc_asprintf(p, "ncacn_np:%s", tree->session->transport->socket->hostname);
    462                 if (s == NULL) return NULL;
    463                 status = dcerpc_parse_binding(p, s, &p->binding);
    464                 talloc_free(s);
    465                 if (!NT_STATUS_IS_OK(status)) {
    466                         return NULL;
    467                 }
    468         }
     76static void dcerpc_pipe_open_smb_done(struct tevent_req *subreq);
     77
     78struct composite_context *dcerpc_pipe_open_smb_send(struct dcecli_connection *c,
     79                                                struct smbXcli_conn *conn,
     80                                                struct smbXcli_session *session,
     81                                                struct smbXcli_tcon *tcon,
     82                                                uint32_t timeout_msec,
     83                                                const char *pipe_name)
     84{
     85        struct composite_context *ctx;
     86        struct dcerpc_pipe_open_smb_state *state;
     87        uint16_t pid = 0;
     88        struct tevent_req *subreq;
    46989
    47090        ctx = composite_create(c, c->event_ctx);
    47191        if (ctx == NULL) return NULL;
    47292
    473         state = talloc(ctx, struct pipe_open_smb_state);
     93        state = talloc(ctx, struct dcerpc_pipe_open_smb_state);
    47494        if (composite_nomem(state, ctx)) return ctx;
    47595        ctx->private_data = state;
    47696
    47797        state->c = c;
    478         state->tree = tree;
    47998        state->ctx = ctx;
    480 
    481         state->open = talloc(state, union smb_open);
    482         if (composite_nomem(state->open, ctx)) return ctx;
    483 
    484         state->open->ntcreatex.level = RAW_OPEN_NTCREATEX;
    485         state->open->ntcreatex.in.flags = 0;
    486         state->open->ntcreatex.in.root_fid.fnum = 0;
    487         state->open->ntcreatex.in.access_mask =
    488                 SEC_STD_READ_CONTROL |
    489                 SEC_FILE_WRITE_ATTRIBUTE |
    490                 SEC_FILE_WRITE_EA |
    491                 SEC_FILE_READ_DATA |
    492                 SEC_FILE_WRITE_DATA;
    493         state->open->ntcreatex.in.file_attr = 0;
    494         state->open->ntcreatex.in.alloc_size = 0;
    495         state->open->ntcreatex.in.share_access =
    496                 NTCREATEX_SHARE_ACCESS_READ |
    497                 NTCREATEX_SHARE_ACCESS_WRITE;
    498         state->open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    499         state->open->ntcreatex.in.create_options = 0;
    500         state->open->ntcreatex.in.impersonation =
    501                 NTCREATEX_IMPERSONATION_IMPERSONATION;
    502         state->open->ntcreatex.in.security_flags = 0;
    50399
    504100        if ((strncasecmp(pipe_name, "/pipe/", 6) == 0) ||
     
    506102                pipe_name += 6;
    507103        }
    508         state->open->ntcreatex.in.fname =
    509                 (pipe_name[0] == '\\') ?
    510                 talloc_strdup(state->open, pipe_name) :
    511                 talloc_asprintf(state->open, "\\%s", pipe_name);
    512         if (composite_nomem(state->open->ntcreatex.in.fname, ctx)) return ctx;
    513 
    514         req = smb_raw_open_send(tree, state->open);
    515         composite_continue_smb(ctx, req, pipe_open_recv, state);
     104        if ((strncasecmp(pipe_name, "/", 1) == 0) ||
     105            (strncasecmp(pipe_name, "\\", 1) == 0)) {
     106                pipe_name += 1;
     107        }
     108        state->fname = talloc_strdup(state, pipe_name);
     109        if (composite_nomem(state->fname, ctx)) return ctx;
     110
     111        state->smb = talloc_zero(state, struct smb_private);
     112        if (composite_nomem(state->smb, ctx)) return ctx;
     113
     114        state->smb->conn = conn;
     115        state->smb->session = session;
     116        state->smb->tcon = tcon;
     117        state->smb->timeout_msec = timeout_msec;
     118
     119        state->c->server_name = strupper_talloc(state->c,
     120                smbXcli_conn_remote_name(conn));
     121        if (composite_nomem(state->c->server_name, ctx)) return ctx;
     122
     123        ctx->status = smbXcli_session_application_key(session,
     124                                                      state->smb,
     125                                                      &state->smb->session_key);
     126        if (NT_STATUS_EQUAL(ctx->status, NT_STATUS_NO_USER_SESSION_KEY)) {
     127                state->smb->session_key = data_blob_null;
     128                ctx->status = NT_STATUS_OK;
     129        }
     130        if (!composite_is_ok(ctx)) return ctx;
     131
     132        subreq = tstream_smbXcli_np_open_send(state, c->event_ctx,
     133                                              conn, session, tcon, pid,
     134                                              timeout_msec, state->fname);
     135        if (composite_nomem(subreq, ctx)) return ctx;
     136        tevent_req_set_callback(subreq, dcerpc_pipe_open_smb_done, state);
     137
    516138        return ctx;
    517139}
    518140
    519 static void pipe_open_recv(struct smbcli_request *req)
    520 {
    521         struct pipe_open_smb_state *state = talloc_get_type(req->async.private_data,
    522                                             struct pipe_open_smb_state);
     141static void dcerpc_pipe_open_smb_done(struct tevent_req *subreq)
     142{
     143        struct dcerpc_pipe_open_smb_state *state =
     144                tevent_req_callback_data(subreq,
     145                struct dcerpc_pipe_open_smb_state);
    523146        struct composite_context *ctx = state->ctx;
    524147        struct dcecli_connection *c = state->c;
    525         struct smb_private *smb;
    526        
    527         ctx->status = smb_raw_open_recv(req, state, state->open);
     148
     149        ctx->status = tstream_smbXcli_np_open_recv(subreq,
     150                                                   state->smb,
     151                                                   &state->c->transport.stream);
     152        TALLOC_FREE(subreq);
    528153        if (!composite_is_ok(ctx)) return;
     154
     155        state->c->transport.write_queue =
     156                tevent_queue_create(state->c, "dcerpc_smb write queue");
     157        if (composite_nomem(state->c->transport.write_queue, ctx)) return;
    529158
    530159        /*
     
    533162        c->transport.transport       = NCACN_NP;
    534163        c->transport.private_data    = NULL;
    535         c->transport.shutdown_pipe   = smb_shutdown_pipe;
    536         c->transport.peer_name       = smb_peer_name;
    537         c->transport.target_hostname = smb_target_hostname;
    538 
    539         c->transport.send_request    = smb_send_request;
    540         c->transport.send_read       = send_read_request;
    541         c->transport.recv_data       = NULL;
    542        
     164
     165        /*
     166         * Windows uses 4280 for ncacn_np,
     167         * so we also use it, this is what our
     168         * tstream_smbXcli_np code relies on.
     169         */
     170        c->srv_max_xmit_frag = 4280;
     171        c->srv_max_recv_frag = 4280;
     172
    543173        /* Over-ride the default session key with the SMB session key */
    544174        c->security_state.session_key = smb_session_key;
    545175
    546         smb = talloc(c, struct smb_private);
    547         if (composite_nomem(smb, ctx)) return;
    548 
    549         smb->fnum       = state->open->ntcreatex.out.file.fnum;
    550         smb->tree       = talloc_reference(smb, state->tree);
    551         smb->server_name= strupper_talloc(smb,
    552                           state->tree->session->transport->called.name);
    553         if (composite_nomem(smb->server_name, ctx)) return;
    554         smb->dead       = false;
    555 
    556         c->transport.private_data = smb;
     176        c->transport.private_data = talloc_move(c, &state->smb);
    557177
    558178        composite_done(ctx);
     
    567187
    568188_PUBLIC_ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p,
    569                               struct smbcli_tree *tree,
     189                              struct smbcli_tree *t,
    570190                              const char *pipe_name)
    571191{
    572         struct composite_context *ctx = dcerpc_pipe_open_smb_send(p, tree,
    573                                                                   pipe_name);
     192        struct smbXcli_conn *conn;
     193        struct smbXcli_session *session;
     194        struct smbXcli_tcon *tcon;
     195        struct composite_context *ctx;
     196
     197        conn = t->session->transport->conn;
     198        session = t->session->smbXcli;
     199        tcon = t->smbXcli;
     200        smb1cli_tcon_set_id(tcon, t->tid);
     201
     202        /* if we don't have a binding on this pipe yet, then create one */
     203        if (p->binding == NULL) {
     204                struct dcerpc_binding *b;
     205                NTSTATUS status;
     206                const char *r = smbXcli_conn_remote_name(conn);
     207                char *str;
     208                SMB_ASSERT(r != NULL);
     209                str = talloc_asprintf(p, "ncacn_np:%s", r);
     210                if (str == NULL) {
     211                        return NT_STATUS_NO_MEMORY;
     212                }
     213                status = dcerpc_parse_binding(p, str, &b);
     214                talloc_free(str);
     215                if (!NT_STATUS_IS_OK(status)) {
     216                        return status;
     217                }
     218                p->binding = b;
     219        }
     220
     221        ctx = dcerpc_pipe_open_smb_send(p->conn,
     222                                        conn, session, tcon,
     223                                        DCERPC_REQUEST_TIMEOUT * 1000,
     224                                        pipe_name);
     225        if (ctx == NULL) {
     226                return NT_STATUS_NO_MEMORY;
     227        }
     228
    574229        return dcerpc_pipe_open_smb_recv(ctx);
    575230}
    576231
    577 /*
    578   return the SMB tree used for a dcerpc over SMB pipe
    579 */
    580 _PUBLIC_ struct smbcli_tree *dcerpc_smb_tree(struct dcecli_connection *c)
     232_PUBLIC_ NTSTATUS dcerpc_pipe_open_smb2(struct dcerpc_pipe *p,
     233                              struct smb2_tree *t,
     234                              const char *pipe_name)
     235{
     236        struct smbXcli_conn *conn;
     237        struct smbXcli_session *session;
     238        struct smbXcli_tcon *tcon;
     239        struct composite_context *ctx;
     240
     241        conn = t->session->transport->conn;
     242        session = t->session->smbXcli;
     243        tcon = t->smbXcli;
     244
     245        /* if we don't have a binding on this pipe yet, then create one */
     246        if (p->binding == NULL) {
     247                struct dcerpc_binding *b;
     248                NTSTATUS status;
     249                const char *r = smbXcli_conn_remote_name(conn);
     250                char *str;
     251                SMB_ASSERT(r != NULL);
     252                str = talloc_asprintf(p, "ncacn_np:%s", r);
     253                if (str == NULL) {
     254                        return NT_STATUS_NO_MEMORY;
     255                }
     256                status = dcerpc_parse_binding(p, str, &b);
     257                talloc_free(str);
     258                if (!NT_STATUS_IS_OK(status)) {
     259                        return status;
     260                }
     261                p->binding = b;
     262        }
     263
     264        ctx = dcerpc_pipe_open_smb_send(p->conn,
     265                                        conn, session, tcon,
     266                                        DCERPC_REQUEST_TIMEOUT * 1000,
     267                                        pipe_name);
     268        if (ctx == NULL) {
     269                return NT_STATUS_NO_MEMORY;
     270        }
     271
     272        return dcerpc_pipe_open_smb_recv(ctx);
     273}
     274
     275struct composite_context *dcerpc_secondary_smb_send(struct dcecli_connection *c1,
     276                                                    struct dcecli_connection *c2,
     277                                                    const char *pipe_name)
    581278{
    582279        struct smb_private *smb;
    583280
    584         if (c->transport.transport != NCACN_NP) return NULL;
    585 
    586         smb = talloc_get_type(c->transport.private_data, struct smb_private);
     281        if (c1->transport.transport != NCACN_NP) return NULL;
     282
     283        smb = talloc_get_type(c1->transport.private_data, struct smb_private);
    587284        if (!smb) return NULL;
    588285
    589         return smb->tree;
    590 }
    591 
    592 /*
    593   return the SMB fnum used for a dcerpc over SMB pipe (hack for torture operations)
    594 */
    595 _PUBLIC_ uint16_t dcerpc_smb_fnum(struct dcecli_connection *c)
    596 {
    597         struct smb_private *smb;
    598 
    599         if (c->transport.transport != NCACN_NP) return 0;
    600 
    601         smb = talloc_get_type(c->transport.private_data, struct smb_private);
    602         if (!smb) return 0;
    603 
    604         return smb->fnum;
    605 }
     286        return dcerpc_pipe_open_smb_send(c2,
     287                                         smb->conn,
     288                                         smb->session,
     289                                         smb->tcon,
     290                                         smb->timeout_msec,
     291                                         pipe_name);
     292}
     293
     294NTSTATUS dcerpc_secondary_smb_recv(struct composite_context *c)
     295{
     296        return dcerpc_pipe_open_smb_recv(c);
     297}
  • vendor/current/source4/librpc/rpc/dcerpc_sock.c

    r860 r988  
    2323
    2424#include "includes.h"
     25#include "system/filesys.h"
    2526#include "lib/events/events.h"
    2627#include "lib/socket/socket.h"
    27 #include "lib/stream/packet.h"
     28#include "lib/tsocket/tsocket.h"
    2829#include "libcli/composite/composite.h"
    2930#include "librpc/rpc/dcerpc.h"
     
    3233#include "librpc/rpc/rpc_common.h"
    3334
    34 /* transport private information used by general socket pipe transports */
    35 struct sock_private {
    36         struct tevent_fd *fde;
    37         struct socket_context *sock;
    38         char *server_name;
    39 
    40         struct packet_context *packet;
    41         uint32_t pending_reads;
    42 
    43         const char *path; /* For ncacn_unix_sock and ncalrpc */
    44 };
    45 
    46 
    47 /*
    48   mark the socket dead
    49 */
    50 static void sock_dead(struct dcecli_connection *p, NTSTATUS status)
    51 {
    52         struct sock_private *sock = (struct sock_private *)p->transport.private_data;
    53 
    54         if (!sock) return;
    55 
    56         if (sock->packet) {
    57                 packet_recv_disable(sock->packet);
    58                 packet_set_fde(sock->packet, NULL);
    59                 packet_set_socket(sock->packet, NULL);
    60         }
    61 
    62         if (sock->fde) {
    63                 talloc_free(sock->fde);
    64                 sock->fde = NULL;
    65         }
    66 
    67         if (sock->sock) {
    68                 talloc_free(sock->sock);
    69                 sock->sock = NULL;
    70         }
    71 
    72         if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
    73                 status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
    74         }
    75 
    76         if (NT_STATUS_EQUAL(NT_STATUS_OK, status)) {
    77                 status = NT_STATUS_END_OF_FILE;
    78         }
    79 
    80         if (p->transport.recv_data) {
    81                 p->transport.recv_data(p, NULL, status);
    82         }
    83 }
    84 
    85 
    86 /*
    87   handle socket recv errors
    88 */
    89 static void sock_error_handler(void *private_data, NTSTATUS status)
    90 {
    91         struct dcecli_connection *p = talloc_get_type(private_data,
    92                                                       struct dcecli_connection);
    93         sock_dead(p, status);
    94 }
    95 
    96 /*
    97   check if a blob is a complete packet
    98 */
    99 static NTSTATUS sock_complete_packet(void *private_data, DATA_BLOB blob, size_t *size)
    100 {
    101         if (blob.length < DCERPC_FRAG_LEN_OFFSET+2) {
    102                 return STATUS_MORE_ENTRIES;
    103         }
    104         *size = dcerpc_get_frag_length(&blob);
    105         if (*size < blob.length) {
    106                 /*
    107                  * something is wrong, let the caller deal with it
    108                  */
    109                 *size = blob.length;
    110         }
    111         if (*size > blob.length) {
    112                 return STATUS_MORE_ENTRIES;
    113         }
    114         return NT_STATUS_OK;
    115 }
    116 
    117 /*
    118   process recv requests
    119 */
    120 static NTSTATUS sock_process_recv(void *private_data, DATA_BLOB blob)
    121 {
    122         struct dcecli_connection *p = talloc_get_type(private_data,
    123                                                       struct dcecli_connection);
    124         struct sock_private *sock = (struct sock_private *)p->transport.private_data;
    125         sock->pending_reads--;
    126         if (sock->pending_reads == 0) {
    127                 packet_recv_disable(sock->packet);
    128         }
    129         p->transport.recv_data(p, &blob, NT_STATUS_OK);
    130         return NT_STATUS_OK;
    131 }
    132 
    133 /*
    134   called when a IO is triggered by the events system
    135 */
    136 static void sock_io_handler(struct tevent_context *ev, struct tevent_fd *fde,
    137                             uint16_t flags, void *private_data)
    138 {
    139         struct dcecli_connection *p = talloc_get_type(private_data,
    140                                                       struct dcecli_connection);
    141         struct sock_private *sock = (struct sock_private *)p->transport.private_data;
    142 
    143         if (flags & EVENT_FD_WRITE) {
    144                 packet_queue_run(sock->packet);
    145                 return;
    146         }
    147 
    148         if (sock->sock == NULL) {
    149                 return;
    150         }
    151 
    152         if (flags & EVENT_FD_READ) {
    153                 packet_recv(sock->packet);
    154         }
    155 }
    156 
    157 /*
    158    initiate a read request - not needed for dcerpc sockets
    159 */
    160 static NTSTATUS sock_send_read(struct dcecli_connection *p)
    161 {
    162         struct sock_private *sock = (struct sock_private *)p->transport.private_data;
    163         sock->pending_reads++;
    164         if (sock->pending_reads == 1) {
    165                 packet_recv_enable(sock->packet);
    166         }
    167         return NT_STATUS_OK;
    168 }
    169 
    170 /*
    171    send an initial pdu in a multi-pdu sequence
    172 */
    173 static NTSTATUS sock_send_request(struct dcecli_connection *p, DATA_BLOB *data,
    174                                   bool trigger_read)
    175 {
    176         struct sock_private *sock = (struct sock_private *)p->transport.private_data;
    177         DATA_BLOB blob;
    178         NTSTATUS status;
    179 
    180         if (sock->sock == NULL) {
    181                 return NT_STATUS_CONNECTION_DISCONNECTED;
    182         }
    183 
    184         blob = data_blob_talloc(sock->packet, data->data, data->length);
    185         if (blob.data == NULL) {
    186                 return NT_STATUS_NO_MEMORY;
    187         }
    188 
    189         status = packet_send(sock->packet, blob);
    190         if (!NT_STATUS_IS_OK(status)) {
    191                 return status;
    192         }
    193 
    194         if (trigger_read) {
    195                 sock_send_read(p);
    196         }
    197 
    198         return NT_STATUS_OK;
    199 }
    200 
    201 /*
    202    shutdown sock pipe connection
    203 */
    204 static NTSTATUS sock_shutdown_pipe(struct dcecli_connection *p, NTSTATUS status)
    205 {
    206         struct sock_private *sock = (struct sock_private *)p->transport.private_data;
    207 
    208         if (sock && sock->sock) {
    209                 sock_dead(p, status);
    210         }
    211 
    212         return status;
    213 }
    214 
    215 /*
    216   return sock server name
    217 */
    218 static const char *sock_peer_name(struct dcecli_connection *p)
    219 {
    220         struct sock_private *sock = talloc_get_type(p->transport.private_data, struct sock_private);
    221         return sock->server_name;
    222 }
    223 
    224 /*
    225   return remote name we make the actual connection (good for kerberos)
    226 */
    227 static const char *sock_target_hostname(struct dcecli_connection *p)
    228 {
    229         struct sock_private *sock = talloc_get_type(p->transport.private_data, struct sock_private);
    230         return sock->server_name;
    231 }
    232 
    233 
    23435struct pipe_open_socket_state {
    23536        struct dcecli_connection *conn;
    23637        struct socket_context *socket_ctx;
    237         struct sock_private *sock;
    23838        struct socket_address *localaddr;
    23939        struct socket_address *server;
    24040        const char *target_hostname;
    24141        enum dcerpc_transport_t transport;
     42        struct socket_address *client;
    24243};
    24344
     
    24647{
    24748        struct dcecli_connection *conn;
    248         struct sock_private *sock;
    249         struct composite_context *c = talloc_get_type(ctx->async.private_data,
    250                                                       struct composite_context);
    251         struct pipe_open_socket_state *s = talloc_get_type(c->private_data,
    252                                                            struct pipe_open_socket_state);
     49        struct composite_context *c = talloc_get_type_abort(
     50                ctx->async.private_data, struct composite_context);
     51        struct pipe_open_socket_state *s = talloc_get_type_abort(
     52                c->private_data, struct pipe_open_socket_state);
     53        int rc;
     54        int sock_fd;
    25355
    25456        /* make it easier to write a function calls */
    25557        conn = s->conn;
    256         sock = s->sock;
    25758
    25859        c->status = socket_connect_recv(ctx);
     
    26566        }
    26667
     68        s->client = socket_get_my_addr(s->socket_ctx, s);
     69        if (s->client == NULL) {
     70                TALLOC_FREE(s->socket_ctx);
     71                composite_error(c, NT_STATUS_NO_MEMORY);
     72                return;
     73        }
     74        sock_fd = socket_get_fd(s->socket_ctx);
     75        socket_set_flags(s->socket_ctx, SOCKET_FLAG_NOCLOSE);
     76        TALLOC_FREE(s->socket_ctx);
     77
    26778        /*
    26879          fill in the transport methods
     
    27182        conn->transport.private_data    = NULL;
    27283
    273         conn->transport.send_request    = sock_send_request;
    274         conn->transport.send_read       = sock_send_read;
    275         conn->transport.recv_data       = NULL;
    276 
    277         conn->transport.shutdown_pipe   = sock_shutdown_pipe;
    278         conn->transport.peer_name       = sock_peer_name;
    279         conn->transport.target_hostname = sock_target_hostname;
    280 
    281         sock->sock          = s->socket_ctx;
    282         sock->pending_reads = 0;
    283         sock->server_name   = strupper_talloc(sock, s->target_hostname);
    284 
    285         sock->fde = event_add_fd(conn->event_ctx, sock->sock, socket_get_fd(sock->sock),
    286                                  EVENT_FD_READ, sock_io_handler, conn);
    287        
    288         conn->transport.private_data = sock;
    289 
    290         sock->packet = packet_init(sock);
    291         if (sock->packet == NULL) {
     84        /*
     85         * Windows uses 5840 for ncacn_ip_tcp,
     86         * so we also use it (for every transport which uses bsd sockets)
     87         */
     88        conn->srv_max_xmit_frag = 5840;
     89        conn->srv_max_recv_frag = 5840;
     90
     91        conn->transport.pending_reads = 0;
     92        conn->server_name   = strupper_talloc(conn, s->target_hostname);
     93
     94        rc = tstream_bsd_existing_socket(conn, sock_fd,
     95                                         &conn->transport.stream);
     96        if (rc < 0) {
     97                close(sock_fd);
    29298                composite_error(c, NT_STATUS_NO_MEMORY);
    293                 talloc_free(sock);
    29499                return;
    295100        }
    296101
    297         packet_set_private(sock->packet, conn);
    298         packet_set_socket(sock->packet, sock->sock);
    299         packet_set_callback(sock->packet, sock_process_recv);
    300         packet_set_full_request(sock->packet, sock_complete_packet);
    301         packet_set_error_handler(sock->packet, sock_error_handler);
    302         packet_set_event_context(sock->packet, conn->event_ctx);
    303         packet_set_fde(sock->packet, sock->fde);
    304         packet_set_serialise(sock->packet);
    305         packet_set_initial_read(sock->packet, 16);
     102        conn->transport.write_queue =
     103                tevent_queue_create(conn, "dcerpc sock write queue");
     104        if (conn->transport.write_queue == NULL) {
     105                TALLOC_FREE(conn->transport.stream);
     106                composite_error(c, NT_STATUS_NO_MEMORY);
     107                return;
     108        }
    306109
    307110        /* ensure we don't get SIGPIPE */
     
    334137        s->transport = transport;
    335138        if (localaddr) {
    336                 s->localaddr = talloc_reference(c, localaddr);
     139                s->localaddr = socket_address_copy(s, localaddr);
    337140                if (composite_nomem(s->localaddr, c)) return c;
    338141        }
    339         s->server    = talloc_reference(c, server);
     142        s->server = socket_address_copy(s, server);
    340143        if (composite_nomem(s->server, c)) return c;
    341         s->target_hostname = talloc_reference(s, target_hostname);
    342 
    343         s->sock = talloc(cn, struct sock_private);
    344         if (composite_nomem(s->sock, c)) return c;
     144        if (target_hostname) {
     145                s->target_hostname = talloc_strdup(s, target_hostname);
     146                if (composite_nomem(s->target_hostname, c)) return c;
     147        }
    345148
    346149        c->status = socket_create(server->family, SOCKET_TYPE_STREAM, &s->socket_ctx, 0);
    347150        if (!composite_is_ok(c)) return c;
    348151
    349         talloc_steal(s->sock, s->socket_ctx);
    350 
    351         s->sock->path = talloc_reference(s->sock, full_path);
     152        talloc_steal(s, s->socket_ctx);
    352153
    353154        conn_req = socket_connect_send(s->socket_ctx, s->localaddr, s->server, 0,
     
    357158}
    358159
    359 
    360 static NTSTATUS dcerpc_pipe_open_socket_recv(struct composite_context *c)
     160static NTSTATUS dcerpc_pipe_open_socket_recv(struct composite_context *c,
     161                                             TALLOC_CTX *mem_ctx,
     162                                             struct socket_address **localaddr)
    361163{
    362164        NTSTATUS status = composite_wait(c);
     165
     166        if (NT_STATUS_IS_OK(status)) {
     167                struct pipe_open_socket_state *s =
     168                        talloc_get_type_abort(c->private_data,
     169                        struct pipe_open_socket_state);
     170
     171                if (localaddr != NULL) {
     172                        *localaddr = talloc_move(mem_ctx, &s->client);
     173                }
     174        }
    363175
    364176        talloc_free(c);
     
    369181        const char *server;
    370182        const char *target_hostname;
    371         const char *address;
     183        const char **addresses;
     184        uint32_t index;
    372185        uint32_t port;
    373186        struct socket_address *localaddr;
     
    375188        struct resolve_context *resolve_ctx;
    376189        struct dcecli_connection *conn;
     190        char *local_address;
     191        char *remote_address;
    377192};
    378193
    379194
    380 #if 0 /* disabled till we can resolve names to ipv6 addresses */
    381 static void continue_ipv6_open_socket(struct composite_context *ctx);
    382 #endif
    383 static void continue_ipv4_open_socket(struct composite_context *ctx);
     195static void continue_ip_open_socket(struct composite_context *ctx);
    384196static void continue_ip_resolve_name(struct composite_context *ctx);
    385197
    386198static void continue_ip_resolve_name(struct composite_context *ctx)
    387199{
    388         struct composite_context *c = talloc_get_type(ctx->async.private_data,
    389                                                       struct composite_context);
    390         struct pipe_tcp_state *s = talloc_get_type(c->private_data,
    391                                                   struct pipe_tcp_state);
    392         struct composite_context *sock_ipv4_req;
    393 
    394         c->status = resolve_name_recv(ctx, s, &s->address);
     200        struct composite_context *c = talloc_get_type_abort(
     201                ctx->async.private_data, struct composite_context);
     202        struct pipe_tcp_state *s = talloc_get_type_abort(
     203                c->private_data, struct pipe_tcp_state);
     204        struct composite_context *sock_ip_req;
     205
     206        c->status = resolve_name_multiple_recv(ctx, s, &s->addresses);
    395207        if (!composite_is_ok(c)) return;
    396208
    397209        /* prepare server address using host ip:port and transport name */
    398         s->srvaddr = socket_address_from_strings(s->conn, "ipv4", s->address, s->port);
     210        s->srvaddr = socket_address_from_strings(s->conn, "ip", s->addresses[s->index], s->port);
     211        s->index++;
    399212        if (composite_nomem(s->srvaddr, c)) return;
    400213
    401         /* resolve_nbt_name gives only ipv4 ... - send socket open request */
    402         sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr,
     214        sock_ip_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr,
    403215                                                     s->srvaddr, s->target_hostname,
    404216                                                     NULL,
    405217                                                     NCACN_IP_TCP);
    406         composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c);
    407 }
     218        composite_continue(c, sock_ip_req, continue_ip_open_socket, c);
     219}
     220
    408221
    409222/*
    410223  Stage 2 of dcerpc_pipe_open_tcp_send: receive result of pipe open request
    411   on IPv6 and send the request on IPv4 unless IPv6 transport succeeded.
    412 */
    413 #if 0 /* disabled till we can resolve names to ipv6 addresses */
    414 static void continue_ipv6_open_socket(struct composite_context *ctx)
    415 {
    416         struct composite_context *c = talloc_get_type(ctx->async.private_data,
    417                                                       struct composite_context);
    418         struct pipe_tcp_state *s = talloc_get_type(c->private_data,
    419                                                    struct pipe_tcp_state);
    420         struct composite_context *sock_ipv4_req;
    421 
    422         /* receive result of socket open request */
    423         c->status = dcerpc_pipe_open_socket_recv(ctx);
    424         if (NT_STATUS_IS_OK(c->status)) {
    425                 composite_done(c);
    426                 return;
    427         }
    428 
    429         talloc_free(s->srvaddr);
    430 
    431         /* prepare server address using host:ip and transport name */
    432         s->srvaddr = socket_address_from_strings(s->conn, "ipv4", s->address, s->port);
    433         if (composite_nomem(s->srvaddr, c)) return;
    434 
    435         /* try IPv4 if IPv6 fails */
    436         sock_ipv4_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr,
    437                                                      s->srvaddr, s->target_hostname,
    438                                                      NCACN_IP_TCP);
    439         composite_continue(c, sock_ipv4_req, continue_ipv4_open_socket, c);
    440 }
    441 #endif
    442 
    443 /*
    444   Stage 2 of dcerpc_pipe_open_tcp_send: receive result of pipe open request
    445   on IPv4 transport.
    446 */
    447 static void continue_ipv4_open_socket(struct composite_context *ctx)
    448 {
    449         struct composite_context *c = talloc_get_type(ctx->async.private_data,
    450                                                       struct composite_context);
    451         struct pipe_tcp_state *s = talloc_get_type(c->private_data,
    452                                                    struct pipe_tcp_state);
    453        
     224  on IP transport.
     225*/
     226static void continue_ip_open_socket(struct composite_context *ctx)
     227{
     228        struct composite_context *c = talloc_get_type_abort(
     229                ctx->async.private_data, struct composite_context);
     230        struct pipe_tcp_state *s = talloc_get_type_abort(
     231                c->private_data, struct pipe_tcp_state);
     232        struct socket_address *localaddr = NULL;
     233
    454234        /* receive result socket open request */
    455         c->status = dcerpc_pipe_open_socket_recv(ctx);
     235        c->status = dcerpc_pipe_open_socket_recv(ctx, s, &localaddr);
    456236        if (!NT_STATUS_IS_OK(c->status)) {
    457237                /* something went wrong... */
    458238                DEBUG(0, ("Failed to connect host %s (%s) on port %d - %s.\n",
    459                           s->address, s->target_hostname,
     239                          s->addresses[s->index - 1], s->target_hostname,
    460240                          s->port, nt_errstr(c->status)));
    461 
    462                 composite_error(c, c->status);
    463                 return;
    464         }
     241                if (s->addresses[s->index]) {
     242                        struct composite_context *sock_ip_req;
     243                        talloc_free(s->srvaddr);
     244                        /* prepare server address using host ip:port and transport name */
     245                        s->srvaddr = socket_address_from_strings(s->conn, "ip", s->addresses[s->index], s->port);
     246                        s->index++;
     247                        if (composite_nomem(s->srvaddr, c)) return;
     248
     249                        sock_ip_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr,
     250                                                                s->srvaddr, s->target_hostname,
     251                                                                NULL,
     252                                                                NCACN_IP_TCP);
     253                        composite_continue(c, sock_ip_req, continue_ip_open_socket, c);
     254
     255                        return;
     256                } else {
     257                        composite_error(c, c->status);
     258                        return;
     259                }
     260        }
     261
     262        s->local_address = talloc_strdup(s, localaddr->addr);
     263        if (composite_nomem(s->local_address, c)) return;
     264        s->remote_address = talloc_strdup(s, s->addresses[s->index - 1]);
     265        if (composite_nomem(s->remote_address, c)) return;
    465266
    466267        composite_done(c);
     
    517318  Receive result of pipe open request on tcp/ip
    518319*/
    519 NTSTATUS dcerpc_pipe_open_tcp_recv(struct composite_context *c)
     320NTSTATUS dcerpc_pipe_open_tcp_recv(struct composite_context *c,
     321                                   TALLOC_CTX *mem_ctx,
     322                                   char **localaddr,
     323                                   char **remoteaddr)
    520324{
    521325        NTSTATUS status;
    522326        status = composite_wait(c);
     327
     328        if (NT_STATUS_IS_OK(status)) {
     329                struct pipe_tcp_state *s = talloc_get_type_abort(
     330                        c->private_data, struct pipe_tcp_state);
     331
     332                if (localaddr != NULL) {
     333                        *localaddr = talloc_move(mem_ctx, &s->local_address);
     334                }
     335                if (remoteaddr != NULL) {
     336                        *remoteaddr = talloc_move(mem_ctx, &s->remote_address);
     337                }
     338        }
    523339
    524340        talloc_free(c);
     
    540356static void continue_unix_open_socket(struct composite_context *ctx)
    541357{
    542         struct composite_context *c = talloc_get_type(ctx->async.private_data,
    543                                                       struct composite_context);
    544 
    545         c->status = dcerpc_pipe_open_socket_recv(ctx);
     358        struct composite_context *c = talloc_get_type_abort(
     359                ctx->async.private_data, struct composite_context);
     360
     361        c->status = dcerpc_pipe_open_socket_recv(ctx, NULL, NULL);
    546362        if (NT_STATUS_IS_OK(c->status)) {
    547363                composite_done(c);
     
    607423static void continue_np_open_socket(struct composite_context *ctx)
    608424{
    609         struct composite_context *c = talloc_get_type(ctx->async.private_data,
    610                                                       struct composite_context);
    611 
    612         c->status = dcerpc_pipe_open_socket_recv(ctx);
     425        struct composite_context *c = talloc_get_type_abort(
     426                ctx->async.private_data, struct composite_context);
     427
     428        c->status = dcerpc_pipe_open_socket_recv(ctx, NULL, NULL);
    613429        if (!composite_is_ok(c)) return;
    614430
     
    678494        return dcerpc_pipe_open_pipe_recv(c);
    679495}
    680 
    681 const char *dcerpc_unix_socket_path(struct dcecli_connection *p)
    682 {
    683         struct sock_private *sock = (struct sock_private *)p->transport.private_data;
    684         return sock->path;
    685 }
    686 
    687 struct socket_address *dcerpc_socket_peer_addr(struct dcecli_connection *p, TALLOC_CTX *mem_ctx)
    688 {
    689         struct sock_private *sock = (struct sock_private *)p->transport.private_data;
    690         return socket_get_peer_addr(sock->sock, mem_ctx);
    691 }
    692 
  • vendor/current/source4/librpc/rpc/dcerpc_util.c

    r919 r988  
    3131#include "librpc/rpc/dcerpc_proto.h"
    3232#include "auth/credentials/credentials.h"
     33#include "auth/gensec/gensec.h"
    3334#include "param/param.h"
    3435#include "librpc/rpc/rpc_common.h"
     
    117118        struct dcerpc_pipe *pipe;
    118119        struct policy_handle handle;
    119         struct GUID guid;
     120        struct GUID object;
    120121        struct epm_twr_t twr;
    121122        struct epm_twr_t *twr_r;
     
    145146        if (!composite_is_ok(c)) return;
    146147
    147         /* prepare requested binding parameters */
    148         s->binding->object         = s->table->syntax_id;
    149 
    150148        c->status = dcerpc_binding_build_tower(s->pipe, s->binding, &s->twr.tower);
    151149        if (!composite_is_ok(c)) return;
    152150       
    153151        /* with some nice pretty paper around it of course */
    154         s->r.in.object        = &s->guid;
     152        s->r.in.object        = &s->object;
    155153        s->r.in.map_tower     = &s->twr;
    156154        s->r.in.entry_handle  = &s->handle;
     
    178176        struct epm_map_binding_state *s = talloc_get_type(c->private_data,
    179177                                                          struct epm_map_binding_state);
     178        const char *endpoint;
    180179
    181180        /* receive result of a rpc request */
     
    203202
    204203        /* get received endpoint */
    205         s->binding->endpoint = talloc_reference(s->binding,
    206                                                 dcerpc_floor_get_rhs_data(c, &s->twr_r->tower.floors[3]));
    207         if (composite_nomem(s->binding->endpoint, c)) return;
     204        endpoint = dcerpc_floor_get_rhs_data(s, &s->twr_r->tower.floors[3]);
     205        if (composite_nomem(endpoint, c)) return;
     206
     207        c->status = dcerpc_binding_set_string_option(s->binding,
     208                                                     "endpoint",
     209                                                     endpoint);
     210        if (!composite_is_ok(c)) {
     211                return;
     212        }
    208213
    209214        composite_done(c);
     
    218223                                                      struct dcerpc_binding *binding,
    219224                                                      const struct ndr_interface_table *table,
     225                                                      struct cli_credentials *creds,
    220226                                                      struct tevent_context *ev,
    221227                                                      struct loadparm_context *lp_ctx)
     
    224230        struct epm_map_binding_state *s;
    225231        struct composite_context *pipe_connect_req;
    226         struct cli_credentials *anon_creds;
    227 
    228232        NTSTATUS status;
    229233        struct dcerpc_binding *epmapper_binding;
     
    245249
    246250        s->binding = binding;
     251        s->object  = dcerpc_binding_get_object(binding);
    247252        s->table   = table;
    248253
    249         /* anonymous credentials for rpc connection used to get endpoint mapping */
    250         anon_creds = cli_credentials_init(mem_ctx);
    251         cli_credentials_set_anonymous(anon_creds);
     254        c->status = dcerpc_binding_set_abstract_syntax(binding,
     255                                                       &table->syntax_id);
     256        if (!composite_is_ok(c)) {
     257                return c;
     258        }
    252259
    253260        /*
    254261          First, check if there is a default endpoint specified in the IDL
    255262        */
    256         if (table != NULL) {
     263        for (i = 0; i < table->endpoints->count; i++) {
    257264                struct dcerpc_binding *default_binding;
    258 
    259                 /* Find one of the default pipes for this interface */
    260                 for (i = 0; i < table->endpoints->count; i++) {
    261                         status = dcerpc_parse_binding(mem_ctx, table->endpoints->names[i], &default_binding);
    262 
    263                         if (NT_STATUS_IS_OK(status)) {
    264                                 if (binding->transport == NCA_UNKNOWN)
    265                                         binding->transport = default_binding->transport;
    266                                 if (default_binding->transport == binding->transport &&
    267                                         default_binding->endpoint) {
    268                                         binding->endpoint = talloc_reference(binding, default_binding->endpoint);
    269                                         talloc_free(default_binding);
    270 
    271                                         composite_done(c);
    272                                         return c;
    273 
    274                                 } else {
    275                                         talloc_free(default_binding);
    276                                 }
     265                enum dcerpc_transport_t transport;
     266                enum dcerpc_transport_t dtransport;
     267                const char *dendpoint = NULL;
     268
     269                status = dcerpc_parse_binding(s,
     270                                              table->endpoints->names[i],
     271                                              &default_binding);
     272                if (!NT_STATUS_IS_OK(status)) {
     273                        continue;
     274                }
     275
     276                transport = dcerpc_binding_get_transport(binding);
     277                dtransport = dcerpc_binding_get_transport(default_binding);
     278                if (transport == NCA_UNKNOWN) {
     279                        c->status = dcerpc_binding_set_transport(binding,
     280                                                                 dtransport);
     281                        if (!composite_is_ok(c)) {
     282                                return c;
    277283                        }
    278                 }
    279         }
    280 
    281         epmapper_binding = talloc_zero(c, struct dcerpc_binding);
     284                        transport = dtransport;
     285                }
     286
     287                if (transport != dtransport) {
     288                        TALLOC_FREE(default_binding);
     289                        continue;
     290                }
     291
     292                dendpoint = dcerpc_binding_get_string_option(default_binding,
     293                                                             "endpoint");
     294                if (dendpoint == NULL) {
     295                        TALLOC_FREE(default_binding);
     296                        continue;
     297                }
     298
     299                c->status = dcerpc_binding_set_string_option(binding,
     300                                                             "endpoint",
     301                                                             dendpoint);
     302                if (!composite_is_ok(c)) {
     303                        return c;
     304                }
     305
     306                TALLOC_FREE(default_binding);
     307                composite_done(c);
     308                return c;
     309        }
     310
     311        epmapper_binding = dcerpc_binding_dup(s, binding);
    282312        if (composite_nomem(epmapper_binding, c)) return c;
    283313
    284314        /* basic endpoint mapping data */
    285         epmapper_binding->transport             = binding->transport;
    286         epmapper_binding->host                  = talloc_reference(epmapper_binding, binding->host);
    287         epmapper_binding->target_hostname       = epmapper_binding->host;
    288         epmapper_binding->options               = NULL;
    289         epmapper_binding->localaddress          = talloc_reference(epmapper_binding, binding->localaddress);
    290         epmapper_binding->flags                 = 0;
    291         epmapper_binding->assoc_group_id        = 0;
    292         epmapper_binding->endpoint              = NULL;
     315        c->status = dcerpc_binding_set_string_option(epmapper_binding,
     316                                                     "endpoint", NULL);
     317        if (!composite_is_ok(c)) {
     318                return c;
     319        }
     320        c->status = dcerpc_binding_set_flags(epmapper_binding, 0, UINT32_MAX);
     321        if (!composite_is_ok(c)) {
     322                return c;
     323        }
     324        c->status = dcerpc_binding_set_assoc_group_id(epmapper_binding, 0);
     325        if (!composite_is_ok(c)) {
     326                return c;
     327        }
     328        c->status = dcerpc_binding_set_object(epmapper_binding, GUID_zero());
     329        if (!composite_is_ok(c)) {
     330                return c;
     331        }
    293332
    294333        /* initiate rpc pipe connection */
    295         pipe_connect_req = dcerpc_pipe_connect_b_send(c, epmapper_binding,
     334        pipe_connect_req = dcerpc_pipe_connect_b_send(s, epmapper_binding,
    296335                                                      &ndr_table_epmapper,
    297                                                       anon_creds, c->event_ctx,
     336                                                      creds, c->event_ctx,
    298337                                                      lp_ctx);
    299338        if (composite_nomem(pipe_connect_req, c)) return c;
     
    324363{
    325364        struct composite_context *c;
    326 
    327         c = dcerpc_epm_map_binding_send(mem_ctx, binding, table, ev, lp_ctx);
     365        struct cli_credentials *epm_creds;
     366
     367        epm_creds = cli_credentials_init_anon(mem_ctx);
     368        if (epm_creds == NULL) {
     369                return NT_STATUS_NO_MEMORY;
     370        }
     371        c = dcerpc_epm_map_binding_send(mem_ctx, binding, table, epm_creds, ev, lp_ctx);
     372        if (c == NULL) {
     373                talloc_free(epm_creds);
     374                return NT_STATUS_NO_MEMORY;
     375        }
     376        talloc_steal(c, epm_creds);
    328377        return dcerpc_epm_map_binding_recv(c);
    329378}
     
    332381struct pipe_auth_state {
    333382        struct dcerpc_pipe *pipe;
    334         struct dcerpc_binding *binding;
     383        const struct dcerpc_binding *binding;
    335384        const struct ndr_interface_table *table;
    336385        struct loadparm_context *lp_ctx;
    337386        struct cli_credentials *credentials;
     387        unsigned int logon_retries;
    338388};
    339389
     
    395445                composite_continue(c, sec_conn_req, continue_ntlmssp_connection, c);
    396446                return;
    397         } else if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) {
    398                 if (cli_credentials_wrong_password(s->credentials)) {
     447        } else if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE) ||
     448                   NT_STATUS_EQUAL(c->status, NT_STATUS_UNSUCCESSFUL)) {
     449                /*
     450                  try a second time on any error. We don't just do it
     451                  on LOGON_FAILURE as some servers will give a
     452                  NT_STATUS_UNSUCCESSFUL on a authentication error on RPC
     453                 */
     454                const char *principal;
     455                const char *endpoint;
     456
     457                principal = gensec_get_target_principal(s->pipe->conn->security_state.generic_state);
     458                if (principal == NULL) {
     459                        const char *hostname = gensec_get_target_hostname(s->pipe->conn->security_state.generic_state);
     460                        const char *service  = gensec_get_target_service(s->pipe->conn->security_state.generic_state);
     461                        if (hostname != NULL && service != NULL) {
     462                                principal = talloc_asprintf(c, "%s/%s", service, hostname);
     463                        }
     464                }
     465
     466                endpoint = dcerpc_binding_get_string_option(s->binding, "endpoint");
     467
     468                if ((cli_credentials_failed_kerberos_login(s->credentials, principal, &s->logon_retries) ||
     469                     cli_credentials_wrong_password(s->credentials)) &&
     470                    endpoint != NULL) {
    399471                        /*
    400472                         * Retry SPNEGO with a better password
     
    524596*/
    525597struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p,
    526                                                 struct dcerpc_binding *binding,
     598                                                const struct dcerpc_binding *binding,
    527599                                                const struct ndr_interface_table *table,
    528600                                                struct cli_credentials *credentials,
     
    553625
    554626        conn = s->pipe->conn;
    555         conn->flags = binding->flags;
     627        conn->flags = dcerpc_binding_get_flags(binding);
    556628
    557629        if (DEBUGLVL(100)) {
    558630                conn->flags |= DCERPC_DEBUG_PRINT_BOTH;
    559631        }
    560        
    561         /* remember the binding string for possible secondary connections */
    562         conn->binding_string = dcerpc_binding_string(p, binding);
     632
     633        if (conn->transport.transport == NCALRPC) {
     634                const char *v = dcerpc_binding_get_string_option(binding,
     635                                                        "auth_type");
     636
     637                if (v != NULL && strcmp(v, "ncalrpc_as_system") == 0) {
     638                        auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
     639                                                 s->credentials,
     640                                                 lpcfg_gensec_settings(c, s->lp_ctx),
     641                                                 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
     642                                                 DCERPC_AUTH_LEVEL_CONNECT,
     643                                                 s->table->authservices->names[0]);
     644                        composite_continue(c, auth_req, continue_auth, c);
     645                        return c;
     646                }
     647        }
    563648
    564649        if (cli_credentials_is_anonymous(s->credentials)) {
     
    568653        }
    569654
    570         if ((binding->flags & DCERPC_SCHANNEL) &&
     655        if ((conn->flags & DCERPC_SCHANNEL) &&
    571656            !cli_credentials_get_netlogon_creds(s->credentials)) {
    572657                /* If we don't already have netlogon credentials for
     
    585670         */
    586671        if (conn->transport.transport == NCACN_NP &&
    587             !(s->binding->flags & (DCERPC_SIGN|DCERPC_SEAL))) {
     672            !(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) {
    588673                auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table);
    589674                composite_continue(c, auth_none_req, continue_auth_none, c);
     
    605690        }
    606691
    607         if (s->binding->flags & DCERPC_AUTH_SPNEGO) {
     692        if (conn->flags & DCERPC_AUTH_SPNEGO) {
    608693                auth_type = DCERPC_AUTH_TYPE_SPNEGO;
    609694
    610         } else if (s->binding->flags & DCERPC_AUTH_KRB5) {
     695        } else if (conn->flags & DCERPC_AUTH_KRB5) {
    611696                auth_type = DCERPC_AUTH_TYPE_KRB5;
    612697
    613         } else if (s->binding->flags & DCERPC_SCHANNEL) {
     698        } else if (conn->flags & DCERPC_SCHANNEL) {
    614699                auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
    615700
    616         } else if (s->binding->flags & DCERPC_AUTH_NTLM) {
     701        } else if (conn->flags & DCERPC_AUTH_NTLM) {
    617702                auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
    618703
     
    657742        if (!NT_STATUS_IS_OK(status)) {
    658743                char *uuid_str = GUID_string(s->pipe, &s->table->syntax_id.uuid);
    659                 DEBUG(0, ("Failed to bind to uuid %s - %s\n", uuid_str, nt_errstr(status)));
     744                DEBUG(0, ("Failed to bind to uuid %s for %s %s\n", uuid_str,
     745                          dcerpc_binding_string(uuid_str, s->binding), nt_errstr(status)));
    660746                talloc_free(uuid_str);
    661747        } else {
     
    676762_PUBLIC_ NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx,
    677763                          struct dcerpc_pipe **p,
    678                           struct dcerpc_binding *binding,
     764                          const struct dcerpc_binding *binding,
    679765                          const struct ndr_interface_table *table,
    680766                          struct cli_credentials *credentials,
     
    691777                                    DATA_BLOB *session_key)
    692778{
     779        *session_key = data_blob_null;
     780
     781        if (c != NULL) {
     782                if (c->transport.transport != NCALRPC &&
     783                    c->transport.transport != NCACN_UNIX_STREAM)
     784                {
     785                        return NT_STATUS_LOCAL_USER_SESSION_KEY;
     786                }
     787        }
     788
    693789        /* this took quite a few CPU cycles to find ... */
    694790        session_key->data = discard_const_p(unsigned char, "SystemLibraryDTC");
     
    735831        for (i=0;i<num_examples;i++) {
    736832                char *name=NULL;
    737                 asprintf(&name, "%s/rpclog/%s-%u.%d.%s",
    738                          lockdir, ndr->name, opnum, i,
    739                          (flags&NDR_IN)?"in":"out");
    740                 if (name == NULL) {
     833                int ret;
     834                ret = asprintf(&name, "%s/rpclog/%s-%u.%d.%s",
     835                               lockdir, ndr->name, opnum, i,
     836                               (flags&NDR_IN)?"in":"out");
     837                if (ret == -1) {
    741838                        return;
    742839                }
     
    779876        p2->transfer_syntax = p->transfer_syntax;
    780877
    781         p2->binding = talloc_reference(p2, p->binding);
     878        p2->binding = dcerpc_binding_dup(p2, p->binding);
     879        if (p2->binding == NULL) {
     880                talloc_free(p2);
     881                return NT_STATUS_NO_MEMORY;
     882        }
    782883
    783884        p2->binding_handle = dcerpc_pipe_binding_handle(p2);
  • vendor/current/source4/librpc/rpc/pyrpc.c

    r740 r988  
    2727#include "librpc/rpc/pyrpc_util.h"
    2828#include "auth/credentials/pycredentials.h"
     29#include "auth/gensec/gensec.h"
    2930
    3031void initbase(void);
    3132
    32 staticforward PyTypeObject dcerpc_InterfaceType;
     33static PyTypeObject dcerpc_InterfaceType;
     34
     35static PyTypeObject *ndr_syntax_id_Type;
    3336
    3437static bool PyString_AsGUID(PyObject *object, struct GUID *uuid)
     
    118121}
    119122
     123static PyObject *py_iface_session_key(PyObject *obj, void *closure)
     124{
     125        dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
     126        DATA_BLOB session_key;
     127
     128        NTSTATUS status = dcerpc_fetch_session_key(iface->pipe, &session_key);
     129        PyErr_NTSTATUS_IS_ERR_RAISE(status);
     130
     131        return PyString_FromStringAndSize((const char *)session_key.data, session_key.length);
     132}
     133
     134static PyObject *py_iface_user_session_key(PyObject *obj, void *closure)
     135{
     136        dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
     137        TALLOC_CTX *mem_ctx;
     138        NTSTATUS status;
     139        struct gensec_security *security = NULL;
     140        DATA_BLOB session_key = data_blob_null;
     141        static PyObject *session_key_obj = NULL;
     142
     143        if (iface->pipe == NULL) {
     144                PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY);
     145                return NULL;
     146        }
     147
     148        if (iface->pipe->conn == NULL) {
     149                PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY);
     150                return NULL;
     151        }
     152
     153        if (iface->pipe->conn->security_state.generic_state == NULL) {
     154                PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY);
     155                return NULL;
     156        }
     157
     158        security = iface->pipe->conn->security_state.generic_state;
     159
     160        mem_ctx = talloc_new(NULL);
     161
     162        status = gensec_session_key(security, mem_ctx, &session_key);
     163        if (!NT_STATUS_IS_OK(status)) {
     164                talloc_free(mem_ctx);
     165                PyErr_SetNTSTATUS(status);
     166                return NULL;
     167        }
     168
     169        session_key_obj = PyString_FromStringAndSize((const char *)session_key.data,
     170                                                     session_key.length);
     171        talloc_free(mem_ctx);
     172        return session_key_obj;
     173}
     174
    120175static PyGetSetDef dcerpc_interface_getsetters[] = {
    121176        { discard_const_p(char, "server_name"), py_iface_server_name, NULL,
     
    125180        { discard_const_p(char, "transfer_syntax"), py_iface_transfer_syntax, NULL,
    126181          discard_const_p(char, "syntax id of the transfersyntax") },
     182        { discard_const_p(char, "session_key"), py_iface_session_key, NULL,
     183          discard_const_p(char, "session key (as used for blob encryption on LSA and SAMR)") },
     184        { discard_const_p(char, "user_session_key"), py_iface_user_session_key, NULL,
     185          discard_const_p(char, "user_session key (as used for blob encryption on DRSUAPI)") },
    127186        { NULL }
    128187};
     
    142201        NTSTATUS status;
    143202        char *in_data;
    144         int in_length;
     203        Py_ssize_t in_length;
    145204        PyObject *ret;
    146205        PyObject *object = NULL;
     
    188247}
    189248
    190 static PyObject *py_iface_alter_context(PyObject *self, PyObject *args, PyObject *kwargs)
    191 {
    192         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self;
    193         NTSTATUS status;
    194         const char *kwnames[] = { "abstract_syntax", "transfer_syntax", NULL };
    195         PyObject *py_abstract_syntax = Py_None, *py_transfer_syntax = Py_None;
    196         struct ndr_syntax_id abstract_syntax, transfer_syntax;
    197 
    198         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:alter_context",
    199                 discard_const_p(char *, kwnames), &py_abstract_syntax,
    200                 &py_transfer_syntax)) {
    201                 return NULL;
    202         }
    203 
    204         if (!ndr_syntax_from_py_object(py_abstract_syntax, &abstract_syntax))
    205                 return NULL;
    206 
    207         if (py_transfer_syntax == Py_None) {
    208                 transfer_syntax = ndr_transfer_syntax;
    209         } else {
    210                 if (!ndr_syntax_from_py_object(py_transfer_syntax,
    211                                                &transfer_syntax))
    212                         return NULL;
    213         }
    214 
    215         status = dcerpc_alter_context(iface->pipe, iface->pipe, &abstract_syntax,
    216                                       &transfer_syntax);
    217 
    218         if (!NT_STATUS_IS_OK(status)) {
    219                 PyErr_SetDCERPCStatus(iface->pipe, status);
    220                 return NULL;
    221         }
    222 
    223         Py_RETURN_NONE;
    224 }
    225 
    226249static PyMethodDef dcerpc_interface_methods[] = {
    227250        { "request", (PyCFunction)py_iface_request, METH_VARARGS|METH_KEYWORDS, "S.request(opnum, data, object=None) -> data\nMake a raw request" },
    228         { "alter_context", (PyCFunction)py_iface_alter_context, METH_VARARGS|METH_KEYWORDS, "S.alter_context(syntax)\nChange to a different interface" },
    229251        { NULL, NULL, 0, NULL },
    230252};
     
    233255{
    234256        dcerpc_InterfaceObject *interface = (dcerpc_InterfaceObject *)self;
    235         talloc_free(interface->mem_ctx);
     257        interface->binding_handle = NULL;
     258        interface->pipe = NULL;
     259        TALLOC_FREE(interface->mem_ctx);
    236260        self->ob_type->tp_free(self);
    237261}
     
    239263static PyObject *dcerpc_interface_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
    240264{
    241         dcerpc_InterfaceObject *ret;
    242         const char *binding_string;
    243         struct cli_credentials *credentials;
    244         struct loadparm_context *lp_ctx = NULL;
    245         PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None;
    246         TALLOC_CTX *mem_ctx;
    247         struct tevent_context *event_ctx;
    248         NTSTATUS status;
    249 
    250         PyObject *syntax, *py_basis = Py_None;
     265        PyObject *ret;
     266        const char *binding_string = NULL;
     267        PyObject *py_lp_ctx = Py_None;
     268        PyObject *py_credentials = Py_None;
     269        PyObject *syntax = Py_None;
     270        PyObject *py_basis = Py_None;
    251271        const char *kwnames[] = {
    252272                "binding", "syntax", "lp_ctx", "credentials", "basis_connection", NULL
    253273        };
    254         struct ndr_interface_table *table;
     274        static struct ndr_interface_table dummy_table;
     275        PyObject *args2 = Py_None;
     276        PyObject *kwargs2 = Py_None;
    255277
    256278        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|OOO:connect", discard_const_p(char *, kwnames), &binding_string, &syntax, &py_lp_ctx, &py_credentials, &py_basis)) {
     
    258280        }
    259281
    260         mem_ctx = talloc_new(NULL);
    261         if (mem_ctx == NULL) {
    262                 PyErr_NoMemory();
    263                 return NULL;
    264         }
    265 
    266         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
    267         if (lp_ctx == NULL) {
    268                 PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
    269                 talloc_free(mem_ctx);
    270                 return NULL;
    271         }
    272 
    273         credentials = cli_credentials_from_py_object(py_credentials);
    274         if (credentials == NULL) {
    275                 PyErr_SetString(PyExc_TypeError, "Expected credentials");
    276                 talloc_free(mem_ctx);
    277                 return NULL;
    278         }
    279         ret = PyObject_New(dcerpc_InterfaceObject, type);
    280         ret->mem_ctx = mem_ctx;
    281 
    282         event_ctx = s4_event_context_init(ret->mem_ctx);
    283 
    284         /* Create a dummy interface table struct. TODO: In the future, we should
     282        if (strncmp(binding_string, "irpc:", 5) == 0) {
     283                PyErr_SetString(PyExc_ValueError, "irpc: transport not supported");
     284                return NULL;
     285        }
     286
     287        /*
     288         * Fill a dummy interface table struct. TODO: In the future, we should
    285289         * rather just allow connecting without requiring an interface table.
     290         *
     291         * We just fill the syntax during the connect, but keep the memory valid
     292         * the whole time.
    286293         */
    287 
    288         table = talloc_zero(ret->mem_ctx, struct ndr_interface_table);
    289 
    290         if (table == NULL) {
    291                 PyErr_SetString(PyExc_MemoryError, "Allocating interface table");
    292                 talloc_free(mem_ctx);
    293                 return NULL;
    294         }
    295 
    296         if (!ndr_syntax_from_py_object(syntax, &table->syntax_id)) {
    297                 talloc_free(mem_ctx);
    298                 return NULL;
    299         }
    300 
    301         ret->pipe = NULL;
    302         ret->binding_handle = NULL;
    303 
    304         if (py_basis != Py_None) {
    305                 struct dcerpc_pipe *base_pipe;
    306 
    307                 if (!PyObject_TypeCheck(py_basis, &dcerpc_InterfaceType)) {
    308                         PyErr_SetString(PyExc_ValueError, "basis_connection must be a DCE/RPC connection");
    309                         talloc_free(mem_ctx);
    310                         return NULL;
    311                 }
    312 
    313                 base_pipe = talloc_reference(ret->mem_ctx,
    314                                          ((dcerpc_InterfaceObject *)py_basis)->pipe);
    315 
    316                 status = dcerpc_secondary_context(base_pipe, &ret->pipe, table);
    317 
    318                 ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe);
    319         } else {
    320                 status = dcerpc_pipe_connect(ret->mem_ctx, &ret->pipe, binding_string,
    321                              table, credentials, event_ctx, lp_ctx);
    322         }
    323 
    324         if (!NT_STATUS_IS_OK(status)) {
    325                 PyErr_SetDCERPCStatus(ret->pipe, status);
    326                 talloc_free(ret->mem_ctx);
    327                 return NULL;
    328         }
    329         ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;
    330         ret->binding_handle = ret->pipe->binding_handle;
    331         return (PyObject *)ret;
     294        if (!ndr_syntax_from_py_object(syntax, &dummy_table.syntax_id)) {
     295                return NULL;
     296        }
     297
     298        args2 = Py_BuildValue("(s)", binding_string);
     299        if (args2 == NULL) {
     300                return NULL;
     301        }
     302
     303        kwargs2 = Py_BuildValue("{s:O,s:O,s:O}",
     304                                "lp_ctx", py_lp_ctx,
     305                                "credentials", py_credentials,
     306                                "basis_connection", py_basis);
     307        if (kwargs2 == NULL) {
     308                Py_DECREF(args2);
     309                return NULL;
     310        }
     311
     312        ret = py_dcerpc_interface_init_helper(type, args2, kwargs2, &dummy_table);
     313        ZERO_STRUCT(dummy_table.syntax_id);
     314        Py_DECREF(args2);
     315        Py_DECREF(kwargs2);
     316        return ret;
    332317}
    333318
     
    350335};
    351336
     337static PyObject *py_transfer_syntax_ndr_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     338{
     339        return py_dcerpc_syntax_init_helper(type, args, kwargs, &ndr_transfer_syntax_ndr);
     340}
     341
     342static PyTypeObject py_transfer_syntax_ndr_SyntaxType = {
     343        PyObject_HEAD_INIT(NULL) 0,
     344        .tp_name = "base.transfer_syntax_ndr",
     345        .tp_doc = "transfer_syntax_ndr()\n",
     346        .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     347        .tp_new = py_transfer_syntax_ndr_new,
     348};
     349
     350static PyObject *py_transfer_syntax_ndr64_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     351{
     352        return py_dcerpc_syntax_init_helper(type, args, kwargs, &ndr_transfer_syntax_ndr64);
     353}
     354
     355static PyTypeObject py_transfer_syntax_ndr64_SyntaxType = {
     356        PyObject_HEAD_INIT(NULL) 0,
     357        .tp_name = "base.transfer_syntax_ndr64",
     358        .tp_doc = "transfer_syntax_ndr64()\n",
     359        .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     360        .tp_new = py_transfer_syntax_ndr64_new,
     361};
     362
     363static PyObject *py_bind_time_features_syntax_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     364{
     365        const char *kwnames[] = {
     366                "features", NULL
     367        };
     368        unsigned long long features = 0;
     369        struct ndr_syntax_id syntax;
     370        PyObject *args2 = Py_None;
     371        PyObject *kwargs2 = Py_None;
     372
     373        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "K:features", discard_const_p(char *, kwnames), &features)) {
     374                return NULL;
     375        }
     376
     377        args2 = Py_BuildValue("()");
     378        if (args2 == NULL) {
     379                return NULL;
     380        }
     381
     382        kwargs2 = Py_BuildValue("{}");
     383        if (kwargs2 == NULL) {
     384                Py_DECREF(args2);
     385                return NULL;
     386        }
     387
     388        syntax = dcerpc_construct_bind_time_features(features);
     389
     390        return py_dcerpc_syntax_init_helper(type, args2, kwargs2, &syntax);
     391}
     392
     393static PyTypeObject py_bind_time_features_syntax_SyntaxType = {
     394        PyObject_HEAD_INIT(NULL) 0,
     395        .tp_name = "base.bind_time_features_syntax",
     396        .tp_doc = "bind_time_features_syntax(features)\n",
     397        .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     398        .tp_new = py_bind_time_features_syntax_new,
     399};
     400
    352401void initbase(void)
    353402{
    354403        PyObject *m;
     404        PyObject *dep_samba_dcerpc_misc;
     405
     406        dep_samba_dcerpc_misc = PyImport_ImportModule("samba.dcerpc.misc");
     407        if (dep_samba_dcerpc_misc == NULL)
     408                return;
     409
     410        ndr_syntax_id_Type = (PyTypeObject *)PyObject_GetAttrString(dep_samba_dcerpc_misc, "ndr_syntax_id");
     411        if (ndr_syntax_id_Type == NULL)
     412                return;
     413
     414        py_transfer_syntax_ndr_SyntaxType.tp_base = ndr_syntax_id_Type;
     415        py_transfer_syntax_ndr_SyntaxType.tp_basicsize = pytalloc_BaseObject_size();
     416        py_transfer_syntax_ndr64_SyntaxType.tp_base = ndr_syntax_id_Type;
     417        py_transfer_syntax_ndr64_SyntaxType.tp_basicsize = pytalloc_BaseObject_size();
     418        py_bind_time_features_syntax_SyntaxType.tp_base = ndr_syntax_id_Type;
     419        py_bind_time_features_syntax_SyntaxType.tp_basicsize = pytalloc_BaseObject_size();
    355420
    356421        if (PyType_Ready(&dcerpc_InterfaceType) < 0)
     422                return;
     423
     424        if (PyType_Ready(&py_transfer_syntax_ndr_SyntaxType) < 0)
     425                return;
     426        if (PyType_Ready(&py_transfer_syntax_ndr64_SyntaxType) < 0)
     427                return;
     428        if (PyType_Ready(&py_bind_time_features_syntax_SyntaxType) < 0)
    357429                return;
    358430
     
    363435        Py_INCREF((PyObject *)&dcerpc_InterfaceType);
    364436        PyModule_AddObject(m, "ClientConnection", (PyObject *)&dcerpc_InterfaceType);
    365 }
     437
     438        Py_INCREF((PyObject *)(void *)&py_transfer_syntax_ndr_SyntaxType);
     439        PyModule_AddObject(m, "transfer_syntax_ndr", (PyObject *)(void *)&py_transfer_syntax_ndr_SyntaxType);
     440        Py_INCREF((PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType);
     441        PyModule_AddObject(m, "transfer_syntax_ndr64", (PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType);
     442        Py_INCREF((PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType);
     443        PyModule_AddObject(m, "bind_time_features_syntax", (PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType);
     444}
  • vendor/current/source4/librpc/rpc/pyrpc.h

    r740 r988  
    5757PyObject *py_import_netr_Validation(TALLOC_CTX *mem_ctx, int level, union netr_Validation *in);
    5858
     59union netr_CONTROL_DATA_INFORMATION *py_export_netr_CONTROL_DATA_INFORMATION(TALLOC_CTX *mem_ctx, int level, PyObject *in);
     60union netr_CONTROL_QUERY_INFORMATION;
     61PyObject *py_import_netr_CONTROL_QUERY_INFORMATION(TALLOC_CTX *mem_ctx, int level, union netr_CONTROL_QUERY_INFORMATION *in);
     62
     63#ifndef NDR_DCERPC_REQUEST_OBJECT_PRESENT
     64#define NDR_DCERPC_REQUEST_OBJECT_PRESENT LIBNDR_FLAG_OBJECT_PRESENT
     65#endif /* NDR_DCERPC_REQUEST_OBJECT_PRESENT */
     66
    5967#endif /* _PYRPC_H_ */
  • vendor/current/source4/librpc/rpc/pyrpc_util.c

    r740 r988  
    4343                PyErr_Format(PyExc_RuntimeError, "Unable to import %s to check type %s",
    4444                        module, type_name);
    45                 return NULL;
     45                return false;
    4646        }
    4747
     
    5151                PyErr_Format(PyExc_RuntimeError, "Unable to find type %s in module %s",
    5252                        module, type_name);
    53                 return NULL;
     53                return false;
    5454        }
    5555
     
    7373                                   struct dcerpc_binding_handle **binding_handle)
    7474{
    75         struct messaging_context *msg;
    76 
    77         msg = messaging_client_init(mem_ctx, lpcfg_messaging_path(mem_ctx, lp_ctx), event_ctx);
     75        struct imessaging_context *msg;
     76
     77        msg = imessaging_client_init(mem_ctx, lp_ctx, event_ctx);
    7878        NT_STATUS_HAVE_NO_MEMORY(msg);
    7979
     
    8484        }
    8585
     86        /*
     87         * Note: this allows nested event loops to happen,
     88         * but as there's no top level event loop it's not that critical.
     89         */
     90        dcerpc_binding_handle_set_sync_ev(*binding_handle, event_ctx);
     91
    8692        return NT_STATUS_OK;
    8793}
     
    9298        dcerpc_InterfaceObject *ret;
    9399        const char *binding_string;
    94         struct cli_credentials *credentials;
    95         struct loadparm_context *lp_ctx = NULL;
    96100        PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None, *py_basis = Py_None;
    97         TALLOC_CTX *mem_ctx = NULL;
    98         struct tevent_context *event_ctx;
    99101        NTSTATUS status;
    100 
    101102        const char *kwnames[] = {
    102103                "binding", "lp_ctx", "credentials", "basis_connection", NULL
     
    107108        }
    108109
    109         mem_ctx = talloc_new(NULL);
    110         if (mem_ctx == NULL) {
    111                 PyErr_NoMemory();
    112                 return NULL;
    113         }
    114 
    115         lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
    116         if (lp_ctx == NULL) {
    117                 PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
    118                 talloc_free(mem_ctx);
    119                 return NULL;
    120         }
    121 
    122         status = dcerpc_init(lp_ctx);
     110        status = dcerpc_init();
    123111        if (!NT_STATUS_IS_OK(status)) {
    124112                PyErr_SetNTSTATUS(status);
    125                 talloc_free(mem_ctx);
    126113                return NULL;
    127114        }
    128115
    129116        ret = PyObject_New(dcerpc_InterfaceObject, type);
    130         ret->mem_ctx = mem_ctx;
    131 
    132         event_ctx = s4_event_context_init(ret->mem_ctx);
     117        ret->pipe = NULL;
     118        ret->binding_handle = NULL;
     119        ret->mem_ctx = talloc_new(NULL);
     120        if (ret->mem_ctx == NULL) {
     121                PyErr_NoMemory();
     122                return NULL;
     123        }
    133124
    134125        if (strncmp(binding_string, "irpc:", 5) == 0) {
    135                 ret->pipe = NULL;
     126                struct tevent_context *event_ctx;
     127                struct loadparm_context *lp_ctx;
     128
     129                event_ctx = s4_event_context_init(ret->mem_ctx);
     130                if (event_ctx == NULL) {
     131                        PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
     132                        TALLOC_FREE(ret->mem_ctx);
     133                        return NULL;
     134                }
     135
     136                lp_ctx = lpcfg_from_py_object(event_ctx, py_lp_ctx);
     137                if (lp_ctx == NULL) {
     138                        PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
     139                        TALLOC_FREE(ret->mem_ctx);
     140                        return NULL;
     141                }
     142
    136143                status = pyrpc_irpc_connect(ret->mem_ctx, binding_string+5, table,
    137144                                            event_ctx, lp_ctx, &ret->binding_handle);
     145                if (!NT_STATUS_IS_OK(status)) {
     146                        PyErr_SetNTSTATUS(status);
     147                        TALLOC_FREE(ret->mem_ctx);
     148                        return NULL;
     149                }
    138150        } else if (py_basis != Py_None) {
    139151                struct dcerpc_pipe *base_pipe;
     
    143155                py_base = PyImport_ImportModule("samba.dcerpc.base");
    144156                if (py_base == NULL) {
    145                         talloc_free(mem_ctx);
     157                        TALLOC_FREE(ret->mem_ctx);
    146158                        return NULL;
    147159                }
     
    150162                if (ClientConnection_Type == NULL) {
    151163                        PyErr_SetNone(PyExc_TypeError);
    152                         talloc_free(mem_ctx);
     164                        TALLOC_FREE(ret->mem_ctx);
    153165                        return NULL;
    154166                }
     
    156168                if (!PyObject_TypeCheck(py_basis, ClientConnection_Type)) {
    157169                        PyErr_SetString(PyExc_TypeError, "basis_connection must be a DCE/RPC connection");
    158                         talloc_free(mem_ctx);
    159                         return NULL;
    160                 }
    161 
    162                 base_pipe = talloc_reference(mem_ctx, ((dcerpc_InterfaceObject *)py_basis)->pipe);
     170                        TALLOC_FREE(ret->mem_ctx);
     171                        return NULL;
     172                }
     173
     174                base_pipe = talloc_reference(ret->mem_ctx,
     175                                         ((dcerpc_InterfaceObject *)py_basis)->pipe);
     176                if (base_pipe == NULL) {
     177                        PyErr_NoMemory();
     178                        TALLOC_FREE(ret->mem_ctx);
     179                        return NULL;
     180                }
    163181
    164182                status = dcerpc_secondary_context(base_pipe, &ret->pipe, table);
     183                if (!NT_STATUS_IS_OK(status)) {
     184                        PyErr_SetNTSTATUS(status);
     185                        TALLOC_FREE(ret->mem_ctx);
     186                        return NULL;
     187                }
    165188
    166189                ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe);
    167190        } else {
     191                struct tevent_context *event_ctx;
     192                struct loadparm_context *lp_ctx;
     193                struct cli_credentials *credentials;
     194
     195                event_ctx = s4_event_context_init(ret->mem_ctx);
     196                if (event_ctx == NULL) {
     197                        PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
     198                        TALLOC_FREE(ret->mem_ctx);
     199                        return NULL;
     200                }
     201
     202                lp_ctx = lpcfg_from_py_object(event_ctx, py_lp_ctx);
     203                if (lp_ctx == NULL) {
     204                        PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
     205                        TALLOC_FREE(ret->mem_ctx);
     206                        return NULL;
     207                }
     208
    168209                credentials = cli_credentials_from_py_object(py_credentials);
    169210                if (credentials == NULL) {
    170211                        PyErr_SetString(PyExc_TypeError, "Expected credentials");
    171                         talloc_free(mem_ctx);
    172                         return NULL;
    173                 }
    174                 status = dcerpc_pipe_connect(event_ctx, &ret->pipe, binding_string,
    175                              table, credentials, event_ctx, lp_ctx);
    176         }
    177         if (NT_STATUS_IS_ERR(status)) {
    178                 PyErr_SetNTSTATUS(status);
    179                 talloc_free(mem_ctx);
    180                 return NULL;
     212                        TALLOC_FREE(ret->mem_ctx);
     213                        return NULL;
     214                }
     215                status = dcerpc_pipe_connect(ret->mem_ctx, &ret->pipe, binding_string,
     216                             table, credentials, event_ctx, lp_ctx);
     217                if (!NT_STATUS_IS_OK(status)) {
     218                        PyErr_SetNTSTATUS(status);
     219                        TALLOC_FREE(ret->mem_ctx);
     220                        return NULL;
     221                }
     222
     223                /*
     224                 * the event context is cached under the connection,
     225                 * so let it be a child of it.
     226                 */
     227                talloc_steal(ret->pipe->conn, event_ctx);
    181228        }
    182229
     
    247294                struct wrapperbase *wb = (struct wrapperbase *)calloc(sizeof(struct wrapperbase), 1);
    248295
     296                if (wb == NULL) {
     297                        return false;
     298                }
    249299                wb->name = discard_const_p(char, mds[i].name);
    250300                wb->flags = PyWrapperFlag_KEYWORDS;
     
    261311}
    262312
     313PyObject *py_dcerpc_syntax_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs,
     314                                       const struct ndr_syntax_id *syntax)
     315{
     316        PyObject *ret;
     317        struct ndr_syntax_id *obj;
     318        const char *kwnames[] = { NULL };
     319
     320        if (!PyArg_ParseTupleAndKeywords(args, kwargs, ":abstract_syntax", discard_const_p(char *, kwnames))) {
     321                return NULL;
     322        }
     323
     324        ret = pytalloc_new(struct ndr_syntax_id, type);
     325        if (ret == NULL) {
     326                return NULL;
     327        }
     328
     329        obj = (struct ndr_syntax_id *)pytalloc_get_ptr(ret);
     330        *obj = *syntax;
     331
     332        return ret;
     333}
     334
    263335void PyErr_SetDCERPCStatus(struct dcerpc_pipe *p, NTSTATUS status)
    264336{
     
    278350  r_ctx is the context that is a parent of r. It will be referenced by
    279351  the resulting python object
     352
     353  This MUST only be used by objects that are based on pytalloc_Object
     354  otherwise the pytalloc_reference_ex() will fail.
    280355 */
    281356PyObject *py_return_ndr_struct(const char *module_name, const char *type_name,
     
    299374        }
    300375
    301         return py_talloc_reference_ex(py_type, r_ctx, r);
     376        return pytalloc_reference_ex(py_type, r_ctx, r);
    302377}
    303378
  • vendor/current/source4/librpc/rpc/pyrpc_util.h

    r740 r988  
    5151PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs, const struct ndr_interface_table *table);
    5252
     53struct ndr_syntax_id;
     54PyObject *py_dcerpc_syntax_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs,
     55                                       const struct ndr_syntax_id *syntax);
     56
    5357PyObject *py_return_ndr_struct(const char *module_name, const char *type_name,
    5458                               TALLOC_CTX *r_ctx, void *r);
  • vendor/current/source4/librpc/tests/binding_string.c

    r740 r988  
    2525#include "librpc/rpc/dcerpc_proto.h"
    2626#include "torture/torture.h"
     27#include "torture/local/proto.h"
    2728#include "lib/util/util_net.h"
    2829
     
    3233        const char *binding = test_data;
    3334        struct dcerpc_binding *b, *b2;
    34         const char *s, *s2;
     35        char *s, *s2, *p;
    3536        struct epm_tower tower;
    3637        TALLOC_CTX *mem_ctx = tctx;
     38        const char *host;
     39        struct GUID object;
    3740
    3841        /* Parse */
     
    4043                "Error parsing binding string");
    4144
     45        object = dcerpc_binding_get_object(b);
     46
    4247        s = dcerpc_binding_string(mem_ctx, b);
    4348        torture_assert(tctx, s != NULL, "Error converting binding back to string");
     
    5560                            "Error generating binding from tower for original binding");
    5661
    57         /* Compare to a stripped down version of the binding string because
    58          * the protocol tower doesn't contain the extra option data */
    59         b->options = NULL;
    60 
    61         b->flags = 0;
    62        
     62        /* The tower doesn't contain the object */
     63        torture_assert_ntstatus_ok(tctx, dcerpc_binding_set_object(b2, object),
     64                            "set object on tower binding");
     65
    6366        s = dcerpc_binding_string(mem_ctx, b);
    6467        torture_assert(tctx, s != NULL, "Error converting binding back to string for (stripped down)");
    6568
     69        /*
     70         * Compare to a stripped down version of the binding string because
     71         * the protocol tower doesn't contain the extra option data
     72         *
     73         * We remove all options except of the endpoint.
     74         */
     75        p = strchr(s, '[');
     76        if (p != NULL) {
     77                char *p2;
     78
     79                p2 = strchr(p + 1, ',');
     80                if (p2 != NULL) {
     81                        /*
     82                         * We only look at the first option,
     83                         * which might be the endpoint.
     84                         */
     85                        p2[0] = ']';
     86                        p2[1] = '\0';
     87                }
     88
     89                p2 = strchr(p + 1, '=');
     90                if (p2 != NULL) {
     91                        /*
     92                         * It's not the endpoint, so remove the
     93                         * whole option section.
     94                         */
     95                        *p = '\0';
     96                }
     97        }
     98
    6699        s2 = dcerpc_binding_string(mem_ctx, b2);
    67100        torture_assert(tctx, s != NULL, "Error converting binding back to string");
    68101
    69         if (is_ipaddress(b->host))
     102        host = dcerpc_binding_get_string_option(b, "host");
     103        if (host && is_ipaddress_v4(host)) {
    70104                torture_assert_casestr_equal(tctx, s, s2, "Mismatch while comparing original and from protocol tower generated binding strings");
     105        }
    71106
    72107        return true;
     
    82117        "ncacn_ip_tcp:127.0.0.1[20]",
    83118        "ncacn_ip_tcp:127.0.0.1[20,sign]",
    84         "ncacn_ip_tcp:127.0.0.1[20,Security=Foobar,sign]",
     119        "ncacn_ip_tcp:127.0.0.1[20,sign,Security=Foobar]",
    85120        "ncacn_http:127.0.0.1",
    86121        "ncacn_http:127.0.0.1[78]",
     
    96131        "ncalrpc:[IDENTIFIER]",
    97132        "ncacn_unix_stream:[/tmp/epmapper,sign]",
     133        "ncacn_ip_tcp:127.0.0.1[75,target_hostname=port75.example.com,target_principal=host/port75.example.com]",
     134        "ncacn_ip_tcp:127.0.0.1[75,connect,target_hostname=port75.example.com,target_principal=host/port75.example.com,assoc_group_id=0x01234567]",
     135        "ncacn_ip_tcp:::",
     136        "ncacn_ip_tcp:::[75]",
     137        "ncacn_ip_tcp:FD00::5357:5F00",
     138        "ncacn_ip_tcp:FD00::5357:5F00[75]",
     139        "ncacn_ip_tcp:FD00::5357:5F00[,target_hostname=port75.example.com]",
     140        "ncacn_ip_tcp:FD00::5357:5F00[75,target_hostname=port75.example.com]",
     141        "ncacn_ip_tcp:fe80::5357:5F00%75",
     142        "ncacn_ip_tcp:fe80::5357:5F00%75[75]",
     143        "ncacn_ip_tcp:fe80::5357:5F00%75[,target_hostname=port75.example.com]",
     144        "ncacn_ip_tcp:fe80::5357:5F00%75[75,target_hostname=port75.example.com]",
    98145};
    99146
     
    102149        struct dcerpc_binding *b;
    103150        struct GUID uuid;
     151        struct GUID object;
     152        struct ndr_syntax_id abstract;
     153        enum dcerpc_transport_t transport;
     154        const char *endpoint;
     155        uint32_t flags;
    104156
    105157        torture_assert_ntstatus_ok(tctx,
     
    108160
    109161        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER", &b), "parse");
    110         torture_assert(tctx, b->transport == NCACN_NP, "ncacn_np expected");
     162        transport = dcerpc_binding_get_transport(b);
     163        torture_assert(tctx, transport == NCACN_NP, "ncacn_np expected");
    111164        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER", &b), "parse");
    112         torture_assert(tctx, b->transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
     165        transport = dcerpc_binding_get_transport(b);
     166        torture_assert(tctx, transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
    113167        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[rpcecho]", &b), "parse");
    114         torture_assert_str_equal(tctx, b->endpoint, "rpcecho", "endpoint");
     168        endpoint = dcerpc_binding_get_string_option(b, "endpoint");
     169        torture_assert_str_equal(tctx, endpoint, "rpcecho", "endpoint");
    115170        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[/pipe/rpcecho]", &b), "parse");
    116171        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[/pipe/rpcecho,sign,seal]", &b), "parse");
    117         torture_assert(tctx, b->flags == DCERPC_SIGN+DCERPC_SEAL, "sign+seal flags");
    118         torture_assert_str_equal(tctx, b->endpoint, "/pipe/rpcecho", "endpoint");
     172        flags = dcerpc_binding_get_flags(b);
     173        torture_assert(tctx, flags == DCERPC_SIGN+DCERPC_SEAL, "sign+seal flags");
     174        endpoint = dcerpc_binding_get_string_option(b, "endpoint");
     175        torture_assert_str_equal(tctx, endpoint, "/pipe/rpcecho", "endpoint");
    119176        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[,sign]", &b), "parse");
    120177        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER[,sign]", &b), "parse");
    121         torture_assert(tctx, b->endpoint == NULL, "endpoint");
    122         torture_assert(tctx, b->flags == DCERPC_SIGN, "sign flag");
     178        endpoint = dcerpc_binding_get_string_option(b, "endpoint");
     179        torture_assert(tctx, endpoint == NULL, "endpoint");
     180        flags = dcerpc_binding_get_flags(b);
     181        torture_assert(tctx, flags == DCERPC_SIGN, "sign flag");
    123182        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncalrpc:", &b), "parse");
    124         torture_assert(tctx, b->transport == NCALRPC, "ncalrpc expected");
     183        transport = dcerpc_binding_get_transport(b);
     184        torture_assert(tctx, transport == NCALRPC, "ncalrpc expected");
    125185        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx,
    126186                "308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_np:$SERVER", &b), "parse");
    127         torture_assert(tctx, GUID_equal(&b->object.uuid, &uuid), "object uuid");
    128         torture_assert_int_equal(tctx, b->object.if_version, 0, "object version");
     187        object = dcerpc_binding_get_object(b);
     188        abstract = dcerpc_binding_get_abstract_syntax(b);
     189        torture_assert(tctx, GUID_equal(&object, &uuid), "object uuid");
     190        torture_assert(tctx, ndr_syntax_id_equal(&abstract, &ndr_syntax_id_null),
     191                       "null abstract syntax");
    129192        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx,
    130193                "308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_ip_tcp:$SERVER", &b), "parse");
    131194        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]", &b), "parse");
    132         torture_assert(tctx, b->transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
    133         torture_assert(tctx, b->flags == (DCERPC_SIGN | DCERPC_LOCALADDRESS), "sign flag");
    134         torture_assert_str_equal(tctx, b->localaddress, "192.168.1.1", "localaddress");
     195        transport = dcerpc_binding_get_transport(b);
     196        torture_assert(tctx, transport == NCACN_IP_TCP, "ncacn_ip_tcp expected");
     197        flags = dcerpc_binding_get_flags(b);
     198        torture_assert(tctx, flags == DCERPC_SIGN, "sign flag");
     199        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "localaddress"),
     200                                 "192.168.1.1", "localaddress");
    135201        torture_assert_str_equal(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]",
    136202                                 dcerpc_binding_string(tctx, b), "back to string");
     203        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "host"),
     204                                 "$SERVER", "host");
     205        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "target_hostname"),
     206                                 "$SERVER", "target_hostname");
     207
     208        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx,
     209                "ncacn_ip_tcp:$HOST[,target_hostname=$HOSTNAME,target_principal=$PRINCIPAL]",
     210                &b), "parse");
     211        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "host"),
     212                                 "$HOST", "host");
     213        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "target_hostname"),
     214                                 "$HOSTNAME", "target_hostname");
     215        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "target_principal"),
     216                                 "$PRINCIPAL", "target_principal");
     217        torture_assert_str_equal(tctx,
     218                                 dcerpc_binding_string(tctx, b),
     219                "ncacn_ip_tcp:$HOST[,target_hostname=$HOSTNAME,target_principal=$PRINCIPAL]",
     220                                 "back to string");
     221
     222        torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx,
     223                "ncacn_ip_tcp:$HOST[,connect,target_hostname=$HOSTNAME,target_principal=$PRINCIPAL,assoc_group_id=0x01234567]",
     224                &b), "parse");
     225        flags = dcerpc_binding_get_flags(b);
     226        torture_assert(tctx, flags == DCERPC_CONNECT, "connect flag");
     227        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "host"),
     228                                 "$HOST", "host");
     229        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "target_hostname"),
     230                                 "$HOSTNAME", "target_hostname");
     231        torture_assert_str_equal(tctx, dcerpc_binding_get_string_option(b, "target_principal"),
     232                                 "$PRINCIPAL", "target_principal");
     233        torture_assert_int_equal(tctx, dcerpc_binding_get_assoc_group_id(b), 0x01234567,
     234                                 "assoc_group_id");
     235        torture_assert_str_equal(tctx,
     236                                 dcerpc_binding_string(tctx, b),
     237                "ncacn_ip_tcp:$HOST[,connect,target_hostname=$HOSTNAME,target_principal=$PRINCIPAL,assoc_group_id=0x01234567]",
     238                                 "back to string");
    137239
    138240        return true;
    139241}
    140242
    141 static bool test_no_transport(struct torture_context *tctx)
     243static bool test_no_transport(struct torture_context *tctx, const void *test_data)
    142244{
    143         const char *binding = "somehost";
     245        const char *binding = test_data;
    144246        struct dcerpc_binding *b;
     247        enum dcerpc_transport_t transport;
    145248        const char *s;
    146249
     
    149252                "Error parsing binding string");
    150253
    151         torture_assert(tctx, b->transport == NCA_UNKNOWN, "invalid transport");
     254        transport = dcerpc_binding_get_transport(b);
     255        torture_assert(tctx, transport == NCA_UNKNOWN, "invalid transport");
    152256
    153257        s = dcerpc_binding_string(tctx, b);
     
    159263        return true;
    160264}
     265
     266static const char *test_no_strings[] = {
     267        "port75.example.com",
     268        "port75.example.com[75]",
     269        "127.0.0.1",
     270        "127.0.0.1[75]",
     271        "127.0.0.1[,target_hostname=port75.example.com]",
     272        "127.0.0.1[75,target_hostname=port75.example.com]",
     273        "::",
     274        "::[75]",
     275        "::[,target_hostname=port75.example.com]",
     276        "::[75,target_hostname=port75.example.com]",
     277        "FD00::5357:5F00",
     278        "FD00::5357:5F00[75]",
     279        "FD00::5357:5F00[,target_hostname=port75.example.com]",
     280        "FD00::5357:5F00[75,target_hostname=port75.example.com]",
     281        "fe80::5357:5F00%75",
     282        "fe80::5357:5F00%75[75]",
     283        "fe80::5357:5F00%75[,target_hostname=port75.example.com]",
     284        "fe80::5357:5F00%75[75,target_hostname=port75.example.com]",
     285};
    161286
    162287struct torture_suite *torture_local_binding_string(TALLOC_CTX *mem_ctx)
     
    171296        }
    172297
    173         torture_suite_add_simple_test(suite, "no transport",test_no_transport);
     298        for (i = 0; i < ARRAY_SIZE(test_no_strings); i++) {
     299                torture_suite_add_simple_tcase_const(suite, test_no_strings[i],
     300                                                     test_no_transport,
     301                                                     test_no_strings[i]);
     302        }
    174303
    175304        torture_suite_add_simple_test(suite, "parsing results",
  • vendor/current/source4/librpc/wscript_build

    r740 r988  
    55bld.RECURSE('idl')
    66
    7 bld.SAMBA_SUBSYSTEM('NDR_SERVER_ID4',
    8         source='gen_ndr/ndr_server_id4.c',
    9         deps='ndr',
    10         public_headers='gen_ndr/server_id4.h',
    11         header_path='gen_ndr'
    12         )
    13 
    147
    158bld.SAMBA_SUBSYSTEM('NDR_WINSTATION',
     
    2114bld.SAMBA_SUBSYSTEM('NDR_IRPC',
    2215        source='gen_ndr/ndr_irpc.c',
    23         public_deps='ndr NDR_SECURITY NDR_NBT'
     16        public_deps='ndr NDR_SECURITY ndr_nbt'
    2417        )
    2518
     
    3225
    3326
    34 bld.SAMBA_SUBSYSTEM('NDR_NFS4ACL',
    35         source='gen_ndr/ndr_nfs4acl.c',
    36         public_deps='ndr NDR_SECURITY'
    37         )
    38 
    39 
    40 
    4127bld.SAMBA_SUBSYSTEM('NDR_WINSIF',
    4228        source='gen_ndr/ndr_winsif.c',
     
    5137
    5238
    53 bld.SAMBA_SUBSYSTEM('NDR_NOTIFY',
    54         source='gen_ndr/ndr_s4_notify.c',
    55         public_deps='ndr NDR_SERVER_ID4'
    56         )
    57 
    58 
    5939bld.SAMBA_SUBSYSTEM('NDR_NTP_SIGND',
    6040        source='gen_ndr/ndr_ntp_signd.c',
     
    6545bld.SAMBA_SUBSYSTEM('NDR_WINSREPL',
    6646        source='gen_ndr/ndr_winsrepl.c',
    67         public_deps='ndr NDR_NBT'
    68         )
    69 
    70 
    71 bld.SAMBA_SUBSYSTEM('NDR_WINBIND',
    72         source='gen_ndr/ndr_winbind.c',
    73         public_deps='NDR_IDMAP ndr ndr-standard'
    74         )
     47        public_deps='ndr ndr_nbt'
     48        )
     49
    7550
    7651# create a grouping library to consolidate our samba4 specific NDR code
    7752bld.SAMBA_LIBRARY('ndr-samba4',
    7853        source=[],
    79         deps='NDR_WINBIND NDR_IRPC NDR_NFS4ACL NDR_OPENDB NDR_NOTIFY ndr-table',
     54        deps='NDR_WINBIND NDR_IRPC NDR_NFS4ACL NDR_OPENDB ndr-table',
    8055        private_library=True,
    8156        grouping_library=True
     
    9267
    9368bld.SAMBA_PIDL_TABLES('GEN_NDR_TABLES', 'gen_ndr/tables.c')
    94 
    95 if bld.env.enable_s3build:
    96     s3_ndr = "NDR_WBINT"
    97 else:
    98     s3_ndr = ""
    9969
    10070bld.SAMBA_SUBSYSTEM('ndr-table',
     
    10575        NDR_OXIDRESOLVER NDR_REMACT NDR_WZCSVC
    10676        NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_TRKWKS NDR_KEYSVC ndr-krb5pac
    107         NDR_XATTR NDR_SCHANNEL NDR_ROT NDR_DRSBLOBS NDR_NBT NDR_WINSREPL
     77        NDR_XATTR NDR_SCHANNEL NDR_ROT NDR_DRSBLOBS ndr_nbt NDR_WINSREPL
    10878        NDR_SECURITY NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB
    10979        NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI
    11080        NDR_FRSTRANS NDR_NFS4ACL NDR_NTP_SIGND NDR_DCOM NDR_WMI
    11181        NDR_NAMED_PIPE_AUTH NDR_NTLMSSP NDR_DFSBLOBS NDR_DNSP
    112         NDR_NTPRINTING NDR_DNS NDR_BACKUPKEY NDR_PREG ''' + s3_ndr,
     82        NDR_NTPRINTING NDR_DNS NDR_BACKUPKEY NDR_PREG NDR_BKUPBLOBS NDR_FSCC
     83        NDR_FRSBLOBS NDR_CLUSAPI''',
    11384        depends_on='GEN_NDR_TABLES'
    11485        )
     
    11990        public_deps='dcerpc NDR_IRPC'
    12091        )
    121 
    122 bld.SAMBA_SUBSYSTEM('RPC_NDR_WINBIND',
    123         source='gen_ndr/ndr_winbind_c.c',
    124         public_deps='dcerpc NDR_WINBIND'
    125         )
    126 
    12792
    12893bld.SAMBA_LIBRARY('dcerpc-samr',
     
    135100        )
    136101
    137 
    138 bld.SAMBA_LIBRARY('dcerpc-atsvc',
    139         source='',
    140         pc_files='dcerpc_atsvc.pc',
    141         vnum='0.0.1',
    142         public_deps='dcerpc ndr-standard RPC_NDR_ATSVC',
    143         public_headers='../../librpc/gen_ndr/ndr_atsvc_c.h',
    144         header_path='gen_ndr'
    145         )
    146 
    147 
    148102bld.SAMBA_SUBSYSTEM('RPC_NDR_WINSIF',
    149103        source='gen_ndr/ndr_winsif_c.c',
     
    154108bld.SAMBA_LIBRARY('dcerpc',
    155109        source='''rpc/dcerpc.c rpc/dcerpc_auth.c rpc/dcerpc_schannel.c
    156         rpc/dcerpc_util.c rpc/dcerpc_smb.c rpc/dcerpc_smb2.c rpc/dcerpc_sock.c
     110        rpc/dcerpc_util.c rpc/dcerpc_smb.c rpc/dcerpc_sock.c
     111        rpc/dcerpc_roh_channel_in.c rpc/dcerpc_roh_channel_out.c rpc/dcerpc_roh.c
    157112        rpc/dcerpc_connect.c rpc/dcerpc_secondary.c''',
    158113        pc_files='dcerpc.pc',
    159         deps='samba_socket LIBCLI_RESOLVE LIBCLI_SMB LIBCLI_SMB2 ndr NDR_DCERPC RPC_NDR_EPMAPPER NDR_SCHANNEL RPC_NDR_NETLOGON RPC_NDR_MGMT gensec LIBCLI_AUTH LIBCLI_RAW LP_RESOLVE UTIL_TEVENT rpccommon',
     114        deps='samba_socket LIBCLI_RESOLVE LIBCLI_SMB LIBCLI_SMB2 ndr NDR_DCERPC RPC_NDR_EPMAPPER NDR_SCHANNEL RPC_NDR_NETLOGON RPC_NDR_MGMT gensec LIBCLI_AUTH smbclient-raw LP_RESOLVE tevent-util dcerpc-binding param_options http',
    160115        autoproto='rpc/dcerpc_proto.h',
    161         public_deps='credentials tevent talloc',
    162         public_headers='''rpc/dcerpc.h ../../librpc/gen_ndr/mgmt.h
    163         ../../librpc/gen_ndr/ndr_mgmt.h ../../librpc/gen_ndr/ndr_mgmt_c.h
    164         ../../librpc/gen_ndr/epmapper.h ../../librpc/gen_ndr/ndr_epmapper.h
    165         ../../librpc/gen_ndr/ndr_epmapper_c.h ../../librpc/rpc/rpc_common.h''',
     116        public_deps='samba-credentials tevent talloc',
     117        public_headers='''rpc/dcerpc.h''',
    166118        # It's very important to keep this form of construction
    167119        # it force the sambawaf extension to put everything that match the first element
     
    177129bld.SAMBA_SUBSYSTEM('pyrpc_util',
    178130        source='rpc/pyrpc_util.c',
    179         public_deps='pytalloc-util pyparam_util dcerpc',
     131        public_deps='pytalloc-util pyparam_util dcerpc MESSAGING',
    180132        pyext=True,
    181133        )
     
    184136bld.SAMBA_PYTHON('python_dcerpc',
    185137        source='rpc/pyrpc.c',
    186         public_deps='LIBCLI_SMB samba-util samba-hostconfig dcerpc-samr RPC_NDR_LSA DYNCONFIG pyrpc_util',
     138        public_deps='LIBCLI_SMB samba-util samba-hostconfig dcerpc-samr RPC_NDR_LSA DYNCONFIG pyrpc_util gensec',
    187139        realname='samba/dcerpc/base.so'
    188140        )
     
    200152        )
    201153
     154bld.SAMBA_PYTHON('python_dns',
     155        source='../../librpc/gen_ndr/py_dns.c',
     156        deps='NDR_DNS pytalloc-util pyrpc_util',
     157        realname='samba/dcerpc/dns.so'
     158        )
     159
     160bld.SAMBA_PYTHON('python_auth',
     161        source='../../librpc/gen_ndr/py_auth.c',
     162        deps='NDR_AUTH pytalloc-util pyrpc_util',
     163        realname='samba/dcerpc/auth.so'
     164        )
     165
     166bld.SAMBA_PYTHON('python_krb5pac',
     167        source='../../librpc/gen_ndr/py_krb5pac.c',
     168        deps='ndr-krb5pac pytalloc-util pyrpc_util',
     169        realname='samba/dcerpc/krb5pac.so'
     170        )
    202171
    203172bld.SAMBA_PYTHON('python_winreg',
     
    238207bld.SAMBA_PYTHON('python_atsvc',
    239208        source='../../librpc/gen_ndr/py_atsvc.c',
    240         deps='dcerpc-atsvc pytalloc-util pyrpc_util',
     209        deps='RPC_NDR_ATSVC pytalloc-util pyrpc_util',
    241210        realname='samba/dcerpc/atsvc.so'
    242211        )
     
    245214bld.SAMBA_PYTHON('python_dcerpc_nbt',
    246215        source='../../librpc/gen_ndr/py_nbt.c',
    247         deps='NDR_NBT RPC_NDR_NBT pytalloc-util pyrpc_util',
     216        deps='ndr_nbt RPC_NDR_NBT pytalloc-util pyrpc_util',
    248217        realname='samba/dcerpc/nbt.so'
    249218        )
     
    284253        )
    285254
     255bld.SAMBA_PYTHON('python_dcerpc_dcerpc',
     256        source='../../librpc/gen_ndr/py_dcerpc.c',
     257        deps='NDR_DCERPC pytalloc-util pyrpc_util',
     258        realname='samba/dcerpc/dcerpc.so'
     259        )
    286260
    287261bld.SAMBA_PYTHON('python_unixinfo',
     
    298272        )
    299273
     274bld.SAMBA_PYTHON('python_server_id',
     275        source='../../librpc/gen_ndr/py_server_id.c',
     276        deps='RPC_NDR_SERVER_ID pytalloc-util pyrpc_util',
     277        realname='samba/dcerpc/server_id.so'
     278        )
     279
    300280bld.SAMBA_PYTHON('python_winbind',
    301         source='gen_ndr/py_winbind.c',
     281        source='../../librpc/gen_ndr/py_winbind.c',
    302282        deps='RPC_NDR_WINBIND pytalloc-util pyrpc_util python_netlogon',
    303283        realname='samba/dcerpc/winbind.so'
     
    331311bld.SAMBA_PYTHON('python_dcerpc_dnsp',
    332312        source='../../librpc/gen_ndr/py_dnsp.c',
    333         deps='pytalloc-util pyrpc_util NDR_SECURITY RPC_NDR_DNSP',
     313        deps='pytalloc-util pyrpc_util NDR_SECURITY NDR_DNSP',
    334314        realname='samba/dcerpc/dnsp.so'
    335315        )
     
    342322        )
    343323
     324bld.SAMBA_PYTHON('python_dcerpc_idmap',
     325        source='../../librpc/gen_ndr/py_idmap.c',
     326        deps='pytalloc-util pyrpc_util RPC_NDR_XATTR',
     327        realname='samba/dcerpc/idmap.so'
     328        )
     329
    344330bld.SAMBA_PYTHON('python_netlogon',
    345331        source='../../librpc/gen_ndr/py_netlogon.c',
     
    348334        )
    349335
     336bld.SAMBA_PYTHON('python_dnsserver',
     337        source='../../librpc/gen_ndr/py_dnsserver.c',
     338        deps='RPC_NDR_DNSSERVER pytalloc-util pyrpc_util',
     339        realname='samba/dcerpc/dnsserver.so'
     340        )
     341
     342bld.SAMBA_PYTHON('python_dcerpc_smb_acl',
     343        source='../../librpc/gen_ndr/py_smb_acl.c',
     344        deps='pytalloc-util pyrpc_util',
     345        realname='samba/dcerpc/smb_acl.so'
     346        )
     347
    350348bld.SAMBA_SCRIPT('python_dcerpc_init',
    351349                 pattern='rpc/dcerpc.py',
Note: See TracChangeset for help on using the changeset viewer.