Changeset 988 for vendor/current/source4/librpc
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- 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 8 8 Requires: ndr 9 9 Version: @PACKAGE_VERSION@ 10 Libs: @LIB_RPATH@ -L${libdir} -ldcerpc 10 Libs: @LIB_RPATH@ -L${libdir} -ldcerpc -ldcerpc-binding 11 11 Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -
vendor/current/source4/librpc/idl/irpc.idl
r740 r988 1 1 #include "idl_types.h" 2 2 3 import "misc.idl", "security.idl", "nbt.idl", "netlogon.idl" ;3 import "misc.idl", "security.idl", "nbt.idl", "netlogon.idl", "server_id.idl"; 4 4 5 5 /* … … 30 30 } irpc_header; 31 31 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 32 43 /****************************************************** 33 44 uptime call - supported by all messaging servers … … 197 208 [in,out,ref] NL_DNS_NAME_INFO_ARRAY *dns_names 198 209 ); 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(); 199 221 } -
vendor/current/source4/librpc/idl/opendb.idl
r740 r988 8 8 */ 9 9 10 import "server_id 4.idl";10 import "server_id.idl"; 11 11 12 12 [ -
vendor/current/source4/librpc/idl/sasl_helpers.idl
r414 r988 2 2 3 3 [ 4 uuid("7512b2f4-5f4f-11e4-bbe6-3c970e8d8226"), 5 version(1.0), 4 6 pointer_default(unique), 5 7 helpstring("SASL helpers") -
vendor/current/source4/librpc/idl/winbind.idl
r740 r988 5 5 #include "idl_types.h" 6 6 7 import "netlogon.idl" , "lsa.idl", "security.idl", "idmap.idl";7 import "netlogon.idl"; 8 8 9 9 [ 10 uuid(" 245f3e6b-3c5d-6e21-3a2d-2a3d645b7221"),10 uuid("b875118e-47a3-4210-b5f7-c240cce656b2"), 11 11 version(1.0), 12 12 pointer_default(unique) … … 16 16 typedef [switch_type(uint16)] union netr_LogonLevel netr_LogonLevel; 17 17 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 */);27 18 28 19 /* … … 37 28 ); 38 29 39 typedef [v1_enum] enum {40 WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS = 1,41 WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS = 242 } 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 50 30 NTSTATUS winbind_DsrUpdateReadOnlyServerDnsRecords( 51 31 [in,unique] [string,charset(UTF16)] uint16 *site_name, -
vendor/current/source4/librpc/idl/winsif.idl
r414 r988 7 7 version(1.0), 8 8 helpstring("WINS Administration Interface1"), 9 helper("../libcli/nbt/libnbt.h"), 9 10 pointer_default(unique) 10 11 ] interface winsif … … 237 238 /* 238 239 * 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. 241 241 */ 242 242 [out,ref,string,charset(DOS),size_is(80)] uint8 *unc_name -
vendor/current/source4/librpc/idl/winsrepl.idl
r740 r988 14 14 [ 15 15 uuid("915f5653-bac1-431c-97ee-9ffb34526921"), 16 helpstring("WINS Replication PDUs") 16 helpstring("WINS Replication PDUs"), 17 helper("../libcli/nbt/libnbt.h") 17 18 ] interface wrepl 18 19 { -
vendor/current/source4/librpc/idl/wscript_build
r740 r988 6 6 7 7 bld.SAMBA_PIDL_LIST('PIDL', 8 source='''irpc.idl nfs4acl.idl s4_notify.idl ntp_signd.idl9 opendb.idl sasl_helpers.idl server_id4.idl winbind.idl8 source='''irpc.idl ntp_signd.idl 9 opendb.idl sasl_helpers.idl 10 10 winsif.idl winsrepl.idl winstation.idl''', 11 11 options="--includedir=%s --header --ndr-parser --client --python --server" % topinclude, -
vendor/current/source4/librpc/ndr/py_misc.c
r740 r988 2 2 Unix SMB/CIFS implementation. 3 3 Samba utility functions 4 4 5 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 5 6 … … 20 21 #include "librpc/gen_ndr/misc.h" 21 22 22 #ifndef Py_RETURN_NONE23 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None24 #endif25 26 23 static int py_GUID_cmp(PyObject *py_self, PyObject *py_other) 27 24 { 28 25 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); 31 28 if (other == NULL) 32 29 return -1; … … 44 41 static PyObject *py_GUID_str(PyObject *py_self) 45 42 { 46 struct GUID *self = py _talloc_get_ptr(py_self);43 struct GUID *self = pytalloc_get_ptr(py_self); 47 44 char *str = GUID_string(NULL, self); 48 45 PyObject *ret = PyString_FromString(str); … … 53 50 static PyObject *py_GUID_repr(PyObject *py_self) 54 51 { 55 struct GUID *self = py _talloc_get_ptr(py_self);52 struct GUID *self = pytalloc_get_ptr(py_self); 56 53 char *str = GUID_string(NULL, self); 57 54 PyObject *ret = PyString_FromFormat("GUID('%s')", str); … … 64 61 PyObject *str = NULL; 65 62 NTSTATUS status; 66 struct GUID *guid = py _talloc_get_ptr(self);63 struct GUID *guid = pytalloc_get_ptr(self); 67 64 const char *kwnames[] = { "str", NULL }; 68 65 … … 103 100 char *str = NULL; 104 101 NTSTATUS status; 105 struct policy_handle *handle = py _talloc_get_ptr(self);102 struct policy_handle *handle = pytalloc_get_ptr(self); 106 103 const char *kwnames[] = { "uuid", "type", NULL }; 107 104 … … 122 119 static PyObject *py_policy_handle_repr(PyObject *py_self) 123 120 { 124 struct policy_handle *self = py _talloc_get_ptr(py_self);121 struct policy_handle *self = pytalloc_get_ptr(py_self); 125 122 char *uuid_str = GUID_string(NULL, &self->uuid); 126 123 PyObject *ret = PyString_FromFormat("policy_handle(%d, '%s')", self->handle_type, uuid_str); … … 131 128 static PyObject *py_policy_handle_str(PyObject *py_self) 132 129 { 133 struct policy_handle *self = py _talloc_get_ptr(py_self);130 struct policy_handle *self = pytalloc_get_ptr(py_self); 134 131 char *uuid_str = GUID_string(NULL, &self->uuid); 135 132 PyObject *ret = PyString_FromFormat("%d, %s", self->handle_type, uuid_str); -
vendor/current/source4/librpc/ndr/py_security.c
r740 r988 2 2 Unix SMB/CIFS implementation. 3 3 Samba utility functions 4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 4 5 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010 5 6 6 7 This program is free software; you can redistribute it and/or modify … … 20 21 #include "libcli/security/security.h" 21 22 22 #ifndef Py_RETURN_NONE23 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None24 #endif25 26 23 static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods) 27 24 { … … 44 41 static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args) 45 42 { 46 struct dom_sid *self = py _talloc_get_ptr(py_self);43 struct dom_sid *self = pytalloc_get_ptr(py_self); 47 44 struct dom_sid *domain_sid; 48 45 TALLOC_CTX *mem_ctx; … … 64 61 } 65 62 66 py_domain_sid = py _talloc_steal(&dom_sid_Type, domain_sid);63 py_domain_sid = pytalloc_steal(&dom_sid_Type, domain_sid); 67 64 talloc_free(mem_ctx); 68 65 return Py_BuildValue("(OI)", py_domain_sid, rid); … … 71 68 static int py_dom_sid_cmp(PyObject *py_self, PyObject *py_other) 72 69 { 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); 75 74 if (other == NULL) 76 75 return -1; 77 76 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; 79 84 } 80 85 81 86 static PyObject *py_dom_sid_str(PyObject *py_self) 82 87 { 83 struct dom_sid *self = py _talloc_get_ptr(py_self);88 struct dom_sid *self = pytalloc_get_ptr(py_self); 84 89 char *str = dom_sid_string(NULL, self); 85 90 PyObject *ret = PyString_FromString(str); … … 90 95 static PyObject *py_dom_sid_repr(PyObject *py_self) 91 96 { 92 struct dom_sid *self = py _talloc_get_ptr(py_self);97 struct dom_sid *self = pytalloc_get_ptr(py_self); 93 98 char *str = dom_sid_string(NULL, self); 94 99 PyObject *ret = PyString_FromFormat("dom_sid('%s')", str); … … 100 105 { 101 106 char *str = NULL; 102 struct dom_sid *sid = py _talloc_get_ptr(self);107 struct dom_sid *sid = pytalloc_get_ptr(self); 103 108 const char *kwnames[] = { "str", NULL }; 104 109 … … 135 140 static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args) 136 141 { 137 struct security_descriptor *desc = py _talloc_get_ptr(self);142 struct security_descriptor *desc = pytalloc_get_ptr(self); 138 143 NTSTATUS status; 139 144 struct security_ace *ace; … … 143 148 return NULL; 144 149 145 ace = py _talloc_get_ptr(py_ace);150 ace = pytalloc_get_ptr(py_ace); 146 151 status = security_descriptor_sacl_add(desc, ace); 147 152 PyErr_NTSTATUS_IS_ERR_RAISE(status); … … 151 156 static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args) 152 157 { 153 struct security_descriptor *desc = py _talloc_get_ptr(self);158 struct security_descriptor *desc = pytalloc_get_ptr(self); 154 159 NTSTATUS status; 155 160 struct security_ace *ace; … … 159 164 return NULL; 160 165 161 ace = py _talloc_get_ptr(py_ace);166 ace = pytalloc_get_ptr(py_ace); 162 167 163 168 status = security_descriptor_dacl_add(desc, ace); … … 168 173 static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args) 169 174 { 170 struct security_descriptor *desc = py _talloc_get_ptr(self);175 struct security_descriptor *desc = pytalloc_get_ptr(self); 171 176 NTSTATUS status; 172 177 struct dom_sid *sid; … … 176 181 return NULL; 177 182 178 sid = py _talloc_get_ptr(py_sid);183 sid = pytalloc_get_ptr(py_sid); 179 184 status = security_descriptor_dacl_del(desc, sid); 180 185 PyErr_NTSTATUS_IS_ERR_RAISE(status); … … 184 189 static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args) 185 190 { 186 struct security_descriptor *desc = py _talloc_get_ptr(self);191 struct security_descriptor *desc = pytalloc_get_ptr(self); 187 192 NTSTATUS status; 188 193 struct dom_sid *sid; … … 192 197 return NULL; 193 198 194 sid = py _talloc_get_ptr(py_sid);199 sid = pytalloc_get_ptr(py_sid); 195 200 status = security_descriptor_sacl_del(desc, sid); 196 201 PyErr_NTSTATUS_IS_ERR_RAISE(status); … … 200 205 static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs) 201 206 { 202 return py _talloc_steal(self, security_descriptor_initialise(NULL));207 return pytalloc_steal(self, security_descriptor_initialise(NULL)); 203 208 } 204 209 … … 213 218 return NULL; 214 219 215 sid = py _talloc_get_ptr(py_sid);220 sid = pytalloc_get_ptr(py_sid); 216 221 217 222 secdesc = sddl_decode(NULL, sddl, sid); … … 221 226 } 222 227 223 return py _talloc_steal((PyTypeObject *)self, secdesc);228 return pytalloc_steal((PyTypeObject *)self, secdesc); 224 229 } 225 230 … … 228 233 struct dom_sid *sid; 229 234 PyObject *py_sid = Py_None; 230 struct security_descriptor *desc = py _talloc_get_ptr(self);235 struct security_descriptor *desc = pytalloc_get_ptr(self); 231 236 char *text; 232 237 PyObject *ret; … … 236 241 237 242 if (py_sid != Py_None) 238 sid = py _talloc_get_ptr(py_sid);243 sid = pytalloc_get_ptr(py_sid); 239 244 else 240 245 sid = NULL; … … 278 283 PyObject *py_sid; 279 284 struct dom_sid *sid; 280 struct security_token *token = py _talloc_get_ptr(self);285 struct security_token *token = pytalloc_get_ptr(self); 281 286 if (!PyArg_ParseTuple(args, "O", &py_sid)) 282 287 return NULL; 283 288 284 sid = py _talloc_get_ptr(py_sid);289 sid = pytalloc_get_ptr(py_sid); 285 290 286 291 return PyBool_FromLong(security_token_is_sid(token, sid)); … … 291 296 PyObject *py_sid; 292 297 struct dom_sid *sid; 293 struct security_token *token = py _talloc_get_ptr(self);298 struct security_token *token = pytalloc_get_ptr(self); 294 299 if (!PyArg_ParseTuple(args, "O", &py_sid)) 295 300 return NULL; 296 301 297 sid = py _talloc_get_ptr(py_sid);302 sid = pytalloc_get_ptr(py_sid); 298 303 299 304 return PyBool_FromLong(security_token_has_sid(token, sid)); … … 302 307 static PyObject *py_token_is_anonymous(PyObject *self) 303 308 { 304 struct security_token *token = py _talloc_get_ptr(self);309 struct security_token *token = pytalloc_get_ptr(self); 305 310 306 311 return PyBool_FromLong(security_token_is_anonymous(token)); … … 309 314 static PyObject *py_token_is_system(PyObject *self) 310 315 { 311 struct security_token *token = py _talloc_get_ptr(self);316 struct security_token *token = pytalloc_get_ptr(self); 312 317 313 318 return PyBool_FromLong(security_token_is_system(token)); … … 316 321 static PyObject *py_token_has_builtin_administrators(PyObject *self) 317 322 { 318 struct security_token *token = py _talloc_get_ptr(self);323 struct security_token *token = pytalloc_get_ptr(self); 319 324 320 325 return PyBool_FromLong(security_token_has_builtin_administrators(token)); … … 323 328 static PyObject *py_token_has_nt_authenticated_users(PyObject *self) 324 329 { 325 struct security_token *token = py _talloc_get_ptr(self);330 struct security_token *token = pytalloc_get_ptr(self); 326 331 327 332 return PyBool_FromLong(security_token_has_nt_authenticated_users(token)); … … 331 336 { 332 337 int priv; 333 struct security_token *token = py _talloc_get_ptr(self);338 struct security_token *token = pytalloc_get_ptr(self); 334 339 335 340 if (!PyArg_ParseTuple(args, "i", &priv)) … … 342 347 { 343 348 int priv; 344 struct security_token *token = py _talloc_get_ptr(self);349 struct security_token *token = pytalloc_get_ptr(self); 345 350 346 351 if (!PyArg_ParseTuple(args, "i", &priv)) … … 353 358 static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs) 354 359 { 355 return py _talloc_steal(self, security_token_initialise(NULL));360 return pytalloc_steal(self, security_token_initialise(NULL)); 356 361 } 357 362 … … 415 420 sid = dom_sid_parse_talloc(NULL, str); 416 421 talloc_free(str); 417 ret = py _talloc_steal(&dom_sid_Type, sid);422 ret = pytalloc_steal(&dom_sid_Type, sid); 418 423 return ret; 419 424 } -
vendor/current/source4/librpc/ndr/py_xattr.c
r740 r988 19 19 20 20 #include <Python.h> 21 22 #ifndef Py_RETURN_NONE23 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None24 #endif25 21 26 22 static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods) … … 64 60 static PyObject *py_ntacl_print(PyObject *self, PyObject *args) 65 61 { 66 struct xattr_NTACL *ntacl = py _talloc_get_ptr(self);62 struct xattr_NTACL *ntacl = pytalloc_get_ptr(self); 67 63 struct ndr_print *pr; 68 64 TALLOC_CTX *mem_ctx; -
vendor/current/source4/librpc/rpc/dcerpc.c
r919 r988 22 22 23 23 #include "includes.h" 24 #include "system/filesys.h" 24 25 #include "../lib/util/dlinklist.h" 25 26 #include "lib/events/events.h" … … 28 29 #include "librpc/gen_ndr/ndr_misc.h" 29 30 #include "librpc/gen_ndr/ndr_dcerpc.h" 30 #include "libcli/composite/composite.h"31 31 #include "auth/gensec/gensec.h" 32 32 #include "param/param.h" 33 33 #include "lib/util/tevent_ntstatus.h" 34 34 #include "librpc/rpc/rpc_common.h" 35 #include "lib/tsocket/tsocket.h" 36 #include "libcli/smb/tstream_smbXcli_np.h" 37 35 38 36 39 enum rpc_request_state { … … 62 65 DATA_BLOB request_data; 63 66 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; 72 70 73 71 struct { … … 77 75 }; 78 76 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(); 82 80 } 83 81 84 82 static 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, 83 static void dcerpc_schedule_io_trigger(struct dcecli_connection *c); 84 85 static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx, 86 struct dcerpc_pipe *p, 88 87 const struct GUID *object, 89 88 uint16_t opnum, … … 105 104 ndr_pull_flags_fn_t ndr_pull, 106 105 ndr_print_function_t ndr_print); 106 static NTSTATUS dcerpc_shutdown_pipe(struct dcecli_connection *p, NTSTATUS status); 107 static NTSTATUS dcerpc_send_request(struct dcecli_connection *p, DATA_BLOB *data, 108 bool trigger_read); 109 static NTSTATUS dcerpc_send_read(struct dcecli_connection *p); 107 110 108 111 /* destroy a dcerpc connection */ … … 139 142 140 143 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; 142 147 c->security_state.session_key = dcerpc_generic_session_key; 143 148 c->security_state.generic_state = NULL; 144 c->binding_string = NULL;145 149 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; 148 158 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 } 149 165 150 166 talloc_set_destructor(c, dcerpc_connection_destructor); … … 166 182 } 167 183 184 if (!hs->p->conn) { 185 return false; 186 } 187 188 if (hs->p->conn->dead) { 189 return false; 190 } 191 168 192 return true; 169 193 } … … 186 210 } 187 211 212 static 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 188 231 struct dcerpc_bh_raw_call_state { 232 struct tevent_context *ev; 189 233 struct dcerpc_binding_handle *h; 190 234 DATA_BLOB in_data; … … 216 260 return NULL; 217 261 } 262 state->ev = ev; 218 263 state->h = h; 219 264 state->in_data.data = discard_const_p(uint8_t, in_data); … … 222 267 ok = dcerpc_bh_is_connected(h); 223 268 if (!ok) { 224 tevent_req_nterror(req, NT_STATUS_ INVALID_CONNECTION);269 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); 225 270 return tevent_req_post(req, ev); 226 271 } 227 272 228 subreq = dcerpc_request_send(hs->p, 273 subreq = dcerpc_request_send(state, 274 hs->p, 229 275 object, 230 276 opnum, … … 261 307 status = dcerpc_fault_to_nt_status(fault_code); 262 308 } 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 263 322 if (!NT_STATUS_IS_OK(status)) { 264 323 tevent_req_nterror(req, status); … … 314 373 ok = dcerpc_bh_is_connected(h); 315 374 if (!ok) { 316 tevent_req_nterror(req, NT_STATUS_ INVALID_CONNECTION);375 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); 317 376 return tevent_req_post(req, ev); 318 377 } … … 427 486 for (i=0;i<num_examples;i++) { 428 487 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) { 433 494 return; 434 495 } … … 522 583 .is_connected = dcerpc_bh_is_connected, 523 584 .set_timeout = dcerpc_bh_set_timeout, 585 .auth_info = dcerpc_bh_auth_info, 524 586 .raw_call_send = dcerpc_bh_raw_call_send, 525 587 .raw_call_recv = dcerpc_bh_raw_call_recv, … … 645 707 enum ndr_err_code ndr_err; 646 708 647 ndr = ndr_pull_init_ flags(c,blob, mem_ctx);709 ndr = ndr_pull_init_blob(blob, mem_ctx); 648 710 if (!ndr) { 649 711 return NT_STATUS_NO_MEMORY; … … 654 716 } 655 717 718 if (CVAL(blob->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) { 719 ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; 720 } 721 656 722 ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt); 723 TALLOC_FREE(ndr); 657 724 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 658 725 return ndr_map_error2ntstatus(ndr_err); … … 677 744 uint32_t auth_length; 678 745 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) { 685 756 case DCERPC_AUTH_LEVEL_PRIVACY: 686 757 case DCERPC_AUTH_LEVEL_INTEGRITY: … … 717 788 pkt->u.response.stub_and_verifier.length -= auth_length; 718 789 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 719 802 /* check signature or unseal the packet */ 720 switch (c->security_state.auth_ info->auth_level) {803 switch (c->security_state.auth_level) { 721 804 case DCERPC_AUTH_LEVEL_PRIVACY: 722 805 status = gensec_unseal_packet(c->security_state.generic_state, 723 mem_ctx,724 806 raw_packet->data + DCERPC_REQUEST_LENGTH, 725 807 pkt->u.response.stub_and_verifier.length, … … 734 816 case DCERPC_AUTH_LEVEL_INTEGRITY: 735 817 status = gensec_check_packet(c->security_state.generic_state, 736 mem_ctx,737 818 pkt->u.response.stub_and_verifier.data, 738 819 pkt->u.response.stub_and_verifier.length, … … 776 857 enum ndr_err_code ndr_err; 777 858 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) { 785 866 case DCERPC_AUTH_LEVEL_PRIVACY: 786 867 case DCERPC_AUTH_LEVEL_INTEGRITY: 868 if (sig_size == 0) { 869 return NT_STATUS_INTERNAL_ERROR; 870 } 787 871 break; 788 872 … … 826 910 whole packet, whereas w2k8 wants it relative to the start 827 911 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); 831 915 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 832 916 return ndr_map_error2ntstatus(ndr_err); … … 834 918 835 919 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; 840 921 841 922 /* 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); 843 924 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 844 925 return ndr_map_error2ntstatus(ndr_err); … … 858 939 859 940 /* sign or seal the packet */ 860 switch (c->security_state.auth_ info->auth_level) {941 switch (c->security_state.auth_level) { 861 942 case DCERPC_AUTH_LEVEL_PRIVACY: 862 943 status = gensec_seal_packet(c->security_state.generic_state, … … 898 979 (unsigned) creds2.length, 899 980 (unsigned) sig_size, 900 (unsigned) c->security_state.auth_info->auth_pad_length,981 (unsigned) auth_info.auth_pad_length, 901 982 (unsigned) pkt->u.request.stub_and_verifier.length)); 902 983 dcerpc_set_frag_length(blob, blob->length + creds2.length); … … 932 1013 map a bind nak reason to a NTSTATUS 933 1014 */ 934 static NTSTATUS dcerpc_map_ reason(uint16_treason)1015 static NTSTATUS dcerpc_map_nak_reason(enum dcerpc_bind_nak_reason reason) 935 1016 { 936 1017 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 1028 static 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: 938 1046 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; 941 1051 } 942 1052 return NT_STATUS_UNSUCCESSFUL; 943 }944 945 /*946 a bind or alter context has failed947 */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);953 1053 } 954 1054 … … 981 1081 conn->dead = true; 982 1082 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); 986 1087 987 1088 /* all pending requests get the error */ … … 996 1097 } 997 1098 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 998 1110 talloc_set_destructor(conn, NULL); 999 1111 if (conn->free_skipped) { … … 1018 1130 struct ncacn_packet pkt; 1019 1131 1132 if (conn->dead) { 1133 return; 1134 } 1135 1020 1136 if (NT_STATUS_IS_OK(status) && blob->length == 0) { 1021 1137 status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; … … 1035 1151 data_blob_free(blob); 1036 1152 dcerpc_connection_dead(conn, status); 1153 return; 1037 1154 } 1038 1155 1039 1156 dcerpc_request_recv_data(conn, blob, &pkt); 1040 }1041 1042 /*1043 Receive a bind reply from the transport1044 */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);1099 1157 } 1100 1158 … … 1120 1178 } 1121 1179 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; 1180 struct dcerpc_bind_state { 1181 struct tevent_context *ev; 1182 struct dcerpc_pipe *p; 1183 }; 1184 1185 static void dcerpc_bind_fail_handler(struct rpc_request *subreq); 1186 static void dcerpc_bind_recv_handler(struct rpc_request *subreq, 1187 DATA_BLOB *raw_packet, 1188 struct ncacn_packet *pkt); 1189 1190 struct 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; 1131 1198 struct ncacn_packet pkt; 1132 1199 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; 1139 1212 1140 1213 p->syntax = *syntax; 1141 1214 p->transfer_syntax = *transfer_syntax; 1215 1216 flags = dcerpc_binding_get_flags(p->binding); 1142 1217 1143 1218 init_ncacn_hdr(p->conn, &pkt); … … 1148 1223 pkt.auth_length = 0; 1149 1224 1150 if ( p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) {1225 if (flags & DCERPC_CONCURRENT_MULTIPLEX) { 1151 1226 pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; 1152 1227 } 1153 1228 1154 if (p-> binding->flags & DCERPC_HEADER_SIGNING) {1229 if (p->conn->flags & DCERPC_PROPOSE_HEADER_SIGNING) { 1155 1230 pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; 1156 1231 } 1157 1232 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); 1161 1236 pkt.u.bind.num_contexts = 1; 1162 1237 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 } 1164 1241 pkt.u.bind.ctx_list[0].context_id = p->context_id; 1165 1242 pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1; … … 1169 1246 1170 1247 /* 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 } 1176 1253 1177 1254 /* … … 1179 1256 * request queue as normal requests 1180 1257 */ 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 1284 static 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 1311 static 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 1441 NTSTATUS dcerpc_bind_recv(struct tevent_req *req) 1442 { 1443 return tevent_req_simple_recv_ntstatus(req); 1212 1444 } 1213 1445 … … 1221 1453 NTSTATUS status; 1222 1454 DATA_BLOB blob; 1455 uint32_t flags; 1456 1457 flags = dcerpc_binding_get_flags(p->binding); 1223 1458 1224 1459 init_ncacn_hdr(p->conn, &pkt); … … 1230 1465 pkt.u.auth3.auth_info = data_blob(NULL, 0); 1231 1466 1232 if ( p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) {1467 if (flags & DCERPC_CONCURRENT_MULTIPLEX) { 1233 1468 pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; 1234 1469 } 1235 1470 1236 if (p->binding->flags & DCERPC_HEADER_SIGNING) {1237 pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;1238 }1239 1240 1471 /* 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); 1244 1474 if (!NT_STATUS_IS_OK(status)) { 1245 1475 return status; … … 1247 1477 1248 1478 /* 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); 1250 1480 if (!NT_STATUS_IS_OK(status)) { 1251 1481 return status; … … 1277 1507 info out of step with the server 1278 1508 */ 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) { 1281 1510 status = ncacn_pull_request_auth(c, raw_packet->data, raw_packet, pkt); 1282 1511 } … … 1306 1535 dcerpc_req_dequeue(req); 1307 1536 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 1308 1544 req->recv_handler(req, raw_packet, pkt); 1309 1545 return; … … 1311 1547 1312 1548 if (pkt->ptype == DCERPC_PKT_FAULT) { 1549 status = dcerpc_fault_to_nt_status(pkt->u.fault.status); 1313 1550 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 } 1314 1559 req->fault_code = pkt->u.fault.status; 1315 1560 req->status = NT_STATUS_NET_WRITE_FAULT; … … 1320 1565 DEBUG(2,("Unexpected packet type %d in dcerpc response\n", 1321 1566 (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; 1325 1569 } 1326 1570 … … 1328 1572 this request accordingly */ 1329 1573 if (!NT_STATUS_IS_OK(status)) { 1330 req->status = status;1331 goto req_done;1574 dcerpc_connection_dead(c, status); 1575 return; 1332 1576 } 1333 1577 1334 1578 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 } 1335 1587 1336 1588 if (length > 0) { … … 1349 1601 1350 1602 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; 1353 1613 } 1354 1614 … … 1359 1619 } 1360 1620 1361 1362 1621 req_done: 1622 data_blob_free(raw_packet); 1623 1363 1624 /* we've got the full payload */ 1625 dcerpc_req_dequeue(req); 1364 1626 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); 1372 1633 1373 1634 if (req->async.callback) { … … 1375 1636 } 1376 1637 } 1638 1639 static NTSTATUS dcerpc_request_prepare_vt(struct rpc_request *req); 1377 1640 1378 1641 /* 1379 1642 perform the send side of a async dcerpc request 1380 1643 */ 1381 static struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p, 1644 static struct rpc_request *dcerpc_request_send(TALLOC_CTX *mem_ctx, 1645 struct dcerpc_pipe *p, 1382 1646 const struct GUID *object, 1383 1647 uint16_t opnum, … … 1385 1649 { 1386 1650 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); 1391 1654 if (req == NULL) { 1392 1655 return NULL; … … 1395 1658 req->p = p; 1396 1659 req->call_id = next_call_id(p->conn); 1397 req->status = NT_STATUS_OK;1398 1660 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;1406 1661 1407 1662 if (object != NULL) { … … 1411 1666 return NULL; 1412 1667 } 1413 } else {1414 req->object = NULL;1415 1668 } 1416 1669 1417 1670 req->opnum = opnum; 1418 1671 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); 1421 1677 return NULL; 1422 1678 } 1423 1679 1424 DLIST_ADD_END(p->conn->request_queue, req , struct rpc_request *);1680 DLIST_ADD_END(p->conn->request_queue, req); 1425 1681 talloc_set_destructor(req, dcerpc_req_dequeue); 1426 1682 1427 dcerpc_s hip_next_request(p->conn);1683 dcerpc_schedule_io_trigger(p->conn); 1428 1684 1429 1685 if (p->request_timeout) { 1430 event_add_timed(dcerpc_event_context(p), req,1686 tevent_add_timer(p->conn->event_ctx, req, 1431 1687 timeval_current_ofs(p->request_timeout, 0), 1432 1688 dcerpc_timeout_handler, req); … … 1434 1690 1435 1691 return req; 1692 } 1693 1694 static 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; 1436 1806 } 1437 1807 … … 1451 1821 size_t sig_size = 0; 1452 1822 bool need_async = false; 1823 bool can_async = true; 1453 1824 1454 1825 req = c->request_queue; … … 1462 1833 if (c->pending) { 1463 1834 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; 1464 1845 } 1465 1846 … … 1476 1857 chunk_size = p->conn->srv_max_recv_frag; 1477 1858 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 1480 1865 sig_size = gensec_sig_size(c->security_state.generic_state, 1481 p->conn->srv_max_recv_frag);1866 max_payload); 1482 1867 if (sig_size) { 1483 1868 chunk_size -= DCERPC_AUTH_TRAILER_LENGTH; … … 1485 1870 } 1486 1871 } 1487 chunk_size -= (chunk_size % 16);1872 chunk_size -= (chunk_size % DCERPC_AUTH_PAD_ALIGNMENT); 1488 1873 1489 1874 pkt.ptype = DCERPC_PKT_REQUEST; … … 1491 1876 pkt.auth_length = 0; 1492 1877 pkt.pfc_flags = 0; 1493 pkt.u.request.alloc_hint = remaining;1494 1878 pkt.u.request.context_id = p->context_id; 1495 1879 pkt.u.request.opnum = req->opnum; … … 1518 1902 } 1519 1903 1904 pkt.u.request.alloc_hint = remaining; 1520 1905 pkt.u.request.stub_and_verifier.data = stub_data->data + 1521 1906 (stub_data->length - remaining); … … 1533 1918 } 1534 1919 1535 req->status = p->conn->transport.send_request(p->conn, &blob, do_trans);1920 req->status = dcerpc_send_request(p->conn, &blob, do_trans); 1536 1921 if (!NT_STATUS_IS_OK(req->status)) { 1537 1922 req->state = RPC_REQUEST_DONE; … … 1541 1926 1542 1927 if (last_frag && !do_trans) { 1543 req->status = p->conn->transport.send_read(p->conn);1928 req->status = dcerpc_send_read(p->conn); 1544 1929 if (!NT_STATUS_IS_OK(req->status)) { 1545 1930 req->state = RPC_REQUEST_DONE; … … 1553 1938 } 1554 1939 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 1940 static 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 1955 static 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 } 1565 1980 1566 1981 /* … … 1574 1989 1575 1990 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) { 1578 1993 return NT_STATUS_CONNECTION_DISCONNECTED; 1579 1994 } … … 1790 2205 _PUBLIC_ const char *dcerpc_server_name(struct dcerpc_pipe *p) 1791 2206 { 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; 1799 2208 } 1800 2209 … … 1819 2228 } 1820 2229 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; 2230 struct dcerpc_alter_context_state { 2231 struct tevent_context *ev; 2232 struct dcerpc_pipe *p; 2233 }; 2234 2235 static void dcerpc_alter_context_fail_handler(struct rpc_request *subreq); 2236 static void dcerpc_alter_context_recv_handler(struct rpc_request *req, 2237 DATA_BLOB *raw_packet, 2238 struct ncacn_packet *pkt); 2239 2240 struct 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; 1882 2248 struct ncacn_packet pkt; 1883 2249 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; 1890 2262 1891 2263 p->syntax = *syntax; 1892 2264 p->transfer_syntax = *transfer_syntax; 2265 2266 flags = dcerpc_binding_get_flags(p->binding); 1893 2267 1894 2268 init_ncacn_hdr(p->conn, &pkt); … … 1899 2273 pkt.auth_length = 0; 1900 2274 1901 if ( p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) {2275 if (flags & DCERPC_CONCURRENT_MULTIPLEX) { 1902 2276 pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; 1903 2277 } 1904 2278 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); 1912 2282 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 } 1915 2287 pkt.u.alter.ctx_list[0].context_id = p->context_id; 1916 2288 pkt.u.alter.ctx_list[0].num_transfer_syntaxes = 1; … … 1920 2292 1921 2293 /* 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 } 1927 2299 1928 2300 /* … … 1930 2302 * request queue as normal requests 1931 2303 */ 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 2330 static 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 2357 static 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 2451 NTSTATUS dcerpc_alter_context_recv(struct tevent_req *req) 2452 { 2453 return tevent_req_simple_recv_ntstatus(req); 1959 2454 } 1960 2455 … … 1967 2462 const struct ndr_syntax_id *transfer_syntax) 1968 2463 { 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 2486 static 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 */ 2511 struct dcerpc_shutdown_pipe_state { 2512 struct dcecli_connection *c; 2513 NTSTATUS status; 2514 }; 2515 2516 static void dcerpc_shutdown_pipe_done(struct tevent_req *subreq); 2517 2518 static 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 2543 static 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 2564 struct dcerpc_send_read_state { 2565 struct dcecli_connection *p; 2566 }; 2567 2568 static 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 2577 static void dcerpc_send_read_done(struct tevent_req *subreq); 2578 2579 static 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 2607 static 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 2646 struct dcerpc_send_request_state { 2647 struct dcecli_connection *p; 2648 DATA_BLOB blob; 2649 struct iovec iov; 2650 }; 2651 2652 static 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 2661 static void dcerpc_send_request_wait_done(struct tevent_req *subreq); 2662 static void dcerpc_send_request_done(struct tevent_req *subreq); 2663 2664 static 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 2734 static 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 2768 static 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 37 37 struct dcerpc_binding_handle; 38 38 struct tstream_context; 39 struct ndr_interface_table; 40 struct resolve_context; 39 41 40 42 /* … … 43 45 struct dcecli_connection; 44 46 struct gensec_settings; 47 struct cli_credentials; 45 48 struct 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; 47 57 struct gensec_security *generic_state; 48 58 49 59 /* get the session key */ 50 60 NTSTATUS (*session_key)(struct dcecli_connection *, DATA_BLOB *); 61 62 bool verified_bitmask1; 63 51 64 }; 52 65 … … 61 74 uint32_t flags; 62 75 struct dcecli_security security_state; 63 const char *binding_string;64 76 struct tevent_context *event_ctx; 77 78 struct tevent_immediate *io_trigger; 79 bool io_trigger_pending; 65 80 66 81 /** Directory in which to save ndrdump-parseable files */ … … 74 89 void *private_data; 75 90 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; 91 98 } transport; 99 100 const char *server_name; 92 101 93 102 /* Requests that have been sent, waiting for a reply */ … … 109 118 uint32_t context_id; 110 119 111 uint32_t assoc_group_id;112 113 120 struct ndr_syntax_id syntax; 114 121 struct ndr_syntax_id transfer_syntax; 115 122 116 123 struct dcecli_connection *conn; 117 struct dcerpc_binding *binding;124 const struct dcerpc_binding *binding; 118 125 119 126 /** the last fault code from a DCERPC fault */ … … 122 129 /** timeout for individual rpc requests, in seconds */ 123 130 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; 124 141 }; 125 142 … … 127 144 #define DCERPC_REQUEST_TIMEOUT 60 128 145 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 140 146 struct epm_tower; 141 147 struct epm_floor; … … 143 149 struct smbcli_tree; 144 150 struct smb2_tree; 151 struct smbXcli_conn; 152 struct smbXcli_session; 153 struct smbXcli_tcon; 154 struct roh_connection; 155 struct tstream_tls_params; 145 156 struct socket_address; 146 157 … … 157 168 struct smbcli_tree *tree, 158 169 const char *pipe_name); 170 NTSTATUS dcerpc_pipe_open_smb2(struct dcerpc_pipe *p, 171 struct smb2_tree *tree, 172 const char *pipe_name); 159 173 NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p, 160 174 const struct ndr_interface_table *table); … … 166 180 167 181 struct composite_context* dcerpc_pipe_connect_b_send(TALLOC_CTX *parent_ctx, 168 struct dcerpc_binding *binding,182 const struct dcerpc_binding *binding, 169 183 const struct ndr_interface_table *table, 170 184 struct cli_credentials *credentials, … … 177 191 NTSTATUS dcerpc_pipe_connect_b(TALLOC_CTX *parent_ctx, 178 192 struct dcerpc_pipe **pp, 179 struct dcerpc_binding *binding,193 const struct dcerpc_binding *binding, 180 194 const struct ndr_interface_table *table, 181 195 struct cli_credentials *credentials, … … 185 199 NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx, 186 200 struct dcerpc_pipe **p, 187 struct dcerpc_binding *binding,201 const struct dcerpc_binding *binding, 188 202 const struct ndr_interface_table *table, 189 203 struct cli_credentials *credentials, … … 191 205 NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, 192 206 struct dcerpc_pipe **p2, 193 struct dcerpc_binding *b);207 const struct dcerpc_binding *b); 194 208 NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx, 195 209 struct dcerpc_pipe *p, … … 198 212 struct loadparm_context *lp_ctx, 199 213 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); 214 NTSTATUS dcerpc_init(void); 215 struct composite_context *dcerpc_secondary_smb_send(struct dcecli_connection *c1, 216 struct dcecli_connection *c2, 217 const char *pipe_name); 218 NTSTATUS dcerpc_secondary_smb_recv(struct composite_context *c); 204 219 NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, 205 220 struct dcerpc_pipe **pp2, … … 229 244 struct loadparm_context *lp_ctx); 230 245 struct composite_context* dcerpc_secondary_auth_connection_send(struct dcerpc_pipe *p, 231 struct dcerpc_binding *binding,246 const struct dcerpc_binding *binding, 232 247 const struct ndr_interface_table *table, 233 248 struct cli_credentials *credentials, … … 236 251 TALLOC_CTX *mem_ctx, 237 252 struct dcerpc_pipe **p); 253 NTSTATUS 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); 238 260 239 261 struct composite_context* dcerpc_secondary_connection_send(struct dcerpc_pipe *p, 240 struct dcerpc_binding *b);262 const struct dcerpc_binding *b); 241 263 void dcerpc_log_packet(const char *lockdir, 242 264 const struct ndr_interface_table *ndr, … … 244 266 const DATA_BLOB *pkt); 245 267 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 251 268 #endif /* __S4_DCERPC_H__ */ -
vendor/current/source4/librpc/rpc/dcerpc.py
r740 r988 1 #!/usr/bin/env python2 3 1 # Unix SMB/CIFS implementation. 4 2 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 5 # 3 # 6 4 # This program is free software; you can redistribute it and/or modify 7 5 # it under the terms of the GNU General Public License as published by 8 6 # the Free Software Foundation; either version 3 of the License, or 9 7 # (at your option) any later version. 10 # 8 # 11 9 # This program is distributed in the hope that it will be useful, 12 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 12 # GNU General Public License for more details. 15 # 13 # 16 14 # You should have received a copy of the GNU General Public License 17 15 # along with this program. If not, see <http://www.gnu.org/licenses/>. -
vendor/current/source4/librpc/rpc/dcerpc_auth.c
r740 r988 23 23 24 24 #include "includes.h" 25 #include <tevent.h> 25 26 #include "libcli/composite/composite.h" 26 27 #include "auth/gensec/gensec.h" … … 41 42 42 43 if (pipe_flags & DCERPC_NDR64) { 43 *transfer_syntax = ndr 64_transfer_syntax;44 *transfer_syntax = ndr_transfer_syntax_ndr64; 44 45 } else { 45 *transfer_syntax = ndr_transfer_syntax ;46 *transfer_syntax = ndr_transfer_syntax_ndr; 46 47 } 47 48 … … 53 54 Send request to do a non-authenticated dcerpc bind 54 55 */ 56 static void dcerpc_bind_auth_none_done(struct tevent_req *subreq); 57 55 58 struct composite_context *dcerpc_bind_auth_none_send(TALLOC_CTX *mem_ctx, 56 59 struct dcerpc_pipe *p, … … 61 64 62 65 struct composite_context *c; 66 struct tevent_req *subreq; 63 67 64 68 c = composite_create(mem_ctx, p->conn->event_ctx); … … 74 78 } 75 79 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 88 static 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 } 82 100 83 101 /* … … 86 104 NTSTATUS dcerpc_bind_auth_none_recv(struct composite_context *ctx) 87 105 { 88 return dcerpc_bind_recv(ctx); 106 NTSTATUS result = composite_wait(ctx); 107 TALLOC_FREE(ctx); 108 return result; 89 109 } 90 110 … … 105 125 struct bind_auth_state { 106 126 struct dcerpc_pipe *pipe; 107 DATA_BLOB credentials; 127 struct dcerpc_auth out_auth_info; 128 struct dcerpc_auth in_auth_info; 108 129 bool more_processing; /* Is there anything more to do after the 109 130 * first bind itself received? */ 110 131 }; 111 132 112 static void bind_auth_recv_alter(struct composite_context *creq);133 static void bind_auth_recv_alter(struct tevent_req *subreq); 113 134 114 135 static void bind_auth_next_step(struct composite_context *c) … … 116 137 struct bind_auth_state *state; 117 138 struct dcecli_security *sec; 118 struct composite_context *creq;139 struct tevent_req *subreq; 119 140 bool more_processing = false; 120 141 121 142 state = talloc_get_type(c->private_data, struct bind_auth_state); 122 143 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 }; 123 165 124 166 /* The status value here, from GENSEC is vital to the security … … 132 174 */ 133 175 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; 138 188 139 189 if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { … … 144 194 if (!composite_is_ok(c)) return; 145 195 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) { 151 197 composite_done(c); 152 198 return; 153 199 } 154 200 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; 156 207 157 208 if (!more_processing) { 158 209 /* NO reply expected, so just send it */ 159 210 c->status = dcerpc_auth3(state->pipe, state); 160 data_blob_free(&state->credentials);161 sec->auth_info->credentials = data_blob(NULL, 0);162 211 if (!composite_is_ok(c)) return; 163 212 … … 168 217 /* We are demanding a reply, so use a request that will get us one */ 169 218 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 228 static 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); 197 233 struct bind_auth_state *state = talloc_get_type(c->private_data, 198 234 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); 201 241 if (!composite_is_ok(c)) return; 242 243 bind_auth_next_step(c); 244 } 245 246 247 static 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 } 202 265 203 266 if (!state->more_processing) { … … 232 295 const char *service) 233 296 { 234 struct composite_context *c , *creq;297 struct composite_context *c; 235 298 struct bind_auth_state *state; 236 299 struct dcecli_security *sec; 237 300 struct tevent_req *subreq; 238 301 struct ndr_syntax_id syntax, transfer_syntax; 302 const char *target_principal = NULL; 239 303 240 304 /* composite context allocation and setup */ … … 256 320 257 321 c->status = gensec_client_start(p, &sec->generic_state, 258 p->conn->event_ctx,259 322 gensec_settings); 260 323 if (!NT_STATUS_IS_OK(c->status)) { … … 274 337 275 338 c->status = gensec_set_target_hostname(sec->generic_state, 276 p->conn->transport.target_hostname(p->conn));339 dcerpc_server_name(p)); 277 340 if (!NT_STATUS_IS_OK(c->status)) { 278 341 DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", … … 293 356 } 294 357 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) { 296 363 c->status = gensec_set_target_principal(sec->generic_state, 297 p->binding->target_principal);364 target_principal); 298 365 if (!NT_STATUS_IS_OK(c->status)) { 299 366 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))); 301 368 composite_error(c, c->status); 302 369 return c; … … 314 381 } 315 382 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 }; 325 397 326 398 /* The status value here, from GENSEC is vital to the security … … 334 406 */ 335 407 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 339 420 if (!NT_STATUS_IS_OK(c->status) && 340 421 !NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { … … 346 427 NT_STATUS_MORE_PROCESSING_REQUIRED); 347 428 348 if (state-> credentials.length == 0) {429 if (state->out_auth_info.credentials.length == 0) { 349 430 composite_done(c); 350 431 return c; 351 432 } 352 433 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; 354 446 355 447 /* The first request always is a dcerpc_bind. The subsequent ones 356 448 * 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 363 454 return c; 364 455 } -
vendor/current/source4/librpc/rpc/dcerpc_connect.c
r740 r988 30 30 #include "libcli/smb2/smb2.h" 31 31 #include "libcli/smb2/smb2_calls.h" 32 #include "libcli/smb/smbXcli_base.h" 32 33 #include "librpc/rpc/dcerpc.h" 33 34 #include "librpc/rpc/dcerpc_proto.h" … … 36 37 #include "libcli/resolve/resolve.h" 37 38 39 struct 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 }; 38 55 39 56 struct pipe_np_smb_state { 40 57 struct smb_composite_connect conn; 41 struct smbcli_tree *tree;42 58 struct dcerpc_pipe_connect io; 43 59 }; … … 59 75 } 60 76 77 static void continue_smb_open(struct composite_context *c); 61 78 62 79 /* … … 65 82 static void continue_smb_connect(struct composite_context *ctx) 66 83 { 67 struct composite_context *open_ctx;68 84 struct composite_context *c = talloc_get_type(ctx->async.private_data, 69 85 struct composite_context); 70 86 struct pipe_np_smb_state *s = talloc_get_type(c->private_data, 71 87 struct pipe_np_smb_state); 72 88 struct smbcli_tree *t; 89 73 90 /* 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; 76 95 77 96 /* 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 107 static 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; 80 112 81 113 /* 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); 83 120 if (composite_nomem(open_ctx, c)) return; 84 121 … … 97 134 struct composite_context *conn_req; 98 135 struct smb_composite_connect *conn; 136 uint32_t flags; 99 137 100 138 /* 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); 102 140 if (c == NULL) return NULL; 103 141 … … 109 147 conn = &s->conn; 110 148 149 if (smbXcli_conn_is_connected(s->io.smb.conn)) { 150 continue_smb_open(c); 151 return c; 152 } 153 111 154 /* prepare smb connection parameters: we're connecting to IPC$ share on 112 155 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 } 119 163 conn->in.socket_options = lpcfg_socket_options(lp_ctx); 120 164 conn->in.service = "IPC$"; … … 133 177 */ 134 178 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)) { 136 181 conn->in.fallback_to_anonymous = true; 137 182 } else { … … 139 184 } 140 185 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 141 191 /* 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, 143 193 s->io.resolve_ctx, 144 s->io.pipe->conn->event_ctx);194 c->event_ctx); 145 195 if (composite_nomem(conn_req, c)) return c; 146 196 … … 161 211 } 162 212 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 186 213 /* 187 214 Stage 2 of ncacn_np_smb2: Open a named pipe after successful smb2 connection 188 215 */ 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); 216 static 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; 196 224 197 225 /* 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 co mposite_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); 209 237 } 210 238 … … 220 248 { 221 249 struct composite_context *c; 222 struct pipe_np_smb 2_state *s;223 struct composite_context *conn_req;250 struct pipe_np_smb_state *s; 251 struct tevent_req *subreq; 224 252 struct smbcli_options options; 253 const char *host; 254 uint32_t flags; 225 255 226 256 /* 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); 228 258 if (c == NULL) return NULL; 229 259 230 s = talloc_zero(c, struct pipe_np_smb 2_state);260 s = talloc_zero(c, struct pipe_np_smb_state); 231 261 if (composite_nomem(s, c)) return c; 232 262 c->private_data = s; 233 263 234 264 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); 235 273 236 274 /* … … 238 276 * schannel connection 239 277 */ 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); 242 280 if (composite_nomem(s->io.creds, c)) return c; 243 244 cli_credentials_guess(s->io.creds, lp_ctx);245 281 } 246 282 247 283 lpcfg_smbcli_options(lp_ctx, &options); 248 284 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 249 296 /* 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, 251 299 lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "smb2", "ports", NULL), 252 "IPC$",253 254 255 c->event_ctx,256 257 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); 261 309 return c; 262 310 } … … 291 339 struct composite_context *c = talloc_get_type(ctx->async.private_data, 292 340 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; 293 345 294 346 /* 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); 296 358 if (!composite_is_ok(c)) return; 297 359 … … 310 372 struct pipe_ip_tcp_state *s; 311 373 struct composite_context *pipe_req; 374 const char *endpoint; 312 375 313 376 /* 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); 315 378 if (c == NULL) return NULL; 316 379 … … 320 383 321 384 /* 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 } 328 401 329 402 /* 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, 331 404 s->port, io->resolve_ctx); 332 405 composite_continue(c, pipe_req, continue_pipe_open_ncacn_ip_tcp, c); … … 347 420 348 421 422 struct 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 */ 440 static 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 */ 468 static 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 587 static NTSTATUS dcerpc_pipe_connect_ncacn_http_recv(struct composite_context *c) 588 { 589 return composite_wait_free(c); 590 } 591 592 349 593 struct pipe_unix_state { 350 594 struct dcerpc_pipe_connect io; … … 381 625 382 626 /* 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); 384 628 if (c == NULL) return NULL; 385 629 … … 391 635 also, verify whether biding endpoint is not null */ 392 636 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); 397 641 return c; 398 642 } 399 643 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 403 644 /* 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); 405 646 composite_continue(c, pipe_req, continue_pipe_open_ncacn_unix_stream, c); 406 647 return c; … … 447 688 */ 448 689 static 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) 450 691 { 451 692 struct composite_context *c; 452 693 struct pipe_ncalrpc_state *s; 453 694 struct composite_context *pipe_req; 695 const char *endpoint; 454 696 455 697 /* 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); 457 699 if (c == NULL) return NULL; 458 700 … … 464 706 s->io = *io; 465 707 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 466 714 /* 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); 469 718 composite_continue(c, pipe_req, continue_pipe_open_ncalrpc, c); 470 719 return c; … … 498 747 static void continue_pipe_connect_ncacn_np_smb(struct composite_context *ctx); 499 748 static void continue_pipe_connect_ncacn_ip_tcp(struct composite_context *ctx); 749 static void continue_pipe_connect_ncacn_http(struct composite_context *ctx); 500 750 static void continue_pipe_connect_ncacn_unix(struct composite_context *ctx); 501 751 static void continue_pipe_connect_ncalrpc(struct composite_context *ctx); … … 513 763 struct pipe_connect_state *s = talloc_get_type(c->private_data, 514 764 struct pipe_connect_state); 515 765 const char *endpoint; 766 516 767 c->status = dcerpc_epm_map_binding_recv(ctx); 517 768 if (!composite_is_ok(c)) return; 518 769 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 521 773 continue_connect(c, s); 522 774 } … … 534 786 struct composite_context *ncacn_np_smb_req; 535 787 struct composite_context *ncacn_ip_tcp_req; 788 struct composite_context *ncacn_http_req; 536 789 struct composite_context *ncacn_unix_req; 537 790 struct composite_context *ncalrpc_req; 791 enum dcerpc_transport_t transport; 792 enum protocol_types min_ipc_protocol; 793 uint32_t flags; 538 794 539 795 /* dcerpc pipe connect input parameters */ 540 pc.pipe = s->pipe; 796 ZERO_STRUCT(pc); 797 pc.conn = s->pipe->conn; 541 798 pc.binding = s->binding; 542 pc.pipe_name = NULL;543 799 pc.interface = s->table; 544 800 pc.creds = s->credentials; 545 801 pc.resolve_ctx = lpcfg_resolve_context(s->lp_ctx); 546 802 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 547 811 /* connect dcerpc pipe depending on required transport */ 548 switch ( s->binding->transport) {812 switch (transport) { 549 813 case NCACN_NP: 550 if ( pc.binding->flags & DCERPC_SMB2) {814 if (flags & DCERPC_SMB2) { 551 815 /* new varient of SMB a.k.a. SMB2 */ 552 816 ncacn_np_smb2_req = dcerpc_pipe_connect_ncacn_np_smb2_send(c, &pc, s->lp_ctx); … … 567 831 return; 568 832 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 569 838 case NCACN_UNIX_STREAM: 570 839 ncacn_unix_req = dcerpc_pipe_connect_ncacn_unix_stream_send(c, &pc); … … 573 842 574 843 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); 576 849 composite_continue(c, ncalrpc_req, continue_pipe_connect_ncalrpc, c); 577 850 return; … … 631 904 632 905 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 */ 915 static 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); 633 923 if (!composite_is_ok(c)) return; 634 924 … … 679 969 struct composite_context *auth_bind_req; 680 970 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)) { 684 973 return; 685 974 } … … 714 1003 struct timeval t, void *private_data) 715 1004 { 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 } 718 1013 } 719 1014 … … 723 1018 */ 724 1019 _PUBLIC_ struct composite_context* dcerpc_pipe_connect_b_send(TALLOC_CTX *parent_ctx, 725 struct dcerpc_binding *binding,1020 const struct dcerpc_binding *binding, 726 1021 const struct ndr_interface_table *table, 727 1022 struct cli_credentials *credentials, … … 731 1026 struct composite_context *c; 732 1027 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; 734 1031 735 1032 /* composite context allocation and setup */ 736 1033 c = composite_create(parent_ctx, ev); 737 1034 if (c == NULL) { 738 talloc_free(new_ev);739 1035 return NULL; 740 1036 } 741 talloc_steal(c, new_ev);742 1037 743 1038 s = talloc_zero(c, struct pipe_connect_state); … … 750 1045 751 1046 if (DEBUGLEVEL >= 10) 752 s->pipe->conn->packet_log_dir = lpcfg_lock dir(lp_ctx);1047 s->pipe->conn->packet_log_dir = lpcfg_lock_directory(lp_ctx); 753 1048 754 1049 /* 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; 756 1052 s->table = table; 757 1053 s->credentials = credentials; 758 1054 s->lp_ctx = lp_ctx; 759 1055 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) { 766 1085 struct composite_context *binding_req; 1086 767 1087 binding_req = dcerpc_epm_map_binding_send(c, s->binding, s->table, 1088 epm_creds, 768 1089 s->pipe->conn->event_ctx, 769 1090 s->lp_ctx); 770 1091 composite_continue(c, binding_req, continue_map_binding, c); 771 1092 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;788 1093 } 789 1094 … … 820 1125 _PUBLIC_ NTSTATUS dcerpc_pipe_connect_b(TALLOC_CTX *parent_ctx, 821 1126 struct dcerpc_pipe **pp, 822 struct dcerpc_binding *binding,1127 const struct dcerpc_binding *binding, 823 1128 const struct ndr_interface_table *table, 824 1129 struct cli_credentials *credentials, -
vendor/current/source4/librpc/rpc/dcerpc_schannel.c
r740 r988 37 37 struct dcerpc_pipe *pipe2; 38 38 struct dcerpc_binding *binding; 39 bool dcerpc_schannel_auto; 39 40 struct cli_credentials *credentials; 40 41 struct netlogon_creds_CredentialState *creds; 41 uint32_t negotiate_flags; 42 uint32_t local_negotiate_flags; 43 uint32_t remote_negotiate_flags; 42 44 struct netr_Credential credentials1; 43 45 struct netr_Credential credentials2; … … 53 55 static void continue_srv_challenge(struct tevent_req *subreq); 54 56 static void continue_srv_auth2(struct tevent_req *subreq); 57 static void continue_get_capabilities(struct tevent_req *subreq); 55 58 56 59 … … 177 180 cli_credentials_get_secure_channel_type(s->credentials); 178 181 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; 180 183 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; 182 185 s->a.out.return_credentials = &s->credentials3; 183 186 … … 185 188 s->a.in.account_name, 186 189 s->a.in.computer_name, 190 s->a.in.secure_channel_type, 187 191 &s->credentials1, &s->credentials2, 188 s->mach_pwd, &s->credentials3, s->negotiate_flags); 192 s->mach_pwd, &s->credentials3, 193 s->local_negotiate_flags); 189 194 if (composite_nomem(s->creds, c)) { 190 195 return; … … 219 224 if (!composite_is_ok(c)) return; 220 225 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 221 293 /* verify credentials */ 222 294 if (!netlogon_creds_client_check(s->creds, s->a.out.return_credentials)) { … … 225 297 } 226 298 227 /* setup current netlogon credentials */228 cli_credentials_set_netlogon_creds(s->credentials, s->creds);229 230 299 composite_done(c); 231 300 } 232 233 301 234 302 /* … … 236 304 on a secondary pipe 237 305 */ 238 st ruct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,306 static struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx, 239 307 struct dcerpc_pipe *p, 240 308 struct cli_credentials *credentials, … … 245 313 struct composite_context *epm_map_req; 246 314 enum netr_SchannelType schannel_type = cli_credentials_get_secure_channel_type(credentials); 247 315 struct cli_credentials *epm_creds = NULL; 316 248 317 /* composite context allocation and setup */ 249 318 c = composite_create(mem_ctx, p->conn->event_ctx); … … 257 326 s->pipe = p; 258 327 s->credentials = credentials; 328 s->local_negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS; 259 329 260 330 /* 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 261 344 /* type of authentication depends on schannel type */ 262 345 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; 269 351 270 352 /* allocate binding structure */ 271 s->binding = talloc_zero(c, struct dcerpc_binding);353 s->binding = dcerpc_binding_dup(s, s->pipe->binding); 272 354 if (composite_nomem(s->binding, c)) return c; 273 274 *s->binding = *s->pipe->binding;275 355 276 356 /* request the netlogon endpoint mapping */ 277 357 epm_map_req = dcerpc_epm_map_binding_send(c, s->binding, 278 358 &ndr_table_netlogon, 359 epm_creds, 279 360 s->pipe->conn->event_ctx, 280 361 lp_ctx); … … 289 370 Receive result of schannel key request 290 371 */ 291 NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c) 372 static NTSTATUS dcerpc_schannel_key_recv(struct composite_context *c, 373 TALLOC_CTX *mem_ctx, 374 struct netlogon_creds_CredentialState **creds) 292 375 { 293 376 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 295 385 talloc_free(c); 296 386 return status; … … 304 394 struct loadparm_context *lp_ctx; 305 395 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; 306 402 }; 307 403 … … 324 420 325 421 /* 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); 327 423 if (!composite_is_ok(c)) { 328 424 DEBUG(1, ("Failed to setup credentials: %s\n", nt_errstr(status))); … … 331 427 332 428 /* send bind auth request with received creds */ 429 cli_credentials_set_netlogon_creds(s->credentials, s->creds_state); 430 333 431 auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, s->credentials, 334 432 lpcfg_gensec_settings(c, s->lp_ctx), … … 349 447 struct composite_context *c = talloc_get_type(ctx->async.private_data, 350 448 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; 351 452 352 453 c->status = dcerpc_bind_auth_recv(ctx); 353 454 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 */ 495 static 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. */ 354 557 355 558 composite_done(c); -
vendor/current/source4/librpc/rpc/dcerpc_secondary.c
r740 r988 32 32 #include "param/param.h" 33 33 #include "libcli/resolve/resolve.h" 34 #include "lib/ socket/socket.h"34 #include "lib/util/util_net.h" 35 35 36 36 struct sec_conn_state { … … 38 38 struct dcerpc_pipe *pipe2; 39 39 struct dcerpc_binding *binding; 40 struct smbcli_tree *tree;41 struct socket_address *peer_addr;42 40 }; 43 41 … … 45 43 static void continue_open_smb(struct composite_context *ctx); 46 44 static void continue_open_tcp(struct composite_context *ctx); 47 static void continue_open_pipe(struct composite_context *ctx); 45 static void continue_open_ncalrpc(struct composite_context *ctx); 46 static void continue_open_ncacn_unix(struct composite_context *ctx); 48 47 static void continue_pipe_open(struct composite_context *c); 49 48 … … 54 53 */ 55 54 _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerpc_pipe *p, 56 55 const struct dcerpc_binding *b) 57 56 { 58 57 struct composite_context *c; … … 60 59 struct composite_context *pipe_smb_req; 61 60 struct composite_context *pipe_tcp_req; 61 const char *localaddress = NULL; 62 62 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 64 69 /* composite context allocation and setup */ 65 70 c = composite_create(p, p->conn->event_ctx); … … 71 76 72 77 s->pipe = p; 73 s->binding = b; 78 s->binding = dcerpc_binding_dup(s, b); 79 if (composite_nomem(s->binding, c)) return c; 74 80 75 81 /* initialise second dcerpc pipe based on primary pipe's event context */ … … 80 86 s->pipe2->conn->packet_log_dir = s->pipe->conn->packet_log_dir; 81 87 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 82 116 /* open second dcerpc pipe using the same transport as for primary pipe */ 83 117 switch (s->pipe->conn->transport.transport) { 84 118 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); 89 128 return c; 90 129 } 91 130 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 } 102 145 } 103 146 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 104 157 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), 109 162 resolve_context_init(s)); 110 163 composite_continue(c, pipe_tcp_req, continue_open_tcp, c); … … 112 165 113 166 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 114 184 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); 118 188 return c; 119 189 … … 135 205 struct composite_context); 136 206 137 c->status = dcerpc_ pipe_open_smb_recv(ctx);207 c->status = dcerpc_secondary_smb_recv(ctx); 138 208 if (!composite_is_ok(c)) return; 139 209 … … 149 219 struct composite_context *c = talloc_get_type(ctx->async.private_data, 150 220 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); 153 237 if (!composite_is_ok(c)) return; 154 238 … … 156 240 } 157 241 158 159 242 /* 160 243 Stage 2 of secondary_connection: Receive result of pipe open request on ncalrpc 161 244 */ 162 static void continue_open_ pipe(struct composite_context *ctx)245 static void continue_open_ncalrpc(struct composite_context *ctx) 163 246 { 164 247 struct composite_context *c = talloc_get_type(ctx->async.private_data, … … 171 254 } 172 255 256 /* 257 Stage 2 of secondary_connection: Receive result of pipe open request on ncacn_unix 258 */ 259 static 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 173 270 174 271 /* … … 183 280 184 281 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)) { 188 284 return; 189 285 } … … 222 318 _PUBLIC_ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, 223 319 struct dcerpc_pipe **p2, 224 struct dcerpc_binding *b)320 const struct dcerpc_binding *b) 225 321 { 226 322 struct composite_context *c; … … 238 334 struct sec_auth_conn_state { 239 335 struct dcerpc_pipe *pipe2; 240 struct dcerpc_binding *binding;336 const struct dcerpc_binding *binding; 241 337 const struct ndr_interface_table *table; 242 338 struct cli_credentials *credentials; … … 249 345 250 346 _PUBLIC_ struct composite_context* dcerpc_secondary_auth_connection_send(struct dcerpc_pipe *p, 251 struct dcerpc_binding *binding,347 const struct dcerpc_binding *binding, 252 348 const struct ndr_interface_table *table, 253 349 struct cli_credentials *credentials, … … 336 432 return status; 337 433 } 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 22 22 23 23 #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" 24 30 #include "libcli/raw/libcliraw.h" 25 #include "libcli/ composite/composite.h"31 #include "libcli/smb2/smb2.h" 26 32 #include "librpc/rpc/dcerpc.h" 27 33 #include "librpc/rpc/dcerpc_proto.h" 28 #include "lib rpc/rpc/rpc_common.h"34 #include "libcli/composite/composite.h" 29 35 30 36 /* transport private information used by SMB pipe transport */ 31 37 struct 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; 36 47 }; 37 38 39 /*40 tell the dcerpc layer that the transport is dead41 */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 call68 */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 completed79 */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 initial142 data in the read buffer143 */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 server205 */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 call219 */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 completed228 */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 request257 */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 completed312 */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 server327 */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 otherwise352 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 connection378 */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 }422 48 423 49 /* … … 426 52 static NTSTATUS smb_session_key(struct dcecli_connection *c, DATA_BLOB *session_key) 427 53 { 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); 429 56 430 57 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 67 struct dcerpc_pipe_open_smb_state { 440 68 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; 443 74 }; 444 75 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 } 76 static void dcerpc_pipe_open_smb_done(struct tevent_req *subreq); 77 78 struct 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; 469 89 470 90 ctx = composite_create(c, c->event_ctx); 471 91 if (ctx == NULL) return NULL; 472 92 473 state = talloc(ctx, struct pipe_open_smb_state);93 state = talloc(ctx, struct dcerpc_pipe_open_smb_state); 474 94 if (composite_nomem(state, ctx)) return ctx; 475 95 ctx->private_data = state; 476 96 477 97 state->c = c; 478 state->tree = tree;479 98 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;503 99 504 100 if ((strncasecmp(pipe_name, "/pipe/", 6) == 0) || … … 506 102 pipe_name += 6; 507 103 } 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 516 138 return ctx; 517 139 } 518 140 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); 141 static 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); 523 146 struct composite_context *ctx = state->ctx; 524 147 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); 528 153 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; 529 158 530 159 /* … … 533 162 c->transport.transport = NCACN_NP; 534 163 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 543 173 /* Over-ride the default session key with the SMB session key */ 544 174 c->security_state.session_key = smb_session_key; 545 175 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); 557 177 558 178 composite_done(ctx); … … 567 187 568 188 _PUBLIC_ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p, 569 struct smbcli_tree *t ree,189 struct smbcli_tree *t, 570 190 const char *pipe_name) 571 191 { 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 574 229 return dcerpc_pipe_open_smb_recv(ctx); 575 230 } 576 231 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 275 struct composite_context *dcerpc_secondary_smb_send(struct dcecli_connection *c1, 276 struct dcecli_connection *c2, 277 const char *pipe_name) 581 278 { 582 279 struct smb_private *smb; 583 280 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); 587 284 if (!smb) return NULL; 588 285 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 294 NTSTATUS 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 23 23 24 24 #include "includes.h" 25 #include "system/filesys.h" 25 26 #include "lib/events/events.h" 26 27 #include "lib/socket/socket.h" 27 #include "lib/ stream/packet.h"28 #include "lib/tsocket/tsocket.h" 28 29 #include "libcli/composite/composite.h" 29 30 #include "librpc/rpc/dcerpc.h" … … 32 33 #include "librpc/rpc/rpc_common.h" 33 34 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 dead49 */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 errors88 */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 packet98 */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 it108 */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 requests119 */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 system135 */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 sockets159 */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 sequence172 */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 connection203 */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 name217 */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 234 35 struct pipe_open_socket_state { 235 36 struct dcecli_connection *conn; 236 37 struct socket_context *socket_ctx; 237 struct sock_private *sock;238 38 struct socket_address *localaddr; 239 39 struct socket_address *server; 240 40 const char *target_hostname; 241 41 enum dcerpc_transport_t transport; 42 struct socket_address *client; 242 43 }; 243 44 … … 246 47 { 247 48 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; 253 55 254 56 /* make it easier to write a function calls */ 255 57 conn = s->conn; 256 sock = s->sock;257 58 258 59 c->status = socket_connect_recv(ctx); … … 265 66 } 266 67 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 267 78 /* 268 79 fill in the transport methods … … 271 82 conn->transport.private_data = NULL; 272 83 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); 292 98 composite_error(c, NT_STATUS_NO_MEMORY); 293 talloc_free(sock);294 99 return; 295 100 } 296 101 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 } 306 109 307 110 /* ensure we don't get SIGPIPE */ … … 334 137 s->transport = transport; 335 138 if (localaddr) { 336 s->localaddr = talloc_reference(c, localaddr);139 s->localaddr = socket_address_copy(s, localaddr); 337 140 if (composite_nomem(s->localaddr, c)) return c; 338 141 } 339 s->server = talloc_reference(c, server);142 s->server = socket_address_copy(s, server); 340 143 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 } 345 148 346 149 c->status = socket_create(server->family, SOCKET_TYPE_STREAM, &s->socket_ctx, 0); 347 150 if (!composite_is_ok(c)) return c; 348 151 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); 352 153 353 154 conn_req = socket_connect_send(s->socket_ctx, s->localaddr, s->server, 0, … … 357 158 } 358 159 359 360 static NTSTATUS dcerpc_pipe_open_socket_recv(struct composite_context *c) 160 static NTSTATUS dcerpc_pipe_open_socket_recv(struct composite_context *c, 161 TALLOC_CTX *mem_ctx, 162 struct socket_address **localaddr) 361 163 { 362 164 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 } 363 175 364 176 talloc_free(c); … … 369 181 const char *server; 370 182 const char *target_hostname; 371 const char *address; 183 const char **addresses; 184 uint32_t index; 372 185 uint32_t port; 373 186 struct socket_address *localaddr; … … 375 188 struct resolve_context *resolve_ctx; 376 189 struct dcecli_connection *conn; 190 char *local_address; 191 char *remote_address; 377 192 }; 378 193 379 194 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); 195 static void continue_ip_open_socket(struct composite_context *ctx); 384 196 static void continue_ip_resolve_name(struct composite_context *ctx); 385 197 386 198 static void continue_ip_resolve_name(struct composite_context *ctx) 387 199 { 388 struct composite_context *c = talloc_get_type (ctx->async.private_data,389 390 struct pipe_tcp_state *s = talloc_get_type (c->private_data,391 392 struct composite_context *sock_ip v4_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); 395 207 if (!composite_is_ok(c)) return; 396 208 397 209 /* 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++; 399 212 if (composite_nomem(s->srvaddr, c)) return; 400 213 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, 403 215 s->srvaddr, s->target_hostname, 404 216 NULL, 405 217 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 408 221 409 222 /* 410 223 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 */ 226 static 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 454 234 /* 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); 456 236 if (!NT_STATUS_IS_OK(c->status)) { 457 237 /* something went wrong... */ 458 238 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, 460 240 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; 465 266 466 267 composite_done(c); … … 517 318 Receive result of pipe open request on tcp/ip 518 319 */ 519 NTSTATUS dcerpc_pipe_open_tcp_recv(struct composite_context *c) 320 NTSTATUS dcerpc_pipe_open_tcp_recv(struct composite_context *c, 321 TALLOC_CTX *mem_ctx, 322 char **localaddr, 323 char **remoteaddr) 520 324 { 521 325 NTSTATUS status; 522 326 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 } 523 339 524 340 talloc_free(c); … … 540 356 static void continue_unix_open_socket(struct composite_context *ctx) 541 357 { 542 struct composite_context *c = talloc_get_type (ctx->async.private_data,543 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); 546 362 if (NT_STATUS_IS_OK(c->status)) { 547 363 composite_done(c); … … 607 423 static void continue_np_open_socket(struct composite_context *ctx) 608 424 { 609 struct composite_context *c = talloc_get_type (ctx->async.private_data,610 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); 613 429 if (!composite_is_ok(c)) return; 614 430 … … 678 494 return dcerpc_pipe_open_pipe_recv(c); 679 495 } 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 31 31 #include "librpc/rpc/dcerpc_proto.h" 32 32 #include "auth/credentials/credentials.h" 33 #include "auth/gensec/gensec.h" 33 34 #include "param/param.h" 34 35 #include "librpc/rpc/rpc_common.h" … … 117 118 struct dcerpc_pipe *pipe; 118 119 struct policy_handle handle; 119 struct GUID guid;120 struct GUID object; 120 121 struct epm_twr_t twr; 121 122 struct epm_twr_t *twr_r; … … 145 146 if (!composite_is_ok(c)) return; 146 147 147 /* prepare requested binding parameters */148 s->binding->object = s->table->syntax_id;149 150 148 c->status = dcerpc_binding_build_tower(s->pipe, s->binding, &s->twr.tower); 151 149 if (!composite_is_ok(c)) return; 152 150 153 151 /* with some nice pretty paper around it of course */ 154 s->r.in.object = &s-> guid;152 s->r.in.object = &s->object; 155 153 s->r.in.map_tower = &s->twr; 156 154 s->r.in.entry_handle = &s->handle; … … 178 176 struct epm_map_binding_state *s = talloc_get_type(c->private_data, 179 177 struct epm_map_binding_state); 178 const char *endpoint; 180 179 181 180 /* receive result of a rpc request */ … … 203 202 204 203 /* 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 } 208 213 209 214 composite_done(c); … … 218 223 struct dcerpc_binding *binding, 219 224 const struct ndr_interface_table *table, 225 struct cli_credentials *creds, 220 226 struct tevent_context *ev, 221 227 struct loadparm_context *lp_ctx) … … 224 230 struct epm_map_binding_state *s; 225 231 struct composite_context *pipe_connect_req; 226 struct cli_credentials *anon_creds;227 228 232 NTSTATUS status; 229 233 struct dcerpc_binding *epmapper_binding; … … 245 249 246 250 s->binding = binding; 251 s->object = dcerpc_binding_get_object(binding); 247 252 s->table = table; 248 253 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 } 252 259 253 260 /* 254 261 First, check if there is a default endpoint specified in the IDL 255 262 */ 256 if (table != NULL) {263 for (i = 0; i < table->endpoints->count; i++) { 257 264 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; 277 283 } 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); 282 312 if (composite_nomem(epmapper_binding, c)) return c; 283 313 284 314 /* 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 } 293 332 294 333 /* 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, 296 335 &ndr_table_epmapper, 297 anon_creds, c->event_ctx,336 creds, c->event_ctx, 298 337 lp_ctx); 299 338 if (composite_nomem(pipe_connect_req, c)) return c; … … 324 363 { 325 364 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); 328 377 return dcerpc_epm_map_binding_recv(c); 329 378 } … … 332 381 struct pipe_auth_state { 333 382 struct dcerpc_pipe *pipe; 334 struct dcerpc_binding *binding;383 const struct dcerpc_binding *binding; 335 384 const struct ndr_interface_table *table; 336 385 struct loadparm_context *lp_ctx; 337 386 struct cli_credentials *credentials; 387 unsigned int logon_retries; 338 388 }; 339 389 … … 395 445 composite_continue(c, sec_conn_req, continue_ntlmssp_connection, c); 396 446 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) { 399 471 /* 400 472 * Retry SPNEGO with a better password … … 524 596 */ 525 597 struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p, 526 struct dcerpc_binding *binding,598 const struct dcerpc_binding *binding, 527 599 const struct ndr_interface_table *table, 528 600 struct cli_credentials *credentials, … … 553 625 554 626 conn = s->pipe->conn; 555 conn->flags = binding->flags;627 conn->flags = dcerpc_binding_get_flags(binding); 556 628 557 629 if (DEBUGLVL(100)) { 558 630 conn->flags |= DCERPC_DEBUG_PRINT_BOTH; 559 631 } 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 } 563 648 564 649 if (cli_credentials_is_anonymous(s->credentials)) { … … 568 653 } 569 654 570 if (( binding->flags & DCERPC_SCHANNEL) &&655 if ((conn->flags & DCERPC_SCHANNEL) && 571 656 !cli_credentials_get_netlogon_creds(s->credentials)) { 572 657 /* If we don't already have netlogon credentials for … … 585 670 */ 586 671 if (conn->transport.transport == NCACN_NP && 587 !( s->binding->flags & (DCERPC_SIGN|DCERPC_SEAL))) {672 !(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) { 588 673 auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table); 589 674 composite_continue(c, auth_none_req, continue_auth_none, c); … … 605 690 } 606 691 607 if ( s->binding->flags & DCERPC_AUTH_SPNEGO) {692 if (conn->flags & DCERPC_AUTH_SPNEGO) { 608 693 auth_type = DCERPC_AUTH_TYPE_SPNEGO; 609 694 610 } else if ( s->binding->flags & DCERPC_AUTH_KRB5) {695 } else if (conn->flags & DCERPC_AUTH_KRB5) { 611 696 auth_type = DCERPC_AUTH_TYPE_KRB5; 612 697 613 } else if ( s->binding->flags & DCERPC_SCHANNEL) {698 } else if (conn->flags & DCERPC_SCHANNEL) { 614 699 auth_type = DCERPC_AUTH_TYPE_SCHANNEL; 615 700 616 } else if ( s->binding->flags & DCERPC_AUTH_NTLM) {701 } else if (conn->flags & DCERPC_AUTH_NTLM) { 617 702 auth_type = DCERPC_AUTH_TYPE_NTLMSSP; 618 703 … … 657 742 if (!NT_STATUS_IS_OK(status)) { 658 743 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))); 660 746 talloc_free(uuid_str); 661 747 } else { … … 676 762 _PUBLIC_ NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx, 677 763 struct dcerpc_pipe **p, 678 struct dcerpc_binding *binding,764 const struct dcerpc_binding *binding, 679 765 const struct ndr_interface_table *table, 680 766 struct cli_credentials *credentials, … … 691 777 DATA_BLOB *session_key) 692 778 { 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 693 789 /* this took quite a few CPU cycles to find ... */ 694 790 session_key->data = discard_const_p(unsigned char, "SystemLibraryDTC"); … … 735 831 for (i=0;i<num_examples;i++) { 736 832 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) { 741 838 return; 742 839 } … … 779 876 p2->transfer_syntax = p->transfer_syntax; 780 877 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 } 782 883 783 884 p2->binding_handle = dcerpc_pipe_binding_handle(p2); -
vendor/current/source4/librpc/rpc/pyrpc.c
r740 r988 27 27 #include "librpc/rpc/pyrpc_util.h" 28 28 #include "auth/credentials/pycredentials.h" 29 #include "auth/gensec/gensec.h" 29 30 30 31 void initbase(void); 31 32 32 staticforward PyTypeObject dcerpc_InterfaceType; 33 static PyTypeObject dcerpc_InterfaceType; 34 35 static PyTypeObject *ndr_syntax_id_Type; 33 36 34 37 static bool PyString_AsGUID(PyObject *object, struct GUID *uuid) … … 118 121 } 119 122 123 static 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 134 static 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 120 175 static PyGetSetDef dcerpc_interface_getsetters[] = { 121 176 { discard_const_p(char, "server_name"), py_iface_server_name, NULL, … … 125 180 { discard_const_p(char, "transfer_syntax"), py_iface_transfer_syntax, NULL, 126 181 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)") }, 127 186 { NULL } 128 187 }; … … 142 201 NTSTATUS status; 143 202 char *in_data; 144 int in_length;203 Py_ssize_t in_length; 145 204 PyObject *ret; 146 205 PyObject *object = NULL; … … 188 247 } 189 248 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 226 249 static PyMethodDef dcerpc_interface_methods[] = { 227 250 { "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" },229 251 { NULL, NULL, 0, NULL }, 230 252 }; … … 233 255 { 234 256 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); 236 260 self->ob_type->tp_free(self); 237 261 } … … 239 263 static PyObject *dcerpc_interface_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) 240 264 { 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; 251 271 const char *kwnames[] = { 252 272 "binding", "syntax", "lp_ctx", "credentials", "basis_connection", NULL 253 273 }; 254 struct ndr_interface_table *table; 274 static struct ndr_interface_table dummy_table; 275 PyObject *args2 = Py_None; 276 PyObject *kwargs2 = Py_None; 255 277 256 278 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|OOO:connect", discard_const_p(char *, kwnames), &binding_string, &syntax, &py_lp_ctx, &py_credentials, &py_basis)) { … … 258 280 } 259 281 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 285 289 * 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. 286 293 */ 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; 332 317 } 333 318 … … 350 335 }; 351 336 337 static 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 342 static 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 350 static 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 355 static 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 363 static 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 393 static 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 352 401 void initbase(void) 353 402 { 354 403 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(); 355 420 356 421 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) 357 429 return; 358 430 … … 363 435 Py_INCREF((PyObject *)&dcerpc_InterfaceType); 364 436 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 57 57 PyObject *py_import_netr_Validation(TALLOC_CTX *mem_ctx, int level, union netr_Validation *in); 58 58 59 union netr_CONTROL_DATA_INFORMATION *py_export_netr_CONTROL_DATA_INFORMATION(TALLOC_CTX *mem_ctx, int level, PyObject *in); 60 union netr_CONTROL_QUERY_INFORMATION; 61 PyObject *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 59 67 #endif /* _PYRPC_H_ */ -
vendor/current/source4/librpc/rpc/pyrpc_util.c
r740 r988 43 43 PyErr_Format(PyExc_RuntimeError, "Unable to import %s to check type %s", 44 44 module, type_name); 45 return NULL;45 return false; 46 46 } 47 47 … … 51 51 PyErr_Format(PyExc_RuntimeError, "Unable to find type %s in module %s", 52 52 module, type_name); 53 return NULL;53 return false; 54 54 } 55 55 … … 73 73 struct dcerpc_binding_handle **binding_handle) 74 74 { 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); 78 78 NT_STATUS_HAVE_NO_MEMORY(msg); 79 79 … … 84 84 } 85 85 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 86 92 return NT_STATUS_OK; 87 93 } … … 92 98 dcerpc_InterfaceObject *ret; 93 99 const char *binding_string; 94 struct cli_credentials *credentials;95 struct loadparm_context *lp_ctx = NULL;96 100 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;99 101 NTSTATUS status; 100 101 102 const char *kwnames[] = { 102 103 "binding", "lp_ctx", "credentials", "basis_connection", NULL … … 107 108 } 108 109 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(); 123 111 if (!NT_STATUS_IS_OK(status)) { 124 112 PyErr_SetNTSTATUS(status); 125 talloc_free(mem_ctx);126 113 return NULL; 127 114 } 128 115 129 116 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 } 133 124 134 125 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 136 143 status = pyrpc_irpc_connect(ret->mem_ctx, binding_string+5, table, 137 144 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 } 138 150 } else if (py_basis != Py_None) { 139 151 struct dcerpc_pipe *base_pipe; … … 143 155 py_base = PyImport_ImportModule("samba.dcerpc.base"); 144 156 if (py_base == NULL) { 145 talloc_free(mem_ctx);157 TALLOC_FREE(ret->mem_ctx); 146 158 return NULL; 147 159 } … … 150 162 if (ClientConnection_Type == NULL) { 151 163 PyErr_SetNone(PyExc_TypeError); 152 talloc_free(mem_ctx);164 TALLOC_FREE(ret->mem_ctx); 153 165 return NULL; 154 166 } … … 156 168 if (!PyObject_TypeCheck(py_basis, ClientConnection_Type)) { 157 169 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 } 163 181 164 182 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 } 165 188 166 189 ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe); 167 190 } 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 168 209 credentials = cli_credentials_from_py_object(py_credentials); 169 210 if (credentials == NULL) { 170 211 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); 181 228 } 182 229 … … 247 294 struct wrapperbase *wb = (struct wrapperbase *)calloc(sizeof(struct wrapperbase), 1); 248 295 296 if (wb == NULL) { 297 return false; 298 } 249 299 wb->name = discard_const_p(char, mds[i].name); 250 300 wb->flags = PyWrapperFlag_KEYWORDS; … … 261 311 } 262 312 313 PyObject *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 263 335 void PyErr_SetDCERPCStatus(struct dcerpc_pipe *p, NTSTATUS status) 264 336 { … … 278 350 r_ctx is the context that is a parent of r. It will be referenced by 279 351 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. 280 355 */ 281 356 PyObject *py_return_ndr_struct(const char *module_name, const char *type_name, … … 299 374 } 300 375 301 return py _talloc_reference_ex(py_type, r_ctx, r);376 return pytalloc_reference_ex(py_type, r_ctx, r); 302 377 } 303 378 -
vendor/current/source4/librpc/rpc/pyrpc_util.h
r740 r988 51 51 PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs, const struct ndr_interface_table *table); 52 52 53 struct ndr_syntax_id; 54 PyObject *py_dcerpc_syntax_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs, 55 const struct ndr_syntax_id *syntax); 56 53 57 PyObject *py_return_ndr_struct(const char *module_name, const char *type_name, 54 58 TALLOC_CTX *r_ctx, void *r); -
vendor/current/source4/librpc/tests/binding_string.c
r740 r988 25 25 #include "librpc/rpc/dcerpc_proto.h" 26 26 #include "torture/torture.h" 27 #include "torture/local/proto.h" 27 28 #include "lib/util/util_net.h" 28 29 … … 32 33 const char *binding = test_data; 33 34 struct dcerpc_binding *b, *b2; 34 c onst char *s, *s2;35 char *s, *s2, *p; 35 36 struct epm_tower tower; 36 37 TALLOC_CTX *mem_ctx = tctx; 38 const char *host; 39 struct GUID object; 37 40 38 41 /* Parse */ … … 40 43 "Error parsing binding string"); 41 44 45 object = dcerpc_binding_get_object(b); 46 42 47 s = dcerpc_binding_string(mem_ctx, b); 43 48 torture_assert(tctx, s != NULL, "Error converting binding back to string"); … … 55 60 "Error generating binding from tower for original binding"); 56 61 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 63 66 s = dcerpc_binding_string(mem_ctx, b); 64 67 torture_assert(tctx, s != NULL, "Error converting binding back to string for (stripped down)"); 65 68 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 66 99 s2 = dcerpc_binding_string(mem_ctx, b2); 67 100 torture_assert(tctx, s != NULL, "Error converting binding back to string"); 68 101 69 if (is_ipaddress(b->host)) 102 host = dcerpc_binding_get_string_option(b, "host"); 103 if (host && is_ipaddress_v4(host)) { 70 104 torture_assert_casestr_equal(tctx, s, s2, "Mismatch while comparing original and from protocol tower generated binding strings"); 105 } 71 106 72 107 return true; … … 82 117 "ncacn_ip_tcp:127.0.0.1[20]", 83 118 "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]", 85 120 "ncacn_http:127.0.0.1", 86 121 "ncacn_http:127.0.0.1[78]", … … 96 131 "ncalrpc:[IDENTIFIER]", 97 132 "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]", 98 145 }; 99 146 … … 102 149 struct dcerpc_binding *b; 103 150 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; 104 156 105 157 torture_assert_ntstatus_ok(tctx, … … 108 160 109 161 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"); 111 164 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"); 113 167 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"); 115 170 torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[/pipe/rpcecho]", &b), "parse"); 116 171 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"); 119 176 torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, "ncacn_np:$SERVER[,sign]", &b), "parse"); 120 177 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"); 123 182 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"); 125 185 torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, 126 186 "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"); 129 192 torture_assert_ntstatus_ok(tctx, dcerpc_parse_binding(tctx, 130 193 "308FB580-1EB2-11CA-923B-08002B1075A7@ncacn_ip_tcp:$SERVER", &b), "parse"); 131 194 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"); 135 201 torture_assert_str_equal(tctx, "ncacn_ip_tcp:$SERVER[,sign,localaddress=192.168.1.1]", 136 202 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"); 137 239 138 240 return true; 139 241 } 140 242 141 static bool test_no_transport(struct torture_context *tctx )243 static bool test_no_transport(struct torture_context *tctx, const void *test_data) 142 244 { 143 const char *binding = "somehost";245 const char *binding = test_data; 144 246 struct dcerpc_binding *b; 247 enum dcerpc_transport_t transport; 145 248 const char *s; 146 249 … … 149 252 "Error parsing binding string"); 150 253 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"); 152 256 153 257 s = dcerpc_binding_string(tctx, b); … … 159 263 return true; 160 264 } 265 266 static 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 }; 161 286 162 287 struct torture_suite *torture_local_binding_string(TALLOC_CTX *mem_ctx) … … 171 296 } 172 297 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 } 174 303 175 304 torture_suite_add_simple_test(suite, "parsing results", -
vendor/current/source4/librpc/wscript_build
r740 r988 5 5 bld.RECURSE('idl') 6 6 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 14 7 15 8 bld.SAMBA_SUBSYSTEM('NDR_WINSTATION', … … 21 14 bld.SAMBA_SUBSYSTEM('NDR_IRPC', 22 15 source='gen_ndr/ndr_irpc.c', 23 public_deps='ndr NDR_SECURITY NDR_NBT'16 public_deps='ndr NDR_SECURITY ndr_nbt' 24 17 ) 25 18 … … 32 25 33 26 34 bld.SAMBA_SUBSYSTEM('NDR_NFS4ACL',35 source='gen_ndr/ndr_nfs4acl.c',36 public_deps='ndr NDR_SECURITY'37 )38 39 40 41 27 bld.SAMBA_SUBSYSTEM('NDR_WINSIF', 42 28 source='gen_ndr/ndr_winsif.c', … … 51 37 52 38 53 bld.SAMBA_SUBSYSTEM('NDR_NOTIFY',54 source='gen_ndr/ndr_s4_notify.c',55 public_deps='ndr NDR_SERVER_ID4'56 )57 58 59 39 bld.SAMBA_SUBSYSTEM('NDR_NTP_SIGND', 60 40 source='gen_ndr/ndr_ntp_signd.c', … … 65 45 bld.SAMBA_SUBSYSTEM('NDR_WINSREPL', 66 46 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 75 50 76 51 # create a grouping library to consolidate our samba4 specific NDR code 77 52 bld.SAMBA_LIBRARY('ndr-samba4', 78 53 source=[], 79 deps='NDR_WINBIND NDR_IRPC NDR_NFS4ACL NDR_OPENDB NDR_NOTIFYndr-table',54 deps='NDR_WINBIND NDR_IRPC NDR_NFS4ACL NDR_OPENDB ndr-table', 80 55 private_library=True, 81 56 grouping_library=True … … 92 67 93 68 bld.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 = ""99 69 100 70 bld.SAMBA_SUBSYSTEM('ndr-table', … … 105 75 NDR_OXIDRESOLVER NDR_REMACT NDR_WZCSVC 106 76 NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_TRKWKS NDR_KEYSVC ndr-krb5pac 107 NDR_XATTR NDR_SCHANNEL NDR_ROT NDR_DRSBLOBS NDR_NBTNDR_WINSREPL77 NDR_XATTR NDR_SCHANNEL NDR_ROT NDR_DRSBLOBS ndr_nbt NDR_WINSREPL 108 78 NDR_SECURITY NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB 109 79 NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI 110 80 NDR_FRSTRANS NDR_NFS4ACL NDR_NTP_SIGND NDR_DCOM NDR_WMI 111 81 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''', 113 84 depends_on='GEN_NDR_TABLES' 114 85 ) … … 119 90 public_deps='dcerpc NDR_IRPC' 120 91 ) 121 122 bld.SAMBA_SUBSYSTEM('RPC_NDR_WINBIND',123 source='gen_ndr/ndr_winbind_c.c',124 public_deps='dcerpc NDR_WINBIND'125 )126 127 92 128 93 bld.SAMBA_LIBRARY('dcerpc-samr', … … 135 100 ) 136 101 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 148 102 bld.SAMBA_SUBSYSTEM('RPC_NDR_WINSIF', 149 103 source='gen_ndr/ndr_winsif_c.c', … … 154 108 bld.SAMBA_LIBRARY('dcerpc', 155 109 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 157 112 rpc/dcerpc_connect.c rpc/dcerpc_secondary.c''', 158 113 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', 160 115 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''', 166 118 # It's very important to keep this form of construction 167 119 # it force the sambawaf extension to put everything that match the first element … … 177 129 bld.SAMBA_SUBSYSTEM('pyrpc_util', 178 130 source='rpc/pyrpc_util.c', 179 public_deps='pytalloc-util pyparam_util dcerpc ',131 public_deps='pytalloc-util pyparam_util dcerpc MESSAGING', 180 132 pyext=True, 181 133 ) … … 184 136 bld.SAMBA_PYTHON('python_dcerpc', 185 137 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', 187 139 realname='samba/dcerpc/base.so' 188 140 ) … … 200 152 ) 201 153 154 bld.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 160 bld.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 166 bld.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 ) 202 171 203 172 bld.SAMBA_PYTHON('python_winreg', … … 238 207 bld.SAMBA_PYTHON('python_atsvc', 239 208 source='../../librpc/gen_ndr/py_atsvc.c', 240 deps=' dcerpc-atsvcpytalloc-util pyrpc_util',209 deps='RPC_NDR_ATSVC pytalloc-util pyrpc_util', 241 210 realname='samba/dcerpc/atsvc.so' 242 211 ) … … 245 214 bld.SAMBA_PYTHON('python_dcerpc_nbt', 246 215 source='../../librpc/gen_ndr/py_nbt.c', 247 deps=' NDR_NBTRPC_NDR_NBT pytalloc-util pyrpc_util',216 deps='ndr_nbt RPC_NDR_NBT pytalloc-util pyrpc_util', 248 217 realname='samba/dcerpc/nbt.so' 249 218 ) … … 284 253 ) 285 254 255 bld.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 ) 286 260 287 261 bld.SAMBA_PYTHON('python_unixinfo', … … 298 272 ) 299 273 274 bld.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 300 280 bld.SAMBA_PYTHON('python_winbind', 301 source=' gen_ndr/py_winbind.c',281 source='../../librpc/gen_ndr/py_winbind.c', 302 282 deps='RPC_NDR_WINBIND pytalloc-util pyrpc_util python_netlogon', 303 283 realname='samba/dcerpc/winbind.so' … … 331 311 bld.SAMBA_PYTHON('python_dcerpc_dnsp', 332 312 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', 334 314 realname='samba/dcerpc/dnsp.so' 335 315 ) … … 342 322 ) 343 323 324 bld.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 344 330 bld.SAMBA_PYTHON('python_netlogon', 345 331 source='../../librpc/gen_ndr/py_netlogon.c', … … 348 334 ) 349 335 336 bld.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 342 bld.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 350 348 bld.SAMBA_SCRIPT('python_dcerpc_init', 351 349 pattern='rpc/dcerpc.py',
Note:
See TracChangeset
for help on using the changeset viewer.