Changeset 988 for vendor/current/source4/libcli
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/libcli
- Files:
-
- 2 added
- 5 deleted
- 81 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/libcli/cliconnect.c
r740 r988 27 27 #include "libcli/auth/libcli_auth.h" 28 28 #include "libcli/smb_composite/smb_composite.h" 29 #include "libcli/smb/smbXcli_base.h" 29 30 30 31 /* … … 36 37 struct resolve_context *resolve_ctx, 37 38 struct smbcli_options *options, 38 const char *socket_options) 39 { 40 struct smbcli_socket *sock; 41 42 sock = smbcli_sock_connect_byname(server, ports, NULL, 43 resolve_ctx, ev_ctx, 44 socket_options); 45 46 if (sock == NULL) return false; 47 48 cli->transport = smbcli_transport_init(sock, cli, true, options); 49 if (!cli->transport) { 39 const char *socket_options, 40 struct nbt_name *calling, 41 struct nbt_name *called) 42 { 43 NTSTATUS status; 44 45 cli->options = *options; 46 47 status = smbcli_sock_connect(cli, 48 NULL, /* host_addr */ 49 ports, 50 server, 51 resolve_ctx, 52 ev_ctx, 53 socket_options, 54 calling, 55 called, 56 &cli->sock); 57 if (!NT_STATUS_IS_OK(status)) { 50 58 return false; 51 59 } 52 60 53 61 return true; 54 }55 56 /* wrapper around smbcli_transport_connect() */57 bool smbcli_transport_establish(struct smbcli_state *cli,58 struct nbt_name *calling,59 struct nbt_name *called)60 {61 return smbcli_transport_connect(cli->transport, calling, called);62 62 } 63 63 … … 65 65 NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol) 66 66 { 67 return smb_raw_negotiate(cli->transport, unicode, maxprotocol); 67 if (unicode) { 68 cli->options.unicode = 1; 69 } else { 70 cli->options.unicode = 0; 71 } 72 73 cli->transport = smbcli_transport_init(cli->sock, cli, 74 true, &cli->options); 75 cli->sock = NULL; 76 if (!cli->transport) { 77 return NT_STATUS_NO_MEMORY; 78 } 79 80 return smb_raw_negotiate(cli->transport, unicode, PROTOCOL_CORE, maxprotocol); 68 81 } 69 82 … … 113 126 /* setup a tree connect */ 114 127 tcon.generic.level = RAW_TCON_TCONX; 115 tcon.tconx.in.flags = 0; 128 tcon.tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE; 129 tcon.tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES; 116 130 if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { 117 131 tcon.tconx.in.password = data_blob(NULL, 0); … … 131 145 132 146 cli->tree->tid = tcon.tconx.out.tid; 147 148 if (tcon.tconx.out.options & SMB_EXTENDED_SIGNATURES) { 149 smb1cli_session_protect_session_key(cli->tree->session->smbXcli); 150 } 133 151 134 152 talloc_free(mem_ctx); -
vendor/current/source4/libcli/clifile.c
r740 r988 52 52 53 53 /**************************************************************************** 54 Map standard UNIX permissions onto wire representations.55 ****************************************************************************/56 uint32_t unix_perms_to_wire(mode_t perms)57 {58 unsigned int ret = 0;59 60 ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0);61 ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0);62 ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0);63 ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0);64 ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0);65 ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0);66 ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0);67 ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0);68 ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0);69 #ifdef S_ISVTX70 ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0);71 #endif72 #ifdef S_ISGID73 ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0);74 #endif75 #ifdef S_ISUID76 ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0);77 #endif78 return ret;79 }80 81 /****************************************************************************82 54 Symlink a file (UNIX extensions). 83 55 ****************************************************************************/ … … 682 654 TALLOC_CTX *mem_ctx; 683 655 NTSTATUS status; 656 int ret = -1; 684 657 685 658 mem_ctx = talloc_init("raw_open"); 686 if (!mem_ctx) return -1;659 if (!mem_ctx) return ret; 687 660 688 661 open_parms.openx.level = RAW_OPEN_CTEMP; … … 692 665 693 666 status = smb_raw_open(tree, mem_ctx, &open_parms); 694 if (tmp_path) { 695 *tmp_path = strdup(open_parms.ctemp.out.name); 667 if (NT_STATUS_IS_OK(status)) { 668 if (tmp_path) { 669 *tmp_path = strdup(open_parms.ctemp.out.name); 670 } 671 ret = open_parms.ctemp.out.file.fnum; 696 672 } 697 673 talloc_free(mem_ctx); 698 if (NT_STATUS_IS_OK(status)) { 699 return open_parms.ctemp.out.file.fnum; 700 } 701 return -1; 702 } 674 return ret; 675 } -
vendor/current/source4/libcli/clilist.c
r414 r988 112 112 int max_matches = 512; 113 113 char *mask; 114 int ff_eos = 0, i , ff_searchcount;114 int ff_eos = 0, i; 115 115 int ff_dir_handle=0; 116 116 … … 155 155 156 156 ff_dir_handle = first_parms.t2ffirst.out.handle; 157 ff_searchcount = first_parms.t2ffirst.out.count;158 157 ff_eos = first_parms.t2ffirst.out.end_of_search; 159 158 … … 182 181 return -1; 183 182 } 184 ff_searchcount = next_parms.t2fnext.out.count;185 183 ff_eos = next_parms.t2fnext.out.end_of_search; 186 184 received = next_parms.t2fnext.out.count; -
vendor/current/source4/libcli/climessage.c
r414 r988 34 34 35 35 req = smbcli_request_setup(tree, SMBsendstrt, 0, 0); 36 if (req == NULL) { 37 return false; 38 } 36 39 smbcli_req_append_string(req, username, STR_TERMINATE); 37 40 smbcli_req_append_string(req, host, STR_TERMINATE); … … 58 61 59 62 req = smbcli_request_setup(tree, SMBsendtxt, 1, 0); 63 if (req == NULL) { 64 return false; 65 } 60 66 SSVAL(req->out.vwv, VWV(0), grp); 61 67 … … 81 87 82 88 req = smbcli_request_setup(tree, SMBsendend, 1, 0); 89 if (req == NULL) { 90 return false; 91 } 83 92 SSVAL(req->out.vwv, VWV(0), grp); 84 93 -
vendor/current/source4/libcli/clireadwrite.c
r414 r988 106 106 parms.writex.in.wmode = write_mode; 107 107 parms.writex.in.remaining = 0; 108 109 while (total < size){108 109 do { 110 110 NTSTATUS status; 111 111 … … 125 125 total += parms.writex.out.nwritten; 126 126 buf += parms.writex.out.nwritten; 127 } 127 } while (total < size); 128 128 129 129 return total; -
vendor/current/source4/libcli/composite/composite.c
r740 r988 56 56 57 57 while (c->state < COMPOSITE_STATE_DONE) { 58 if ( event_loop_once(c->event_ctx) != 0) {58 if (tevent_loop_once(c->event_ctx) != 0) { 59 59 return NT_STATUS_UNSUCCESSFUL; 60 60 } … … 107 107 } 108 108 if (!ctx->used_wait && !ctx->async.fn) { 109 event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx);109 tevent_add_timer(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); 110 110 } 111 111 ctx->status = status; … … 137 137 { 138 138 if (!ctx->used_wait && !ctx->async.fn) { 139 event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx);139 tevent_add_timer(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); 140 140 } 141 141 ctx->state = COMPOSITE_STATE_DONE; … … 158 158 immediate event, otherwise we can be stuck forever */ 159 159 if (new_ctx->state >= COMPOSITE_STATE_DONE && continuation) { 160 event_add_timed(new_ctx->event_ctx, new_ctx, timeval_zero(), composite_trigger, new_ctx);160 tevent_add_timer(new_ctx->event_ctx, new_ctx, timeval_zero(), composite_trigger, new_ctx); 161 161 } 162 162 } … … 168 168 { 169 169 if (composite_nomem(new_req, ctx)) return; 170 if (new_req->state > SMBCLI_REQUEST_RECV) { 171 composite_error(ctx, new_req->status); 172 return; 173 } 170 174 new_req->async.fn = continuation; 171 175 new_req->async.private_data = private_data; … … 178 182 { 179 183 if (composite_nomem(new_req, ctx)) return; 184 if (new_req->state > SMB2_REQUEST_RECV) { 185 composite_error(ctx, new_req->status); 186 return; 187 } 180 188 new_req->async.fn = continuation; 181 189 new_req->async.private_data = private_data; -
vendor/current/source4/libcli/dgram/dgramsocket.c
r740 r988 49 49 50 50 blob = data_blob_talloc(tmp_ctx, NULL, dsize); 51 if ( blob.data == NULL) {51 if ((dsize != 0) && (blob.data == NULL)) { 52 52 talloc_free(tmp_ctx); 53 53 return; … … 132 132 } 133 133 134 EVENT_FD_NOT_WRITEABLE(dgmsock->fde);134 TEVENT_FD_NOT_WRITEABLE(dgmsock->fde); 135 135 return; 136 136 } … … 145 145 struct nbt_dgram_socket *dgmsock = talloc_get_type(private_data, 146 146 struct nbt_dgram_socket); 147 if (flags & EVENT_FD_WRITE) {147 if (flags & TEVENT_FD_WRITE) { 148 148 dgm_socket_send(dgmsock); 149 149 } 150 if (flags & EVENT_FD_READ) {150 if (flags & TEVENT_FD_READ) { 151 151 dgm_socket_recv(dgmsock); 152 152 } … … 176 176 talloc_steal(dgmsock, dgmsock->sock); 177 177 178 dgmsock->fde = event_add_fd(dgmsock->event_ctx, dgmsock,178 dgmsock->fde = tevent_add_fd(dgmsock->event_ctx, dgmsock, 179 179 socket_get_fd(dgmsock->sock), 0, 180 180 dgm_socket_handler, dgmsock); … … 203 203 dgmsock->incoming.handler = handler; 204 204 dgmsock->incoming.private_data = private_data; 205 EVENT_FD_READABLE(dgmsock->fde);205 TEVENT_FD_READABLE(dgmsock->fde); 206 206 return NT_STATUS_OK; 207 207 } … … 232 232 } 233 233 234 DLIST_ADD_END(dgmsock->send_queue, req , struct nbt_dgram_request *);235 236 EVENT_FD_WRITEABLE(dgmsock->fde);234 DLIST_ADD_END(dgmsock->send_queue, req); 235 236 TEVENT_FD_WRITEABLE(dgmsock->fde); 237 237 238 238 return NT_STATUS_OK; -
vendor/current/source4/libcli/dgram/mailslot.c
r740 r988 72 72 talloc_set_destructor(dgmslot, dgram_mailslot_destructor); 73 73 74 EVENT_FD_READABLE(dgmsock->fde);74 TEVENT_FD_READABLE(dgmsock->fde); 75 75 76 76 return dgmslot; -
vendor/current/source4/libcli/finddcs_cldap.c
r740 r988 28 28 #include "libcli/security/security.h" 29 29 #include "lib/util/tevent_ntstatus.h" 30 #include "lib/tsocket/tsocket.h" 30 31 #include "libcli/composite/composite.h" 32 #include "lib/util/util_net.h" 31 33 32 34 struct finddcs_cldap_state { … … 41 43 struct cldap_socket *cldap; 42 44 struct cldap_netlogon *netlogon; 45 NTSTATUS status; 43 46 }; 44 47 … … 53 56 struct resolve_context *resolve_ctx, 54 57 struct tevent_context *event_ctx); 58 static void finddcs_cldap_nbt_resolved(struct composite_context *ctx); 59 static bool finddcs_cldap_name_lookup(struct finddcs_cldap_state *state, 60 struct finddcs *io, 61 struct resolve_context *resolve_ctx, 62 struct tevent_context *event_ctx); 55 63 static void finddcs_cldap_name_resolved(struct composite_context *ctx); 56 64 static void finddcs_cldap_next_server(struct finddcs_cldap_state *state); … … 60 68 /* 61 69 * find a list of DCs via DNS/CLDAP 62 *63 70 */ 64 71 struct tevent_req *finddcs_cldap_send(TALLOC_CTX *mem_ctx, … … 78 85 state->ev = event_ctx; 79 86 state->minimum_dc_flags = io->in.minimum_dc_flags; 80 state->domain_name = talloc_strdup(state, io->in.domain_name); 81 if (tevent_req_nomem(state->domain_name, req)) { 82 return tevent_req_post(req, event_ctx); 87 88 if (io->in.domain_name) { 89 state->domain_name = talloc_strdup(state, io->in.domain_name); 90 if (tevent_req_nomem(state->domain_name, req)) { 91 return tevent_req_post(req, event_ctx); 92 } 93 } else { 94 state->domain_name = NULL; 83 95 } 84 96 … … 93 105 94 106 if (io->in.server_address) { 95 DEBUG(4,("finddcs: searching for a DC by IP %s\n", io->in.server_address)); 96 if (!finddcs_cldap_ipaddress(state, io)) { 97 return tevent_req_post(req, event_ctx); 98 } 99 } else if (strchr(state->domain_name, '.')) { 100 /* looks like a DNS name */ 101 DEBUG(4,("finddcs: searching for a DC by DNS domain %s\n", state->domain_name)); 102 if (!finddcs_cldap_srv_lookup(state, io, resolve_ctx, event_ctx)) { 103 return tevent_req_post(req, event_ctx); 107 if (is_ipaddress(io->in.server_address)) { 108 DEBUG(4,("finddcs: searching for a DC by IP %s\n", 109 io->in.server_address)); 110 if (!finddcs_cldap_ipaddress(state, io)) { 111 return tevent_req_post(req, event_ctx); 112 } 113 } else { 114 if (!finddcs_cldap_name_lookup(state, io, resolve_ctx, 115 event_ctx)) { 116 return tevent_req_post(req, event_ctx); 117 } 118 } 119 } else if (io->in.domain_name) { 120 if (strchr(state->domain_name, '.')) { 121 /* looks like a DNS name */ 122 DEBUG(4,("finddcs: searching for a DC by DNS domain %s\n", state->domain_name)); 123 if (!finddcs_cldap_srv_lookup(state, io, resolve_ctx, 124 event_ctx)) { 125 return tevent_req_post(req, event_ctx); 126 } 127 } else { 128 DEBUG(4,("finddcs: searching for a DC by NBT lookup %s\n", state->domain_name)); 129 if (!finddcs_cldap_nbt_lookup(state, io, resolve_ctx, 130 event_ctx)) { 131 return tevent_req_post(req, event_ctx); 132 } 104 133 } 105 134 } else { 106 DEBUG(4,("finddcs: searching for a DC by NBT lookup %s\n", state->domain_name));107 if (!finddcs_cldap_nbt_lookup(state, io, resolve_ctx, event_ctx)) {108 return tevent_req_post(req, event_ctx);109 }135 /* either we have the domain name or the IP address */ 136 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); 137 DEBUG(2,("finddcs: Please specify at least the domain name or the IP address! \n")); 138 return tevent_req_post(req, event_ctx); 110 139 } 111 140 … … 132 161 state->srv_addresses[1] = NULL; 133 162 state->srv_address_index = 0; 134 status = cldap_socket_init(state, state->ev, NULL, NULL, &state->cldap);135 if (tevent_req_nterror(state->req, status)) {136 return false;137 }138 163 139 164 finddcs_cldap_next_server(state); … … 191 216 return false; 192 217 } 218 creq->async.fn = finddcs_cldap_nbt_resolved; 219 creq->async.private_data = state; 220 return true; 221 } 222 223 static bool finddcs_cldap_name_lookup(struct finddcs_cldap_state *state, 224 struct finddcs *io, 225 struct resolve_context *resolve_ctx, 226 struct tevent_context *event_ctx) 227 { 228 struct composite_context *creq; 229 struct nbt_name name; 230 231 make_nbt_name(&name, io->in.server_address, NBT_NAME_SERVER); 232 creq = resolve_name_send(resolve_ctx, state, &name, event_ctx); 233 if (tevent_req_nomem(creq, state->req)) { 234 return false; 235 } 193 236 creq->async.fn = finddcs_cldap_name_resolved; 194 237 creq->async.private_data = state; … … 202 245 { 203 246 struct tevent_req *subreq; 247 struct tsocket_address *dest; 248 int ret; 249 250 TALLOC_FREE(state->cldap); 204 251 205 252 if (state->srv_addresses[state->srv_address_index] == NULL) { 206 tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND); 253 if (NT_STATUS_IS_OK(state->status)) { 254 tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND); 255 } else { 256 tevent_req_nterror(state->req, state->status); 257 } 207 258 DEBUG(2,("finddcs: No matching CLDAP server found\n")); 208 259 return; 209 260 } 210 261 262 /* we should get the port from the SRV response */ 263 ret = tsocket_address_inet_from_strings(state, "ip", 264 state->srv_addresses[state->srv_address_index], 265 389, 266 &dest); 267 if (ret == 0) { 268 state->status = NT_STATUS_OK; 269 } else { 270 state->status = map_nt_error_from_unix_common(errno); 271 } 272 if (!NT_STATUS_IS_OK(state->status)) { 273 state->srv_address_index++; 274 finddcs_cldap_next_server(state); 275 return; 276 } 277 278 state->status = cldap_socket_init(state, NULL, dest, &state->cldap); 279 if (!NT_STATUS_IS_OK(state->status)) { 280 state->srv_address_index++; 281 finddcs_cldap_next_server(state); 282 return; 283 } 284 285 TALLOC_FREE(state->netlogon); 211 286 state->netlogon = talloc_zero(state, struct cldap_netlogon); 212 if ( tevent_req_nomem(state->netlogon, state->req)) {213 return;214 }215 216 state->netlogon->in.dest_address = state->srv_addresses[state->srv_address_index];217 /* we should get the port from the SRV response */218 state->netlogon->in.dest_port = 389; 219 if ( strchr(state->domain_name, '.')) {287 if (state->netlogon == NULL) { 288 state->status = NT_STATUS_NO_MEMORY; 289 state->srv_address_index++; 290 finddcs_cldap_next_server(state); 291 return; 292 } 293 294 if ((state->domain_name != NULL) && (strchr(state->domain_name, '.'))) { 220 295 state->netlogon->in.realm = state->domain_name; 221 296 } 222 297 if (state->domain_sid) { 223 298 state->netlogon->in.domain_sid = dom_sid_string(state, state->domain_sid); 224 if (tevent_req_nomem(state->netlogon->in.domain_sid, state->req)) { 299 if (state->netlogon->in.domain_sid == NULL) { 300 state->status = NT_STATUS_NO_MEMORY; 301 state->srv_address_index++; 302 finddcs_cldap_next_server(state); 225 303 return; 226 304 } … … 233 311 state->netlogon->in.map_response = true; 234 312 235 DEBUG(4,("finddcs: performing CLDAP query on %s\n", state->netlogon->in.dest_address)); 236 237 subreq = cldap_netlogon_send(state, state->cldap, state->netlogon); 238 if (tevent_req_nomem(subreq, state->req)) { 313 DEBUG(4,("finddcs: performing CLDAP query on %s\n", 314 state->srv_addresses[state->srv_address_index])); 315 316 subreq = cldap_netlogon_send(state, state->ev, 317 state->cldap, state->netlogon); 318 if (subreq == NULL) { 319 state->status = NT_STATUS_NO_MEMORY; 320 state->srv_address_index++; 321 finddcs_cldap_next_server(state); 239 322 return; 240 323 } … … 255 338 256 339 status = cldap_netlogon_recv(subreq, state->netlogon, state->netlogon); 257 talloc_free(subreq); 340 TALLOC_FREE(subreq); 341 TALLOC_FREE(state->cldap); 258 342 if (!NT_STATUS_IS_OK(status)) { 343 state->status = status; 259 344 state->srv_address_index++; 260 345 finddcs_cldap_next_server(state); … … 280 365 } 281 366 282 /*283 handle NBT name lookup reply284 */285 367 static void finddcs_cldap_name_resolved(struct composite_context *ctx) 286 368 { 287 369 struct finddcs_cldap_state *state = 288 370 talloc_get_type(ctx->async.private_data, struct finddcs_cldap_state); 289 const char *address; 290 NTSTATUS status; 291 292 status = resolve_name_recv(ctx, state, &address); 371 NTSTATUS status; 372 unsigned i; 373 374 status = resolve_name_multiple_recv(ctx, state, &state->srv_addresses); 375 if (tevent_req_nterror(state->req, status)) { 376 DEBUG(2,("finddcs: No matching server found\n")); 377 return; 378 } 379 380 for (i=0; state->srv_addresses[i]; i++) { 381 DEBUG(4,("finddcs: response %u at '%s'\n", 382 i, state->srv_addresses[i])); 383 } 384 385 state->srv_address_index = 0; 386 387 state->status = NT_STATUS_OK; 388 finddcs_cldap_next_server(state); 389 } 390 391 /* 392 handle NBT name lookup reply 393 */ 394 static void finddcs_cldap_nbt_resolved(struct composite_context *ctx) 395 { 396 struct finddcs_cldap_state *state = 397 talloc_get_type(ctx->async.private_data, struct finddcs_cldap_state); 398 NTSTATUS status; 399 unsigned i; 400 401 status = resolve_name_multiple_recv(ctx, state, &state->srv_addresses); 293 402 if (tevent_req_nterror(state->req, status)) { 294 403 DEBUG(2,("finddcs: No matching NBT <1c> server found\n")); … … 296 405 } 297 406 298 DEBUG(4,("finddcs: Found NBT <1c> server at %s\n", address)); 299 300 state->srv_addresses = talloc_array(state, const char *, 2); 301 if (tevent_req_nomem(state->srv_addresses, state->req)) { 302 return; 303 } 304 state->srv_addresses[0] = address; 305 state->srv_addresses[1] = NULL; 407 for (i=0; state->srv_addresses[i]; i++) { 408 DEBUG(4,("finddcs: NBT <1c> response %u at '%s'\n", 409 i, state->srv_addresses[i])); 410 } 306 411 307 412 state->srv_address_index = 0; 308 309 status = cldap_socket_init(state, state->ev, NULL, NULL, &state->cldap);310 if (tevent_req_nterror(state->req, status)) {311 return;312 }313 413 314 414 finddcs_cldap_next_server(state); … … 338 438 state->srv_address_index = 0; 339 439 340 status = cldap_socket_init(state, state->ev, NULL, NULL, &state->cldap); 341 if (tevent_req_nterror(state->req, status)) { 342 return; 343 } 344 440 state->status = NT_STATUS_OK; 345 441 finddcs_cldap_next_server(state); 346 442 } … … 358 454 return NT_STATUS_INTERNAL_ERROR; 359 455 } 360 status = tevent_req_simple_recv_ntstatus(req); 361 if (NT_STATUS_IS_OK(status)) { 362 talloc_steal(mem_ctx, state->netlogon); 363 io->out.netlogon = state->netlogon->out.netlogon; 364 io->out.address = talloc_steal(mem_ctx, state->srv_addresses[state->srv_address_index]); 365 } 456 if (tevent_req_is_nterror(req, &status)) { 457 tevent_req_received(req); 458 return status; 459 } 460 461 talloc_steal(mem_ctx, state->netlogon); 462 io->out.netlogon = state->netlogon->out.netlogon; 463 io->out.address = talloc_steal( 464 mem_ctx, state->srv_addresses[state->srv_address_index]); 465 366 466 tevent_req_received(req); 367 return status;467 return NT_STATUS_OK; 368 468 } 369 469 -
vendor/current/source4/libcli/finddcs_nbt.c
r740 r988 29 29 #include "libcli/resolve/resolve.h" 30 30 #include "lib/util/tevent_ntstatus.h" 31 #include "libcli/finddc.h" 31 32 32 33 struct finddcs_nbt_state { 33 34 struct tevent_context *ev; 34 35 struct tevent_req *req; 35 struct messaging_context *msg_ctx;36 struct imessaging_context *msg_ctx; 36 37 37 38 const char *my_netbios_name; … … 70 71 struct resolve_context *resolve_ctx, 71 72 struct tevent_context *event_ctx, 72 struct messaging_context *msg_ctx)73 struct imessaging_context *msg_ctx) 73 74 { 74 75 struct finddcs_nbt_state *state; … … 95 96 96 97 if (domain_sid) { 97 state->domain_sid = talloc_reference(state, domain_sid);98 state->domain_sid = dom_sid_dup(state, domain_sid); 98 99 if (tevent_req_nomem(state->domain_sid, req)) { 99 100 return tevent_req_post(req, event_ctx); … … 284 285 *dcs = talloc_steal(mem_ctx, state->dcs); 285 286 } 286 talloc_free(req);287 287 return status; 288 288 } … … 295 295 struct resolve_context *resolve_ctx, 296 296 struct tevent_context *event_ctx, 297 struct messaging_context *msg_ctx,297 struct imessaging_context *msg_ctx, 298 298 int *num_dcs, struct nbt_dc_name **dcs) 299 299 { 300 NTSTATUS status; 300 301 struct tevent_req *req = finddcs_nbt_send(mem_ctx, 301 302 my_netbios_name, … … 305 306 resolve_ctx, 306 307 event_ctx, msg_ctx); 307 return finddcs_nbt_recv(req, mem_ctx, num_dcs, dcs); 308 } 308 status = finddcs_nbt_recv(req, mem_ctx, num_dcs, dcs); 309 talloc_free(req); 310 return status; 311 } -
vendor/current/source4/libcli/ldap/ldap_bind.c
r740 r988 28 28 #include "lib/tls/tls.h" 29 29 #include "auth/gensec/gensec.h" 30 #include "auth/gensec/gensec_internal.h" /* TODO: remove this */ 31 #include "source4/auth/gensec/gensec_tstream.h" 30 32 #include "auth/credentials/credentials.h" 31 33 #include "lib/stream/packet.h" 32 34 #include "param/param.h" 35 #include "param/loadparm.h" 33 36 34 37 struct ldap_simple_creds { … … 214 217 struct ldap_SearchResEntry *search; 215 218 int count, i; 216 219 bool first = true; 220 int wrap_flags = 0; 217 221 const char **sasl_names; 218 222 uint32_t old_gensec_features; … … 221 225 NULL 222 226 }; 223 224 gensec_init(lp_ctx); 227 unsigned int logon_retries = 0; 228 size_t queue_length; 229 230 if (conn->sockets.active == NULL) { 231 status = NT_STATUS_CONNECTION_DISCONNECTED; 232 goto failed; 233 } 234 235 queue_length = tevent_queue_length(conn->sockets.send_queue); 236 if (queue_length != 0) { 237 status = NT_STATUS_INVALID_PARAMETER_MIX; 238 DEBUG(1, ("SASL bind triggered with non empty send_queue[%zu]: %s\n", 239 queue_length, nt_errstr(status))); 240 goto failed; 241 } 242 243 if (conn->pending != NULL) { 244 status = NT_STATUS_INVALID_PARAMETER_MIX; 245 DEBUG(1, ("SASL bind triggered with pending requests: %s\n", 246 nt_errstr(status))); 247 goto failed; 248 } 249 250 status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs, 251 false, NULL, NULL, &sasl_mechs_msgs); 252 if (!NT_STATUS_IS_OK(status)) { 253 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n", 254 nt_errstr(status))); 255 goto failed; 256 } 257 258 count = ildap_count_entries(conn, sasl_mechs_msgs); 259 if (count != 1) { 260 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n", 261 count)); 262 goto failed; 263 } 264 265 tmp_ctx = talloc_new(conn); 266 if (tmp_ctx == NULL) goto failed; 267 268 search = &sasl_mechs_msgs[0]->r.SearchResultEntry; 269 if (search->num_attributes != 1) { 270 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n", 271 search->num_attributes)); 272 goto failed; 273 } 274 275 sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1); 276 if (!sasl_names) { 277 DEBUG(1, ("talloc_arry(char *, %d) failed\n", 278 count)); 279 goto failed; 280 } 281 282 for (i=0; i<search->attributes[0].num_values; i++) { 283 sasl_names[i] = (const char *)search->attributes[0].values[i].data; 284 } 285 sasl_names[i] = NULL; 286 287 gensec_init(); 288 289 if (conn->sockets.active == conn->sockets.tls) { 290 /* 291 * require Kerberos SIGN/SEAL only if we don't use SSL 292 * Windows seem not to like double encryption 293 */ 294 wrap_flags = 0; 295 } else if (cli_credentials_is_anonymous(creds)) { 296 /* 297 * anonymous isn't protected 298 */ 299 wrap_flags = 0; 300 } else { 301 wrap_flags = lpcfg_client_ldap_sasl_wrapping(lp_ctx); 302 } 303 304 try_logon_again: 305 /* 306 we loop back here on a logon failure, and re-create the 307 gensec session. The logon_retries counter ensures we don't 308 loop forever. 309 */ 310 data_blob_free(&input); 311 TALLOC_FREE(conn->gensec); 225 312 226 313 status = gensec_client_start(conn, &conn->gensec, 227 conn->event.event_ctx,228 314 lpcfg_gensec_settings(conn, lp_ctx)); 229 315 if (!NT_STATUS_IS_OK(status)) { … … 232 318 } 233 319 234 /* require Kerberos SIGN/SEAL only if we don't use SSL235 * Windows seem not to like double encryption */236 320 old_gensec_features = cli_credentials_get_gensec_features(creds); 237 if ( tls_enabled(conn->sock)) {321 if (wrap_flags == 0) { 238 322 cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)); 239 323 } … … 250 334 * context, so we don't tatoo it ) */ 251 335 cli_credentials_set_gensec_features(creds, old_gensec_features); 336 337 if (wrap_flags & ADS_AUTH_SASL_SEAL) { 338 gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); 339 gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL); 340 } 341 if (wrap_flags & ADS_AUTH_SASL_SIGN) { 342 gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN); 343 } 344 345 /* 346 * This is an indication for the NTLMSSP backend to 347 * also encrypt when only GENSEC_FEATURE_SIGN is requested 348 * in gensec_[un]wrap(). 349 */ 350 gensec_want_feature(conn->gensec, GENSEC_FEATURE_LDAP_STYLE); 252 351 253 352 if (conn->host) { … … 267 366 } 268 367 269 status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs,270 false, NULL, NULL, &sasl_mechs_msgs);271 if (!NT_STATUS_IS_OK(status)) {272 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n",273 nt_errstr(status)));274 goto failed;275 }276 277 count = ildap_count_entries(conn, sasl_mechs_msgs);278 if (count != 1) {279 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n",280 count));281 goto failed;282 }283 284 tmp_ctx = talloc_new(conn);285 if (tmp_ctx == NULL) goto failed;286 287 search = &sasl_mechs_msgs[0]->r.SearchResultEntry;288 if (search->num_attributes != 1) {289 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n",290 search->num_attributes));291 goto failed;292 }293 294 sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1);295 if (!sasl_names) {296 DEBUG(1, ("talloc_arry(char *, %d) failed\n",297 count));298 goto failed;299 }300 301 for (i=0; i<search->attributes[0].num_values; i++) {302 sasl_names[i] = (const char *)search->attributes[0].values[i].data;303 }304 sasl_names[i] = NULL;305 306 368 status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names); 307 369 if (!NT_STATUS_IS_OK(status)) { … … 318 380 int result = LDAP_OTHER; 319 381 320 status = gensec_update(conn->gensec, tmp_ctx, 382 status = gensec_update_ev(conn->gensec, tmp_ctx, 383 conn->event.event_ctx, 321 384 input, 322 385 &output); … … 328 391 * 329 392 * Likewise, you must not feed GENSEC too much (after the OK), 330 * it doesn't like that either 393 * it doesn't like that either. 394 * 395 * For SASL/EXTERNAL, there is no data to send, but we still 396 * must send the actual Bind request the first time around. 397 * Otherwise, a result of NT_STATUS_OK with 0 output means the 398 * end of a multi-step authentication, and no message must be 399 * sent. 331 400 */ 332 401 … … 338 407 } 339 408 if (NT_STATUS_IS_OK(status) && output.length == 0) { 340 break; 341 } 409 if (!first) 410 break; 411 } 412 first = false; 342 413 343 414 /* Perhaps we should make gensec_start_mech_by_sasl_list() return the name we got? */ … … 367 438 result = response->r.BindResponse.response.resultcode; 368 439 440 if (result == LDAP_STRONG_AUTH_REQUIRED) { 441 if (wrap_flags == 0) { 442 wrap_flags = ADS_AUTH_SASL_SIGN; 443 goto try_logon_again; 444 } 445 } 446 447 if (result == LDAP_INVALID_CREDENTIALS) { 448 /* 449 try a second time on invalid credentials, to 450 give the user a chance to re-enter the 451 password and to handle the case where our 452 kerberos ticket is invalid as the server 453 password has changed 454 */ 455 const char *principal; 456 457 principal = gensec_get_target_principal(conn->gensec); 458 if (principal == NULL) { 459 const char *hostname = gensec_get_target_hostname(conn->gensec); 460 const char *service = gensec_get_target_service(conn->gensec); 461 if (hostname != NULL && service != NULL) { 462 principal = talloc_asprintf(tmp_ctx, "%s/%s", service, hostname); 463 } 464 } 465 466 if (cli_credentials_failed_kerberos_login(creds, principal, &logon_retries) || 467 cli_credentials_wrong_password(creds)) { 468 /* 469 destroy our gensec session and loop 470 back up to the top to retry, 471 offering the user a chance to enter 472 new credentials, or get a new ticket 473 if using kerberos 474 */ 475 goto try_logon_again; 476 } 477 } 478 369 479 if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) { 370 480 status = ldap_check_response(conn, … … 384 494 } 385 495 386 talloc_free(tmp_ctx); 387 388 if (NT_STATUS_IS_OK(status)) { 389 struct socket_context *sasl_socket; 390 status = gensec_socket_init(conn->gensec, 391 conn, 392 conn->sock, 393 conn->event.event_ctx, 394 ldap_read_io_handler, 395 conn, 396 &sasl_socket); 397 if (!NT_STATUS_IS_OK(status)) goto failed; 398 399 conn->sock = sasl_socket; 400 packet_set_socket(conn->packet, conn->sock); 401 402 conn->bind.type = LDAP_BIND_SASL; 403 conn->bind.creds = creds; 404 } 405 406 return status; 496 TALLOC_FREE(tmp_ctx); 497 498 if (!NT_STATUS_IS_OK(status)) { 499 goto failed; 500 } 501 502 conn->bind.type = LDAP_BIND_SASL; 503 conn->bind.creds = creds; 504 505 if (wrap_flags & ADS_AUTH_SASL_SEAL) { 506 if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) { 507 return NT_STATUS_INVALID_NETWORK_RESPONSE; 508 } 509 510 if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) { 511 return NT_STATUS_INVALID_NETWORK_RESPONSE; 512 } 513 } else if (wrap_flags & ADS_AUTH_SASL_SIGN) { 514 if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) { 515 return NT_STATUS_INVALID_NETWORK_RESPONSE; 516 } 517 } 518 519 if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) && 520 !gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) { 521 return NT_STATUS_OK; 522 } 523 524 status = gensec_create_tstream(conn->sockets.raw, 525 conn->gensec, 526 conn->sockets.raw, 527 &conn->sockets.sasl); 528 if (!NT_STATUS_IS_OK(status)) { 529 goto failed; 530 } 531 532 conn->sockets.active = conn->sockets.sasl; 533 534 return NT_STATUS_OK; 407 535 408 536 failed: -
vendor/current/source4/libcli/ldap/ldap_client.c
r740 r988 26 26 #include <tevent.h> 27 27 #include "lib/socket/socket.h" 28 #include "lib/tsocket/tsocket.h" 29 #include "libcli/util/tstream.h" 28 30 #include "../lib/util/asn1.h" 29 31 #include "../lib/util/dlinklist.h" … … 32 34 #include "libcli/ldap/ldap_client.h" 33 35 #include "libcli/composite/composite.h" 34 #include "lib/stream/packet.h"35 36 #include "lib/tls/tls.h" 36 37 #include "auth/gensec/gensec.h" … … 39 40 #include "libcli/resolve/resolve.h" 40 41 42 static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status); 43 44 static int ldap_connection_destructor(struct ldap_connection *conn) 45 { 46 /* 47 * NT_STATUS_OK means that callbacks of pending requests are not 48 * triggered 49 */ 50 ldap_connection_dead(conn, NT_STATUS_OK); 51 return 0; 52 } 53 41 54 /** 42 55 create a new ldap_connection stucture. The event context is optional 43 56 */ 57 44 58 _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, 45 59 struct loadparm_context *lp_ctx, … … 60 74 conn->event.event_ctx = ev; 61 75 76 conn->sockets.send_queue = tevent_queue_create(conn, 77 "ldap_connection send_queue"); 78 if (conn->sockets.send_queue == NULL) { 79 TALLOC_FREE(conn); 80 return NULL; 81 } 82 62 83 conn->lp_ctx = lp_ctx; 63 84 … … 67 88 /* explicitly avoid reconnections by default */ 68 89 conn->reconnect.max_retries = 0; 69 90 91 talloc_set_destructor(conn, ldap_connection_destructor); 70 92 return conn; 71 93 } … … 74 96 the connection is dead 75 97 */ 76 static void ldap_connection_dead(struct ldap_connection *conn )98 static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status) 77 99 { 78 100 struct ldap_request *req; 79 101 80 talloc_free(conn->sock); /* this will also free event.fde */ 81 talloc_free(conn->packet); 82 conn->sock = NULL; 83 conn->event.fde = NULL; 84 conn->packet = NULL; 102 tevent_queue_stop(conn->sockets.send_queue); 103 TALLOC_FREE(conn->sockets.recv_subreq); 104 conn->sockets.active = NULL; 105 TALLOC_FREE(conn->sockets.sasl); 106 TALLOC_FREE(conn->sockets.tls); 107 TALLOC_FREE(conn->sockets.raw); 85 108 86 109 /* return an error for any pending request ... */ … … 88 111 req = conn->pending; 89 112 DLIST_REMOVE(req->conn->pending, req); 113 req->conn = NULL; 90 114 req->state = LDAP_REQUEST_DONE; 91 req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; 115 if (NT_STATUS_IS_OK(status)) { 116 continue; 117 } 118 req->status = status; 92 119 if (req->async.fn) { 93 120 req->async.fn(req); … … 101 128 handle packet errors 102 129 */ 103 static void ldap_error_handler(void *private_data, NTSTATUS status) 104 { 105 struct ldap_connection *conn = talloc_get_type(private_data, 106 struct ldap_connection); 107 ldap_connection_dead(conn); 130 static void ldap_error_handler(struct ldap_connection *conn, NTSTATUS status) 131 { 132 ldap_connection_dead(conn, status); 108 133 109 134 /* but try to reconnect so that the ldb client can go on */ … … 131 156 DEBUG(0,("ldap: no matching message id for %u\n", 132 157 msg->messageid)); 133 talloc_free(msg);158 TALLOC_FREE(msg); 134 159 return; 135 160 } … … 139 164 if (!msg->controls_decoded[i] && 140 165 msg->controls[i]->critical) { 166 TALLOC_FREE(msg); 141 167 req->status = NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION); 142 168 req->state = LDAP_REQUEST_DONE; … … 150 176 151 177 /* add to the list of replies received */ 152 talloc_steal(req, msg);153 178 req->replies = talloc_realloc(req, req->replies, 154 179 struct ldap_message *, req->num_replies+1); 155 180 if (req->replies == NULL) { 181 TALLOC_FREE(msg); 156 182 req->status = NT_STATUS_NO_MEMORY; 157 183 req->state = LDAP_REQUEST_DONE; … … 179 205 } 180 206 207 static void ldap_connection_recv_done(struct tevent_req *subreq); 208 209 static void ldap_connection_recv_next(struct ldap_connection *conn) 210 { 211 struct tevent_req *subreq = NULL; 212 213 if (conn->sockets.recv_subreq != NULL) { 214 return; 215 } 216 217 if (conn->sockets.active == NULL) { 218 return; 219 } 220 221 if (conn->pending == NULL) { 222 return; 223 } 224 225 /* 226 * The minimum size of a LDAP pdu is 7 bytes 227 * 228 * dumpasn1 -hh ldap-unbind-min.dat 229 * 230 * <30 05 02 01 09 42 00> 231 * 0 5: SEQUENCE { 232 * <02 01 09> 233 * 2 1: INTEGER 9 234 * <42 00> 235 * 5 0: [APPLICATION 2] 236 * : Error: Object has zero length. 237 * : } 238 * 239 * dumpasn1 -hh ldap-unbind-windows.dat 240 * 241 * <30 84 00 00 00 05 02 01 09 42 00> 242 * 0 5: SEQUENCE { 243 * <02 01 09> 244 * 6 1: INTEGER 9 245 * <42 00> 246 * 9 0: [APPLICATION 2] 247 * : Error: Object has zero length. 248 * : } 249 * 250 * This means using an initial read size 251 * of 7 is ok. 252 */ 253 subreq = tstream_read_pdu_blob_send(conn, 254 conn->event.event_ctx, 255 conn->sockets.active, 256 7, /* initial_read_size */ 257 ldap_full_packet, 258 conn); 259 if (subreq == NULL) { 260 ldap_error_handler(conn, NT_STATUS_NO_MEMORY); 261 return; 262 } 263 tevent_req_set_callback(subreq, ldap_connection_recv_done, conn); 264 conn->sockets.recv_subreq = subreq; 265 return; 266 } 181 267 182 268 /* 183 269 decode/process LDAP data 184 270 */ 185 static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob)271 static void ldap_connection_recv_done(struct tevent_req *subreq) 186 272 { 187 273 NTSTATUS status; 188 struct ldap_connection *conn = talloc_get_type(private_data, 189 struct ldap_connection); 190 struct ldap_message *msg = talloc(conn, struct ldap_message); 191 struct asn1_data *asn1 = asn1_init(conn); 192 193 if (asn1 == NULL || msg == NULL) { 194 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); 195 } 196 197 if (!asn1_load(asn1, blob)) { 198 talloc_free(msg); 199 talloc_free(asn1); 200 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); 201 } 202 274 struct ldap_connection *conn = 275 tevent_req_callback_data(subreq, 276 struct ldap_connection); 277 struct ldap_message *msg; 278 struct asn1_data *asn1; 279 DATA_BLOB blob; 280 281 msg = talloc_zero(conn, struct ldap_message); 282 if (msg == NULL) { 283 ldap_error_handler(conn, NT_STATUS_NO_MEMORY); 284 return; 285 } 286 287 asn1 = asn1_init(conn); 288 if (asn1 == NULL) { 289 TALLOC_FREE(msg); 290 ldap_error_handler(conn, NT_STATUS_NO_MEMORY); 291 return; 292 } 293 294 conn->sockets.recv_subreq = NULL; 295 296 status = tstream_read_pdu_blob_recv(subreq, 297 asn1, 298 &blob); 299 TALLOC_FREE(subreq); 300 if (!NT_STATUS_IS_OK(status)) { 301 TALLOC_FREE(msg); 302 asn1_free(asn1); 303 ldap_error_handler(conn, status); 304 return; 305 } 306 307 asn1_load_nocopy(asn1, blob.data, blob.length); 308 203 309 status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); 310 asn1_free(asn1); 204 311 if (!NT_STATUS_IS_OK(status)) { 205 asn1_free(asn1); 206 return status; 312 TALLOC_FREE(msg); 313 ldap_error_handler(conn, status); 314 return; 207 315 } 208 316 209 317 ldap_match_message(conn, msg); 210 211 data_blob_free(&blob); 212 asn1_free(asn1); 213 return NT_STATUS_OK; 214 } 215 216 /* Handle read events, from the GENSEC socket callback, or real events */ 217 void ldap_read_io_handler(void *private_data, uint16_t flags) 218 { 219 struct ldap_connection *conn = talloc_get_type(private_data, 220 struct ldap_connection); 221 packet_recv(conn->packet); 222 } 223 224 /* 225 handle ldap socket events 226 */ 227 static void ldap_io_handler(struct tevent_context *ev, struct tevent_fd *fde, 228 uint16_t flags, void *private_data) 229 { 230 struct ldap_connection *conn = talloc_get_type(private_data, 231 struct ldap_connection); 232 if (flags & TEVENT_FD_WRITE) { 233 packet_queue_run(conn->packet); 234 if (!tls_enabled(conn->sock)) return; 235 } 236 if (flags & TEVENT_FD_READ) { 237 ldap_read_io_handler(private_data, flags); 238 } 318 ldap_connection_recv_next(conn); 319 320 return; 239 321 } 240 322 … … 285 367 struct composite_context *ctx; 286 368 struct ldap_connection *conn; 369 struct socket_context *sock; 370 struct tstream_context *raw; 371 struct tstream_tls_params *tls_params; 372 struct tstream_context *tls; 287 373 }; 288 374 … … 328 414 char path[1025]; 329 415 330 NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, & conn->sock, 0);416 NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &state->sock, 0); 331 417 if (!NT_STATUS_IS_OK(status)) { 332 418 return NULL; 333 419 } 334 talloc_steal( conn, conn->sock);420 talloc_steal(state, state->sock); 335 421 SMB_ASSERT(sizeof(protocol)>10); 336 422 SMB_ASSERT(sizeof(path)>1024); … … 355 441 356 442 rfc1738_unescape(path); 357 358 unix_addr = socket_address_from_strings( conn, conn->sock->backend_name,443 444 unix_addr = socket_address_from_strings(state, state->sock->backend_name, 359 445 path, 0); 360 if (!unix_addr) { 361 return NULL; 362 } 363 364 ctx = socket_connect_send(conn->sock, NULL, unix_addr, 365 0, conn->event.event_ctx); 446 if (composite_nomem(unix_addr, result)) { 447 return result; 448 } 449 450 451 ctx = socket_connect_send(state->sock, NULL, unix_addr, 452 0, result->event_ctx); 366 453 ctx->async.fn = ldap_connect_recv_unix_conn; 367 454 ctx->async.private_data = state; … … 370 457 NTSTATUS status = ldap_parse_basic_url(conn, url, &conn->host, 371 458 &conn->port, &conn->ldaps); 372 if (!NT_STATUS_IS_OK(stat e->ctx->status)) {373 composite_error( state->ctx, status);459 if (!NT_STATUS_IS_OK(status)) { 460 composite_error(result, status); 374 461 return result; 375 462 } 376 463 464 if (conn->ldaps) { 465 char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx); 466 char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx); 467 const char *tls_priority = lpcfg_tls_priority(conn->lp_ctx); 468 enum tls_verify_peer_state verify_peer = 469 lpcfg_tls_verify_peer(conn->lp_ctx); 470 471 status = tstream_tls_params_client(state, 472 ca_file, 473 crl_file, 474 tls_priority, 475 verify_peer, 476 conn->host, 477 &state->tls_params); 478 if (!NT_STATUS_IS_OK(status)) { 479 composite_error(result, status); 480 return result; 481 } 482 } 483 377 484 ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port, 378 lpcfg_resolve_context(conn->lp_ctx), conn->event.event_ctx); 379 if (ctx == NULL) goto failed; 485 lpcfg_resolve_context(conn->lp_ctx), 486 result->event_ctx); 487 if (composite_nomem(ctx, result)) { 488 return result; 489 } 380 490 381 491 ctx->async.fn = ldap_connect_recv_tcp_conn; … … 388 498 } 389 499 500 static void ldap_connect_got_tls(struct tevent_req *subreq); 501 390 502 static void ldap_connect_got_sock(struct composite_context *ctx, 391 struct ldap_connection *conn) 392 { 393 /* setup a handler for events on this socket */ 394 conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock, 395 socket_get_fd(conn->sock), 396 TEVENT_FD_READ, ldap_io_handler, conn); 397 if (conn->event.fde == NULL) { 398 composite_error(ctx, NT_STATUS_INTERNAL_ERROR); 399 return; 400 } 401 402 tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn); 403 socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE); 404 405 talloc_steal(conn, conn->sock); 406 if (conn->ldaps) { 407 struct socket_context *tls_socket; 408 char *cafile = lpcfg_tls_cafile(conn->sock, conn->lp_ctx); 409 410 if (!cafile || !*cafile) { 411 talloc_free(conn->sock); 412 return; 413 } 414 415 tls_socket = tls_init_client(conn->sock, conn->event.fde, cafile); 416 talloc_free(cafile); 417 418 if (tls_socket == NULL) { 419 talloc_free(conn->sock); 420 return; 421 } 422 423 conn->sock = talloc_steal(conn, tls_socket); 424 } 425 426 conn->packet = packet_init(conn); 427 if (conn->packet == NULL) { 428 talloc_free(conn->sock); 429 return; 430 } 431 432 packet_set_private(conn->packet, conn); 433 packet_set_socket(conn->packet, conn->sock); 434 packet_set_callback(conn->packet, ldap_recv_handler); 435 packet_set_full_request(conn->packet, ldap_full_packet); 436 packet_set_error_handler(conn->packet, ldap_error_handler); 437 packet_set_event_context(conn->packet, conn->event.event_ctx); 438 packet_set_fde(conn->packet, conn->event.fde); 439 /* packet_set_serialise(conn->packet); */ 440 441 if (conn->ldaps) { 442 packet_set_unreliable_select(conn->packet); 443 } 444 445 composite_done(ctx); 503 struct ldap_connection *conn) 504 { 505 struct ldap_connect_state *state = 506 talloc_get_type_abort(ctx->private_data, 507 struct ldap_connect_state); 508 struct tevent_req *subreq = NULL; 509 int fd; 510 int ret; 511 512 socket_set_flags(state->sock, SOCKET_FLAG_NOCLOSE); 513 fd = socket_get_fd(state->sock); 514 TALLOC_FREE(state->sock); 515 516 smb_set_close_on_exec(fd); 517 518 ret = set_blocking(fd, false); 519 if (ret == -1) { 520 NTSTATUS status = map_nt_error_from_unix_common(errno); 521 composite_error(state->ctx, status); 522 return; 523 } 524 525 ret = tstream_bsd_existing_socket(state, fd, &state->raw); 526 if (ret == -1) { 527 NTSTATUS status = map_nt_error_from_unix_common(errno); 528 composite_error(state->ctx, status); 529 return; 530 } 531 532 if (!conn->ldaps) { 533 conn->sockets.raw = talloc_move(conn, &state->raw); 534 conn->sockets.active = conn->sockets.raw; 535 composite_done(state->ctx); 536 return; 537 } 538 539 subreq = tstream_tls_connect_send(state, state->ctx->event_ctx, 540 state->raw, state->tls_params); 541 if (composite_nomem(subreq, state->ctx)) { 542 return; 543 } 544 tevent_req_set_callback(subreq, ldap_connect_got_tls, state); 545 } 546 547 static void ldap_connect_got_tls(struct tevent_req *subreq) 548 { 549 struct ldap_connect_state *state = 550 tevent_req_callback_data(subreq, 551 struct ldap_connect_state); 552 int err; 553 int ret; 554 555 ret = tstream_tls_connect_recv(subreq, &err, state, &state->tls); 556 TALLOC_FREE(subreq); 557 if (ret == -1) { 558 NTSTATUS status = map_nt_error_from_unix_common(err); 559 composite_error(state->ctx, status); 560 return; 561 } 562 563 talloc_steal(state->tls, state->tls_params); 564 565 state->conn->sockets.raw = talloc_move(state->conn, &state->raw); 566 state->conn->sockets.tls = talloc_move(state->conn->sockets.raw, 567 &state->tls); 568 state->conn->sockets.active = state->conn->sockets.tls; 569 composite_done(state->ctx); 446 570 } 447 571 … … 449 573 { 450 574 struct ldap_connect_state *state = 451 talloc_get_type (ctx->async.private_data,452 575 talloc_get_type_abort(ctx->async.private_data, 576 struct ldap_connect_state); 453 577 struct ldap_connection *conn = state->conn; 454 578 uint16_t port; 455 NTSTATUS status = socket_connect_multi_recv(ctx, state, & conn->sock,579 NTSTATUS status = socket_connect_multi_recv(ctx, state, &state->sock, 456 580 &port); 457 581 if (!NT_STATUS_IS_OK(status)) { … … 466 590 { 467 591 struct ldap_connect_state *state = 468 talloc_get_type (ctx->async.private_data,469 592 talloc_get_type_abort(ctx->async.private_data, 593 struct ldap_connect_state); 470 594 struct ldap_connection *conn = state->conn; 471 595 … … 534 658 status = ldap_rebind(conn); 535 659 if ( ! NT_STATUS_IS_OK(status)) { 536 ldap_connection_dead(conn); 537 } 660 ldap_connection_dead(conn, status); 661 } 662 } 663 664 static void ldap_request_destructor_abandon(struct ldap_request *abandon) 665 { 666 TALLOC_FREE(abandon); 538 667 } 539 668 … … 542 671 { 543 672 if (req->state == LDAP_REQUEST_PENDING) { 673 struct ldap_message msg = { 674 .type = LDAP_TAG_AbandonRequest, 675 .r.AbandonRequest.messageid = req->messageid, 676 }; 677 struct ldap_request *abandon = NULL; 678 544 679 DLIST_REMOVE(req->conn->pending, req); 545 } 680 681 abandon = ldap_request_send(req->conn, &msg); 682 if (abandon == NULL) { 683 ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY); 684 return 0; 685 } 686 abandon->async.fn = ldap_request_destructor_abandon; 687 abandon->async.private_data = NULL; 688 } 689 546 690 return 0; 547 691 } 548 692 549 /* 550 called on timeout of a ldap request 551 */ 552 static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te, 553 struct timeval t, void *private_data) 554 { 555 struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); 556 req->status = NT_STATUS_IO_TIMEOUT; 693 static void ldap_request_timeout_abandon(struct ldap_request *abandon) 694 { 695 struct ldap_request *req = 696 talloc_get_type_abort(abandon->async.private_data, 697 struct ldap_request); 698 557 699 if (req->state == LDAP_REQUEST_PENDING) { 558 700 DLIST_REMOVE(req->conn->pending, req); … … 564 706 } 565 707 566 567 /* 568 called on completion of a failed ldap request 569 */ 570 static void ldap_request_failed_complete(struct tevent_context *ev, struct tevent_timer *te, 708 /* 709 called on timeout of a ldap request 710 */ 711 static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te, 571 712 struct timeval t, void *private_data) 572 713 { 573 struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); 574 if (req->async.fn) { 575 req->async.fn(req); 576 } 577 } 578 579 /* 580 called on completion of a one-way ldap request 581 */ 582 static void ldap_request_oneway_complete(void *private_data) 583 { 584 struct ldap_request *req = talloc_get_type(private_data, struct ldap_request); 714 struct ldap_request *req = 715 talloc_get_type_abort(private_data, 716 struct ldap_request); 717 718 req->status = NT_STATUS_IO_TIMEOUT; 585 719 if (req->state == LDAP_REQUEST_PENDING) { 720 struct ldap_message msg = { 721 .type = LDAP_TAG_AbandonRequest, 722 .r.AbandonRequest.messageid = req->messageid, 723 }; 724 struct ldap_request *abandon = NULL; 725 726 abandon = ldap_request_send(req->conn, &msg); 727 if (abandon == NULL) { 728 ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY); 729 return; 730 } 731 talloc_reparent(req->conn, req, abandon); 732 abandon->async.fn = ldap_request_timeout_abandon; 733 abandon->async.private_data = req; 586 734 DLIST_REMOVE(req->conn->pending, req); 735 return; 587 736 } 588 737 req->state = LDAP_REQUEST_DONE; … … 591 740 } 592 741 } 742 743 744 /* 745 called on completion of a failed ldap request 746 */ 747 static void ldap_request_failed_complete(struct tevent_context *ev, struct tevent_timer *te, 748 struct timeval t, void *private_data) 749 { 750 struct ldap_request *req = 751 talloc_get_type_abort(private_data, 752 struct ldap_request); 753 754 if (req->async.fn) { 755 req->async.fn(req); 756 } 757 } 758 759 static void ldap_request_written(struct tevent_req *subreq); 760 593 761 /* 594 762 send a ldap message - async interface … … 599 767 struct ldap_request *req; 600 768 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 601 packet_send_callback_fn_t send_callback= NULL;769 struct tevent_req *subreq = NULL; 602 770 603 771 req = talloc_zero(conn, struct ldap_request); 604 772 if (req == NULL) return NULL; 605 773 606 if (conn->sock == NULL) {774 if (conn->sockets.active == NULL) { 607 775 status = NT_STATUS_INVALID_CONNECTION; 608 776 goto failed; … … 629 797 } 630 798 631 if (req->type == LDAP_TAG_AbandonRequest ||632 req->type == LDAP_TAG_UnbindRequest) {633 send_callback = ldap_request_oneway_complete;634 }635 636 status = packet_send_callback(conn->packet, req->data,637 send_callback, req);638 if (!NT_STATUS_IS_OK(status)) {639 goto failed;640 }641 642 req->state = LDAP_REQUEST_PENDING;643 DLIST_ADD(conn->pending, req);644 645 799 /* put a timeout on the request */ 646 800 req->time_event = tevent_add_timer(conn->event.event_ctx, req, 647 801 timeval_current_ofs(conn->timeout, 0), 648 802 ldap_request_timeout, req); 803 if (req->time_event == NULL) { 804 status = NT_STATUS_NO_MEMORY; 805 goto failed; 806 } 807 808 req->write_iov.iov_base = req->data.data; 809 req->write_iov.iov_len = req->data.length; 810 811 subreq = tstream_writev_queue_send(req, conn->event.event_ctx, 812 conn->sockets.active, 813 conn->sockets.send_queue, 814 &req->write_iov, 1); 815 if (subreq == NULL) { 816 status = NT_STATUS_NO_MEMORY; 817 goto failed; 818 } 819 tevent_req_set_callback(subreq, ldap_request_written, req); 820 821 req->state = LDAP_REQUEST_PENDING; 822 DLIST_ADD(conn->pending, req); 649 823 650 824 return req; … … 659 833 } 660 834 835 static void ldap_request_written(struct tevent_req *subreq) 836 { 837 struct ldap_request *req = 838 tevent_req_callback_data(subreq, 839 struct ldap_request); 840 int err; 841 ssize_t ret; 842 843 ret = tstream_writev_queue_recv(subreq, &err); 844 TALLOC_FREE(subreq); 845 if (ret == -1) { 846 NTSTATUS error = map_nt_error_from_unix_common(err); 847 ldap_error_handler(req->conn, error); 848 return; 849 } 850 851 if (req->type == LDAP_TAG_AbandonRequest || 852 req->type == LDAP_TAG_UnbindRequest) 853 { 854 if (req->state == LDAP_REQUEST_PENDING) { 855 DLIST_REMOVE(req->conn->pending, req); 856 } 857 req->state = LDAP_REQUEST_DONE; 858 if (req->async.fn) { 859 req->async.fn(req); 860 } 861 return; 862 } 863 864 ldap_connection_recv_next(req->conn); 865 } 866 661 867 662 868 /* … … 668 874 while (req->state < LDAP_REQUEST_DONE) { 669 875 if (tevent_loop_once(req->conn->event.event_ctx) != 0) { 876 req->state = LDAP_REQUEST_ERROR; 670 877 req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; 671 878 break; -
vendor/current/source4/libcli/ldap/ldap_client.h
r740 r988 21 21 22 22 23 #include "system/network.h" /* for struct iovec */ 23 24 #include "libcli/ldap/libcli_ldap.h" 24 25 … … 40 41 NTSTATUS status; 41 42 DATA_BLOB data; 43 struct iovec write_iov; 44 42 45 struct { 43 46 void (*fn)(struct ldap_request *); … … 51 54 /* main context for a ldap client connection */ 52 55 struct ldap_connection { 53 struct socket_context *sock; 56 struct { 57 struct tstream_context *raw; 58 struct tstream_context *tls; 59 struct tstream_context *sasl; 60 struct tstream_context *active; 61 62 struct tevent_queue *send_queue; 63 struct tevent_req *recv_subreq; 64 } sockets; 65 54 66 struct loadparm_context *lp_ctx; 55 67 … … 90 102 struct { 91 103 struct tevent_context *event_ctx; 92 struct tevent_fd *fde;93 104 } event; 94 95 struct packet_context *packet;96 105 }; 97 106 -
vendor/current/source4/libcli/ldap/ldap_controls.c
r740 r988 427 427 } 428 428 429 static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out) 430 { 431 void **out = (void **)_out; 432 DATA_BLOB name; 433 struct asn1_data *data = asn1_init(mem_ctx); 434 struct ldb_verify_name_control *lvnc; 435 int len; 436 437 if (!data) return false; 438 439 if (!asn1_load(data, in)) { 440 return false; 441 } 442 443 lvnc = talloc(mem_ctx, struct ldb_verify_name_control); 444 if (!lvnc) { 445 return false; 446 } 447 448 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { 449 return false; 450 } 451 452 if (!asn1_read_Integer(data, &(lvnc->flags))) { 453 return false; 454 } 455 456 if (!asn1_read_OctetString(data, mem_ctx, &name)) { 457 return false; 458 } 459 460 if (name.length) { 461 len = utf16_len_n(name.data, name.length); 462 convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, 463 name.data, len, 464 (void **)&lvnc->gc, &lvnc->gc_len); 465 466 if (!(lvnc->gc)) { 467 return false; 468 } 469 } else { 470 lvnc->gc_len = 0; 471 lvnc->gc = NULL; 472 } 473 474 if (!asn1_end_tag(data)) { 475 return false; 476 } 477 478 *out = lvnc; 479 return true; 480 } 481 482 static bool encode_verify_name_request(void *mem_ctx, void *in, DATA_BLOB *out) 483 { 484 struct ldb_verify_name_control *lvnc = talloc_get_type(in, struct ldb_verify_name_control); 485 struct asn1_data *data = asn1_init(mem_ctx); 486 DATA_BLOB gc_utf16; 487 488 if (!data) return false; 489 490 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { 491 return false; 492 } 493 494 if (!asn1_write_Integer(data, lvnc->flags)) { 495 return false; 496 } 497 498 if (lvnc->gc_len) { 499 convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, 500 lvnc->gc, lvnc->gc_len, 501 (void **)&gc_utf16.data, &gc_utf16.length); 502 if (!asn1_write_OctetString(data, gc_utf16.data, gc_utf16.length)) { 503 return false; 504 } 505 } else { 506 if (!asn1_write_OctetString(data, NULL, 0)) { 507 return false; 508 } 509 } 510 511 if (!asn1_pop_tag(data)) { 512 return false; 513 } 514 515 if (!asn1_extract_blob(data, mem_ctx, out)) { 516 return false; 517 } 518 519 talloc_free(data); 520 521 return true; 522 } 523 429 524 static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out) 430 525 { … … 622 717 } 623 718 624 *out = data_blob_talloc(mem_ctx, data->data, data->length);625 if (out->data == NULL) {626 return false;627 } 719 if (!asn1_extract_blob(data, mem_ctx, out)) { 720 return false; 721 } 722 628 723 talloc_free(data); 629 724 … … 680 775 } 681 776 682 *out = data_blob_talloc(mem_ctx, data->data, data->length);683 if (out->data == NULL) {684 return false;685 } 777 if (!asn1_extract_blob(data, mem_ctx, out)) { 778 return false; 779 } 780 686 781 talloc_free(data); 687 782 … … 715 810 } 716 811 717 *out = data_blob_talloc(mem_ctx, data->data, data->length);718 if (out->data == NULL) {719 return false;720 } 812 if (!asn1_extract_blob(data, mem_ctx, out)) { 813 return false; 814 } 815 721 816 talloc_free(data); 722 817 … … 743 838 } 744 839 745 *out = data_blob_talloc(mem_ctx, data->data, data->length);746 if (out->data == NULL) {747 return false;748 } 840 if (!asn1_extract_blob(data, mem_ctx, out)) { 841 return false; 842 } 843 749 844 talloc_free(data); 750 845 … … 771 866 } 772 867 773 *out = data_blob_talloc(mem_ctx, data->data, data->length);774 if (out->data == NULL) {775 return false;776 } 868 if (!asn1_extract_blob(data, mem_ctx, out)) { 869 return false; 870 } 871 777 872 talloc_free(data); 778 873 … … 803 898 } 804 899 805 *out = data_blob_talloc(mem_ctx, data->data, data->length);806 if (out->data == NULL) {807 return false;808 } 900 if (!asn1_extract_blob(data, mem_ctx, out)) { 901 return false; 902 } 903 809 904 talloc_free(data); 810 905 … … 841 936 } 842 937 843 *out = data_blob_talloc(mem_ctx, data->data, data->length);844 if (out->data == NULL) {845 return false;846 } 938 if (!asn1_extract_blob(data, mem_ctx, out)) { 939 return false; 940 } 941 847 942 talloc_free(data); 848 943 … … 877 972 } 878 973 879 *out = data_blob_talloc(mem_ctx, data->data, data->length);880 if (out->data == NULL) {881 return false;882 } 974 if (!asn1_extract_blob(data, mem_ctx, out)) { 975 return false; 976 } 977 883 978 talloc_free(data); 884 979 … … 953 1048 } 954 1049 955 *out = data_blob_talloc(mem_ctx, data->data, data->length);956 if (out->data == NULL) {957 return false;958 } 1050 if (!asn1_extract_blob(data, mem_ctx, out)) { 1051 return false; 1052 } 1053 959 1054 talloc_free(data); 960 1055 … … 995 1090 } 996 1091 997 *out = data_blob_talloc(mem_ctx, data->data, data->length);998 if (out->data == NULL) {999 return false;1000 } 1092 if (!asn1_extract_blob(data, mem_ctx, out)) { 1093 return false; 1094 } 1095 1001 1096 talloc_free(data); 1002 1097 … … 1035 1130 } 1036 1131 1037 asn1_pop_tag(data); 1038 asn1_pop_tag(data); 1039 } 1040 asn1_pop_tag(data); 1041 1042 *out = data_blob_talloc(mem_ctx, data->data, data->length); 1043 if (out->data == NULL) { 1044 return false; 1045 } 1132 if (!asn1_pop_tag(data)) { 1133 return false; 1134 } 1135 if (!asn1_pop_tag(data)) { 1136 return false; 1137 } 1138 } 1139 if (!asn1_pop_tag(data)) { 1140 return false; 1141 } 1142 1143 if (!asn1_extract_blob(data, mem_ctx, out)) { 1144 return false; 1145 } 1146 1046 1147 talloc_free(data); 1047 1148 return true; … … 1087 1188 } 1088 1189 1089 asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute); 1090 asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn); 1190 if (!asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute)) { 1191 return false; 1192 } 1193 if (!asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn)) { 1194 return false; 1195 } 1091 1196 if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { 1092 1197 if (!asn1_start_tag(data, ASN1_CONTEXT(0))) { 1093 1198 return false; 1094 1199 } 1095 1096 ldap_decode_attribs_bare(r, data, &r[i]->attributes,1097 &r[i]->num_attributes);1098 1200 if (!ldap_decode_attribs_bare(r, data, &r[i]->attributes, 1201 &r[i]->num_attributes)) { 1202 return false; 1203 } 1099 1204 if (!asn1_end_tag(data)) { 1100 1205 return false; … … 1152 1257 { LDB_CONTROL_ASQ_OID, decode_asq_control, encode_asq_control }, 1153 1258 { LDB_CONTROL_DIRSYNC_OID, decode_dirsync_request, encode_dirsync_request }, 1259 { LDB_CONTROL_DIRSYNC_EX_OID, decode_dirsync_request, encode_dirsync_request }, 1154 1260 { LDB_CONTROL_VLV_REQ_OID, decode_vlv_request, encode_vlv_request }, 1155 1261 { LDB_CONTROL_VLV_RESP_OID, decode_vlv_response, encode_vlv_response }, … … 1159 1265 { LDB_CONTROL_RELAX_OID, decode_flag_request, encode_flag_request }, 1160 1266 { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference }, 1161 1162 /* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */ 1267 { LDB_CONTROL_VERIFY_NAME_OID, decode_verify_name_request, encode_verify_name_request }, 1268 1269 /* the following are internal only, with a network 1270 representation */ 1271 { DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID, decode_flag_request, encode_flag_request }, 1272 1273 /* all the ones below are internal only, and have no network 1274 * representation */ 1163 1275 { DSDB_CONTROL_CURRENT_PARTITION_OID, NULL, NULL }, 1164 /* DSDB_CONTROL_REPLICATED_UPDATE_OID is internal only, and has no network representation */1165 1276 { DSDB_CONTROL_REPLICATED_UPDATE_OID, NULL, NULL }, 1166 /* DSDB_CONTROL_DN_STORAGE_FORMAT_OID is internal only, and has no network representation */1167 1277 { DSDB_CONTROL_DN_STORAGE_FORMAT_OID, NULL, NULL }, 1168 /* LDB_CONTROL_RECALCULATE_SD_OID is internal only, and has no network representation */1169 1278 { LDB_CONTROL_RECALCULATE_SD_OID, NULL, NULL }, 1170 /* LDB_CONTROL_REVEAL_INTERNALS is internal only, and has no network representation */1171 1279 { LDB_CONTROL_REVEAL_INTERNALS, NULL, NULL }, 1172 /* LDB_CONTROL_AS_SYSTEM_OID is internal only, and has no network representation */1173 1280 { LDB_CONTROL_AS_SYSTEM_OID, NULL, NULL }, 1174 /* DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID is internal only, and has no network representation */1175 1281 { DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID, NULL, NULL }, 1176 /* DSDB_CONTROL_PASSWORD_HASH_VALUES_OID is internal only, and has no network representation */1177 1282 { DSDB_CONTROL_PASSWORD_HASH_VALUES_OID, NULL, NULL }, 1178 /* DSDB_CONTROL_PASSWORD_CHANGE_OID is internal only, and has no network representation */1179 1283 { DSDB_CONTROL_PASSWORD_CHANGE_OID, NULL, NULL }, 1180 /* DSDB_CONTROL_APPLY_LINKS is internal only, and has no network representation */1181 1284 { DSDB_CONTROL_APPLY_LINKS, NULL, NULL }, 1182 /* DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID is internal only, and has an empty network representation */1183 { DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID, decode_flag_request, encode_flag_request },1184 /* LDB_CONTROL_BYPASS_OPERATIONAL_OID is internal only, and has no network representation */1185 1285 { LDB_CONTROL_BYPASS_OPERATIONAL_OID, NULL, NULL }, 1186 /* DSDB_CONTROL_CHANGEREPLMETADATA_OID is internal only, and has no network representation */1187 1286 { DSDB_CONTROL_CHANGEREPLMETADATA_OID, NULL, NULL }, 1188 /* LDB_CONTROL_PROVISION_OID is internal only, and has no network representation */1189 1287 { LDB_CONTROL_PROVISION_OID, NULL, NULL }, 1190 /* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */1191 1288 { DSDB_EXTENDED_REPLICATED_OBJECTS_OID, NULL, NULL }, 1192 /* DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID is internal only, and has no network representation */1193 1289 { DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID, NULL, NULL }, 1194 /* DSDB_EXTENDED_ALLOCATE_RID_POOL is internal only, and has no network representation */1195 1290 { DSDB_EXTENDED_ALLOCATE_RID_POOL, NULL, NULL }, 1291 { DSDB_CONTROL_NO_GLOBAL_CATALOG, NULL, NULL }, 1292 { DSDB_EXTENDED_SCHEMA_UPGRADE_IN_PROGRESS_OID, NULL, NULL }, 1196 1293 { NULL, NULL, NULL } 1197 1294 }; -
vendor/current/source4/libcli/ldap/ldap_ildap.c
r740 r988 120 120 struct ldap_message ***results) 121 121 { 122 NTSTATUS status; 122 123 struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression); 123 NTSTATUS status; 124 125 if (tree == NULL) { 126 return NT_STATUS_INVALID_PARAMETER; 127 } 124 128 status = ildap_search_bytree(conn, basedn, scope, tree, attrs, 125 129 attributesonly, control_req, -
vendor/current/source4/libcli/ldap/wscript_build
r740 r988 4 4 source='ldap_client.c ldap_bind.c ldap_ildap.c ldap_controls.c', 5 5 autoproto='ldap_proto.h', 6 public_deps=' errors tevent LIBPACKET',7 p ublic_headers='libcli_ldap.h:ldap-util.h',8 deps=' LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS LIBCLI_LDAP_NDR ndr LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE',6 public_deps='samba-errors tevent', 7 private_headers='libcli_ldap.h:ldap-util.h', 8 deps='cli_composite LIBSAMBA_TSOCKET samba_socket NDR_SAMR LIBTLS ndr LP_RESOLVE gensec cli-ldap-common', 9 9 private_library=True 10 10 ) -
vendor/current/source4/libcli/libcli.h
r414 r988 23 23 24 24 #include "librpc/gen_ndr/nbt.h" 25 #include "libcli/raw/libcliraw.h" 25 26 26 27 struct substitute_context; … … 31 32 */ 32 33 struct smbcli_state { 34 struct smbcli_options options; 35 struct smbcli_socket *sock; /* NULL if connected */ 33 36 struct smbcli_transport *transport; 34 37 struct smbcli_session *session; … … 62 65 }; 63 66 64 65 66 67 #include "libcli/raw/libcliraw.h" 67 68 struct gensec_settings; 68 #include "libcli/libcli_proto.h" 69 70 ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset, size_t size); 71 72 /**************************************************************************** 73 write to a file 74 write_mode: 0x0001 disallow write cacheing 75 0x0002 return bytes remaining 76 0x0004 use raw named pipe protocol 77 0x0008 start of message mode named pipe protocol 78 ****************************************************************************/ 79 ssize_t smbcli_write(struct smbcli_tree *tree, 80 int fnum, uint16_t write_mode, 81 const void *_buf, off_t offset, size_t size); 82 83 /**************************************************************************** 84 write to a file using a SMBwrite and not bypassing 0 byte writes 85 ****************************************************************************/ 86 ssize_t smbcli_smbwrite(struct smbcli_tree *tree, 87 int fnum, const void *_buf, off_t offset, size_t size1); 88 89 bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, 90 const char **ports, 91 struct tevent_context *ev_ctx, 92 struct resolve_context *resolve_ctx, 93 struct smbcli_options *options, 94 const char *socket_options, 95 struct nbt_name *calling, 96 struct nbt_name *called); 97 NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol); 98 NTSTATUS smbcli_session_setup(struct smbcli_state *cli, 99 struct cli_credentials *credentials, 100 const char *workgroup, 101 struct smbcli_session_options options, 102 struct gensec_settings *gensec_settings); 103 NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename, 104 const char *devtype, const char *password); 105 NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, 106 struct smbcli_state **ret_cli, 107 const char *host, 108 const char **ports, 109 const char *sharename, 110 const char *devtype, 111 const char *socket_options, 112 struct cli_credentials *credentials, 113 struct resolve_context *resolve_ctx, 114 struct tevent_context *ev, 115 struct smbcli_options *options, 116 struct smbcli_session_options *session_options, 117 struct gensec_settings *gensec_settings); 118 NTSTATUS smbcli_tdis(struct smbcli_state *cli); 119 120 /**************************************************************************** 121 Initialise a client state structure. 122 ****************************************************************************/ 123 struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx); 124 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx, 125 char **hostname, char **sharename); 126 127 /**************************************************************************** 128 Symlink a file (UNIX extensions). 129 ****************************************************************************/ 130 NTSTATUS smbcli_unix_symlink(struct smbcli_tree *tree, const char *fname_src, 131 const char *fname_dst); 132 133 /**************************************************************************** 134 Hard a file (UNIX extensions). 135 ****************************************************************************/ 136 NTSTATUS smbcli_unix_hardlink(struct smbcli_tree *tree, const char *fname_src, 137 const char *fname_dst); 138 139 /**************************************************************************** 140 chmod a file (UNIX extensions). 141 ****************************************************************************/ 142 NTSTATUS smbcli_unix_chmod(struct smbcli_tree *tree, const char *fname, mode_t mode); 143 144 /**************************************************************************** 145 chown a file (UNIX extensions). 146 ****************************************************************************/ 147 NTSTATUS smbcli_unix_chown(struct smbcli_tree *tree, const char *fname, uid_t uid, 148 gid_t gid); 149 150 /**************************************************************************** 151 Rename a file. 152 ****************************************************************************/ 153 NTSTATUS smbcli_rename(struct smbcli_tree *tree, const char *fname_src, 154 const char *fname_dst); 155 156 /**************************************************************************** 157 Delete a file. 158 ****************************************************************************/ 159 NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname); 160 161 /**************************************************************************** 162 Create a directory. 163 ****************************************************************************/ 164 NTSTATUS smbcli_mkdir(struct smbcli_tree *tree, const char *dname); 165 166 /**************************************************************************** 167 Remove a directory. 168 ****************************************************************************/ 169 NTSTATUS smbcli_rmdir(struct smbcli_tree *tree, const char *dname); 170 171 /**************************************************************************** 172 Set or clear the delete on close flag. 173 ****************************************************************************/ 174 NTSTATUS smbcli_nt_delete_on_close(struct smbcli_tree *tree, int fnum, 175 bool flag); 176 177 /**************************************************************************** 178 Create/open a file - exposing the full horror of the NT API :-). 179 Used in CIFS-on-CIFS NTVFS. 180 ****************************************************************************/ 181 int smbcli_nt_create_full(struct smbcli_tree *tree, const char *fname, 182 uint32_t CreatFlags, uint32_t DesiredAccess, 183 uint32_t FileAttributes, uint32_t ShareAccess, 184 uint32_t CreateDisposition, uint32_t CreateOptions, 185 uint8_t SecurityFlags); 186 187 /**************************************************************************** 188 Open a file (using SMBopenx) 189 WARNING: if you open with O_WRONLY then getattrE won't work! 190 ****************************************************************************/ 191 int smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, 192 int share_mode); 193 194 /**************************************************************************** 195 Close a file. 196 ****************************************************************************/ 197 NTSTATUS smbcli_close(struct smbcli_tree *tree, int fnum); 198 199 /**************************************************************************** 200 send a lock with a specified locktype 201 this is used for testing LOCKING_ANDX_CANCEL_LOCK 202 ****************************************************************************/ 203 NTSTATUS smbcli_locktype(struct smbcli_tree *tree, int fnum, 204 uint32_t offset, uint32_t len, int timeout, 205 uint8_t locktype); 206 207 /**************************************************************************** 208 Lock a file. 209 ****************************************************************************/ 210 NTSTATUS smbcli_lock(struct smbcli_tree *tree, int fnum, 211 uint32_t offset, uint32_t len, int timeout, 212 enum brl_type lock_type); 213 214 /**************************************************************************** 215 Unlock a file. 216 ****************************************************************************/ 217 NTSTATUS smbcli_unlock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint32_t len); 218 219 /**************************************************************************** 220 Lock a file with 64 bit offsets. 221 ****************************************************************************/ 222 NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum, 223 off_t offset, off_t len, int timeout, 224 enum brl_type lock_type); 225 226 /**************************************************************************** 227 Unlock a file with 64 bit offsets. 228 ****************************************************************************/ 229 NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, off_t offset, 230 off_t len); 231 232 /**************************************************************************** 233 Do a SMBgetattrE call. 234 ****************************************************************************/ 235 NTSTATUS smbcli_getattrE(struct smbcli_tree *tree, int fnum, 236 uint16_t *attr, size_t *size, 237 time_t *c_time, time_t *a_time, time_t *m_time); 238 239 /**************************************************************************** 240 Do a SMBgetatr call 241 ****************************************************************************/ 242 NTSTATUS smbcli_getatr(struct smbcli_tree *tree, const char *fname, 243 uint16_t *attr, size_t *size, time_t *t); 244 245 /**************************************************************************** 246 Do a SMBsetatr call. 247 ****************************************************************************/ 248 NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mode, 249 time_t t); 250 251 /**************************************************************************** 252 Do a setfileinfo basic_info call. 253 ****************************************************************************/ 254 NTSTATUS smbcli_fsetatr(struct smbcli_tree *tree, int fnum, uint16_t mode, 255 NTTIME create_time, NTTIME access_time, 256 NTTIME write_time, NTTIME change_time); 257 258 /**************************************************************************** 259 truncate a file to a given size 260 ****************************************************************************/ 261 NTSTATUS smbcli_ftruncate(struct smbcli_tree *tree, int fnum, uint64_t size); 262 263 /**************************************************************************** 264 Check for existence of a dir. 265 ****************************************************************************/ 266 NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path); 267 268 /**************************************************************************** 269 Query disk space. 270 ****************************************************************************/ 271 NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, uint32_t *bsize, 272 uint64_t *total, uint64_t *avail); 273 274 /**************************************************************************** 275 Create and open a temporary file. 276 ****************************************************************************/ 277 int smbcli_ctemp(struct smbcli_tree *tree, const char *path, char **tmp_path); 278 279 /**************************************************************************** 280 Interpret a long filename structure. 281 ****************************************************************************/ 282 int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, 283 enum smb_search_data_level level, 284 void (*fn)(struct clilist_file_info *, const char *, void *), 285 void *caller_state); 286 287 /**************************************************************************** 288 Interpret a short filename structure. 289 The length of the structure is returned. 290 ****************************************************************************/ 291 int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, 292 void (*fn)(struct clilist_file_info *, const char *, void *), 293 void *caller_state); 294 295 /**************************************************************************** 296 Do a directory listing, calling fn on each file found. 297 This auto-switches between old and new style. 298 ****************************************************************************/ 299 int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute, 300 void (*fn)(struct clilist_file_info *, const char *, void *), void *state); 301 302 /**************************************************************************** 303 send a qpathinfo call 304 ****************************************************************************/ 305 NTSTATUS smbcli_qpathinfo(struct smbcli_tree *tree, const char *fname, 306 time_t *c_time, time_t *a_time, time_t *m_time, 307 size_t *size, uint16_t *mode); 308 309 /**************************************************************************** 310 send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level 311 ****************************************************************************/ 312 NTSTATUS smbcli_qpathinfo2(struct smbcli_tree *tree, const char *fname, 313 time_t *c_time, time_t *a_time, time_t *m_time, 314 time_t *w_time, size_t *size, uint16_t *mode, 315 ino_t *ino); 316 317 /**************************************************************************** 318 send a qfileinfo QUERY_FILE_NAME_INFO call 319 ****************************************************************************/ 320 NTSTATUS smbcli_qfilename(struct smbcli_tree *tree, int fnum, const char **name); 321 322 /**************************************************************************** 323 send a qfileinfo call 324 ****************************************************************************/ 325 NTSTATUS smbcli_qfileinfo(struct smbcli_tree *tree, int fnum, 326 uint16_t *mode, size_t *size, 327 time_t *c_time, time_t *a_time, time_t *m_time, 328 time_t *w_time, ino_t *ino); 329 330 /**************************************************************************** 331 send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call 332 ****************************************************************************/ 333 NTSTATUS smbcli_qpathinfo_alt_name(struct smbcli_tree *tree, const char *fname, 334 const char **alt_name); 335 336 /* The following definitions come from ../source4/libcli/climessage.c */ 337 338 339 /**************************************************************************** 340 start a message sequence 341 ****************************************************************************/ 342 bool smbcli_message_start(struct smbcli_tree *tree, const char *host, const char *username, 343 int *grp); 344 345 /**************************************************************************** 346 send a message 347 ****************************************************************************/ 348 bool smbcli_message_text(struct smbcli_tree *tree, char *msg, int len, int grp); 349 350 /**************************************************************************** 351 end a message 352 ****************************************************************************/ 353 bool smbcli_message_end(struct smbcli_tree *tree, int grp); 354 355 int smbcli_deltree(struct smbcli_tree *tree, const char *dname); 69 356 70 357 #endif /* __LIBCLI_H__ */ -
vendor/current/source4/libcli/rap/rap.c
r740 r988 31 31 struct rap_call *call; 32 32 33 call = talloc(mem_ctx, struct rap_call); 34 35 if (call == NULL) 33 call = talloc_zero(mem_ctx, struct rap_call); 34 if (call == NULL) { 36 35 return NULL; 36 } 37 37 38 38 call->callno = callno; 39 39 call->rcv_paramlen = 4; 40 40 41 call-> paramdesc = NULL;42 call->datadesc = NULL;43 call->auxdatadesc = NULL;44 45 call->ndr_push_param = ndr_push_init_ctx(mem_ctx);41 call->ndr_push_param = ndr_push_init_ctx(call); 42 if (call->ndr_push_param == NULL) { 43 talloc_free(call); 44 return NULL; 45 } 46 46 call->ndr_push_param->flags = RAPNDR_FLAGS; 47 47 48 call->ndr_push_data = ndr_push_init_ctx(mem_ctx); 48 call->ndr_push_data = ndr_push_init_ctx(call); 49 if (call->ndr_push_data == NULL) { 50 talloc_free(call); 51 return NULL; 52 } 49 53 call->ndr_push_data->flags = RAPNDR_FLAGS; 54 55 call->pull_mem_ctx = mem_ctx; 50 56 51 57 return call; … … 222 228 call->ndr_pull_param = ndr_pull_init_blob(&trans.out.params, call); 223 229 call->ndr_pull_param->flags = RAPNDR_FLAGS; 224 230 call->ndr_pull_param->current_mem_ctx = call->pull_mem_ctx; 225 231 call->ndr_pull_data = ndr_pull_init_blob(&trans.out.data, call); 226 232 call->ndr_pull_data->flags = RAPNDR_FLAGS; 233 call->ndr_pull_data->current_mem_ctx = call->pull_mem_ctx; 227 234 228 235 return result; -
vendor/current/source4/libcli/rap/rap.h
r740 r988 61 61 const char *auxdatadesc; 62 62 63 uint16_t status;64 uint16_t convert;65 66 63 uint16_t rcv_paramlen, rcv_datalen; 67 64 68 65 struct ndr_push *ndr_push_param; 69 66 struct ndr_push *ndr_push_data; 67 68 TALLOC_CTX *pull_mem_ctx; 70 69 struct ndr_pull *ndr_pull_param; 71 70 struct ndr_pull *ndr_pull_data; -
vendor/current/source4/libcli/rap/wscript_build
r740 r988 3 3 bld.SAMBA_SUBSYSTEM('LIBCLI_RAP', 4 4 source='rap.c', 5 public_deps=' LIBCLI_RAWNDR_RAP',5 public_deps='smbclient-raw NDR_RAP', 6 6 autoproto='proto.h' 7 7 ) -
vendor/current/source4/libcli/raw/clioplock.c
r414 r988 31 31 32 32 req = smbcli_request_setup(tree, SMBlockingX, 8, 0); 33 if (req == NULL) { 34 return false; 35 } 33 36 34 37 SSVAL(req->out.vwv,VWV(0),0xFF); … … 41 44 SSVAL(req->out.vwv,VWV(7),0); 42 45 43 /* this request does not expect a reply, so tell the signing 44 subsystem not to allocate an id for a reply */ 45 req->one_way_request = 1; 46 47 ret = smbcli_request_send(req); 46 /* 47 * The low level code knows it is a 48 * one way request by looking at SMBlockingX, 49 * wct == 8 and LOCKING_ANDX_OPLOCK_RELEASE 50 */ 51 ret = smbcli_request_send(req); 48 52 49 53 return ret; -
vendor/current/source4/libcli/raw/clisession.c
r414 r988 24 24 #include "libcli/raw/raw_proto.h" 25 25 #include "system/filesys.h" 26 #include "../libcli/smb/smbXcli_base.h" 26 27 27 28 #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \ … … 55 56 session->vuid = UID_FIELD_INVALID; 56 57 session->options = options; 57 58 59 /* 60 * for now session->vuid is still used by the callers, but we call: 61 * smb1cli_session_set_id(session->smbXcli, session->vuid); 62 * before using session->smbXcli, in future we should remove 63 * session->vuid. 64 */ 65 session->smbXcli = smbXcli_session_create(session, transport->conn); 66 if (session->smbXcli == NULL) { 67 talloc_free(session); 68 return NULL; 69 } 70 58 71 capabilities = transport->negotiate.capabilities; 59 72 … … 69 82 flags2 |= FLAGS2_EXTENDED_SECURITY; 70 83 } 71 if (s ession->transport->negotiate.sign_info.doing_signing) {84 if (smb1cli_conn_signing_is_active(session->transport->conn)) { 72 85 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; 73 86 } -
vendor/current/source4/libcli/raw/clisocket.c
r740 r988 22 22 23 23 #include "includes.h" 24 #include "system/network.h" 25 #include "../lib/async_req/async_sock.h" 26 #include "../lib/util/tevent_ntstatus.h" 24 27 #include "lib/events/events.h" 25 28 #include "libcli/raw/libcliraw.h" … … 29 32 #include "param/param.h" 30 33 #include "libcli/raw/raw_proto.h" 34 #include "../libcli/smb/read_smb.h" 35 36 struct smbcli_transport_connect_state { 37 struct tevent_context *ev; 38 struct socket_context *sock; 39 struct tevent_req *io_req; 40 uint8_t *request; 41 struct iovec iov; 42 uint8_t *response; 43 }; 44 45 static void smbcli_transport_connect_cleanup(struct tevent_req *req, 46 enum tevent_req_state req_state); 47 static void smbcli_transport_connect_writev_done(struct tevent_req *subreq); 48 static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq); 49 50 static struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx, 51 struct tevent_context *ev, 52 struct socket_context *sock, 53 uint16_t port, 54 uint32_t timeout_msec, 55 struct nbt_name *calling, 56 struct nbt_name *called) 57 { 58 struct tevent_req *req; 59 struct smbcli_transport_connect_state *state; 60 struct tevent_req *subreq; 61 DATA_BLOB calling_blob, called_blob; 62 uint8_t *p; 63 NTSTATUS status; 64 65 req = tevent_req_create(mem_ctx, &state, 66 struct smbcli_transport_connect_state); 67 if (req == NULL) { 68 return NULL; 69 } 70 state->ev = ev; 71 state->sock = sock; 72 73 if (port != 139) { 74 tevent_req_done(req); 75 return tevent_req_post(req, ev); 76 } 77 78 tevent_req_set_cleanup_fn(req, smbcli_transport_connect_cleanup); 79 80 status = nbt_name_to_blob(state, &calling_blob, calling); 81 if (tevent_req_nterror(req, status)) { 82 return tevent_req_post(req, ev); 83 } 84 85 status = nbt_name_to_blob(state, &called_blob, called); 86 if (tevent_req_nterror(req, status)) { 87 return tevent_req_post(req, ev); 88 } 89 90 state->request = talloc_array(state, uint8_t, 91 NBT_HDR_SIZE + 92 called_blob.length + 93 calling_blob.length); 94 if (tevent_req_nomem(state->request, req)) { 95 return tevent_req_post(req, ev); 96 } 97 98 /* put in the destination name */ 99 p = state->request + NBT_HDR_SIZE; 100 memcpy(p, called_blob.data, called_blob.length); 101 p += called_blob.length; 102 103 memcpy(p, calling_blob.data, calling_blob.length); 104 p += calling_blob.length; 105 106 _smb_setlen_nbt(state->request, 107 PTR_DIFF(p, state->request) - NBT_HDR_SIZE); 108 SCVAL(state->request, 0, NBSSrequest); 109 110 state->iov.iov_len = talloc_array_length(state->request); 111 state->iov.iov_base = (void *)state->request; 112 113 subreq = writev_send(state, ev, NULL, 114 sock->fd, 115 true, /* err_on_readability */ 116 &state->iov, 1); 117 if (tevent_req_nomem(subreq, req)) { 118 return tevent_req_post(req, ev); 119 } 120 tevent_req_set_callback(subreq, 121 smbcli_transport_connect_writev_done, 122 req); 123 state->io_req = subreq; 124 125 if (timeout_msec > 0) { 126 struct timeval endtime; 127 128 endtime = timeval_current_ofs_msec(timeout_msec); 129 if (!tevent_req_set_endtime(req, ev, endtime)) { 130 return tevent_req_post(req, ev); 131 } 132 } 133 134 return req; 135 } 136 137 static void smbcli_transport_connect_cleanup(struct tevent_req *req, 138 enum tevent_req_state req_state) 139 { 140 struct smbcli_transport_connect_state *state = 141 tevent_req_data(req, 142 struct smbcli_transport_connect_state); 143 144 TALLOC_FREE(state->io_req); 145 146 if (state->sock == NULL) { 147 return; 148 } 149 150 if (state->sock->fd == -1) { 151 return; 152 } 153 154 if (req_state == TEVENT_REQ_DONE) { 155 /* 156 * we keep the socket open for the caller to use 157 */ 158 state->sock = NULL; 159 return; 160 } 161 162 close(state->sock->fd); 163 state->sock->fd = -1; 164 state->sock = NULL; 165 } 166 167 static void smbcli_transport_connect_writev_done(struct tevent_req *subreq) 168 { 169 struct tevent_req *req = 170 tevent_req_callback_data(subreq, 171 struct tevent_req); 172 struct smbcli_transport_connect_state *state = 173 tevent_req_data(req, 174 struct smbcli_transport_connect_state); 175 ssize_t ret; 176 int err; 177 178 state->io_req = NULL; 179 180 ret = writev_recv(subreq, &err); 181 TALLOC_FREE(subreq); 182 if (ret == -1) { 183 NTSTATUS status = map_nt_error_from_unix_common(err); 184 tevent_req_nterror(req, status); 185 return; 186 } 187 188 subreq = read_smb_send(state, state->ev, 189 state->sock->fd); 190 if (tevent_req_nomem(subreq, req)) { 191 return; 192 } 193 tevent_req_set_callback(subreq, 194 smbcli_transport_connect_read_smb_done, 195 req); 196 state->io_req = subreq; 197 } 198 199 static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq) 200 { 201 struct tevent_req *req = 202 tevent_req_callback_data(subreq, 203 struct tevent_req); 204 struct smbcli_transport_connect_state *state = 205 tevent_req_data(req, 206 struct smbcli_transport_connect_state); 207 ssize_t ret; 208 int err; 209 NTSTATUS status; 210 uint8_t error; 211 212 state->io_req = NULL; 213 214 ret = read_smb_recv(subreq, state, 215 &state->response, &err); 216 TALLOC_FREE(subreq); 217 if (ret == -1) { 218 status = map_nt_error_from_unix_common(err); 219 tevent_req_nterror(req, status); 220 return; 221 } 222 223 if (ret < 4) { 224 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 225 return; 226 } 227 228 switch (CVAL(state->response, 0)) { 229 case NBSSpositive: 230 tevent_req_done(req); 231 return; 232 233 case NBSSnegative: 234 if (ret < 5) { 235 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 236 return; 237 } 238 239 error = CVAL(state->response, 4); 240 switch (error) { 241 case 0x80: 242 case 0x81: 243 status = NT_STATUS_REMOTE_NOT_LISTENING; 244 break; 245 case 0x82: 246 status = NT_STATUS_RESOURCE_NAME_NOT_FOUND; 247 break; 248 case 0x83: 249 status = NT_STATUS_REMOTE_RESOURCES; 250 break; 251 default: 252 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 253 break; 254 } 255 break; 256 257 case NBSSretarget: 258 DEBUG(1,("Warning: session retarget not supported\n")); 259 status = NT_STATUS_NOT_SUPPORTED; 260 break; 261 262 default: 263 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 264 break; 265 } 266 267 tevent_req_nterror(req, status); 268 } 269 270 static NTSTATUS smbcli_transport_connect_recv(struct tevent_req *req) 271 { 272 return tevent_req_simple_recv_ntstatus(req); 273 } 31 274 32 275 struct sock_connect_state { … … 37 280 const char *socket_options; 38 281 struct smbcli_socket *result; 282 struct socket_connect_multi_ex multi_ex; 283 struct nbt_name calling; 284 struct nbt_name called; 39 285 }; 40 286 … … 43 289 if port is 0 then choose 445 then 139 44 290 */ 291 292 static struct tevent_req *smbcli_sock_establish_send(TALLOC_CTX *mem_ctx, 293 struct tevent_context *ev, 294 struct socket_context *sock, 295 struct socket_address *addr, 296 void *private_data) 297 { 298 struct sock_connect_state *state = 299 talloc_get_type_abort(private_data, 300 struct sock_connect_state); 301 uint32_t timeout_msec = 15 * 1000; 302 303 return smbcli_transport_connect_send(state, 304 ev, 305 sock, 306 addr->port, 307 timeout_msec, 308 &state->calling, 309 &state->called); 310 } 311 312 static NTSTATUS smbcli_sock_establish_recv(struct tevent_req *req) 313 { 314 return smbcli_transport_connect_recv(req); 315 } 45 316 46 317 static void smbcli_sock_connect_recv_conn(struct composite_context *ctx); … … 52 323 struct resolve_context *resolve_ctx, 53 324 struct tevent_context *event_ctx, 54 const char *socket_options) 325 const char *socket_options, 326 struct nbt_name *calling, 327 struct nbt_name *called) 55 328 { 56 329 struct composite_context *result, *ctx; 57 330 struct sock_connect_state *state; 331 NTSTATUS status; 58 332 int i; 59 333 … … 85 359 } 86 360 87 ctx = socket_connect_multi_send(state, host_addr, 88 state->num_ports, state->ports, 89 resolve_ctx, 90 state->ctx->event_ctx); 361 state->multi_ex.private_data = state; 362 state->multi_ex.establish_send = smbcli_sock_establish_send; 363 state->multi_ex.establish_recv = smbcli_sock_establish_recv; 364 365 status = nbt_name_dup(state, calling, &state->calling); 366 if (!NT_STATUS_IS_OK(status)) { 367 goto failed; 368 } 369 status = nbt_name_dup(state, called, &state->called); 370 if (!NT_STATUS_IS_OK(status)) { 371 goto failed; 372 } 373 374 ctx = socket_connect_multi_ex_send(state, host_addr, 375 state->num_ports, state->ports, 376 resolve_ctx, 377 state->ctx->event_ctx, 378 &state->multi_ex); 91 379 if (ctx == NULL) goto failed; 92 380 ctx->async.fn = smbcli_sock_connect_recv_conn; … … 107 395 uint16_t port; 108 396 109 state->ctx->status = socket_connect_multi_ recv(ctx, state, &sock,110 397 state->ctx->status = socket_connect_multi_ex_recv(ctx, state, &sock, 398 &port); 111 399 if (!composite_is_ok(state->ctx)) return; 112 400 … … 158 446 struct resolve_context *resolve_ctx, 159 447 struct tevent_context *event_ctx, 160 const char *socket_options, 448 const char *socket_options, 449 struct nbt_name *calling, 450 struct nbt_name *called, 161 451 struct smbcli_socket **result) 162 452 { … … 164 454 smbcli_sock_connect_send(mem_ctx, host_addr, ports, host_name, 165 455 resolve_ctx, 166 event_ctx, socket_options); 456 event_ctx, socket_options, 457 calling, called); 167 458 return smbcli_sock_connect_recv(c, mem_ctx, result); 168 459 } 169 170 171 /****************************************************************************172 mark the socket as dead173 ****************************************************************************/174 _PUBLIC_ void smbcli_sock_dead(struct smbcli_socket *sock)175 {176 talloc_free(sock->event.fde);177 sock->event.fde = NULL;178 talloc_free(sock->sock);179 sock->sock = NULL;180 }181 182 /****************************************************************************183 Set socket options on a open connection.184 ****************************************************************************/185 void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options)186 {187 socket_set_option(sock->sock, options, NULL);188 }189 190 /****************************************************************************191 resolve a hostname and connect192 ****************************************************************************/193 _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports,194 TALLOC_CTX *mem_ctx,195 struct resolve_context *resolve_ctx,196 struct tevent_context *event_ctx,197 const char *socket_options)198 {199 int name_type = NBT_NAME_SERVER;200 const char *address;201 NTSTATUS status;202 struct nbt_name nbt_name;203 char *name, *p;204 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);205 struct smbcli_socket *result;206 207 if (event_ctx == NULL) {208 DEBUG(0, ("Invalid NULL event context passed in as parameter\n"));209 return NULL;210 }211 212 if (tmp_ctx == NULL) {213 DEBUG(0, ("talloc_new failed\n"));214 return NULL;215 }216 217 name = talloc_strdup(tmp_ctx, host);218 if (name == NULL) {219 DEBUG(0, ("talloc_strdup failed\n"));220 talloc_free(tmp_ctx);221 return NULL;222 }223 224 /* allow hostnames of the form NAME#xx and do a netbios lookup */225 if ((p = strchr(name, '#'))) {226 name_type = strtol(p+1, NULL, 16);227 *p = 0;228 }229 230 make_nbt_name(&nbt_name, host, name_type);231 232 status = resolve_name(resolve_ctx, &nbt_name, tmp_ctx, &address, event_ctx);233 if (!NT_STATUS_IS_OK(status)) {234 talloc_free(tmp_ctx);235 return NULL;236 }237 238 status = smbcli_sock_connect(mem_ctx, address, ports, name, resolve_ctx,239 event_ctx,240 socket_options, &result);241 242 if (!NT_STATUS_IS_OK(status)) {243 DEBUG(9, ("smbcli_sock_connect failed: %s\n",244 nt_errstr(status)));245 talloc_free(tmp_ctx);246 return NULL;247 }248 249 talloc_free(tmp_ctx);250 251 return result;252 } -
vendor/current/source4/libcli/raw/clitransport.c
r740 r988 21 21 22 22 #include "includes.h" 23 #include "system/network.h" 24 #include "../lib/async_req/async_sock.h" 25 #include "../lib/util/tevent_ntstatus.h" 23 26 #include "libcli/raw/libcliraw.h" 24 27 #include "libcli/raw/raw_proto.h" 25 28 #include "lib/socket/socket.h" 26 #include "../lib/util/dlinklist.h"27 29 #include "lib/events/events.h" 28 #include "lib/stream/packet.h"29 30 #include "librpc/gen_ndr/ndr_nbt.h" 30 31 #include "../libcli/nbt/libnbt.h" 31 32 33 /* 34 an event has happened on the socket 35 */ 36 static void smbcli_transport_event_handler(struct tevent_context *ev, 37 struct tevent_fd *fde, 38 uint16_t flags, void *private_data) 39 { 40 struct smbcli_transport *transport = talloc_get_type(private_data, 41 struct smbcli_transport); 42 if (flags & EVENT_FD_READ) { 43 packet_recv(transport->packet); 44 return; 45 } 46 if (flags & EVENT_FD_WRITE) { 47 packet_queue_run(transport->packet); 48 } 49 } 32 #include "../libcli/smb/smbXcli_base.h" 33 #include "../libcli/smb/read_smb.h" 50 34 51 35 /* … … 57 41 return 0; 58 42 } 59 60 61 /*62 handle receive errors63 */64 static void smbcli_transport_error(void *private_data, NTSTATUS status)65 {66 struct smbcli_transport *transport = talloc_get_type(private_data, struct smbcli_transport);67 smbcli_transport_dead(transport, status);68 }69 70 static NTSTATUS smbcli_transport_finish_recv(void *private_data, DATA_BLOB blob);71 43 72 44 /* … … 79 51 { 80 52 struct smbcli_transport *transport; 53 uint32_t smb1_capabilities; 81 54 82 55 transport = talloc_zero(parent_ctx, struct smbcli_transport); 83 56 if (!transport) return NULL; 84 57 85 if (primary) { 86 transport->socket = talloc_steal(transport, sock); 87 } else { 88 transport->socket = talloc_reference(transport, sock); 89 } 90 transport->negotiate.protocol = PROTOCOL_NT1; 58 transport->ev = sock->event.ctx; 91 59 transport->options = *options; 92 transport->negotiate.max_xmit = transport->options.max_xmit; 93 94 /* setup the stream -> packet parser */ 95 transport->packet = packet_init(transport); 96 if (transport->packet == NULL) { 97 talloc_free(transport); 60 61 if (transport->options.max_protocol == PROTOCOL_DEFAULT) { 62 transport->options.max_protocol = PROTOCOL_NT1; 63 } 64 65 if (transport->options.max_protocol > PROTOCOL_NT1) { 66 transport->options.max_protocol = PROTOCOL_NT1; 67 } 68 69 TALLOC_FREE(sock->event.fde); 70 TALLOC_FREE(sock->event.te); 71 72 smb1_capabilities = 0; 73 smb1_capabilities |= CAP_LARGE_FILES; 74 smb1_capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS; 75 smb1_capabilities |= CAP_LOCK_AND_READ | CAP_NT_FIND; 76 smb1_capabilities |= CAP_DFS | CAP_W2K_SMBS; 77 smb1_capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX; 78 smb1_capabilities |= CAP_LWIO; 79 80 if (options->ntstatus_support) { 81 smb1_capabilities |= CAP_STATUS32; 82 } 83 84 if (options->unicode) { 85 smb1_capabilities |= CAP_UNICODE; 86 } 87 88 if (options->use_spnego) { 89 smb1_capabilities |= CAP_EXTENDED_SECURITY; 90 } 91 92 if (options->use_level2_oplocks) { 93 smb1_capabilities |= CAP_LEVEL_II_OPLOCKS; 94 } 95 96 transport->conn = smbXcli_conn_create(transport, 97 sock->sock->fd, 98 sock->hostname, 99 options->signing, 100 smb1_capabilities, 101 NULL, /* client_guid */ 102 0); /* smb2_capabilities */ 103 if (transport->conn == NULL) { 104 TALLOC_FREE(sock); 105 TALLOC_FREE(transport); 98 106 return NULL; 99 107 } 100 packet_set_private(transport->packet, transport); 101 packet_set_socket(transport->packet, transport->socket->sock); 102 packet_set_callback(transport->packet, smbcli_transport_finish_recv); 103 packet_set_full_request(transport->packet, packet_full_request_nbt); 104 packet_set_error_handler(transport->packet, smbcli_transport_error); 105 packet_set_event_context(transport->packet, transport->socket->event.ctx); 106 packet_set_nofree(transport->packet); 107 packet_set_initial_read(transport->packet, 4); 108 109 smbcli_init_signing(transport); 110 111 ZERO_STRUCT(transport->called); 112 113 /* take over event handling from the socket layer - it only 114 handles events up until we are connected */ 115 talloc_free(transport->socket->event.fde); 116 transport->socket->event.fde = event_add_fd(transport->socket->event.ctx, 117 transport->socket->sock, 118 socket_get_fd(transport->socket->sock), 119 EVENT_FD_READ, 120 smbcli_transport_event_handler, 121 transport); 122 123 packet_set_fde(transport->packet, transport->socket->event.fde); 124 packet_set_serialise(transport->packet); 108 sock->sock->fd = -1; 109 TALLOC_FREE(sock); 110 125 111 talloc_set_destructor(transport, transport_destructor); 126 112 … … 133 119 void smbcli_transport_dead(struct smbcli_transport *transport, NTSTATUS status) 134 120 { 135 smbcli_sock_dead(transport->socket);136 137 121 if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) { 138 122 status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; 139 123 } 140 141 /* kill only the first pending receive - this is so that if 142 that async function frees the connection we don't die trying 143 to use old memory. The caller has to cope with only one 144 network error */ 145 if (transport->pending_recv) { 146 struct smbcli_request *req = transport->pending_recv; 147 req->state = SMBCLI_REQUEST_ERROR; 148 req->status = status; 149 DLIST_REMOVE(transport->pending_recv, req); 150 if (req->async.fn) { 151 req->async.fn(req); 152 } 153 } 154 } 155 156 157 /* 158 send a session request 159 */ 160 struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *transport, 161 struct nbt_name *calling, 162 struct nbt_name *called) 163 { 164 uint8_t *p; 165 struct smbcli_request *req; 166 DATA_BLOB calling_blob, called_blob; 167 TALLOC_CTX *tmp_ctx = talloc_new(transport); 168 NTSTATUS status; 169 170 status = nbt_name_dup(transport, called, &transport->called); 171 if (!NT_STATUS_IS_OK(status)) goto failed; 172 173 status = nbt_name_to_blob(tmp_ctx, &calling_blob, calling); 174 if (!NT_STATUS_IS_OK(status)) goto failed; 175 176 status = nbt_name_to_blob(tmp_ctx, &called_blob, called); 177 if (!NT_STATUS_IS_OK(status)) goto failed; 178 179 /* allocate output buffer */ 180 req = smbcli_request_setup_nonsmb(transport, 181 NBT_HDR_SIZE + 182 calling_blob.length + called_blob.length); 183 if (req == NULL) goto failed; 184 185 /* put in the destination name */ 186 p = req->out.buffer + NBT_HDR_SIZE; 187 memcpy(p, called_blob.data, called_blob.length); 188 p += called_blob.length; 189 190 memcpy(p, calling_blob.data, calling_blob.length); 191 p += calling_blob.length; 192 193 _smb_setlen(req->out.buffer, PTR_DIFF(p, req->out.buffer) - NBT_HDR_SIZE); 194 SCVAL(req->out.buffer,0,0x81); 195 196 if (!smbcli_request_send(req)) { 197 smbcli_request_destroy(req); 198 goto failed; 199 } 200 201 talloc_free(tmp_ctx); 202 return req; 203 204 failed: 205 talloc_free(tmp_ctx); 206 return NULL; 207 } 208 209 /* 210 map a session request error to a NTSTATUS 211 */ 212 static NTSTATUS map_session_refused_error(uint8_t error) 213 { 214 switch (error) { 215 case 0x80: 216 case 0x81: 217 return NT_STATUS_REMOTE_NOT_LISTENING; 218 case 0x82: 219 return NT_STATUS_RESOURCE_NAME_NOT_FOUND; 220 case 0x83: 221 return NT_STATUS_REMOTE_RESOURCES; 222 } 223 return NT_STATUS_UNEXPECTED_IO_ERROR; 224 } 225 226 227 /* 228 finish a smbcli_transport_connect() 229 */ 230 NTSTATUS smbcli_transport_connect_recv(struct smbcli_request *req) 231 { 232 NTSTATUS status; 233 234 if (!smbcli_request_receive(req)) { 235 smbcli_request_destroy(req); 236 return NT_STATUS_UNEXPECTED_NETWORK_ERROR; 237 } 238 239 switch (CVAL(req->in.buffer,0)) { 240 case 0x82: 241 status = NT_STATUS_OK; 242 break; 243 case 0x83: 244 status = map_session_refused_error(CVAL(req->in.buffer,4)); 245 break; 246 case 0x84: 247 DEBUG(1,("Warning: session retarget not supported\n")); 248 status = NT_STATUS_NOT_SUPPORTED; 249 break; 250 default: 251 status = NT_STATUS_UNEXPECTED_IO_ERROR; 252 break; 253 } 254 255 smbcli_request_destroy(req); 256 return status; 257 } 258 259 260 /* 261 send a session request (if needed) 262 */ 263 bool smbcli_transport_connect(struct smbcli_transport *transport, 264 struct nbt_name *calling, 265 struct nbt_name *called) 266 { 267 struct smbcli_request *req; 268 NTSTATUS status; 269 270 if (transport->socket->port == 445) { 271 return true; 272 } 273 274 req = smbcli_transport_connect_send(transport, 275 calling, called); 276 status = smbcli_transport_connect_recv(req); 277 return NT_STATUS_IS_OK(status); 278 } 279 280 /**************************************************************************** 281 get next mid in sequence 282 ****************************************************************************/ 283 uint16_t smbcli_transport_next_mid(struct smbcli_transport *transport) 284 { 285 uint16_t mid; 286 struct smbcli_request *req; 287 288 mid = transport->next_mid; 289 290 again: 291 /* now check to see if this mid is being used by one of the 292 pending requests. This is quite efficient because the list is 293 usually very short */ 294 295 /* the zero mid is reserved for requests that don't have a mid */ 296 if (mid == 0) mid = 1; 297 298 for (req=transport->pending_recv; req; req=req->next) { 299 if (req->mid == mid) { 300 mid++; 301 goto again; 302 } 303 } 304 305 transport->next_mid = mid+1; 306 return mid; 124 if (NT_STATUS_IS_OK(status)) { 125 status = NT_STATUS_LOCAL_DISCONNECT; 126 } 127 128 smbXcli_conn_disconnect(transport->conn, status); 307 129 } 308 130 … … 312 134 struct smbcli_transport *transport = talloc_get_type(private_data, 313 135 struct smbcli_transport); 314 struct timeval next = timeval_add(&t, 0, transport->idle.period); 315 transport->socket->event.te = event_add_timed(transport->socket->event.ctx, 316 transport, 317 next, 318 idle_handler, transport); 136 struct timeval next; 137 319 138 transport->idle.func(transport, transport->idle.private_data); 139 140 next = timeval_current_ofs_usec(transport->idle.period); 141 142 transport->idle.te = tevent_add_timer(transport->ev, 143 transport, 144 next, 145 idle_handler, 146 transport); 320 147 } 321 148 … … 329 156 void *private_data) 330 157 { 158 TALLOC_FREE(transport->idle.te); 159 331 160 transport->idle.func = idle_func; 332 161 transport->idle.private_data = private_data; 333 162 transport->idle.period = period; 334 163 335 if (transport->socket->event.te != NULL) { 336 talloc_free(transport->socket->event.te); 337 } 338 339 transport->socket->event.te = event_add_timed(transport->socket->event.ctx, 340 transport, 341 timeval_current_ofs(0, period), 342 idle_handler, transport); 343 } 344 345 /* 346 we have a full request in our receive buffer - match it to a pending request 347 and process 348 */ 349 static NTSTATUS smbcli_transport_finish_recv(void *private_data, DATA_BLOB blob) 350 { 351 struct smbcli_transport *transport = talloc_get_type(private_data, 352 struct smbcli_transport); 353 uint8_t *buffer, *hdr, *vwv; 354 int len; 355 uint16_t wct=0, mid = 0, op = 0; 356 struct smbcli_request *req = NULL; 357 358 buffer = blob.data; 359 len = blob.length; 360 361 hdr = buffer+NBT_HDR_SIZE; 362 vwv = hdr + HDR_VWV; 363 364 /* see if it could be an oplock break request */ 365 if (smbcli_handle_oplock_break(transport, len, hdr, vwv)) { 366 talloc_free(buffer); 367 return NT_STATUS_OK; 368 } 369 370 /* at this point we need to check for a readbraw reply, as 371 these can be any length */ 372 if (transport->readbraw_pending) { 373 transport->readbraw_pending = 0; 374 375 /* it must match the first entry in the pending queue 376 as the client is not allowed to have outstanding 377 readbraw requests */ 378 req = transport->pending_recv; 379 if (!req) goto error; 380 381 req->in.buffer = buffer; 382 talloc_steal(req, buffer); 383 req->in.size = len; 384 req->in.allocated = req->in.size; 385 goto async; 386 } 387 388 if (len >= MIN_SMB_SIZE) { 389 /* extract the mid for matching to pending requests */ 390 mid = SVAL(hdr, HDR_MID); 391 wct = CVAL(hdr, HDR_WCT); 392 op = CVAL(hdr, HDR_COM); 393 } 394 395 /* match the incoming request against the list of pending requests */ 396 for (req=transport->pending_recv; req; req=req->next) { 397 if (req->mid == mid) break; 398 } 399 400 /* see if it's a ntcancel reply for the current MID */ 401 req = smbcli_handle_ntcancel_reply(req, len, hdr); 402 403 if (!req) { 404 DEBUG(1,("Discarding unmatched reply with mid %d op %d\n", mid, op)); 405 goto error; 406 } 407 408 /* fill in the 'in' portion of the matching request */ 409 req->in.buffer = buffer; 410 talloc_steal(req, buffer); 411 req->in.size = len; 412 req->in.allocated = req->in.size; 413 414 /* handle NBT session replies */ 415 if (req->in.size >= 4 && req->in.buffer[0] != 0) { 416 req->status = NT_STATUS_OK; 417 goto async; 418 } 419 420 /* handle non-SMB replies */ 421 if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) { 422 req->state = SMBCLI_REQUEST_ERROR; 423 goto error; 424 } 425 426 if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { 427 DEBUG(2,("bad reply size for mid %d\n", mid)); 428 req->status = NT_STATUS_UNSUCCESSFUL; 429 req->state = SMBCLI_REQUEST_ERROR; 430 goto error; 431 } 432 433 req->in.hdr = hdr; 434 req->in.vwv = vwv; 435 req->in.wct = wct; 436 if (req->in.size >= NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) { 437 req->in.data = req->in.vwv + VWV(wct) + 2; 438 req->in.data_size = SVAL(req->in.vwv, VWV(wct)); 439 if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct) + req->in.data_size) { 440 DEBUG(3,("bad data size for mid %d\n", mid)); 441 /* blergh - w2k3 gives a bogus data size values in some 442 openX replies */ 443 req->in.data_size = req->in.size - (NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)); 444 } 445 } 446 req->in.ptr = req->in.data; 447 req->flags2 = SVAL(req->in.hdr, HDR_FLG2); 448 449 smb_setup_bufinfo(req); 450 451 if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) { 452 int eclass = CVAL(req->in.hdr,HDR_RCLS); 453 int code = SVAL(req->in.hdr,HDR_ERR); 454 if (eclass == 0 && code == 0) { 455 transport->error.e.nt_status = NT_STATUS_OK; 456 } else { 457 transport->error.e.nt_status = NT_STATUS_DOS(eclass, code); 458 } 459 } else { 460 transport->error.e.nt_status = NT_STATUS(IVAL(req->in.hdr, HDR_RCLS)); 461 } 462 463 req->status = transport->error.e.nt_status; 464 if (NT_STATUS_IS_OK(req->status)) { 465 transport->error.etype = ETYPE_NONE; 466 } else { 467 transport->error.etype = ETYPE_SMB; 468 } 469 470 if (!smbcli_request_check_sign_mac(req)) { 471 transport->error.etype = ETYPE_SOCKET; 472 transport->error.e.socket_error = SOCKET_READ_BAD_SIG; 473 req->state = SMBCLI_REQUEST_ERROR; 474 req->status = NT_STATUS_ACCESS_DENIED; 475 goto error; 476 }; 477 478 async: 479 /* if this request has an async handler then call that to 480 notify that the reply has been received. This might destroy 481 the request so it must happen last */ 482 483 req->state = SMBCLI_REQUEST_DONE; 484 485 if (req->recv_helper.fn) { 486 /* 487 * let the recv helper decide in 488 * what state the request really is 489 */ 490 req->state = req->recv_helper.fn(req); 491 492 /* if more parts are needed, wait for them */ 493 if (req->state <= SMBCLI_REQUEST_RECV) { 494 return NT_STATUS_OK; 495 } 496 } 497 DLIST_REMOVE(transport->pending_recv, req); 498 if (req->async.fn) { 499 req->async.fn(req); 500 } 501 return NT_STATUS_OK; 502 503 error: 504 if (req) { 505 DLIST_REMOVE(transport->pending_recv, req); 506 req->state = SMBCLI_REQUEST_ERROR; 507 if (req->async.fn) { 508 req->async.fn(req); 509 } 510 } else { 511 talloc_free(buffer); 512 } 513 return NT_STATUS_OK; 164 transport->idle.te = tevent_add_timer(transport->ev, 165 transport, 166 timeval_current_ofs_usec(period), 167 idle_handler, 168 transport); 514 169 } 515 170 … … 520 175 _PUBLIC_ bool smbcli_transport_process(struct smbcli_transport *transport) 521 176 { 522 NTSTATUS status; 523 size_t npending; 524 525 packet_queue_run(transport->packet); 526 if (transport->socket->sock == NULL) { 177 struct tevent_req *subreq = NULL; 178 int ret; 179 180 if (!smbXcli_conn_is_connected(transport->conn)) { 527 181 return false; 528 182 } 529 183 530 status = socket_pending(transport->socket->sock, &npending); 531 if (NT_STATUS_IS_OK(status) && npending > 0) { 532 packet_recv(transport->packet); 533 } 534 if (transport->socket->sock == NULL) { 184 if (!smbXcli_conn_has_async_calls(transport->conn)) { 185 return true; 186 } 187 188 /* 189 * do not block for more than 500 micro seconds 190 */ 191 subreq = tevent_wakeup_send(transport, 192 transport->ev, 193 timeval_current_ofs_usec(500)); 194 if (subreq == NULL) { 535 195 return false; 536 196 } 197 198 ret = tevent_loop_once(transport->ev); 199 if (ret != 0) { 200 return false; 201 } 202 203 TALLOC_FREE(subreq); 204 205 if (!smbXcli_conn_is_connected(transport->conn)) { 206 return false; 207 } 208 537 209 return true; 538 210 } 539 211 540 /* 541 handle timeouts of individual smb requests 542 */ 543 static void smbcli_timeout_handler(struct tevent_context *ev, struct tevent_timer *te, 544 struct timeval t, void *private_data) 545 { 546 struct smbcli_request *req = talloc_get_type(private_data, struct smbcli_request); 547 548 if (req->state == SMBCLI_REQUEST_RECV) { 549 DLIST_REMOVE(req->transport->pending_recv, req); 550 } 551 req->status = NT_STATUS_IO_TIMEOUT; 552 req->state = SMBCLI_REQUEST_ERROR; 553 if (req->async.fn) { 554 req->async.fn(req); 555 } 556 } 557 558 559 /* 560 destroy a request 561 */ 562 static int smbcli_request_destructor(struct smbcli_request *req) 563 { 564 if (req->state == SMBCLI_REQUEST_RECV) { 565 DLIST_REMOVE(req->transport->pending_recv, req); 566 } 567 return 0; 568 } 569 212 static void smbcli_transport_break_handler(struct tevent_req *subreq); 213 static void smbcli_request_done(struct tevent_req *subreq); 214 215 struct tevent_req *smbcli_transport_setup_subreq(struct smbcli_request *req) 216 { 217 struct smbcli_transport *transport = req->transport; 218 uint8_t smb_command; 219 uint8_t additional_flags; 220 uint8_t clear_flags; 221 uint16_t additional_flags2; 222 uint16_t clear_flags2; 223 uint32_t pid; 224 struct smbXcli_tcon *tcon = NULL; 225 struct smbXcli_session *session = NULL; 226 uint32_t timeout_msec = transport->options.request_timeout * 1000; 227 struct iovec *bytes_iov = NULL; 228 struct tevent_req *subreq = NULL; 229 230 smb_command = SVAL(req->out.hdr, HDR_COM); 231 additional_flags = CVAL(req->out.hdr, HDR_FLG); 232 additional_flags2 = SVAL(req->out.hdr, HDR_FLG2); 233 pid = SVAL(req->out.hdr, HDR_PID); 234 pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16; 235 236 clear_flags = ~additional_flags; 237 clear_flags2 = ~additional_flags2; 238 239 if (req->session) { 240 session = req->session->smbXcli; 241 } 242 243 if (req->tree) { 244 tcon = req->tree->smbXcli; 245 } 246 247 bytes_iov = talloc(req, struct iovec); 248 if (bytes_iov == NULL) { 249 return NULL; 250 } 251 bytes_iov->iov_base = (void *)req->out.data; 252 bytes_iov->iov_len = req->out.data_size; 253 254 subreq = smb1cli_req_create(req, 255 transport->ev, 256 transport->conn, 257 smb_command, 258 additional_flags, 259 clear_flags, 260 additional_flags2, 261 clear_flags2, 262 timeout_msec, 263 pid, 264 tcon, 265 session, 266 req->out.wct, 267 (uint16_t *)req->out.vwv, 268 1, bytes_iov); 269 if (subreq == NULL) { 270 return NULL; 271 } 272 273 ZERO_STRUCT(req->out); 274 275 return subreq; 276 } 570 277 571 278 /* … … 574 281 void smbcli_transport_send(struct smbcli_request *req) 575 282 { 576 DATA_BLOB blob;283 struct smbcli_transport *transport = req->transport; 577 284 NTSTATUS status; 578 579 /* check if the transport is dead */ 580 if (req->transport->socket->sock == NULL) { 285 bool need_pending_break = false; 286 struct tevent_req *subreq = NULL; 287 size_t i; 288 size_t num_subreqs = 0; 289 290 if (transport->oplock.handler) { 291 need_pending_break = true; 292 } 293 294 if (transport->break_subreq) { 295 need_pending_break = false; 296 } 297 298 if (need_pending_break) { 299 subreq = smb1cli_req_create(transport, 300 transport->ev, 301 transport->conn, 302 0, /* smb_command */ 303 0, /* additional_flags */ 304 0, /* clear_flags */ 305 0, /* additional_flags2 */ 306 0, /* clear_flags2 */ 307 0, /* timeout_msec */ 308 0, /* pid */ 309 NULL, /* tcon */ 310 NULL, /* session */ 311 0, /* wct */ 312 NULL, /* vwv */ 313 0, /* iov_count */ 314 NULL); /* bytes_iov */ 315 if (subreq != NULL) { 316 smb1cli_req_set_mid(subreq, 0xFFFF); 317 smbXcli_req_set_pending(subreq); 318 tevent_req_set_callback(subreq, 319 smbcli_transport_break_handler, 320 transport); 321 transport->break_subreq = subreq; 322 subreq = NULL; 323 } 324 } 325 326 subreq = smbcli_transport_setup_subreq(req); 327 if (subreq == NULL) { 581 328 req->state = SMBCLI_REQUEST_ERROR; 582 req->status = NT_STATUS_N ET_WRITE_FAULT;329 req->status = NT_STATUS_NO_MEMORY; 583 330 return; 584 331 } 585 332 586 blob = data_blob_const(req->out.buffer, req->out.size); 587 status = packet_send(req->transport->packet, blob); 333 for (i = 0; i < ARRAY_SIZE(req->subreqs); i++) { 334 if (req->subreqs[i] == NULL) { 335 req->subreqs[i] = subreq; 336 subreq = NULL; 337 } 338 if (req->subreqs[i] == NULL) { 339 break; 340 } 341 342 if (!tevent_req_is_in_progress(req->subreqs[i])) { 343 req->state = SMBCLI_REQUEST_ERROR; 344 req->status = NT_STATUS_INTERNAL_ERROR; 345 return; 346 } 347 } 348 num_subreqs = i; 349 350 req->state = SMBCLI_REQUEST_RECV; 351 tevent_req_set_callback(req->subreqs[0], smbcli_request_done, req); 352 353 status = smb1cli_req_chain_submit(req->subreqs, num_subreqs); 588 354 if (!NT_STATUS_IS_OK(status)) { 355 req->status = status; 589 356 req->state = SMBCLI_REQUEST_ERROR; 590 req->status = status; 357 smbXcli_conn_disconnect(transport->conn, status); 358 } 359 } 360 361 static void smbcli_request_done(struct tevent_req *subreq) 362 { 363 struct smbcli_request *req = 364 tevent_req_callback_data(subreq, 365 struct smbcli_request); 366 struct smbcli_transport *transport = req->transport; 367 ssize_t len; 368 size_t i; 369 uint8_t *hdr = NULL; 370 uint8_t wct = 0; 371 uint16_t *vwv = NULL; 372 uint32_t num_bytes = 0; 373 uint8_t *bytes = NULL; 374 struct iovec *recv_iov = NULL; 375 uint8_t *inbuf = NULL; 376 377 req->status = smb1cli_req_recv(req->subreqs[0], req, 378 &recv_iov, 379 &hdr, 380 &wct, 381 &vwv, 382 NULL, /* pvwv_offset */ 383 &num_bytes, 384 &bytes, 385 NULL, /* pbytes_offset */ 386 &inbuf, 387 NULL, 0); /* expected */ 388 TALLOC_FREE(req->subreqs[0]); 389 if (!NT_STATUS_IS_OK(req->status)) { 390 if (recv_iov == NULL) { 391 req->state = SMBCLI_REQUEST_ERROR; 392 transport->error.e.nt_status = req->status; 393 transport->error.etype = ETYPE_SOCKET; 394 if (req->async.fn) { 395 req->async.fn(req); 396 } 397 return; 398 } 399 } 400 401 /* 402 * For SMBreadBraw hdr is NULL 403 */ 404 len = recv_iov[0].iov_len; 405 for (i=1; hdr != NULL && i < 3; i++) { 406 uint8_t *p = recv_iov[i-1].iov_base; 407 uint8_t *c1 = recv_iov[i].iov_base; 408 uint8_t *c2 = p + recv_iov[i-1].iov_len; 409 410 len += recv_iov[i].iov_len; 411 412 c2 += i; 413 len += i; 414 415 if (recv_iov[i].iov_len == 0) { 416 continue; 417 } 418 419 if (c1 != c2) { 420 req->state = SMBCLI_REQUEST_ERROR; 421 req->status = NT_STATUS_INTERNAL_ERROR; 422 transport->error.e.nt_status = req->status; 423 transport->error.etype = ETYPE_SMB; 424 if (req->async.fn) { 425 req->async.fn(req); 426 } 427 return; 428 } 429 } 430 431 /* fill in the 'in' portion of the matching request */ 432 req->in.buffer = inbuf; 433 req->in.size = NBT_HDR_SIZE + len; 434 req->in.allocated = req->in.size; 435 436 req->in.hdr = hdr; 437 req->in.vwv = (uint8_t *)vwv; 438 req->in.wct = wct; 439 req->in.data = bytes; 440 req->in.data_size = num_bytes; 441 req->in.ptr = req->in.data; 442 if (hdr != NULL) { 443 req->flags2 = SVAL(req->in.hdr, HDR_FLG2); 444 } 445 446 smb_setup_bufinfo(req); 447 448 transport->error.e.nt_status = req->status; 449 if (NT_STATUS_IS_OK(req->status)) { 450 transport->error.etype = ETYPE_NONE; 451 } else { 452 transport->error.etype = ETYPE_SMB; 453 } 454 455 req->state = SMBCLI_REQUEST_DONE; 456 if (req->async.fn) { 457 req->async.fn(req); 458 } 459 } 460 461 static void smbcli_transport_break_handler(struct tevent_req *subreq) 462 { 463 struct smbcli_transport *transport = 464 tevent_req_callback_data(subreq, 465 struct smbcli_transport); 466 NTSTATUS status; 467 struct iovec *recv_iov = NULL; 468 uint8_t *hdr = NULL; 469 uint16_t *vwv = NULL; 470 const struct smb1cli_req_expected_response expected[] = { 471 { 472 .status = NT_STATUS_OK, 473 .wct = 8, 474 } 475 }; 476 uint16_t tid; 477 uint16_t fnum; 478 uint8_t level; 479 480 transport->break_subreq = NULL; 481 482 status = smb1cli_req_recv(subreq, transport, 483 &recv_iov, 484 &hdr, 485 NULL, /* pwct */ 486 &vwv, 487 NULL, /* pvwv_offset */ 488 NULL, /* pnum_bytes */ 489 NULL, /* pbytes */ 490 NULL, /* pbytes_offset */ 491 NULL, /* pinbuf */ 492 expected, 493 ARRAY_SIZE(expected)); 494 TALLOC_FREE(subreq); 495 if (!NT_STATUS_IS_OK(status)) { 496 TALLOC_FREE(recv_iov); 497 smbcli_transport_dead(transport, status); 591 498 return; 592 499 } 593 500 594 packet_queue_run(req->transport->packet); 595 if (req->transport->socket->sock == NULL) { 596 req->state = SMBCLI_REQUEST_ERROR; 597 req->status = NT_STATUS_NET_WRITE_FAULT; 598 return; 599 } 600 601 if (req->one_way_request) { 602 req->state = SMBCLI_REQUEST_DONE; 603 smbcli_request_destroy(req); 604 return; 605 } 606 607 req->state = SMBCLI_REQUEST_RECV; 608 DLIST_ADD(req->transport->pending_recv, req); 609 610 /* add a timeout */ 611 if (req->transport->options.request_timeout) { 612 event_add_timed(req->transport->socket->event.ctx, req, 613 timeval_current_ofs(req->transport->options.request_timeout, 0), 614 smbcli_timeout_handler, req); 615 } 616 617 talloc_set_destructor(req, smbcli_request_destructor); 501 /* 502 * Setup the subreq to handle the 503 * next incoming SMB2 Break. 504 */ 505 subreq = smb1cli_req_create(transport, 506 transport->ev, 507 transport->conn, 508 0, /* smb_command */ 509 0, /* additional_flags */ 510 0, /* clear_flags */ 511 0, /* additional_flags2 */ 512 0, /* clear_flags2 */ 513 0, /* timeout_msec */ 514 0, /* pid */ 515 NULL, /* tcon */ 516 NULL, /* session */ 517 0, /* wct */ 518 NULL, /* vwv */ 519 0, /* iov_count */ 520 NULL); /* bytes_iov */ 521 if (subreq != NULL) { 522 smb1cli_req_set_mid(subreq, 0xFFFF); 523 smbXcli_req_set_pending(subreq); 524 tevent_req_set_callback(subreq, 525 smbcli_transport_break_handler, 526 transport); 527 transport->break_subreq = subreq; 528 } 529 530 tid = SVAL(hdr, HDR_TID); 531 fnum = SVAL(vwv+2, 0); 532 level = CVAL(vwv+3, 1); 533 534 TALLOC_FREE(recv_iov); 535 536 if (transport->oplock.handler) { 537 transport->oplock.handler(transport, tid, fnum, level, 538 transport->oplock.private_data); 539 } else { 540 DEBUG(5,("Got SMB oplock break with no handler\n")); 541 } 542 618 543 } 619 544 -
vendor/current/source4/libcli/raw/clitree.c
r740 r988 25 25 #include "libcli/raw/raw_proto.h" 26 26 #include "libcli/smb_composite/smb_composite.h" 27 #include "../libcli/smb/smbXcli_base.h" 27 28 28 29 #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \ … … 50 51 } 51 52 53 tree->smbXcli = smbXcli_tcon_create(tree); 54 if (tree->smbXcli == NULL) { 55 talloc_free(tree); 56 return NULL; 57 } 52 58 53 59 return tree; … … 116 122 ZERO_STRUCT(parms->tconx.out); 117 123 parms->tconx.out.tid = SVAL(req->in.hdr, HDR_TID); 118 if (req->in.wct >= 4) { 119 parms->tconx.out.options = SVAL(req->in.vwv, VWV(3)); 124 if (req->in.wct >= 3) { 125 parms->tconx.out.options = SVAL(req->in.vwv, VWV(2)); 126 } 127 if (req->in.wct >= 7) { 128 parms->tconx.out.max_access = IVAL(req->in.vwv, VWV(3)); 129 parms->tconx.out.guest_max_access = IVAL(req->in.vwv, VWV(5)); 120 130 } 121 131 … … 159 169 if (!tree) return NT_STATUS_OK; 160 170 req = smbcli_request_setup(tree, SMBtdis, 0, 0); 171 if (req == NULL) { 172 return NT_STATUS_NO_MEMORY; 173 } 161 174 162 175 if (smbcli_request_send(req)) { -
vendor/current/source4/libcli/raw/interfaces.h
r740 r988 23 23 #define __LIBCLI_RAW_INTERFACES_H__ 24 24 25 #include " libcli/raw/smb.h"25 #include "source4/libcli/raw/smb.h" 26 26 #include "../libcli/smb/smb_common.h" 27 27 #include "librpc/gen_ndr/misc.h" /* for struct GUID */ 28 #include "librpc/gen_ndr/smb2_lease_struct.h" 28 29 29 30 /* this structure is just a wrapper for a string, the only reason we … … 55 56 }; 56 57 57 /*58 SMB2 lease structure (per MS-SMB2 2.2.13)59 */60 struct smb2_lease_key {61 uint64_t data[2];62 };63 64 struct smb2_lease {65 struct smb2_lease_key lease_key;66 uint32_t lease_state;67 uint32_t lease_flags; /* should be 0 */68 uint64_t lease_duration; /* should be 0 */69 };70 71 58 struct smb2_lease_break { 72 59 struct smb2_lease current_lease; 60 uint16_t new_epoch; /* only for v2 leases */ 73 61 uint32_t break_flags; 74 62 uint32_t new_lease_state; … … 284 272 struct { 285 273 uint16_t options; 274 uint32_t max_access; 275 uint32_t guest_max_access; 286 276 char *dev_type; 287 277 char *fs_type; … … 925 915 RAW_SFILEINFO_UNIX_BASIC = SMB_SFILEINFO_UNIX_BASIC, 926 916 RAW_SFILEINFO_UNIX_INFO2 = SMB_SFILEINFO_UNIX_INFO2, 927 RAW_SFILEINFO_UNIX_LINK = SMB_S FILEINFO_UNIX_LINK,928 RAW_SFILEINFO_UNIX_HLINK = SMB_S FILEINFO_UNIX_HLINK,917 RAW_SFILEINFO_UNIX_LINK = SMB_SET_FILE_UNIX_LINK, 918 RAW_SFILEINFO_UNIX_HLINK = SMB_SET_FILE_UNIX_HLINK, 929 919 RAW_SFILEINFO_BASIC_INFORMATION = SMB_SFILEINFO_BASIC_INFORMATION, 930 920 RAW_SFILEINFO_RENAME_INFORMATION = SMB_SFILEINFO_RENAME_INFORMATION, … … 1141 1131 } unix_link, unix_hlink; 1142 1132 1143 /* RAW_ FILEINFO_SET_SEC_DESC */1133 /* RAW_SFILEINFO_SEC_DESC */ 1144 1134 struct { 1145 1135 enum smb_setfileinfo_level level; … … 1178 1168 RAW_QFS_QUOTA_INFORMATION = SMB_QFS_QUOTA_INFORMATION, 1179 1169 RAW_QFS_FULL_SIZE_INFORMATION = SMB_QFS_FULL_SIZE_INFORMATION, 1180 RAW_QFS_OBJECTID_INFORMATION = SMB_QFS_OBJECTID_INFORMATION}; 1170 RAW_QFS_OBJECTID_INFORMATION = SMB_QFS_OBJECTID_INFORMATION, 1171 RAW_QFS_SECTOR_SIZE_INFORMATION = SMB_QFS_SECTOR_SIZE_INFORMATION, 1172 }; 1181 1173 1182 1174 … … 1342 1334 } out; 1343 1335 } objectid_information; 1344 }; 1345 1346 1336 1337 /* trans2 RAW_QFS_SECTOR_SIZE_INFORMATION interface */ 1338 struct { 1339 enum smb_fsinfo_level level; 1340 struct smb2_handle handle; /* only for smb2 */ 1341 1342 struct { 1343 uint32_t logical_bytes_per_sector; 1344 uint32_t phys_bytes_per_sector_atomic; 1345 uint32_t phys_bytes_per_sector_perf; 1346 uint32_t fs_effective_phys_bytes_per_sector_atomic; 1347 uint32_t flags; 1348 uint32_t byte_off_sector_align; 1349 uint32_t byte_off_partition_align; 1350 } out; 1351 } sector_size_info; 1352 }; 1353 1354 1355 enum smb_setfsinfo_level { 1356 RAW_SETFS_UNIX_INFO = SMB_SET_CIFS_UNIX_INFO}; 1357 1358 union smb_setfsinfo { 1359 /* generic interface */ 1360 struct { 1361 enum smb_setfsinfo_level level; 1362 } generic; 1363 1364 /* TRANS2 RAW_QFS_UNIX_INFO interface */ 1365 struct { 1366 enum smb_setfsinfo_level level; 1367 1368 struct { 1369 uint16_t major_version; 1370 uint16_t minor_version; 1371 uint64_t capability; 1372 } in; 1373 } unix_info; 1374 }; 1347 1375 1348 1376 enum smb_open_level { … … 1710 1738 bool durable_open; 1711 1739 struct smb2_handle *durable_handle; 1740 1741 /* data for durable handle v2 */ 1742 bool durable_open_v2; 1743 struct GUID create_guid; 1744 bool persistent_open; 1745 uint32_t timeout; 1746 struct smb2_handle *durable_handle_v2; 1747 1712 1748 bool query_maximal_access; 1713 1749 NTTIME timewarp; 1714 1750 bool query_on_disk_id; 1715 1751 struct smb2_lease *lease_request; 1716 1752 struct smb2_lease *lease_request_v2; 1753 1754 struct GUID *app_instance_id; 1755 1717 1756 /* and any additional blobs the caller wants */ 1718 1757 struct smb2_create_blobs blobs; … … 1742 1781 uint8_t on_disk_id[32]; 1743 1782 struct smb2_lease lease_response; 1783 struct smb2_lease lease_response_v2; 1784 bool durable_open; 1785 1786 /* durable handle v2 */ 1787 bool durable_open_v2; 1788 bool persistent_open; 1789 uint32_t timeout; 1744 1790 1745 1791 /* tagged blobs in the reply */ … … 1783 1829 uint16_t compaction_mode; 1784 1830 uint32_t nread; 1831 uint16_t flags2; 1832 uint16_t data_offset; 1785 1833 } out; 1786 1834 } readx, generic; … … 2711 2759 uint32_t ea_size; 2712 2760 uint64_t file_id; 2761 uint8_t short_name_buf[24]; 2713 2762 struct smb_wire_string short_name; 2714 2763 struct smb_wire_string name; -
vendor/current/source4/libcli/raw/libcliraw.h
r740 r988 23 23 #define __LIBCLI_RAW_H__ 24 24 25 #include "../libcli/smb/smb_common.h" 25 26 #include "libcli/raw/request.h" 26 27 #include "librpc/gen_ndr/nbt.h" 28 #include "libcli/raw/interfaces.h" 27 29 28 30 struct smbcli_tree; /* forward declare */ … … 52 54 53 55 uint8_t sec_mode; /* security mode returned by negprot */ 54 uint8_t key_len;55 DATA_BLOB server_guid; /* server_guid */56 56 DATA_BLOB secblob; /* cryptkey or negTokenInit blob */ 57 57 uint32_t sesskey; 58 59 struct smb_signing_context sign_info;60 58 61 59 /* capabilities that the server reported */ … … 64 62 int server_zone; 65 63 time_t server_time; 64 66 65 unsigned int readbraw_supported:1; 67 66 unsigned int writebraw_supported:1; 68 67 unsigned int lockread_supported:1; 69 70 char *server_domain;71 68 }; 72 69 … … 99 96 unsigned int unicode:1; 100 97 unsigned int ntstatus_support:1; 98 int min_protocol; 101 99 int max_protocol; 102 100 uint32_t max_xmit; 103 101 uint16_t max_mux; 104 102 int request_timeout; 105 enum smb_signing_state signing; 103 enum smb_signing_setting signing; 104 uint32_t smb2_capabilities; 105 struct GUID client_guid; 106 106 }; 107 107 108 108 /* this is the context for the client transport layer */ 109 109 struct smbcli_transport { 110 /* socket level info */ 111 struct smbcli_socket *socket; 112 113 /* the next mid to be allocated - needed for signing and 114 request matching */ 115 uint16_t next_mid; 116 110 struct tevent_context *ev; /* TODO: remove this !!! */ 111 struct smbXcli_conn *conn; 112 117 113 /* negotiated protocol information */ 118 114 struct smbcli_negotiate negotiate; … … 121 117 struct smbcli_options options; 122 118 123 /* is a readbraw pending? we need to handle that case124 specially on receiving packets */125 unsigned int readbraw_pending:1;126 127 119 /* an idle function - if this is defined then it will be 128 120 called once every period microseconds while we are waiting … … 132 124 void *private_data; 133 125 unsigned int period; 126 struct tevent_timer *te; 134 127 } idle; 135 128 … … 155 148 void *private_data; 156 149 } oplock; 157 158 /* a list of async requests that are pending for receive on this connection */ 159 struct smbcli_request *pending_recv; 160 161 /* remember the called name - some sub-protocols require us to 162 know the server name */ 163 struct nbt_name called; 164 165 /* context of the stream -> packet parser */ 166 struct packet_context *packet; 150 struct tevent_req *break_subreq; 167 151 }; 168 152 … … 176 160 /* after a session setup the server provides us with 177 161 a vuid identifying the security context */ 162 struct smbXcli_session *smbXcli; 178 163 uint16_t vuid; 179 164 … … 184 169 the user to control these for torture testing */ 185 170 uint16_t flags2; 186 187 DATA_BLOB user_session_key;188 171 189 172 /* the spnego context if we use extented security */ … … 207 190 struct smbcli_session *session; 208 191 192 struct smbXcli_tcon *smbXcli; 209 193 uint16_t tid; /* tree id, aka cnum */ 210 194 char *device; … … 225 209 * This will allow requests to be multi-threaded. */ 226 210 struct smbcli_request { 227 /* allow a request to be part of a list of requests*/228 struct smbcli_request *next, *prev;211 /* smbXcli_req */ 212 struct tevent_req *subreqs[2]; 229 213 230 214 /* each request is in one of 4 possible states */ … … 237 221 struct smbcli_tree *tree; 238 222 239 /* a receive helper, smbcli_transport_finish_recv will not call240 req->async.fn callback handler unless the recv_helper returns241 a value > SMBCLI_REQUEST_RECV. */242 struct {243 enum smbcli_request_state (*fn)(struct smbcli_request *);244 void *private_data;245 } recv_helper;246 247 223 /* the flags2 from the SMB request, in raw form (host byte 248 224 order). Used to parse strings */ … … 252 228 or code detecting error. */ 253 229 NTSTATUS status; 254 255 /* the sequence number of this packet - used for signing */256 unsigned int seq_num;257 258 /* list of ntcancel request for this requests */259 struct smbcli_request *ntcancel;260 261 /* set if this is a one-way request, meaning we are not262 expecting a reply from the server. */263 unsigned int one_way_request:1;264 265 /* set this when the request should only increment the signing266 counter by one */267 unsigned int sign_single_increment:1;268 230 269 231 /* the caller wants to do the signing check */ … … 273 235 bool do_not_free; 274 236 275 /* the mid of this packet - used to match replies */276 uint16_t mid;277 278 237 struct smb_request_buffer in; 279 238 struct smb_request_buffer out; 239 240 struct smb_trans2 trans2; 241 struct smb_nttrans nttrans; 280 242 281 243 /* information on what to do with a reply when it is received … … 304 266 goto failed; \ 305 267 } 306 307 #include "libcli/raw/interfaces.h"308 268 309 269 NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms); … … 316 276 NTSTATUS smbcli_request_destroy(struct smbcli_request *req); 317 277 struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms); 278 NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms); 318 279 struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms); 319 280 NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms); … … 323 284 const char *smbcli_errstr(struct smbcli_tree *tree); 324 285 NTSTATUS smb_raw_fsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo); 286 NTSTATUS smb_raw_setfsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_setfsinfo *set_fsinfo); 325 287 NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms); 326 288 NTSTATUS smb_raw_shadow_data(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_shadow_copy *info); … … 376 338 struct smb_trans2 *parms); 377 339 378 struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports,379 TALLOC_CTX *mem_ctx,380 struct resolve_context *resolve_ctx,381 struct tevent_context *event_ctx,382 const char *socket_options);383 void smbcli_sock_dead(struct smbcli_socket *sock);384 385 340 #endif /* __LIBCLI_RAW__H__ */ -
vendor/current/source4/libcli/raw/raweas.c
r740 r988 244 244 } 245 245 246 if (ofs + next_ofs < ofs) { 247 return NT_STATUS_INVALID_PARAMETER; 248 } 249 246 250 ofs += next_ofs; 247 248 if (ofs+4 > blob->length) { 251 if (ofs+4 > blob->length || ofs+4 < ofs) { 249 252 return NT_STATUS_INVALID_PARAMETER; 250 253 } -
vendor/current/source4/libcli/raw/rawfile.c
r740 r988 29 29 if (!req) return NULL; \ 30 30 } while (0) 31 32 /**33 Return a string representing a CIFS attribute for a file.34 **/35 char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib)36 {37 int i, len;38 const struct {39 char c;40 uint16_t attr;41 } attr_strs[] = {42 {'V', FILE_ATTRIBUTE_VOLUME},43 {'D', FILE_ATTRIBUTE_DIRECTORY},44 {'A', FILE_ATTRIBUTE_ARCHIVE},45 {'H', FILE_ATTRIBUTE_HIDDEN},46 {'S', FILE_ATTRIBUTE_SYSTEM},47 {'N', FILE_ATTRIBUTE_NORMAL},48 {'R', FILE_ATTRIBUTE_READONLY},49 {'d', FILE_ATTRIBUTE_DEVICE},50 {'t', FILE_ATTRIBUTE_TEMPORARY},51 {'s', FILE_ATTRIBUTE_SPARSE},52 {'r', FILE_ATTRIBUTE_REPARSE_POINT},53 {'c', FILE_ATTRIBUTE_COMPRESSED},54 {'o', FILE_ATTRIBUTE_OFFLINE},55 {'n', FILE_ATTRIBUTE_NONINDEXED},56 {'e', FILE_ATTRIBUTE_ENCRYPTED}57 };58 char *ret;59 60 ret = talloc_array(mem_ctx, char, ARRAY_SIZE(attr_strs)+1);61 if (!ret) {62 return NULL;63 }64 65 for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) {66 if (attrib & attr_strs[i].attr) {67 ret[len++] = attr_strs[i].c;68 }69 }70 71 ret[len] = 0;72 73 talloc_set_name_const(ret, ret);74 75 return ret;76 }77 31 78 32 /**************************************************************************** … … 951 905 } 952 906 case RAW_LOCK_SMB2: 907 case RAW_LOCK_SMB2_BREAK: 953 908 return NULL; 954 909 } … … 979 934 struct smbcli_request *req; 980 935 981 SETUP_REQUEST(SMBch kpth, 0, 0);936 SETUP_REQUEST(SMBcheckpath, 0, 0); 982 937 983 938 smbcli_req_append_ascii4(req, parms->chkpath.in.path, STR_TERMINATE); -
vendor/current/source4/libcli/raw/rawfileinfo.c
r740 r988 52 52 bool ret; 53 53 void *vstr; 54 size_t converted_size = 0; 55 54 56 io->streams = 55 57 talloc_realloc(mem_ctx, io->streams, struct stream_struct, n+1); … … 65 67 ret = convert_string_talloc(io->streams, 66 68 CH_UTF16, CH_UNIX, 67 blob.data+ofs+24, nlen, &vstr, NULL, false);69 blob.data+ofs+24, nlen, &vstr, &converted_size); 68 70 if (!ret) { 69 71 return NT_STATUS_ILLEGAL_CHARACTER; -
vendor/current/source4/libcli/raw/rawfsinfo.c
r740 r988 34 34 35 35 req = smbcli_request_setup(tree, SMBdskattr, 0, 0); 36 if (req == NULL) { 37 return NULL; 38 } 36 39 37 40 if (!smbcli_request_send(req)) { … … 224 227 } 225 228 break; 229 230 case RAW_QFS_SECTOR_SIZE_INFORMATION: 231 QFS_CHECK_SIZE(28); 232 fsinfo->sector_size_info.out.logical_bytes_per_sector 233 = IVAL(blob.data, 0); 234 fsinfo->sector_size_info.out.phys_bytes_per_sector_atomic 235 = IVAL(blob.data, 4); 236 fsinfo->sector_size_info.out.phys_bytes_per_sector_perf 237 = IVAL(blob.data, 8); 238 fsinfo->sector_size_info.out.fs_effective_phys_bytes_per_sector_atomic 239 = IVAL(blob.data, 12); 240 fsinfo->sector_size_info.out.flags = IVAL(blob.data, 16); 241 fsinfo->sector_size_info.out.byte_off_sector_align 242 = IVAL(blob.data, 20); 243 fsinfo->sector_size_info.out.byte_off_partition_align 244 = IVAL(blob.data, 24); 245 break; 226 246 } 227 247 … … 317 337 return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, 318 338 RAW_QFS_OBJECTID_INFORMATION, fsinfo); 339 340 case RAW_QFS_SECTOR_SIZE_INFORMATION: 341 return smb_raw_fsinfo_passthru_parse(blob, mem_ctx, 342 RAW_QFS_SECTOR_SIZE_INFORMATION, fsinfo); 319 343 } 320 344 … … 333 357 return smb_raw_fsinfo_recv(req, mem_ctx, fsinfo); 334 358 } 359 360 /**************************************************************************** 361 Set FSInfo raw interface (async recv) 362 ****************************************************************************/ 363 static NTSTATUS smb_raw_setfsinfo_recv(struct smbcli_request *req, 364 TALLOC_CTX *mem_ctx, 365 union smb_setfsinfo *set_fsinfo) 366 { 367 DATA_BLOB blob = data_blob_null; 368 NTSTATUS status; 369 370 if (set_fsinfo->generic.level != RAW_SETFS_UNIX_INFO) { 371 return NT_STATUS_INVALID_PARAMETER; 372 } 373 374 status = smb_raw_qfsinfo_blob_recv(req, mem_ctx, &blob); 375 data_blob_free(&blob); 376 return status; 377 } 378 379 /**************************************************************************** 380 Set FSInfo raw interface (async send) 381 ****************************************************************************/ 382 static struct smbcli_request *smb_raw_setfsinfo_send(struct smbcli_tree *tree, 383 TALLOC_CTX *mem_ctx, 384 union smb_setfsinfo *set_fsinfo) 385 { 386 struct smb_trans2 tp; 387 uint16_t info_level; 388 uint16_t setup = TRANSACT2_SETFSINFO; 389 390 if (set_fsinfo->generic.level != RAW_SETFS_UNIX_INFO) { 391 return NULL; 392 } 393 tp.in.max_setup = 0; 394 tp.in.flags = 0; 395 tp.in.timeout = 0; 396 tp.in.setup_count = 1; 397 tp.in.max_param = 0; 398 tp.in.max_data = 0xFFFF; 399 tp.in.setup = &setup; 400 tp.in.timeout = 0; 401 402 tp.in.params = data_blob_talloc(mem_ctx, NULL, 4); 403 if (!tp.in.params.data) { 404 return NULL; 405 } 406 info_level = (uint16_t)set_fsinfo->generic.level; 407 SSVAL(tp.in.params.data, 0, 0); 408 SSVAL(tp.in.params.data, 2, info_level); 409 410 tp.in.data = data_blob_talloc(mem_ctx, NULL, 12); 411 if (!tp.in.data.data) { 412 return NULL; 413 } 414 415 SSVAL(tp.in.data.data, 0, set_fsinfo->unix_info.in.major_version); 416 SSVAL(tp.in.data.data, 2, set_fsinfo->unix_info.in.minor_version); 417 SBVAL(tp.in.data.data, 4, set_fsinfo->unix_info.in.capability); 418 419 return smb_raw_trans2_send(tree, &tp); 420 } 421 422 /**************************************************************************** 423 Set FSInfo raw interface (sync interface) 424 ****************************************************************************/ 425 _PUBLIC_ NTSTATUS smb_raw_setfsinfo(struct smbcli_tree *tree, 426 TALLOC_CTX *mem_ctx, 427 union smb_setfsinfo *set_fsinfo) 428 { 429 struct smbcli_request *req = smb_raw_setfsinfo_send(tree, mem_ctx, set_fsinfo); 430 return smb_raw_setfsinfo_recv(req, mem_ctx, set_fsinfo); 431 } -
vendor/current/source4/libcli/raw/rawnegotiate.c
r740 r988 22 22 23 23 #include "includes.h" 24 #include <tevent.h> 25 #include "system/time.h" 24 26 #include "libcli/raw/libcliraw.h" 25 27 #include "libcli/raw/raw_proto.h" 26 #include "system/time.h" 28 #include "../libcli/smb/smbXcli_base.h" 29 #include "../lib/util/tevent_ntstatus.h" 27 30 28 static const struct { 29 enum protocol_types prot; 30 const char *name; 31 } prots[] = { 32 {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, 33 {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, 34 {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, 35 {PROTOCOL_LANMAN1,"LANMAN1.0"}, 36 {PROTOCOL_LANMAN1,"Windows for Workgroups 3.1a"}, 37 {PROTOCOL_LANMAN2,"LM1.2X002"}, 38 {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, 39 {PROTOCOL_LANMAN2,"LANMAN2.1"}, 40 {PROTOCOL_LANMAN2,"Samba"}, 41 {PROTOCOL_NT1,"NT LANMAN 1.0"}, 42 {PROTOCOL_NT1,"NT LM 0.12"}, 43 #if 0 44 /* we don't yet handle chaining a SMB transport onto SMB2 */ 45 {PROTOCOL_SMB2,"SMB 2.002"}, 46 #endif 31 struct smb_raw_negotiate_state { 32 struct smbcli_transport *transport; 47 33 }; 48 34 49 /* 50 Send a negprot command. 51 */ 52 struct smbcli_request *smb_raw_negotiate_send(struct smbcli_transport *transport, 53 bool unicode, 54 int maxprotocol) 35 static void smb_raw_negotiate_done(struct tevent_req *subreq); 36 37 struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx, 38 struct tevent_context *ev, 39 struct smbcli_transport *transport, 40 int minprotocol, 41 int maxprotocol) 55 42 { 56 struct smbcli_request *req; 57 int i; 58 uint16_t flags2 = 0; 43 struct tevent_req *req; 44 struct smb_raw_negotiate_state *state; 45 struct tevent_req *subreq; 46 uint32_t timeout_msec = transport->options.request_timeout * 1000; 59 47 60 req = smbcli_request_setup_transport(transport, SMBnegprot, 0, 0); 61 if (!req) { 48 req = tevent_req_create(mem_ctx, &state, 49 struct smb_raw_negotiate_state);; 50 if (req == NULL) { 62 51 return NULL; 63 52 } 53 state->transport = transport; 64 54 65 flags2 |= FLAGS2_32_BIT_ERROR_CODES; 66 if (unicode) { 67 flags2 |= FLAGS2_UNICODE_STRINGS; 68 } 69 flags2 |= FLAGS2_EXTENDED_ATTRIBUTES; 70 flags2 |= FLAGS2_LONG_PATH_COMPONENTS; 71 flags2 |= FLAGS2_IS_LONG_NAME; 72 73 if (transport->options.use_spnego) { 74 flags2 |= FLAGS2_EXTENDED_SECURITY; 55 if (maxprotocol > PROTOCOL_NT1) { 56 maxprotocol = PROTOCOL_NT1; 75 57 } 76 58 77 SSVAL(req->out.hdr,HDR_FLG2, flags2); 59 subreq = smbXcli_negprot_send(state, ev, 60 transport->conn, 61 timeout_msec, 62 minprotocol, 63 maxprotocol); 64 if (tevent_req_nomem(subreq, req)) { 65 return tevent_req_post(req, ev); 66 } 67 tevent_req_set_callback(subreq, smb_raw_negotiate_done, req); 78 68 79 /* setup the protocol strings */ 80 for (i=0; i < ARRAY_SIZE(prots) && prots[i].prot <= maxprotocol; i++) { 81 smbcli_req_append_bytes(req, (const uint8_t *)"\2", 1); 82 smbcli_req_append_string(req, prots[i].name, STR_TERMINATE | STR_ASCII); 69 return req; 70 } 71 72 static void smb_raw_negotiate_done(struct tevent_req *subreq) 73 { 74 struct tevent_req *req = 75 tevent_req_callback_data(subreq, 76 struct tevent_req); 77 struct smb_raw_negotiate_state *state = 78 tevent_req_data(req, 79 struct smb_raw_negotiate_state); 80 struct smbcli_negotiate *n = &state->transport->negotiate; 81 struct smbXcli_conn *c = state->transport->conn; 82 NTSTATUS status; 83 NTTIME ntt; 84 85 status = smbXcli_negprot_recv(subreq); 86 TALLOC_FREE(subreq); 87 if (tevent_req_nterror(req, status)) { 88 return; 83 89 } 84 90 85 if (!smbcli_request_send(req)) { 86 smbcli_request_destroy(req); 87 return NULL; 91 n->protocol = smbXcli_conn_protocol(c); 92 93 n->sec_mode = smb1cli_conn_server_security_mode(c); 94 n->max_mux = smbXcli_conn_max_requests(c); 95 n->max_xmit = smb1cli_conn_max_xmit(c); 96 n->sesskey = smb1cli_conn_server_session_key(c); 97 n->capabilities = smb1cli_conn_capabilities(c);; 98 99 /* this time arrives in real GMT */ 100 ntt = smbXcli_conn_server_system_time(c); 101 n->server_time = nt_time_to_unix(ntt); 102 n->server_zone = smb1cli_conn_server_time_zone(c); 103 104 if (n->capabilities & CAP_EXTENDED_SECURITY) { 105 const DATA_BLOB *b = smbXcli_conn_server_gss_blob(c); 106 if (b) { 107 n->secblob = *b; 108 } 109 } else { 110 const uint8_t *p = smb1cli_conn_server_challenge(c); 111 if (p) { 112 n->secblob = data_blob_const(p, 8); 113 } 88 114 } 89 115 90 return req; 116 n->readbraw_supported = smb1cli_conn_server_readbraw(c); 117 n->readbraw_supported = smb1cli_conn_server_writebraw(c); 118 n->lockread_supported = smb1cli_conn_server_lockread(c); 119 120 tevent_req_done(req); 91 121 } 92 122 … … 94 124 Send a negprot command. 95 125 */ 96 NTSTATUS smb_raw_negotiate_recv(struct smbcli_request*req)126 NTSTATUS smb_raw_negotiate_recv(struct tevent_req *req) 97 127 { 98 struct smbcli_transport *transport = req->transport; 99 int protocol; 100 101 if (!smbcli_request_receive(req) || 102 smbcli_request_is_error(req)) { 103 return smbcli_request_destroy(req); 104 } 105 106 SMBCLI_CHECK_MIN_WCT(req, 1); 107 108 protocol = SVALS(req->in.vwv, VWV(0)); 109 110 if (protocol >= ARRAY_SIZE(prots) || protocol < 0) { 111 req->status = NT_STATUS_UNSUCCESSFUL; 112 return smbcli_request_destroy(req); 113 } 114 115 transport->negotiate.protocol = prots[protocol].prot; 116 117 if (transport->negotiate.protocol >= PROTOCOL_NT1) { 118 NTTIME ntt; 119 120 /* NT protocol */ 121 SMBCLI_CHECK_WCT(req, 17); 122 transport->negotiate.sec_mode = CVAL(req->in.vwv,VWV(1)); 123 transport->negotiate.max_mux = SVAL(req->in.vwv,VWV(1)+1); 124 transport->negotiate.max_xmit = IVAL(req->in.vwv,VWV(3)+1); 125 transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(7)+1); 126 transport->negotiate.capabilities = IVAL(req->in.vwv,VWV(9)+1); 127 128 /* this time arrives in real GMT */ 129 ntt = smbcli_pull_nttime(req->in.vwv, VWV(11)+1); 130 transport->negotiate.server_time = nt_time_to_unix(ntt); 131 transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(15)+1) * 60; 132 transport->negotiate.key_len = CVAL(req->in.vwv,VWV(16)+1); 133 134 if (transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) { 135 if (req->in.data_size < 16) { 136 goto failed; 137 } 138 transport->negotiate.server_guid = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, 16); 139 transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data + 16, req->in.data_size - 16); 140 } else { 141 if (req->in.data_size < (transport->negotiate.key_len)) { 142 goto failed; 143 } 144 transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, transport->negotiate.key_len); 145 smbcli_req_pull_string(&req->in.bufinfo, transport, &transport->negotiate.server_domain, 146 req->in.data+transport->negotiate.key_len, 147 req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN); 148 /* here comes the server name */ 149 } 150 151 if (transport->negotiate.capabilities & CAP_RAW_MODE) { 152 transport->negotiate.readbraw_supported = true; 153 transport->negotiate.writebraw_supported = true; 154 } 155 156 if (transport->negotiate.capabilities & CAP_LOCK_AND_READ) 157 transport->negotiate.lockread_supported = true; 158 } else if (transport->negotiate.protocol >= PROTOCOL_LANMAN1) { 159 SMBCLI_CHECK_WCT(req, 13); 160 transport->negotiate.sec_mode = SVAL(req->in.vwv,VWV(1)); 161 transport->negotiate.max_xmit = SVAL(req->in.vwv,VWV(2)); 162 transport->negotiate.sesskey = IVAL(req->in.vwv,VWV(6)); 163 transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(10)) * 60; 164 165 /* this time is converted to GMT by raw_pull_dos_date */ 166 transport->negotiate.server_time = raw_pull_dos_date(transport, 167 req->in.vwv+VWV(8)); 168 if ((SVAL(req->in.vwv,VWV(5)) & 0x1)) { 169 transport->negotiate.readbraw_supported = 1; 170 } 171 if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) { 172 transport->negotiate.writebraw_supported = 1; 173 } 174 transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, 175 req->in.data, req->in.data_size); 176 } else { 177 /* the old core protocol */ 178 transport->negotiate.sec_mode = 0; 179 transport->negotiate.server_time = time(NULL); 180 transport->negotiate.max_xmit = transport->options.max_xmit; 181 transport->negotiate.server_zone = get_time_zone(transport->negotiate.server_time); 182 } 183 184 /* a way to force ascii SMB */ 185 if (!transport->options.unicode) { 186 transport->negotiate.capabilities &= ~CAP_UNICODE; 187 } 188 189 if (!transport->options.ntstatus_support) { 190 transport->negotiate.capabilities &= ~CAP_STATUS32; 191 } 192 193 if (!transport->options.use_level2_oplocks) { 194 transport->negotiate.capabilities &= ~CAP_LEVEL_II_OPLOCKS; 195 } 196 197 failed: 198 return smbcli_request_destroy(req); 128 return tevent_req_simple_recv_ntstatus(req); 199 129 } 200 130 … … 203 133 Send a negprot command (sync interface) 204 134 */ 205 NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, int maxprotocol) 135 NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, 136 int minprotocol, int maxprotocol) 206 137 { 207 struct smbcli_request *req = smb_raw_negotiate_send(transport, unicode, maxprotocol); 208 return smb_raw_negotiate_recv(req); 138 NTSTATUS status = NT_STATUS_INTERNAL_ERROR; 139 struct tevent_req *subreq = NULL; 140 bool ok; 141 142 subreq = smb_raw_negotiate_send(transport, 143 transport->ev, 144 transport, 145 minprotocol, 146 maxprotocol); 147 if (subreq == NULL) { 148 return NT_STATUS_NO_MEMORY; 149 } 150 151 ok = tevent_req_poll(subreq, transport->ev); 152 if (!ok) { 153 status = map_nt_error_from_unix_common(errno); 154 goto failed; 155 } 156 157 status = smb_raw_negotiate_recv(subreq); 158 159 failed: 160 TALLOC_FREE(subreq); 161 return status; 209 162 } -
vendor/current/source4/libcli/raw/rawnotify.c
r740 r988 19 19 20 20 #include "includes.h" 21 #include <tevent.h> 21 22 #include "libcli/raw/libcliraw.h" 22 23 #include "libcli/raw/raw_proto.h" 23 #include "../lib/util/dlinklist.h"24 24 25 25 /**************************************************************************** … … 102 102 103 103 /**************************************************************************** 104 handle ntcancel replies from the server,105 as the MID of the real reply and the ntcancel reply is the same106 we need to do find out to what request the reply belongs107 ****************************************************************************/108 struct smbcli_request *smbcli_handle_ntcancel_reply(struct smbcli_request *req,109 size_t len, const uint8_t *hdr)110 {111 struct smbcli_request *ntcancel;112 113 if (!req) return req;114 115 if (!req->ntcancel) return req;116 117 if (len >= MIN_SMB_SIZE + NBT_HDR_SIZE &&118 (CVAL(hdr, HDR_FLG) & FLAG_REPLY) &&119 CVAL(hdr,HDR_COM) == SMBntcancel) {120 ntcancel = req->ntcancel;121 DLIST_REMOVE(req->ntcancel, ntcancel);122 123 /*124 * TODO: untill we understand how the125 * smb_signing works for this case we126 * return NULL, to just ignore the packet127 */128 /*return ntcancel;*/129 return NULL;130 }131 132 return req;133 }134 135 /****************************************************************************136 104 Send a NT Cancel request - used to hurry along a pending request. Usually 137 105 used to cancel a pending change notify request … … 140 108 NTSTATUS smb_raw_ntcancel(struct smbcli_request *oldreq) 141 109 { 142 struct smbcli_request *req;110 bool ok; 143 111 144 req = smbcli_request_setup_transport(oldreq->transport, SMBntcancel, 0, 0); 112 if (oldreq->subreqs[0] == NULL) { 113 return NT_STATUS_OK; 114 } 145 115 146 SSVAL(req->out.hdr, HDR_MID, SVAL(oldreq->out.hdr, HDR_MID)); 147 SSVAL(req->out.hdr, HDR_PID, SVAL(oldreq->out.hdr, HDR_PID)); 148 SSVAL(req->out.hdr, HDR_TID, SVAL(oldreq->out.hdr, HDR_TID)); 149 SSVAL(req->out.hdr, HDR_UID, SVAL(oldreq->out.hdr, HDR_UID)); 150 151 /* this request does not expect a reply, so tell the signing 152 subsystem not to allocate an id for a reply */ 153 req->sign_single_increment = 1; 154 req->one_way_request = 1; 155 156 /* 157 * smbcli_request_send() free's oneway requests 158 * but we want to keep it under oldreq->ntcancel 159 */ 160 req->do_not_free = true; 161 talloc_steal(oldreq, req); 162 163 smbcli_request_send(req); 164 165 DLIST_ADD_END(oldreq->ntcancel, req, struct smbcli_request *); 116 ok = tevent_req_cancel(oldreq->subreqs[0]); 117 if (!ok) { 118 return NT_STATUS_INTERNAL_ERROR; 119 } 166 120 167 121 return NT_STATUS_OK; -
vendor/current/source4/libcli/raw/rawreadwrite.c
r414 r988 105 105 } 106 106 107 /* the transport layer needs to know that a readbraw is pending108 and handle receives a little differently */109 if (parms->generic.level == RAW_READ_READBRAW) {110 tree->session->transport->readbraw_pending = 1;111 }112 113 107 return req; 114 108 } … … 162 156 parms->readx.out.compaction_mode = SVAL(req->in.vwv, VWV(3)); 163 157 parms->readx.out.nread = SVAL(req->in.vwv, VWV(5)); 158 parms->readx.out.flags2 = req->flags2; 159 parms->readx.out.data_offset = SVAL(req->in.vwv, VWV(6)); 164 160 165 161 /* handle oversize replies for non-chained readx replies with … … 303 299 raw write interface (async recv) 304 300 ****************************************************************************/ 305 NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms)301 _PUBLIC_ NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms) 306 302 { 307 303 if (!smbcli_request_receive(req) || -
vendor/current/source4/libcli/raw/rawrequest.c
r740 r988 26 26 #include "libcli/raw/libcliraw.h" 27 27 #include "libcli/raw/raw_proto.h" 28 #include "../lib/util/dlinklist.h"29 28 #include "lib/events/events.h" 30 29 #include "librpc/ndr/libndr.h" 31 30 #include "librpc/gen_ndr/ndr_misc.h" 31 #include "../libcli/smb/smbXcli_base.h" 32 32 33 33 /* we over allocate the data buffer to prevent too many realloc calls */ … … 60 60 if (!req) return NT_STATUS_UNSUCCESSFUL; 61 61 62 if (req->transport) {63 /* remove it from the list of pending requests (a null op if64 its not in the list) */65 DLIST_REMOVE(req->transport->pending_recv, req);66 }67 68 62 if (req->state == SMBCLI_REQUEST_ERROR && 69 63 NT_STATUS_IS_OK(req->status)) { … … 82 76 83 77 /* 84 low-level function to setup a request buffer for a non-SMB packet85 at the transport level 86 */ 87 struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *transport, size_t size)78 setup a SMB packet at transport level 79 */ 80 struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport, 81 uint8_t command, unsigned int wct, unsigned int buflen) 88 82 { 89 83 struct smbcli_request *req; 90 91 req = talloc(transport, struct smbcli_request); 84 size_t size; 85 86 size = NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen; 87 88 req = talloc_zero(transport, struct smbcli_request); 92 89 if (!req) { 93 90 return NULL; 94 91 } 95 ZERO_STRUCTP(req);96 92 97 93 /* setup the request context */ 98 94 req->state = SMBCLI_REQUEST_INIT; 99 95 req->transport = transport; 100 req->session = NULL;101 req->tree = NULL;102 96 req->out.size = size; 103 97 … … 105 99 req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; 106 100 107 req->out.buffer = talloc_ array(req, uint8_t, req->out.allocated);101 req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated); 108 102 if (!req->out.buffer) { 109 103 return NULL; 110 104 } 111 105 112 SIVAL(req->out.buffer, 0, 0);113 114 return req;115 }116 117 118 /*119 setup a SMB packet at transport level120 */121 struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,122 uint8_t command, unsigned int wct, unsigned int buflen)123 {124 struct smbcli_request *req;125 126 req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen);127 128 if (!req) return NULL;129 130 106 req->out.hdr = req->out.buffer + NBT_HDR_SIZE; 131 107 req->out.vwv = req->out.hdr + HDR_VWV; … … 144 120 SSVAL(req->out.hdr,HDR_FLG2, 0); 145 121 146 if (command != SMBtranss && command != SMBtranss2) {147 /* assign a mid */148 req->mid = smbcli_transport_next_mid(transport);149 }150 151 122 /* copy the pid, uid and mid to the request */ 152 123 SSVAL(req->out.hdr, HDR_PID, 0); 153 124 SSVAL(req->out.hdr, HDR_UID, 0); 154 SSVAL(req->out.hdr, HDR_MID, req->mid);125 SSVAL(req->out.hdr, HDR_MID, 0); 155 126 SSVAL(req->out.hdr, HDR_TID,0); 156 127 SSVAL(req->out.hdr, HDR_PIDHIGH,0); … … 176 147 if (!req) return NULL; 177 148 149 smb1cli_session_set_id(session->smbXcli, session->vuid); 150 178 151 req->session = session; 179 152 … … 197 170 req = smbcli_request_setup_session(tree->session, command, wct, buflen); 198 171 if (req) { 172 smb1cli_tcon_set_id(tree->smbXcli, tree->tid); 173 199 174 req->tree = tree; 200 175 SSVAL(req->out.hdr,HDR_TID,tree->tid); … … 277 252 unsigned int wct, size_t buflen) 278 253 { 279 unsigned int new_size = 1 + (wct*2) + 2 + buflen; 280 281 SSVAL(req->out.vwv, VWV(0), command); 282 SSVAL(req->out.vwv, VWV(1), req->out.size - NBT_HDR_SIZE); 283 284 smbcli_req_grow_allocation(req, req->out.data_size + new_size); 285 286 req->out.vwv = req->out.buffer + req->out.size + 1; 287 SCVAL(req->out.vwv, -1, wct); 254 size_t wct_ofs; 255 size_t size; 256 257 /* 258 * here we only support one chained command 259 * If someone needs longer chains, the low 260 * level code should be used directly. 261 */ 262 if (req->subreqs[0] != NULL) { 263 return NT_STATUS_INVALID_PARAMETER_MIX; 264 } 265 if (req->subreqs[1] != NULL) { 266 return NT_STATUS_INVALID_PARAMETER_MIX; 267 } 268 269 req->subreqs[0] = smbcli_transport_setup_subreq(req); 270 if (req->subreqs[0] == NULL) { 271 return NT_STATUS_NO_MEMORY; 272 } 273 274 wct_ofs = smb1cli_req_wct_ofs(req->subreqs, 1); 275 276 size = NBT_HDR_SIZE + wct_ofs + 1 + VWV(wct) + 2 + buflen; 277 278 req->out.size = size; 279 280 /* over allocate by a small amount */ 281 req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; 282 283 req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated); 284 if (!req->out.buffer) { 285 return NT_STATUS_NO_MEMORY; 286 } 287 288 req->out.hdr = req->out.buffer + NBT_HDR_SIZE; 289 req->out.vwv = req->out.hdr + wct_ofs; 290 req->out.wct = wct; 291 req->out.data = req->out.vwv + VWV(wct) + 2; 292 req->out.data_size = buflen; 293 req->out.ptr = req->out.data; 294 295 SCVAL(req->out.hdr, HDR_WCT, wct); 288 296 SSVAL(req->out.vwv, VWV(wct), buflen); 289 297 290 req->out.size += new_size; 291 req->out.data_size += new_size; 298 memcpy(req->out.hdr, "\377SMB", 4); 299 SCVAL(req->out.hdr,HDR_COM,command); 300 301 SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES); 302 SSVAL(req->out.hdr,HDR_FLG2, 0); 303 304 /* copy the pid, uid and mid to the request */ 305 SSVAL(req->out.hdr, HDR_PID, 0); 306 SSVAL(req->out.hdr, HDR_UID, 0); 307 SSVAL(req->out.hdr, HDR_MID, 0); 308 SSVAL(req->out.hdr, HDR_TID,0); 309 SSVAL(req->out.hdr, HDR_PIDHIGH,0); 310 SIVAL(req->out.hdr, HDR_RCLS, 0); 311 memset(req->out.hdr+HDR_SS_FIELD, 0, 10); 312 313 if (req->session != NULL) { 314 SSVAL(req->out.hdr, HDR_FLG2, req->session->flags2); 315 SSVAL(req->out.hdr, HDR_PID, req->session->pid & 0xFFFF); 316 SSVAL(req->out.hdr, HDR_PIDHIGH, req->session->pid >> 16); 317 SSVAL(req->out.hdr, HDR_UID, req->session->vuid); 318 } 319 320 if (req->tree != NULL) { 321 SSVAL(req->out.hdr, HDR_TID, req->tree->tid); 322 } 292 323 293 324 return NT_STATUS_OK; … … 295 326 296 327 /* 297 a advance to the next chained reply in a request328 advance to the next chained reply in a request 298 329 */ 299 330 NTSTATUS smbcli_chained_advance(struct smbcli_request *req) 300 331 { 301 uint8_t *buffer; 302 303 if (CVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE) { 304 return NT_STATUS_NOT_FOUND; 305 } 306 307 buffer = req->in.hdr + SVAL(req->in.vwv, VWV(1)); 308 309 if (buffer + 3 > req->in.buffer + req->in.size) { 310 return NT_STATUS_BUFFER_TOO_SMALL; 311 } 312 313 req->in.vwv = buffer + 1; 314 req->in.wct = CVAL(buffer, 0); 315 if (buffer + 3 + req->in.wct*2 > req->in.buffer + req->in.size) { 316 return NT_STATUS_BUFFER_TOO_SMALL; 317 } 318 req->in.data = req->in.vwv + 2 + req->in.wct * 2; 319 req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct)); 320 321 /* fix the bufinfo */ 332 struct smbcli_transport *transport = req->transport; 333 uint8_t *hdr = NULL; 334 uint8_t wct = 0; 335 uint16_t *vwv = NULL; 336 uint32_t num_bytes = 0; 337 uint8_t *bytes = NULL; 338 struct iovec *recv_iov = NULL; 339 uint8_t *inbuf = NULL; 340 341 if (req->subreqs[0] != NULL) { 342 return NT_STATUS_INVALID_PARAMETER_MIX; 343 } 344 if (req->subreqs[1] == NULL) { 345 return NT_STATUS_INVALID_PARAMETER_MIX; 346 } 347 348 req->status = smb1cli_req_recv(req->subreqs[1], req, 349 &recv_iov, 350 &hdr, 351 &wct, 352 &vwv, 353 NULL, /* pvwv_offset */ 354 &num_bytes, 355 &bytes, 356 NULL, /* pbytes_offset */ 357 &inbuf, 358 NULL, 0); /* expected */ 359 TALLOC_FREE(req->subreqs[1]); 360 if (!NT_STATUS_IS_OK(req->status)) { 361 if (recv_iov == NULL) { 362 req->state = SMBCLI_REQUEST_ERROR; 363 return req->status; 364 } 365 } 366 367 /* fill in the 'in' portion of the matching request */ 368 req->in.buffer = inbuf; 369 req->in.size = NBT_HDR_SIZE + PTR_DIFF(bytes, hdr) + num_bytes; 370 req->in.allocated = req->in.size; 371 372 req->in.hdr = hdr; 373 req->in.vwv = (uint8_t *)vwv; 374 req->in.wct = wct; 375 req->in.data = bytes; 376 req->in.data_size = num_bytes; 377 req->in.ptr = req->in.data; 378 req->flags2 = SVAL(req->in.hdr, HDR_FLG2); 379 322 380 smb_setup_bufinfo(req); 323 381 324 if (buffer + 3 + req->in.wct*2 + req->in.data_size > 325 req->in.buffer + req->in.size) { 326 return NT_STATUS_BUFFER_TOO_SMALL; 327 } 382 transport->error.e.nt_status = req->status; 383 if (NT_STATUS_IS_OK(req->status)) { 384 transport->error.etype = ETYPE_NONE; 385 } else { 386 transport->error.etype = ETYPE_SMB; 387 } 388 389 req->state = SMBCLI_REQUEST_DONE; 328 390 329 391 return NT_STATUS_OK; … … 336 398 bool smbcli_request_send(struct smbcli_request *req) 337 399 { 338 if (IVAL(req->out.buffer, 0) == 0) {339 _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);340 }341 342 smbcli_request_calculate_sign_mac(req);343 344 400 smbcli_transport_send(req); 345 346 401 return true; 347 402 } … … 359 414 /* keep receiving packets until this one is replied to */ 360 415 while (req->state <= SMBCLI_REQUEST_RECV) { 361 if ( event_loop_once(req->transport->socket->event.ctx) != 0) {416 if (tevent_loop_once(req->transport->ev) != 0) { 362 417 return false; 363 418 } … … 365 420 366 421 return req->state == SMBCLI_REQUEST_DONE; 367 }368 369 370 /*371 handle oplock break requests from the server - return true if the request was372 an oplock break373 */374 bool smbcli_handle_oplock_break(struct smbcli_transport *transport, unsigned int len, const uint8_t *hdr, const uint8_t *vwv)375 {376 /* we must be very fussy about what we consider an oplock break to avoid377 matching readbraw replies */378 if (len != MIN_SMB_SIZE + VWV(8) + NBT_HDR_SIZE ||379 (CVAL(hdr, HDR_FLG) & FLAG_REPLY) ||380 CVAL(hdr,HDR_COM) != SMBlockingX ||381 SVAL(hdr, HDR_MID) != 0xFFFF ||382 SVAL(vwv,VWV(6)) != 0 ||383 SVAL(vwv,VWV(7)) != 0) {384 return false;385 }386 387 if (transport->oplock.handler) {388 uint16_t tid = SVAL(hdr, HDR_TID);389 uint16_t fnum = SVAL(vwv,VWV(2));390 uint8_t level = CVAL(vwv,VWV(3)+1);391 transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private_data);392 }393 394 return true;395 422 } 396 423 … … 587 614 } 588 615 589 ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest, &ret_size , false);616 ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest, &ret_size); 590 617 if (!ret) { 591 618 *dest = NULL; … … 630 657 } 631 658 632 ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)dest, &ret_size , false);659 ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)dest, &ret_size); 633 660 634 661 if (!ret) { … … 784 811 src_len2 = utf16_len_n(src, src_len); 785 812 786 ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2, &ret_size , false);813 ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2, &ret_size); 787 814 if (!ret) { 788 815 *dest = NULL; … … 831 858 } 832 859 833 ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2, &ret_size , false);860 ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2, &ret_size); 834 861 835 862 if (!ret) { -
vendor/current/source4/libcli/raw/rawsearch.c
r740 r988 457 457 &data->id_both_directory_info.short_name, 458 458 68, 70, STR_LEN8BIT | STR_UNICODE); 459 memcpy(data->id_both_directory_info.short_name_buf, blob->data + 70, 24); 459 460 data->id_both_directory_info.file_id = BVAL(blob->data, 96); 460 461 len = smbcli_blob_pull_string(NULL, mem_ctx, blob, -
vendor/current/source4/libcli/raw/rawsetfileinfo.c
r740 r988 80 80 NEED_BLOB(20); 81 81 SIVAL(blob->data, 0, parms->rename_information.in.overwrite); 82 SIVAL(blob->data, 4, 0); 82 83 SBVAL(blob->data, 8, parms->rename_information.in.root_fid); 83 84 len = smbcli_blob_append_string(NULL, mem_ctx, blob, … … 263 264 parms, blob); 264 265 265 /* Unhandled levels */ 266 266 /* Unhandled levels */ 267 267 case RAW_SFILEINFO_UNIX_LINK: 268 268 case RAW_SFILEINFO_UNIX_HLINK: 269 269 case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: 270 case RAW_SFILEINFO_LINK_INFORMATION: 270 271 break; 271 272 } -
vendor/current/source4/libcli/raw/rawshadow.c
r414 r988 23 23 #include "libcli/raw/libcliraw.h" 24 24 #include "libcli/raw/raw_proto.h" 25 #include " libcli/raw/ioctl.h"25 #include "../libcli/smb/smb_constants.h" 26 26 27 27 /* -
vendor/current/source4/libcli/raw/rawtrans.c
r740 r988 20 20 21 21 #include "includes.h" 22 #include "../lib/util/dlinklist.h"22 #include <tevent.h> 23 23 #include "libcli/raw/libcliraw.h" 24 24 #include "libcli/raw/raw_proto.h" 25 26 #define TORTURE_TRANS_DATA 0 27 28 /* 29 check out of bounds for incoming data 30 */ 31 static bool raw_trans_oob(struct smbcli_request *req, 32 unsigned int offset, unsigned int count) 33 { 34 uint8_t *ptr; 35 36 if (count == 0) { 37 return false; 38 } 39 40 ptr = req->in.hdr + offset; 41 42 /* be careful with wraparound! */ 43 if ((uintptr_t)ptr < (uintptr_t)req->in.data || 44 (uintptr_t)ptr >= (uintptr_t)req->in.data + req->in.data_size || 45 count > req->in.data_size || 46 (uintptr_t)ptr + count > (uintptr_t)req->in.data + req->in.data_size) { 47 return true; 48 } 49 return false; 50 } 51 52 static size_t raw_trans_space_left(struct smbcli_request *req) 53 { 54 if (req->transport->negotiate.max_xmit <= req->out.size) { 55 return 0; 56 } 57 58 return req->transport->negotiate.max_xmit - req->out.size; 59 } 60 61 struct smb_raw_trans2_recv_state { 62 uint8_t command; 63 uint32_t params_total; 64 uint32_t data_total; 65 uint32_t params_left; 66 uint32_t data_left; 67 bool got_first; 68 uint32_t recvd_data; 69 uint32_t recvd_param; 70 struct smb_trans2 io; 71 }; 25 #include "../libcli/smb/smbXcli_base.h" 26 27 static void smb_raw_trans_backend_done(struct tevent_req *subreq); 28 29 static struct smbcli_request *smb_raw_trans_backend_send(struct smbcli_tree *tree, 30 struct smb_trans2 *parms, 31 uint8_t command) 32 { 33 struct smbcli_request *req; 34 uint8_t additional_flags; 35 uint8_t clear_flags; 36 uint16_t additional_flags2; 37 uint16_t clear_flags2; 38 uint32_t pid; 39 struct smbXcli_tcon *tcon = NULL; 40 struct smbXcli_session *session = NULL; 41 const char *pipe_name = NULL; 42 uint8_t s; 43 uint32_t timeout_msec; 44 uint32_t tmp; 45 46 tmp = parms->in.params.length + parms->in.data.length; 47 48 req = smbcli_request_setup(tree, command, parms->in.setup_count, tmp); 49 if (req == NULL) { 50 return NULL; 51 } 52 53 additional_flags = CVAL(req->out.hdr, HDR_FLG); 54 additional_flags2 = SVAL(req->out.hdr, HDR_FLG2); 55 pid = SVAL(req->out.hdr, HDR_PID); 56 pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16; 57 58 if (req->session) { 59 session = req->session->smbXcli; 60 } 61 62 if (req->tree) { 63 tcon = req->tree->smbXcli; 64 } 65 66 clear_flags = ~additional_flags; 67 clear_flags2 = ~additional_flags2; 68 69 timeout_msec = req->transport->options.request_timeout * 1000; 70 71 for (s=0; s < parms->in.setup_count; s++) { 72 SSVAL(req->out.vwv, VWV(s), parms->in.setup[s]); 73 } 74 75 memcpy(req->out.data, 76 parms->in.params.data, 77 parms->in.params.length); 78 memcpy(req->out.data + parms->in.params.length, 79 parms->in.data.data, 80 parms->in.data.length); 81 82 if (command == SMBtrans && parms->in.trans_name) { 83 pipe_name = parms->in.trans_name; 84 } 85 86 req->subreqs[0] = smb1cli_trans_send(req, 87 req->transport->ev, 88 req->transport->conn, 89 command, 90 additional_flags, 91 clear_flags, 92 additional_flags2, 93 clear_flags2, 94 timeout_msec, 95 pid, 96 tcon, 97 session, 98 pipe_name, 99 0xFFFF, /* fid */ 100 0, /* function */ 101 parms->in.flags, 102 (uint16_t *)req->out.vwv, 103 parms->in.setup_count, 104 parms->in.max_setup, 105 req->out.data, 106 parms->in.params.length, 107 parms->in.max_param, 108 req->out.data+ 109 parms->in.params.length, 110 parms->in.data.length, 111 parms->in.max_data); 112 if (req->subreqs[0] == NULL) { 113 talloc_free(req); 114 return NULL; 115 } 116 tevent_req_set_callback(req->subreqs[0], 117 smb_raw_trans_backend_done, 118 req); 119 120 return req; 121 } 122 123 static void smb_raw_trans_backend_done(struct tevent_req *subreq) 124 { 125 struct smbcli_request *req = 126 tevent_req_callback_data(subreq, 127 struct smbcli_request); 128 struct smbcli_transport *transport = req->transport; 129 uint16_t *setup = NULL; 130 uint8_t num_setup = 0; 131 uint8_t s; 132 uint8_t *param = NULL; 133 uint32_t num_param = 0; 134 uint8_t *data = NULL; 135 uint32_t num_data = 0; 136 137 req->status = smb1cli_trans_recv(req->subreqs[0], req, 138 &req->flags2, 139 &setup, 140 0, /* min_setup */ 141 &num_setup, 142 ¶m, 143 0, /* min_param */ 144 &num_param, 145 &data, 146 0, /* min_data */ 147 &num_data); 148 TALLOC_FREE(req->subreqs[0]); 149 if (NT_STATUS_IS_ERR(req->status)) { 150 req->state = SMBCLI_REQUEST_ERROR; 151 transport->error.e.nt_status = req->status; 152 transport->error.etype = ETYPE_SMB; 153 if (req->async.fn) { 154 req->async.fn(req); 155 } 156 return; 157 } 158 159 req->trans2.out.setup_count = num_setup; 160 req->trans2.out.setup = talloc_array(req, uint16_t, num_setup); 161 if (req->trans2.out.setup == NULL) { 162 req->state = SMBCLI_REQUEST_ERROR; 163 req->status = NT_STATUS_NO_MEMORY; 164 transport->error.e.nt_status = req->status; 165 transport->error.etype = ETYPE_SMB; 166 if (req->async.fn) { 167 req->async.fn(req); 168 } 169 return; 170 } 171 for (s = 0; s < num_setup; s++) { 172 req->trans2.out.setup[s] = SVAL(setup, VWV(s)); 173 } 174 175 req->trans2.out.params.data = param; 176 req->trans2.out.params.length = num_param; 177 178 req->trans2.out.data.data = data; 179 req->trans2.out.data.length = num_data; 180 181 transport->error.e.nt_status = req->status; 182 if (NT_STATUS_IS_OK(req->status)) { 183 transport->error.etype = ETYPE_NONE; 184 } else { 185 transport->error.etype = ETYPE_SMB; 186 } 187 188 req->state = SMBCLI_REQUEST_DONE; 189 if (req->async.fn) { 190 req->async.fn(req); 191 } 192 } 193 194 static NTSTATUS smb_raw_trans_backend_recv(struct smbcli_request *req, 195 TALLOC_CTX *mem_ctx, 196 struct smb_trans2 *parms) 197 { 198 if (!smbcli_request_receive(req) || 199 smbcli_request_is_error(req)) { 200 goto failed; 201 } 202 203 parms->out = req->trans2.out; 204 talloc_steal(mem_ctx, parms->out.setup); 205 talloc_steal(mem_ctx, parms->out.params.data); 206 talloc_steal(mem_ctx, parms->out.data.data); 207 208 failed: 209 return smbcli_request_destroy(req); 210 } 211 212 _PUBLIC_ struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree, 213 struct smb_trans2 *parms) 214 { 215 return smb_raw_trans_backend_send(tree, parms, SMBtrans); 216 } 217 218 _PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req, 219 TALLOC_CTX *mem_ctx, 220 struct smb_trans2 *parms) 221 { 222 return smb_raw_trans_backend_recv(req, mem_ctx, parms); 223 } 224 225 _PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree, 226 TALLOC_CTX *mem_ctx, 227 struct smb_trans2 *parms) 228 { 229 struct smbcli_request *req; 230 req = smb_raw_trans_send(tree, parms); 231 if (!req) return NT_STATUS_UNSUCCESSFUL; 232 return smb_raw_trans_recv(req, mem_ctx, parms); 233 } 234 235 struct smbcli_request *smb_raw_trans2_send(struct smbcli_tree *tree, 236 struct smb_trans2 *parms) 237 { 238 return smb_raw_trans_backend_send(tree, parms, SMBtrans2); 239 } 72 240 73 241 NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req, … … 75 243 struct smb_trans2 *parms) 76 244 { 77 struct smb_raw_trans2_recv_state *state; 78 79 if (!smbcli_request_receive(req) || 80 smbcli_request_is_error(req)) { 81 goto failed; 82 } 83 84 state = talloc_get_type(req->recv_helper.private_data, 85 struct smb_raw_trans2_recv_state); 86 87 parms->out = state->io.out; 88 talloc_steal(mem_ctx, parms->out.setup); 89 talloc_steal(mem_ctx, parms->out.params.data); 90 talloc_steal(mem_ctx, parms->out.data.data); 91 talloc_free(state); 92 93 ZERO_STRUCT(req->recv_helper); 94 95 failed: 96 return smbcli_request_destroy(req); 97 } 98 99 static enum smbcli_request_state smb_raw_trans2_ship_rest(struct smbcli_request *req, 100 struct smb_raw_trans2_recv_state *state); 101 102 /* 103 * This helper returns SMBCLI_REQUEST_RECV until all data has arrived 104 */ 105 static enum smbcli_request_state smb_raw_trans2_recv_helper(struct smbcli_request *req) 106 { 107 struct smb_raw_trans2_recv_state *state = talloc_get_type(req->recv_helper.private_data, 108 struct smb_raw_trans2_recv_state); 109 uint16_t param_count, param_ofs, param_disp; 110 uint16_t data_count, data_ofs, data_disp; 111 uint16_t total_data, total_param; 112 uint8_t setup_count; 113 114 /* 115 * An NT RPC pipe call can return ERRDOS, ERRmoredata 116 * to a trans call. This is not an error and should not 117 * be treated as such. 118 */ 119 if (smbcli_request_is_error(req)) { 120 goto failed; 121 } 122 123 if (state->params_left > 0 || state->data_left > 0) { 124 return smb_raw_trans2_ship_rest(req, state); 125 } 126 127 SMBCLI_CHECK_MIN_WCT(req, 10); 128 129 total_data = SVAL(req->in.vwv, VWV(1)); 130 total_param = SVAL(req->in.vwv, VWV(0)); 131 setup_count = CVAL(req->in.vwv, VWV(9)); 132 133 param_count = SVAL(req->in.vwv, VWV(3)); 134 param_ofs = SVAL(req->in.vwv, VWV(4)); 135 param_disp = SVAL(req->in.vwv, VWV(5)); 136 137 data_count = SVAL(req->in.vwv, VWV(6)); 138 data_ofs = SVAL(req->in.vwv, VWV(7)); 139 data_disp = SVAL(req->in.vwv, VWV(8)); 140 141 if (!state->got_first) { 142 if (total_param > 0) { 143 state->io.out.params = data_blob_talloc(state, NULL, total_param); 144 if (!state->io.out.params.data) { 145 goto nomem; 146 } 147 } 148 149 if (total_data > 0) { 150 state->io.out.data = data_blob_talloc(state, NULL, total_data); 151 if (!state->io.out.data.data) { 152 goto nomem; 153 } 154 } 155 156 if (setup_count > 0) { 157 uint16_t i; 158 159 SMBCLI_CHECK_WCT(req, 10 + setup_count); 160 161 state->io.out.setup_count = setup_count; 162 state->io.out.setup = talloc_array(state, uint16_t, setup_count); 163 if (!state->io.out.setup) { 164 goto nomem; 165 } 166 for (i=0; i < setup_count; i++) { 167 state->io.out.setup[i] = SVAL(req->in.vwv, VWV(10+i)); 168 } 169 } 170 171 state->got_first = true; 172 } 173 174 if (total_data > state->io.out.data.length || 175 total_param > state->io.out.params.length) { 176 /* they must *only* shrink */ 177 DEBUG(1,("smb_raw_trans2_recv_helper: data/params expanded!\n")); 178 req->status = NT_STATUS_BUFFER_TOO_SMALL; 179 goto failed; 180 } 181 182 state->io.out.data.length = total_data; 183 state->io.out.params.length = total_param; 184 185 if (data_count + data_disp > total_data || 186 param_count + param_disp > total_param) { 187 DEBUG(1,("smb_raw_trans2_recv_helper: Buffer overflow\n")); 188 req->status = NT_STATUS_BUFFER_TOO_SMALL; 189 goto failed; 190 } 191 192 /* check the server isn't being nasty */ 193 if (raw_trans_oob(req, param_ofs, param_count) || 194 raw_trans_oob(req, data_ofs, data_count)) { 195 DEBUG(1,("smb_raw_trans2_recv_helper: out of bounds parameters!\n")); 196 req->status = NT_STATUS_BUFFER_TOO_SMALL; 197 goto failed; 198 } 199 200 if (data_count) { 201 memcpy(state->io.out.data.data + data_disp, 202 req->in.hdr + data_ofs, 203 data_count); 204 } 205 206 if (param_count) { 207 memcpy(state->io.out.params.data + param_disp, 208 req->in.hdr + param_ofs, 209 param_count); 210 } 211 212 state->recvd_param += param_count; 213 state->recvd_data += data_count; 214 215 if (state->recvd_data < total_data || 216 state->recvd_param < total_param) { 217 218 /* we don't need the in buffer any more */ 219 talloc_free(req->in.buffer); 220 ZERO_STRUCT(req->in); 221 222 /* we still wait for more data */ 223 DEBUG(10,("smb_raw_trans2_recv_helper: more data needed\n")); 224 return SMBCLI_REQUEST_RECV; 225 } 226 227 DEBUG(10,("smb_raw_trans2_recv_helper: done\n")); 228 return SMBCLI_REQUEST_DONE; 229 230 nomem: 231 req->status = NT_STATUS_NO_MEMORY; 232 failed: 233 return SMBCLI_REQUEST_ERROR; 234 } 235 236 _PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req, 237 TALLOC_CTX *mem_ctx, 238 struct smb_trans2 *parms) 239 { 240 return smb_raw_trans2_recv(req, mem_ctx, parms); 241 } 242 243 244 /* 245 trans/trans2 raw async interface - only BLOBs used in this interface. 246 */ 247 struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree, 248 struct smb_trans2 *parms, 249 uint8_t command) 250 { 251 struct smb_raw_trans2_recv_state *state; 252 struct smbcli_request *req; 253 int i; 254 int padding; 255 size_t space_left; 256 size_t namelen = 0; 257 DATA_BLOB params_chunk; 258 uint16_t ofs; 259 uint16_t params_ofs = 0; 260 DATA_BLOB data_chunk; 261 uint16_t data_ofs = 0; 262 263 if (parms->in.params.length > UINT16_MAX || 264 parms->in.data.length > UINT16_MAX) { 265 DEBUG(3,("Attempt to send invalid trans2 request (params %u, data %u)\n", 266 (unsigned)parms->in.params.length, (unsigned)parms->in.data.length)); 267 return NULL; 268 } 269 270 271 if (command == SMBtrans) 272 padding = 1; 273 else 274 padding = 3; 275 276 req = smbcli_request_setup(tree, command, 277 14 + parms->in.setup_count, 278 padding); 279 if (!req) { 280 return NULL; 281 } 282 283 state = talloc_zero(req, struct smb_raw_trans2_recv_state); 284 if (!state) { 285 smbcli_request_destroy(req); 286 return NULL; 287 } 288 289 state->command = command; 290 291 /* make sure we don't leak data via the padding */ 292 memset(req->out.data, 0, padding); 293 294 /* Watch out, this changes the req->out.* pointers */ 295 if (command == SMBtrans && parms->in.trans_name) { 296 namelen = smbcli_req_append_string(req, parms->in.trans_name, 297 STR_TERMINATE); 298 } 299 300 ofs = PTR_DIFF(req->out.data,req->out.hdr)+padding+namelen; 301 302 /* see how much bytes of the params block we can ship in the first request */ 303 space_left = raw_trans_space_left(req); 304 305 params_chunk.length = MIN(parms->in.params.length, space_left); 306 params_chunk.data = parms->in.params.data; 307 params_ofs = ofs; 308 309 state->params_left = parms->in.params.length - params_chunk.length; 310 311 if (state->params_left > 0) { 312 /* we copy the whole params block, if needed we can optimize that latter */ 313 state->io.in.params = data_blob_talloc(state, NULL, parms->in.params.length); 314 if (!state->io.in.params.data) { 315 smbcli_request_destroy(req); 316 return NULL; 317 } 318 memcpy(state->io.in.params.data, 319 parms->in.params.data, 320 parms->in.params.length); 321 } 322 323 /* see how much bytes of the data block we can ship in the first request */ 324 space_left -= params_chunk.length; 325 326 #if TORTURE_TRANS_DATA 327 if (space_left > 1) { 328 space_left /= 2; 329 } 330 #endif 331 332 data_chunk.length = MIN(parms->in.data.length, space_left); 333 data_chunk.data = parms->in.data.data; 334 data_ofs = params_ofs + params_chunk.length; 335 336 state->data_left = parms->in.data.length - data_chunk.length; 337 338 if (state->data_left > 0) { 339 /* we copy the whole params block, if needed we can optimize that latter */ 340 state->io.in.data = data_blob_talloc(state, NULL, parms->in.data.length); 341 if (!state->io.in.data.data) { 342 smbcli_request_destroy(req); 343 return NULL; 344 } 345 memcpy(state->io.in.data.data, 346 parms->in.data.data, 347 parms->in.data.length); 348 } 349 350 state->params_total = parms->in.params.length; 351 state->data_total = parms->in.data.length; 352 353 /* primary request */ 354 SSVAL(req->out.vwv,VWV(0),parms->in.params.length); 355 SSVAL(req->out.vwv,VWV(1),parms->in.data.length); 356 SSVAL(req->out.vwv,VWV(2),parms->in.max_param); 357 SSVAL(req->out.vwv,VWV(3),parms->in.max_data); 358 SCVAL(req->out.vwv,VWV(4),parms->in.max_setup); 359 SCVAL(req->out.vwv,VWV(4)+1,0); /* reserved */ 360 SSVAL(req->out.vwv,VWV(5),parms->in.flags); 361 SIVAL(req->out.vwv,VWV(6),parms->in.timeout); 362 SSVAL(req->out.vwv,VWV(8),0); /* reserved */ 363 SSVAL(req->out.vwv,VWV(9),params_chunk.length); 364 SSVAL(req->out.vwv,VWV(10),params_ofs); 365 SSVAL(req->out.vwv,VWV(11),data_chunk.length); 366 SSVAL(req->out.vwv,VWV(12),data_ofs); 367 SCVAL(req->out.vwv,VWV(13),parms->in.setup_count); 368 SCVAL(req->out.vwv,VWV(13)+1,0); /* reserved */ 369 for (i=0;i<parms->in.setup_count;i++) { 370 SSVAL(req->out.vwv,VWV(14)+VWV(i),parms->in.setup[i]); 371 } 372 smbcli_req_append_blob(req, ¶ms_chunk); 373 smbcli_req_append_blob(req, &data_chunk); 374 375 /* add the helper which will check that all multi-part replies are 376 in before an async client callack will be issued */ 377 req->recv_helper.fn = smb_raw_trans2_recv_helper; 378 req->recv_helper.private_data = state; 379 380 if (!smbcli_request_send(req)) { 381 smbcli_request_destroy(req); 382 return NULL; 383 } 384 385 return req; 386 } 387 388 static enum smbcli_request_state smb_raw_trans2_ship_next(struct smbcli_request *req, 389 struct smb_raw_trans2_recv_state *state) 390 { 391 struct smbcli_request *req2; 392 size_t space_left; 393 DATA_BLOB params_chunk; 394 uint16_t ofs; 395 uint16_t params_ofs = 0; 396 uint16_t params_disp = 0; 397 DATA_BLOB data_chunk; 398 uint16_t data_ofs = 0; 399 uint16_t data_disp = 0; 400 uint8_t wct; 401 402 if (state->command == SMBtrans2) { 403 wct = 9; 404 } else { 405 wct = 8; 406 } 407 408 req2 = smbcli_request_setup(req->tree, state->command+1, wct, 0); 409 if (!req2) { 410 goto nomem; 411 } 412 req2->mid = req->mid; 413 SSVAL(req2->out.hdr, HDR_MID, req2->mid); 414 415 ofs = PTR_DIFF(req2->out.data,req2->out.hdr); 416 417 /* see how much bytes of the params block we can ship in the first request */ 418 space_left = raw_trans_space_left(req2); 419 420 params_disp = state->io.in.params.length - state->params_left; 421 params_chunk.length = MIN(state->params_left, space_left); 422 params_chunk.data = state->io.in.params.data + params_disp; 423 params_ofs = ofs; 424 425 state->params_left -= params_chunk.length; 426 427 /* see how much bytes of the data block we can ship in the first request */ 428 space_left -= params_chunk.length; 429 430 #if TORTURE_TRANS_DATA 431 if (space_left > 1) { 432 space_left /= 2; 433 } 434 #endif 435 436 data_disp = state->io.in.data.length - state->data_left; 437 data_chunk.length = MIN(state->data_left, space_left); 438 data_chunk.data = state->io.in.data.data + data_disp; 439 data_ofs = params_ofs+params_chunk.length; 440 441 state->data_left -= data_chunk.length; 442 443 SSVAL(req2->out.vwv,VWV(0), state->params_total); 444 SSVAL(req2->out.vwv,VWV(1), state->data_total); 445 SSVAL(req2->out.vwv,VWV(2), params_chunk.length); 446 SSVAL(req2->out.vwv,VWV(3), params_ofs); 447 SSVAL(req2->out.vwv,VWV(4), params_disp); 448 SSVAL(req2->out.vwv,VWV(5), data_chunk.length); 449 SSVAL(req2->out.vwv,VWV(6), data_ofs); 450 SSVAL(req2->out.vwv,VWV(7), data_disp); 451 if (wct == 9) { 452 SSVAL(req2->out.vwv,VWV(8), 0xFFFF); 453 } 454 455 smbcli_req_append_blob(req2, ¶ms_chunk); 456 smbcli_req_append_blob(req2, &data_chunk); 457 458 /* 459 * it's a one way request but we need 460 * the seq_num, so we destroy req2 by hand 461 */ 462 if (!smbcli_request_send(req2)) { 463 goto failed; 464 } 465 466 req->seq_num = req2->seq_num; 467 smbcli_request_destroy(req2); 468 469 return SMBCLI_REQUEST_RECV; 470 471 nomem: 472 req->status = NT_STATUS_NO_MEMORY; 473 failed: 474 if (req2) { 475 req->status = smbcli_request_destroy(req2); 476 } 477 return SMBCLI_REQUEST_ERROR; 478 } 479 480 static enum smbcli_request_state smb_raw_trans2_ship_rest(struct smbcli_request *req, 481 struct smb_raw_trans2_recv_state *state) 482 { 483 enum smbcli_request_state ret = SMBCLI_REQUEST_ERROR; 484 485 while (state->params_left > 0 || state->data_left > 0) { 486 ret = smb_raw_trans2_ship_next(req, state); 487 if (ret != SMBCLI_REQUEST_RECV) { 488 break; 489 } 490 } 491 492 return ret; 493 } 494 495 496 /* 497 trans/trans2 raw async interface - only BLOBs used in this interface. 498 note that this doesn't yet support multi-part requests 499 */ 500 _PUBLIC_ struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree, 501 struct smb_trans2 *parms) 502 { 503 return smb_raw_trans_send_backend(tree, parms, SMBtrans); 504 } 505 506 struct smbcli_request *smb_raw_trans2_send(struct smbcli_tree *tree, 507 struct smb_trans2 *parms) 508 { 509 return smb_raw_trans_send_backend(tree, parms, SMBtrans2); 510 } 511 512 /* 513 trans2 synchronous blob interface 514 */ 245 return smb_raw_trans_backend_recv(req, mem_ctx, parms); 246 } 247 515 248 NTSTATUS smb_raw_trans2(struct smbcli_tree *tree, 516 249 TALLOC_CTX *mem_ctx, … … 523 256 } 524 257 525 526 /* 527 trans synchronous blob interface 528 */ 529 _PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree, 530 TALLOC_CTX *mem_ctx, 531 struct smb_trans2 *parms) 258 static void smb_raw_nttrans_done(struct tevent_req *subreq); 259 260 struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree, 261 struct smb_nttrans *parms) 532 262 { 533 263 struct smbcli_request *req; 534 req = smb_raw_trans_send(tree, parms); 535 if (!req) return NT_STATUS_UNSUCCESSFUL; 536 return smb_raw_trans_recv(req, mem_ctx, parms); 537 } 538 539 struct smb_raw_nttrans_recv_state { 540 uint32_t params_total; 541 uint32_t data_total; 542 uint32_t params_left; 543 uint32_t data_left; 544 bool got_first; 545 uint32_t recvd_data; 546 uint32_t recvd_param; 547 struct smb_nttrans io; 548 }; 264 uint8_t additional_flags; 265 uint8_t clear_flags; 266 uint16_t additional_flags2; 267 uint16_t clear_flags2; 268 uint32_t pid; 269 struct smbXcli_tcon *tcon = NULL; 270 struct smbXcli_session *session = NULL; 271 uint32_t timeout_msec; 272 uint32_t tmp; 273 274 tmp = parms->in.params.length + parms->in.data.length; 275 276 req = smbcli_request_setup(tree, SMBnttrans, parms->in.setup_count, tmp); 277 if (req == NULL) { 278 return NULL; 279 } 280 281 additional_flags = CVAL(req->out.hdr, HDR_FLG); 282 additional_flags2 = SVAL(req->out.hdr, HDR_FLG2); 283 pid = SVAL(req->out.hdr, HDR_PID); 284 pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16; 285 286 if (req->session) { 287 session = req->session->smbXcli; 288 } 289 290 if (req->tree) { 291 tcon = req->tree->smbXcli; 292 } 293 294 clear_flags = ~additional_flags; 295 clear_flags2 = ~additional_flags2; 296 297 timeout_msec = req->transport->options.request_timeout * 1000; 298 299 memcpy(req->out.vwv, 300 parms->in.setup, 301 parms->in.setup_count * 2); 302 303 memcpy(req->out.data, 304 parms->in.params.data, 305 parms->in.params.length); 306 memcpy(req->out.data + parms->in.params.length, 307 parms->in.data.data, 308 parms->in.data.length); 309 310 req->subreqs[0] = smb1cli_trans_send(req, 311 req->transport->ev, 312 req->transport->conn, 313 SMBnttrans, 314 additional_flags, 315 clear_flags, 316 additional_flags2, 317 clear_flags2, 318 timeout_msec, 319 pid, 320 tcon, 321 session, 322 NULL, /* pipe_name */ 323 0xFFFF, /* fid */ 324 parms->in.function, 325 0, /* flags */ 326 (uint16_t *)req->out.vwv, 327 parms->in.setup_count, 328 parms->in.max_setup, 329 req->out.data, 330 parms->in.params.length, 331 parms->in.max_param, 332 req->out.data+ 333 parms->in.params.length, 334 parms->in.data.length, 335 parms->in.max_data); 336 if (req->subreqs[0] == NULL) { 337 talloc_free(req); 338 return NULL; 339 } 340 tevent_req_set_callback(req->subreqs[0], 341 smb_raw_nttrans_done, 342 req); 343 344 return req; 345 } 346 347 static void smb_raw_nttrans_done(struct tevent_req *subreq) 348 { 349 struct smbcli_request *req = 350 tevent_req_callback_data(subreq, 351 struct smbcli_request); 352 struct smbcli_transport *transport = req->transport; 353 uint16_t *setup = NULL; 354 uint8_t num_setup = 0; 355 uint8_t *param = NULL; 356 uint32_t num_param = 0; 357 uint8_t *data = NULL; 358 uint32_t num_data = 0; 359 360 req->status = smb1cli_trans_recv(req->subreqs[0], req, 361 &req->flags2, 362 &setup, 363 0, /* min_setup */ 364 &num_setup, 365 ¶m, 366 0, /* min_param */ 367 &num_param, 368 &data, 369 0, /* min_data */ 370 &num_data); 371 TALLOC_FREE(req->subreqs[0]); 372 if (NT_STATUS_IS_ERR(req->status)) { 373 req->state = SMBCLI_REQUEST_ERROR; 374 transport->error.e.nt_status = req->status; 375 transport->error.etype = ETYPE_SMB; 376 if (req->async.fn) { 377 req->async.fn(req); 378 } 379 return; 380 } 381 382 req->nttrans.out.setup_count = num_setup; 383 req->nttrans.out.setup = (uint8_t *)setup; 384 385 req->nttrans.out.params.data = param; 386 req->nttrans.out.params.length = num_param; 387 388 req->nttrans.out.data.data = data; 389 req->nttrans.out.data.length = num_data; 390 391 transport->error.e.nt_status = req->status; 392 if (NT_STATUS_IS_OK(req->status)) { 393 transport->error.etype = ETYPE_NONE; 394 } else { 395 transport->error.etype = ETYPE_SMB; 396 } 397 398 req->state = SMBCLI_REQUEST_DONE; 399 if (req->async.fn) { 400 req->async.fn(req); 401 } 402 } 549 403 550 404 NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req, … … 552 406 struct smb_nttrans *parms) 553 407 { 554 struct smb_raw_nttrans_recv_state *state;555 556 408 if (!smbcli_request_receive(req) || 557 409 smbcli_request_is_error(req)) { … … 559 411 } 560 412 561 state = talloc_get_type(req->recv_helper.private_data, 562 struct smb_raw_nttrans_recv_state); 563 564 parms->out = state->io.out; 413 parms->out = req->nttrans.out; 565 414 talloc_steal(mem_ctx, parms->out.setup); 566 415 talloc_steal(mem_ctx, parms->out.params.data); 567 416 talloc_steal(mem_ctx, parms->out.data.data); 568 talloc_free(state);569 570 ZERO_STRUCT(req->recv_helper);571 417 572 418 failed: 573 419 return smbcli_request_destroy(req); 574 420 } 575 576 static enum smbcli_request_state smb_raw_nttrans_ship_rest(struct smbcli_request *req,577 struct smb_raw_nttrans_recv_state *state);578 579 /*580 * This helper returns SMBCLI_REQUEST_RECV until all data has arrived581 */582 static enum smbcli_request_state smb_raw_nttrans_recv_helper(struct smbcli_request *req)583 {584 struct smb_raw_nttrans_recv_state *state = talloc_get_type(req->recv_helper.private_data,585 struct smb_raw_nttrans_recv_state);586 uint32_t param_count, param_ofs, param_disp;587 uint32_t data_count, data_ofs, data_disp;588 uint32_t total_data, total_param;589 uint8_t setup_count;590 591 /*592 * An NT RPC pipe call can return ERRDOS, ERRmoredata593 * to a trans call. This is not an error and should not594 * be treated as such.595 */596 if (smbcli_request_is_error(req)) {597 goto failed;598 }599 600 /* sanity check */601 if (CVAL(req->in.hdr, HDR_COM) != SMBnttrans) {602 DEBUG(0,("smb_raw_nttrans_recv_helper: Expected %s response, got command 0x%02x\n",603 "SMBnttrans",604 CVAL(req->in.hdr,HDR_COM)));605 req->status = NT_STATUS_INVALID_NETWORK_RESPONSE;606 goto failed;607 }608 609 if (state->params_left > 0 || state->data_left > 0) {610 return smb_raw_nttrans_ship_rest(req, state);611 }612 613 /* this is the first packet of the response */614 SMBCLI_CHECK_MIN_WCT(req, 18);615 616 total_param = IVAL(req->in.vwv, 3);617 total_data = IVAL(req->in.vwv, 7);618 setup_count = CVAL(req->in.vwv, 35);619 620 param_count = IVAL(req->in.vwv, 11);621 param_ofs = IVAL(req->in.vwv, 15);622 param_disp = IVAL(req->in.vwv, 19);623 624 data_count = IVAL(req->in.vwv, 23);625 data_ofs = IVAL(req->in.vwv, 27);626 data_disp = IVAL(req->in.vwv, 31);627 628 if (!state->got_first) {629 if (total_param > 0) {630 state->io.out.params = data_blob_talloc(state, NULL, total_param);631 if (!state->io.out.params.data) {632 goto nomem;633 }634 }635 636 if (total_data > 0) {637 state->io.out.data = data_blob_talloc(state, NULL, total_data);638 if (!state->io.out.data.data) {639 goto nomem;640 }641 }642 643 if (setup_count > 0) {644 SMBCLI_CHECK_WCT(req, 18 + setup_count);645 646 state->io.out.setup_count = setup_count;647 state->io.out.setup = talloc_array(state, uint8_t,648 setup_count * VWV(1));649 if (!state->io.out.setup) {650 goto nomem;651 }652 memcpy(state->io.out.setup, (uint8_t *)req->out.vwv + VWV(18),653 setup_count * VWV(1));654 }655 656 state->got_first = true;657 }658 659 if (total_data > state->io.out.data.length ||660 total_param > state->io.out.params.length) {661 /* they must *only* shrink */662 DEBUG(1,("smb_raw_nttrans_recv_helper: data/params expanded!\n"));663 req->status = NT_STATUS_BUFFER_TOO_SMALL;664 goto failed;665 }666 667 state->io.out.data.length = total_data;668 state->io.out.params.length = total_param;669 670 if (data_count + data_disp > total_data ||671 param_count + param_disp > total_param) {672 DEBUG(1,("smb_raw_nttrans_recv_helper: Buffer overflow\n"));673 req->status = NT_STATUS_BUFFER_TOO_SMALL;674 goto failed;675 }676 677 /* check the server isn't being nasty */678 if (raw_trans_oob(req, param_ofs, param_count) ||679 raw_trans_oob(req, data_ofs, data_count)) {680 DEBUG(1,("smb_raw_nttrans_recv_helper: out of bounds parameters!\n"));681 req->status = NT_STATUS_BUFFER_TOO_SMALL;682 goto failed;683 }684 685 if (data_count) {686 memcpy(state->io.out.data.data + data_disp,687 req->in.hdr + data_ofs,688 data_count);689 }690 691 if (param_count) {692 memcpy(state->io.out.params.data + param_disp,693 req->in.hdr + param_ofs,694 param_count);695 }696 697 state->recvd_param += param_count;698 state->recvd_data += data_count;699 700 if (state->recvd_data < total_data ||701 state->recvd_param < total_param) {702 703 /* we don't need the in buffer any more */704 talloc_free(req->in.buffer);705 ZERO_STRUCT(req->in);706 707 /* we still wait for more data */708 DEBUG(10,("smb_raw_nttrans_recv_helper: more data needed\n"));709 return SMBCLI_REQUEST_RECV;710 }711 712 DEBUG(10,("smb_raw_nttrans_recv_helper: done\n"));713 return SMBCLI_REQUEST_DONE;714 715 nomem:716 req->status = NT_STATUS_NO_MEMORY;717 failed:718 return SMBCLI_REQUEST_ERROR;719 }720 721 /****************************************************************************722 nttrans raw - only BLOBs used in this interface.723 at the moment we only handle a single primary request724 ****************************************************************************/725 struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree,726 struct smb_nttrans *parms)727 {728 struct smbcli_request *req;729 struct smb_raw_nttrans_recv_state *state;730 uint32_t ofs;731 size_t space_left;732 DATA_BLOB params_chunk;733 uint32_t params_ofs;734 DATA_BLOB data_chunk;735 uint32_t data_ofs;736 int align = 0;737 738 /* only align if there are parameters or data */739 if (parms->in.params.length || parms->in.data.length) {740 align = 3;741 }742 743 req = smbcli_request_setup(tree, SMBnttrans,744 19 + parms->in.setup_count, align);745 if (!req) {746 return NULL;747 }748 749 state = talloc_zero(req, struct smb_raw_nttrans_recv_state);750 if (!state) {751 talloc_free(req);752 return NULL;753 }754 755 /* fill in SMB parameters */756 757 if (align != 0) {758 memset(req->out.data, 0, align);759 }760 761 ofs = PTR_DIFF(req->out.data,req->out.hdr)+align;762 763 /* see how much bytes of the params block we can ship in the first request */764 space_left = raw_trans_space_left(req);765 766 params_chunk.length = MIN(parms->in.params.length, space_left);767 params_chunk.data = parms->in.params.data;768 params_ofs = ofs;769 770 state->params_left = parms->in.params.length - params_chunk.length;771 772 if (state->params_left > 0) {773 /* we copy the whole params block, if needed we can optimize that latter */774 state->io.in.params = data_blob_talloc(state, NULL, parms->in.params.length);775 if (!state->io.in.params.data) {776 smbcli_request_destroy(req);777 return NULL;778 }779 memcpy(state->io.in.params.data,780 parms->in.params.data,781 parms->in.params.length);782 }783 784 /* see how much bytes of the data block we can ship in the first request */785 space_left -= params_chunk.length;786 787 #if TORTURE_TRANS_DATA788 if (space_left > 1) {789 space_left /= 2;790 }791 #endif792 793 data_chunk.length = MIN(parms->in.data.length, space_left);794 data_chunk.data = parms->in.data.data;795 data_ofs = params_ofs + params_chunk.length;796 797 state->data_left = parms->in.data.length - data_chunk.length;798 799 if (state->data_left > 0) {800 /* we copy the whole params block, if needed we can optimize that latter */801 state->io.in.data = data_blob_talloc(state, NULL, parms->in.data.length);802 if (!state->io.in.data.data) {803 smbcli_request_destroy(req);804 return NULL;805 }806 memcpy(state->io.in.data.data,807 parms->in.data.data,808 parms->in.data.length);809 }810 811 state->params_total = parms->in.params.length;812 state->data_total = parms->in.data.length;813 814 SCVAL(req->out.vwv, 0, parms->in.max_setup);815 SSVAL(req->out.vwv, 1, 0); /* reserved */816 SIVAL(req->out.vwv, 3, parms->in.params.length);817 SIVAL(req->out.vwv, 7, parms->in.data.length);818 SIVAL(req->out.vwv, 11, parms->in.max_param);819 SIVAL(req->out.vwv, 15, parms->in.max_data);820 SIVAL(req->out.vwv, 19, params_chunk.length);821 SIVAL(req->out.vwv, 23, params_ofs);822 SIVAL(req->out.vwv, 27, data_chunk.length);823 SIVAL(req->out.vwv, 31, data_ofs);824 SCVAL(req->out.vwv, 35, parms->in.setup_count);825 SSVAL(req->out.vwv, 36, parms->in.function);826 memcpy(req->out.vwv + VWV(19), parms->in.setup,827 sizeof(uint16_t) * parms->in.setup_count);828 829 smbcli_req_append_blob(req, ¶ms_chunk);830 smbcli_req_append_blob(req, &data_chunk);831 832 /* add the helper which will check that all multi-part replies are833 in before an async client callack will be issued */834 req->recv_helper.fn = smb_raw_nttrans_recv_helper;835 req->recv_helper.private_data = state;836 837 if (!smbcli_request_send(req)) {838 smbcli_request_destroy(req);839 return NULL;840 }841 842 return req;843 }844 845 static enum smbcli_request_state smb_raw_nttrans_ship_next(struct smbcli_request *req,846 struct smb_raw_nttrans_recv_state *state)847 {848 struct smbcli_request *req2;849 size_t space_left;850 DATA_BLOB params_chunk;851 uint32_t ofs;852 uint32_t params_ofs = 0;853 uint32_t params_disp = 0;854 DATA_BLOB data_chunk;855 uint32_t data_ofs = 0;856 uint32_t data_disp = 0;857 858 req2 = smbcli_request_setup(req->tree, SMBnttranss, 18, 0);859 if (!req2) {860 goto nomem;861 }862 req2->mid = req->mid;863 SSVAL(req2->out.hdr, HDR_MID, req2->mid);864 865 ofs = PTR_DIFF(req2->out.data,req2->out.hdr);866 867 /* see how much bytes of the params block we can ship in the first request */868 space_left = raw_trans_space_left(req2);869 870 params_disp = state->io.in.params.length - state->params_left;871 params_chunk.length = MIN(state->params_left, space_left);872 params_chunk.data = state->io.in.params.data + params_disp;873 params_ofs = ofs;874 875 state->params_left -= params_chunk.length;876 877 /* see how much bytes of the data block we can ship in the first request */878 space_left -= params_chunk.length;879 880 #if TORTURE_TRANS_DATA881 if (space_left > 1) {882 space_left /= 2;883 }884 #endif885 886 data_disp = state->io.in.data.length - state->data_left;887 data_chunk.length = MIN(state->data_left, space_left);888 data_chunk.data = state->io.in.data.data + data_disp;889 data_ofs = params_ofs+params_chunk.length;890 891 state->data_left -= data_chunk.length;892 893 SSVAL(req2->out.vwv,0, 0); /* reserved */894 SCVAL(req2->out.vwv,2, 0); /* reserved */895 SIVAL(req2->out.vwv,3, state->params_total);896 SIVAL(req2->out.vwv,7, state->data_total);897 SIVAL(req2->out.vwv,11, params_chunk.length);898 SIVAL(req2->out.vwv,15, params_ofs);899 SIVAL(req2->out.vwv,19, params_disp);900 SIVAL(req2->out.vwv,23, data_chunk.length);901 SIVAL(req2->out.vwv,27, data_ofs);902 SIVAL(req2->out.vwv,31, data_disp);903 SCVAL(req2->out.vwv,35, 0); /* reserved */904 905 smbcli_req_append_blob(req2, ¶ms_chunk);906 smbcli_req_append_blob(req2, &data_chunk);907 908 /*909 * it's a one way request but we need910 * the seq_num, so we destroy req2 by hand911 */912 if (!smbcli_request_send(req2)) {913 goto failed;914 }915 916 req->seq_num = req2->seq_num;917 smbcli_request_destroy(req2);918 919 return SMBCLI_REQUEST_RECV;920 921 nomem:922 req->status = NT_STATUS_NO_MEMORY;923 failed:924 if (req2) {925 req->status = smbcli_request_destroy(req2);926 }927 return SMBCLI_REQUEST_ERROR;928 }929 930 static enum smbcli_request_state smb_raw_nttrans_ship_rest(struct smbcli_request *req,931 struct smb_raw_nttrans_recv_state *state)932 {933 enum smbcli_request_state ret = SMBCLI_REQUEST_ERROR;934 935 while (state->params_left > 0 || state->data_left > 0) {936 ret = smb_raw_nttrans_ship_next(req, state);937 if (ret != SMBCLI_REQUEST_RECV) {938 break;939 }940 }941 942 return ret;943 }944 945 421 946 422 /**************************************************************************** -
vendor/current/source4/libcli/raw/signing.h
r414 r988 27 27 }; 28 28 29 enum smb_signing_state {30 SMB_SIGNING_OFF, SMB_SIGNING_SUPPORTED,31 SMB_SIGNING_REQUIRED, SMB_SIGNING_AUTO};32 33 29 struct smb_signing_context { 34 30 enum smb_signing_engine_state signing_state; -
vendor/current/source4/libcli/raw/smb.h
r740 r988 24 24 */ 25 25 26 #ifndef _ SMB_H27 #define _ SMB_H26 #ifndef _RAW_SMB_H 27 #define _RAW_SMB_H 28 28 29 29 /* deny modes */ … … 207 207 #define NTCREATEX_ACTION_UNKNOWN 5 208 208 209 #define SMB_MAGIC 0x424D53FF /* 0xFF 'S' 'M' 'B' */210 211 /* the basic packet size, assuming no words or bytes. Does not include the NBT header */212 #define MIN_SMB_SIZE 35213 214 /* when using NBT encapsulation every packet has a 4 byte header */215 #define NBT_HDR_SIZE 4216 217 /* offsets into message header for common items - NOTE: These have218 changed from being offsets from the base of the NBT packet to the base of the SMB packet.219 this has reduced all these values by 4220 */221 #define HDR_COM 4222 #define HDR_RCLS 5223 #define HDR_REH 6224 #define HDR_ERR 7225 #define HDR_FLG 9226 #define HDR_FLG2 10227 #define HDR_PIDHIGH 12228 #define HDR_SS_FIELD 14229 #define HDR_TID 24230 #define HDR_PID 26231 #define HDR_UID 28232 #define HDR_MID 30233 #define HDR_WCT 32234 #define HDR_VWV 33235 236 237 /* types of buffers in core SMB protocol */238 #define SMB_DATA_BLOCK 0x1239 #define SMB_ASCII4 0x4240 241 242 /* flag defines. CIFS spec 3.1.1 */243 #define FLAG_SUPPORT_LOCKREAD 0x01244 #define FLAG_CLIENT_BUF_AVAIL 0x02245 #define FLAG_RESERVED 0x04246 #define FLAG_CASELESS_PATHNAMES 0x08247 #define FLAG_CANONICAL_PATHNAMES 0x10248 #define FLAG_REQUEST_OPLOCK 0x20249 #define FLAG_REQUEST_BATCH_OPLOCK 0x40250 #define FLAG_REPLY 0x80251 252 /* the complete */253 #define SMBmkdir 0x00 /* create directory */254 #define SMBrmdir 0x01 /* delete directory */255 #define SMBopen 0x02 /* open file */256 #define SMBcreate 0x03 /* create file */257 #define SMBclose 0x04 /* close file */258 #define SMBflush 0x05 /* flush file */259 #define SMBunlink 0x06 /* delete file */260 #define SMBmv 0x07 /* rename file */261 #define SMBgetatr 0x08 /* get file attributes */262 #define SMBsetatr 0x09 /* set file attributes */263 #define SMBread 0x0A /* read from file */264 #define SMBwrite 0x0B /* write to file */265 #define SMBlock 0x0C /* lock byte range */266 #define SMBunlock 0x0D /* unlock byte range */267 #define SMBctemp 0x0E /* create temporary file */268 #define SMBmknew 0x0F /* make new file */269 #define SMBchkpth 0x10 /* check directory path */270 #define SMBexit 0x11 /* process exit */271 #define SMBlseek 0x12 /* seek */272 #define SMBtcon 0x70 /* tree connect */273 #define SMBtconX 0x75 /* tree connect and X*/274 #define SMBtdis 0x71 /* tree disconnect */275 #define SMBnegprot 0x72 /* negotiate protocol */276 #define SMBdskattr 0x80 /* get disk attributes */277 #define SMBsearch 0x81 /* search directory */278 #define SMBsplopen 0xC0 /* open print spool file */279 #define SMBsplwr 0xC1 /* write to print spool file */280 #define SMBsplclose 0xC2 /* close print spool file */281 #define SMBsplretq 0xC3 /* return print queue */282 #define SMBsends 0xD0 /* send single block message */283 #define SMBsendb 0xD1 /* send broadcast message */284 #define SMBfwdname 0xD2 /* forward user name */285 #define SMBcancelf 0xD3 /* cancel forward */286 #define SMBgetmac 0xD4 /* get machine name */287 #define SMBsendstrt 0xD5 /* send start of multi-block message */288 #define SMBsendend 0xD6 /* send end of multi-block message */289 #define SMBsendtxt 0xD7 /* send text of multi-block message */290 291 /* Core+ protocol */292 #define SMBlockread 0x13 /* Lock a range and read */293 #define SMBwriteunlock 0x14 /* write then range then unlock it */294 #define SMBreadbraw 0x1a /* read a block of data with no smb header */295 #define SMBwritebraw 0x1d /* write a block of data with no smb header */296 #define SMBwritec 0x20 /* secondary write request */297 #define SMBwriteclose 0x2c /* write a file then close it */298 299 /* dos extended protocol */300 #define SMBreadBraw 0x1A /* read block raw */301 #define SMBreadBmpx 0x1B /* read block multiplexed */302 #define SMBreadBs 0x1C /* read block (secondary response) */303 #define SMBwriteBraw 0x1D /* write block raw */304 #define SMBwriteBmpx 0x1E /* write block multiplexed */305 #define SMBwriteBs 0x1F /* write block (secondary request) */306 #define SMBwriteC 0x20 /* write complete response */307 #define SMBsetattrE 0x22 /* set file attributes expanded */308 #define SMBgetattrE 0x23 /* get file attributes expanded */309 #define SMBlockingX 0x24 /* lock/unlock byte ranges and X */310 #define SMBtrans 0x25 /* transaction - name, bytes in/out */311 #define SMBtranss 0x26 /* transaction (secondary request/response) */312 #define SMBioctl 0x27 /* IOCTL */313 #define SMBioctls 0x28 /* IOCTL (secondary request/response) */314 #define SMBcopy 0x29 /* copy */315 #define SMBmove 0x2A /* move */316 #define SMBecho 0x2B /* echo */317 #define SMBopenX 0x2D /* open and X */318 #define SMBreadX 0x2E /* read and X */319 #define SMBwriteX 0x2F /* write and X */320 #define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */321 #define SMBffirst 0x82 /* find first */322 #define SMBfunique 0x83 /* find unique */323 #define SMBfclose 0x84 /* find close */324 #define SMBkeepalive 0x85 /* keepalive */325 #define SMBinvalid 0xFE /* invalid command */326 327 /* Extended 2.0 protocol */328 #define SMBtrans2 0x32 /* TRANS2 protocol set */329 #define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */330 #define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */331 #define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */332 #define SMBulogoffX 0x74 /* user logoff */333 334 /* NT SMB extensions. */335 #define SMBnttrans 0xA0 /* NT transact */336 #define SMBnttranss 0xA1 /* NT transact secondary */337 #define SMBntcreateX 0xA2 /* NT create and X */338 #define SMBntcancel 0xA4 /* NT cancel */339 #define SMBntrename 0xA5 /* NT rename */340 341 /* used to indicate end of chain */342 #define SMB_CHAIN_NONE 0xFF343 344 /* These are the trans subcommands */345 #define TRANSACT_SETNAMEDPIPEHANDLESTATE 0x01346 #define TRANSACT_DCERPCCMD 0x26347 #define TRANSACT_WAITNAMEDPIPEHANDLESTATE 0x53348 349 /* These are the NT transact sub commands. */350 #define NT_TRANSACT_CREATE 1351 #define NT_TRANSACT_IOCTL 2352 #define NT_TRANSACT_SET_SECURITY_DESC 3353 #define NT_TRANSACT_NOTIFY_CHANGE 4354 #define NT_TRANSACT_RENAME 5355 #define NT_TRANSACT_QUERY_SECURITY_DESC 6356 357 /* this is used on a TConX. I'm not sure the name is very helpful though */358 #define SMB_SUPPORT_SEARCH_BITS 0x0001359 #define SMB_SHARE_IN_DFS 0x0002360 361 209 /* Named pipe write mode flags. Used in writeX calls. */ 362 210 #define PIPE_RAW_MODE 0x4 … … 366 214 #define DESIRED_ACCESS_PIPE 0x2019f 367 215 368 369 /* FileAttributes (search attributes) field */370 #define FILE_ATTRIBUTE_READONLY 0x0001371 #define FILE_ATTRIBUTE_HIDDEN 0x0002372 #define FILE_ATTRIBUTE_SYSTEM 0x0004373 #define FILE_ATTRIBUTE_VOLUME 0x0008374 #define FILE_ATTRIBUTE_DIRECTORY 0x0010375 #define FILE_ATTRIBUTE_ARCHIVE 0x0020376 #define FILE_ATTRIBUTE_DEVICE 0x0040377 #define FILE_ATTRIBUTE_NORMAL 0x0080378 #define FILE_ATTRIBUTE_TEMPORARY 0x0100379 #define FILE_ATTRIBUTE_SPARSE 0x0200380 #define FILE_ATTRIBUTE_REPARSE_POINT 0x0400381 #define FILE_ATTRIBUTE_COMPRESSED 0x0800382 #define FILE_ATTRIBUTE_OFFLINE 0x1000383 #define FILE_ATTRIBUTE_NONINDEXED 0x2000384 #define FILE_ATTRIBUTE_ENCRYPTED 0x4000385 #define FILE_ATTRIBUTE_ALL_MASK 0x7FFF386 387 /* Flags - combined with attributes. */388 #define FILE_FLAG_WRITE_THROUGH 0x80000000L389 #define FILE_FLAG_NO_BUFFERING 0x20000000L390 #define FILE_FLAG_RANDOM_ACCESS 0x10000000L391 #define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000L392 #define FILE_FLAG_DELETE_ON_CLOSE 0x04000000L393 #define FILE_FLAG_BACKUP_SEMANTICS 0x02000000L /* only if backup/restore privilege? */394 #define FILE_FLAG_POSIX_SEMANTICS 0x01000000L395 396 /* Responses when opening a file. */397 #define FILE_WAS_SUPERSEDED 0398 #define FILE_WAS_OPENED 1399 #define FILE_WAS_CREATED 2400 #define FILE_WAS_OVERWRITTEN 3401 402 /* File type flags */403 #define FILE_TYPE_DISK 0404 #define FILE_TYPE_BYTE_MODE_PIPE 1405 #define FILE_TYPE_MESSAGE_MODE_PIPE 2406 #define FILE_TYPE_PRINTER 3407 #define FILE_TYPE_COMM_DEVICE 4408 #define FILE_TYPE_UNKNOWN 0xFFFF409 410 216 /* Flag for NT transact rename call. */ 411 217 #define RENAME_REPLACE_IF_EXISTS 1 … … 416 222 #define RENAME_FLAG_RENAME 0x104 417 223 #define RENAME_FLAG_COPY 0x105 418 419 /* Filesystem Attributes. */420 #define FILE_CASE_SENSITIVE_SEARCH 0x01421 #define FILE_CASE_PRESERVED_NAMES 0x02422 #define FILE_UNICODE_ON_DISK 0x04423 /* According to cifs9f, this is 4, not 8 */424 /* Acconding to testing, this actually sets the security attribute! */425 #define FILE_PERSISTENT_ACLS 0x08426 /* These entries added from cifs9f --tsb */427 #define FILE_FILE_COMPRESSION 0x10428 #define FILE_VOLUME_QUOTAS 0x20429 /* I think this is wrong. JRA #define FILE_DEVICE_IS_MOUNTED 0x20 */430 #define FILE_VOLUME_SPARSE_FILE 0x40431 #define FILE_VOLUME_IS_COMPRESSED 0x8000432 224 433 225 /* ChangeNotify flags. */ … … 473 265 /* where to find the base of the SMB packet proper */ 474 266 /* REWRITE TODO: smb_base needs to be removed */ 475 #define smb_base(buf) (((c har *)(buf))+4)267 #define smb_base(buf) (((const char *)(buf))+4) 476 268 477 269 /* we don't allow server strings to be longer than 48 characters as … … 499 291 #define BROWSER_CONSTANT 0xaa55 500 292 501 /* Sercurity mode bits. */502 #define NEGOTIATE_SECURITY_USER_LEVEL 0x01503 #define NEGOTIATE_SECURITY_CHALLENGE_RESPONSE 0x02504 #define NEGOTIATE_SECURITY_SIGNATURES_ENABLED 0x04505 #define NEGOTIATE_SECURITY_SIGNATURES_REQUIRED 0x08506 507 /* NT Flags2 bits - cifs6.txt section 3.1.2 */508 #define FLAGS2_LONG_PATH_COMPONENTS 0x0001509 #define FLAGS2_EXTENDED_ATTRIBUTES 0x0002510 #define FLAGS2_SMB_SECURITY_SIGNATURES 0x0004511 #define FLAGS2_IS_LONG_NAME 0x0040512 #define FLAGS2_EXTENDED_SECURITY 0x0800513 #define FLAGS2_DFS_PATHNAMES 0x1000514 #define FLAGS2_READ_PERMIT_EXECUTE 0x2000515 #define FLAGS2_32_BIT_ERROR_CODES 0x4000516 #define FLAGS2_UNICODE_STRINGS 0x8000517 518 519 /* CIFS protocol capabilities */520 #define CAP_RAW_MODE 0x00000001521 #define CAP_MPX_MODE 0x00000002522 #define CAP_UNICODE 0x00000004523 #define CAP_LARGE_FILES 0x00000008524 #define CAP_NT_SMBS 0x00000010525 #define CAP_RPC_REMOTE_APIS 0x00000020526 #define CAP_STATUS32 0x00000040527 #define CAP_LEVEL_II_OPLOCKS 0x00000080528 #define CAP_LOCK_AND_READ 0x00000100529 #define CAP_NT_FIND 0x00000200530 #define CAP_DFS 0x00001000531 #define CAP_W2K_SMBS 0x00002000532 #define CAP_LARGE_READX 0x00004000533 #define CAP_LARGE_WRITEX 0x00008000534 #define CAP_UNIX 0x00800000 /* Capabilities for UNIX extensions. Created by HP. */535 #define CAP_EXTENDED_SECURITY 0x80000000536 537 293 /* 538 294 * Global value meaning that the smb_uid field should be … … 541 297 542 298 #define UID_FIELD_INVALID 0 543 544 /* Lock types. */545 #define LOCKING_ANDX_EXCLUSIVE_LOCK 0x00546 #define LOCKING_ANDX_SHARED_LOCK 0x01547 #define LOCKING_ANDX_OPLOCK_RELEASE 0x02548 #define LOCKING_ANDX_CHANGE_LOCKTYPE 0x04549 #define LOCKING_ANDX_CANCEL_LOCK 0x08550 #define LOCKING_ANDX_LARGE_FILES 0x10551 552 /*553 * Bits we test with.554 */555 556 #define OPLOCK_NONE 0557 #define OPLOCK_EXCLUSIVE 1558 #define OPLOCK_BATCH 2559 #define OPLOCK_LEVEL_II 4560 561 #define CORE_OPLOCK_GRANTED (1<<5)562 #define EXTENDED_OPLOCK_GRANTED (1<<15)563 564 /*565 * Return values for oplock types.566 */567 568 #define NO_OPLOCK_RETURN 0569 #define EXCLUSIVE_OPLOCK_RETURN 1570 #define BATCH_OPLOCK_RETURN 2571 #define LEVEL_II_OPLOCK_RETURN 3572 573 /* oplock levels sent in oplock break */574 #define OPLOCK_BREAK_TO_NONE 0575 #define OPLOCK_BREAK_TO_LEVEL_II 1576 577 578 #define CMD_REPLY 0x8000579 299 580 300 /* The maximum length of a trust account password. … … 603 323 #define FS_ATTR_NAMED_STREAMS 0x00040000 604 324 605 #define smb_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16)) 606 #define _smb_setlen(buf,len) do {(buf)[0] = 0; (buf)[1] = ((len)&0x10000)>>16; \ 607 (buf)[2] = ((len)&0xFF00)>>8; (buf)[3] = (len)&0xFF;} while (0) 608 #define _smb2_setlen(buf,len) do {(buf)[0] = 0; (buf)[1] = ((len)&0xFF0000)>>16; \ 609 (buf)[2] = ((len)&0xFF00)>>8; (buf)[3] = (len)&0xFF;} while (0) 610 611 #include "libcli/raw/trans2.h" 325 #include "source4/libcli/raw/trans2.h" 612 326 #include "libcli/raw/interfaces.h" 613 614 #endif /* _SMB_H */ 327 #include "libcli/smb/smb_common.h" 328 329 #endif /* _RAW_SMB_H */ -
vendor/current/source4/libcli/raw/smb_signing.c
r746 r988 43 43 } 44 44 45 /***********************************************************46 SMB signing - Common code before we set a new signing implementation47 ************************************************************/48 static bool smbcli_set_smb_signing_common(struct smbcli_transport *transport)49 {50 if (!set_smb_signing_common(&transport->negotiate.sign_info)) {51 return false;52 }53 54 if (!(transport->negotiate.sec_mode &55 (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) {56 DEBUG(5, ("SMB Signing is not negotiated by the peer\n"));57 return false;58 }59 60 /* These calls are INCOMPATIBLE with SMB signing */61 transport->negotiate.readbraw_supported = false;62 transport->negotiate.writebraw_supported = false;63 64 return true;65 }66 67 45 void mark_packet_signed(struct smb_request_buffer *out) 68 46 { … … 203 181 } 204 182 205 static void smbcli_req_allocate_seq_num(struct smbcli_request *req)206 {207 req->seq_num = req->transport->negotiate.sign_info.next_seq_num;208 209 /* some requests (eg. NTcancel) are one way, and the sequence number210 should be increased by 1 not 2 */211 if (req->sign_single_increment) {212 req->transport->negotiate.sign_info.next_seq_num += 1;213 } else {214 req->transport->negotiate.sign_info.next_seq_num += 2;215 }216 }217 218 /***********************************************************219 SMB signing - Simple implementation - calculate a MAC to send.220 ************************************************************/221 void smbcli_request_calculate_sign_mac(struct smbcli_request *req)222 {223 #if 0224 /* enable this when packet signing is preventing you working out why valgrind225 says that data is uninitialised */226 file_save("pkt.dat", req->out.buffer, req->out.size);227 #endif228 229 switch (req->transport->negotiate.sign_info.signing_state) {230 case SMB_SIGNING_ENGINE_OFF:231 break;232 233 case SMB_SIGNING_ENGINE_BSRSPYL:234 /* mark the packet as signed - BEFORE we sign it...*/235 mark_packet_signed(&req->out);236 237 /* I wonder what BSRSPYL stands for - but this is what MS238 actually sends! */239 memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8);240 break;241 242 case SMB_SIGNING_ENGINE_ON:243 244 smbcli_req_allocate_seq_num(req);245 sign_outgoing_message(&req->out,246 &req->transport->negotiate.sign_info.mac_key,247 req->seq_num);248 break;249 }250 return;251 }252 253 254 183 /** 255 184 SMB signing - NULL implementation … … 266 195 return true; 267 196 } 268 269 /**270 SMB signing - TEMP implementation - setup the MAC key.271 272 */273 bool smbcli_temp_set_signing(struct smbcli_transport *transport)274 {275 if (!smbcli_set_smb_signing_common(transport)) {276 return false;277 }278 DEBUG(5, ("BSRSPYL SMB signing enabled\n"));279 smbcli_set_signing_off(&transport->negotiate.sign_info);280 281 transport->negotiate.sign_info.mac_key = data_blob(NULL, 0);282 transport->negotiate.sign_info.signing_state = SMB_SIGNING_ENGINE_BSRSPYL;283 284 return true;285 }286 287 /***********************************************************288 SMB signing - Simple implementation - check a MAC sent by server.289 ************************************************************/290 /**291 * Check a packet supplied by the server.292 * @return false if we had an established signing connection293 * which had a back checksum, true otherwise294 */295 bool smbcli_request_check_sign_mac(struct smbcli_request *req)296 {297 bool good;298 299 if (!req->transport->negotiate.sign_info.doing_signing &&300 req->sign_caller_checks) {301 return true;302 }303 304 req->sign_caller_checks = false;305 306 switch (req->transport->negotiate.sign_info.signing_state)307 {308 case SMB_SIGNING_ENGINE_OFF:309 return true;310 case SMB_SIGNING_ENGINE_BSRSPYL:311 return true;312 313 case SMB_SIGNING_ENGINE_ON:314 {315 if (req->in.size < (HDR_SS_FIELD + 8)) {316 return false;317 } else {318 good = check_signed_incoming_message(&req->in,319 &req->transport->negotiate.sign_info.mac_key,320 req->seq_num+1);321 322 return signing_good(&req->transport->negotiate.sign_info,323 req->seq_num+1, good);324 }325 }326 }327 return false;328 }329 330 197 331 198 /*********************************************************** … … 363 230 } 364 231 365 366 /***********************************************************367 SMB signing - Simple implementation - setup the MAC key.368 ************************************************************/369 bool smbcli_transport_simple_set_signing(struct smbcli_transport *transport,370 const DATA_BLOB user_session_key,371 const DATA_BLOB response)372 {373 if (!smbcli_set_smb_signing_common(transport)) {374 return false;375 }376 377 return smbcli_simple_set_signing(transport,378 &transport->negotiate.sign_info,379 &user_session_key,380 &response);381 }382 383 384 bool smbcli_init_signing(struct smbcli_transport *transport)385 {386 transport->negotiate.sign_info.next_seq_num = 0;387 transport->negotiate.sign_info.mac_key = data_blob(NULL, 0);388 if (!smbcli_set_signing_off(&transport->negotiate.sign_info)) {389 return false;390 }391 392 switch (transport->options.signing) {393 case SMB_SIGNING_OFF:394 transport->negotiate.sign_info.allow_smb_signing = false;395 break;396 case SMB_SIGNING_SUPPORTED:397 case SMB_SIGNING_AUTO:398 transport->negotiate.sign_info.allow_smb_signing = true;399 break;400 case SMB_SIGNING_REQUIRED:401 transport->negotiate.sign_info.allow_smb_signing = true;402 transport->negotiate.sign_info.mandatory_signing = true;403 break;404 }405 return true;406 } -
vendor/current/source4/libcli/raw/trans2.h
r414 r988 22 22 #ifndef _TRANS2_H_ 23 23 #define _TRANS2_H_ 24 25 /* These are the TRANS2 sub commands */26 #define TRANSACT2_OPEN 027 #define TRANSACT2_FINDFIRST 128 #define TRANSACT2_FINDNEXT 229 #define TRANSACT2_QFSINFO 330 #define TRANSACT2_SETFSINFO 431 #define TRANSACT2_QPATHINFO 532 #define TRANSACT2_SETPATHINFO 633 #define TRANSACT2_QFILEINFO 734 #define TRANSACT2_SETFILEINFO 835 #define TRANSACT2_FSCTL 936 #define TRANSACT2_IOCTL 0xA37 #define TRANSACT2_FINDNOTIFYFIRST 0xB38 #define TRANSACT2_FINDNOTIFYNEXT 0xC39 #define TRANSACT2_MKDIR 0xD40 #define TRANSACT2_SESSION_SETUP 0xE41 #define TRANSACT2_GET_DFS_REFERRAL 0x1042 #define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x1143 24 44 25 … … 83 64 #define SMB_QFS_FULL_SIZE_INFORMATION 1007 84 65 #define SMB_QFS_OBJECTID_INFORMATION 1008 66 #define SMB_QFS_SECTOR_SIZE_INFORMATION 1011 85 67 86 68 … … 303 285 #define QFS_TYPE_VIRTUAL 0x40 304 286 287 /* SMB_QFS_SECTOR_SIZE_INFORMATION values */ 288 #define QFS_SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001 289 #define QFS_SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002 290 #define QFS_SSINFO_FLAGS_NO_SEEK_PENALTY 0x00000004 291 #define QFS_SSINFO_FLAGS_TRIM_ENABLED 0x00000008 292 293 #define QFS_SSINFO_OFFSET_UNKNOWN 0xffffffff 305 294 306 295 /* … … 317 306 #define SMB_QFS_MAC_FS_INFO 0x301 318 307 319 320 321 /* UNIX CIFS Extensions - created by HP */322 /*323 * UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved.324 * Supposedly Microsoft have agreed to this.325 */326 327 #define MIN_UNIX_INFO_LEVEL 0x200328 #define MAX_UNIX_INFO_LEVEL 0x2FF329 330 #define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL))331 332 #define SMB_MODE_NO_CHANGE 0xFFFFFFFF /* file mode value which */333 /* means "don't change it" */334 #define SMB_UID_NO_CHANGE 0xFFFFFFFF335 #define SMB_GID_NO_CHANGE 0xFFFFFFFF336 337 #define SMB_SIZE_NO_CHANGE_LO 0xFFFFFFFF338 #define SMB_SIZE_NO_CHANGE_HI 0xFFFFFFFF339 340 #define SMB_TIME_NO_CHANGE_LO 0xFFFFFFFF341 #define SMB_TIME_NO_CHANGE_HI 0xFFFFFFFF342 343 /*344 UNIX_BASIC info level:345 346 Offset Size Name347 0 LARGE_INTEGER EndOfFile File size348 8 LARGE_INTEGER Blocks Number of bytes used on disk (st_blocks).349 16 LARGE_INTEGER CreationTime Creation time350 24 LARGE_INTEGER LastAccessTime Last access time351 32 LARGE_INTEGER LastModificationTime Last modification time352 40 LARGE_INTEGER Uid Numeric user id for the owner353 48 LARGE_INTEGER Gid Numeric group id of owner354 56 ULONG Type Enumeration specifying the pathname type:355 0 -- File356 1 -- Directory357 2 -- Symbolic link358 3 -- Character device359 4 -- Block device360 5 -- FIFO (named pipe)361 6 -- Unix domain socket362 363 60 LARGE_INTEGER devmajor Major device number if type is device364 68 LARGE_INTEGER devminor Minor device number if type is device365 76 LARGE_INTEGER uniqueid This is a server-assigned unique id for the file. The client366 will typically map this onto an inode number. The scope of367 uniqueness is the share.368 84 LARGE_INTEGER permissions Standard UNIX file permissions - see below.369 92 LARGE_INTEGER nlinks The number of directory entries that map to this entry370 (number of hard links)371 372 100 - end.373 */374 375 /*376 SMB_QUERY_FILE_UNIX_INFO2 is SMB_QUERY_FILE_UNIX_BASIC with create377 time and file flags appended. The corresponding info level for378 findfirst/findnext is SMB_FIND_FILE_UNIX_UNIX2.379 380 Size Offset Value381 ---------------------382 0 LARGE_INTEGER EndOfFile File size383 8 LARGE_INTEGER Blocks Number of blocks used on disk384 16 LARGE_INTEGER ChangeTime Attribute change time385 24 LARGE_INTEGER LastAccessTime Last access time386 32 LARGE_INTEGER LastModificationTime Last modification time387 40 LARGE_INTEGER Uid Numeric user id for the owner388 48 LARGE_INTEGER Gid Numeric group id of owner389 56 ULONG Type Enumeration specifying the file type390 60 LARGE_INTEGER devmajor Major device number if type is device391 68 LARGE_INTEGER devminor Minor device number if type is device392 76 LARGE_INTEGER uniqueid This is a server-assigned unique id393 84 LARGE_INTEGER permissions Standard UNIX permissions394 92 LARGE_INTEGER nlinks Number of hard link)395 100 LARGE_INTEGER CreationTime Create/birth time396 108 ULONG FileFlags File flags enumeration397 112 ULONG FileFlagsMask Mask of valid flags398 */399 400 /* UNIX filetype mappings. */401 402 #define UNIX_TYPE_FILE 0403 #define UNIX_TYPE_DIR 1404 #define UNIX_TYPE_SYMLINK 2405 #define UNIX_TYPE_CHARDEV 3406 #define UNIX_TYPE_BLKDEV 4407 #define UNIX_TYPE_FIFO 5408 #define UNIX_TYPE_SOCKET 6409 #define UNIX_TYPE_UNKNOWN 0xFFFFFFFF410 411 /*412 * Oh this is fun. "Standard UNIX permissions" has no413 * meaning in POSIX. We need to define the mapping onto414 * and off the wire as this was not done in the original HP415 * spec. JRA.416 */417 418 #define UNIX_X_OTH 0000001419 #define UNIX_W_OTH 0000002420 #define UNIX_R_OTH 0000004421 #define UNIX_X_GRP 0000010422 #define UNIX_W_GRP 0000020423 #define UNIX_R_GRP 0000040424 #define UNIX_X_USR 0000100425 #define UNIX_W_USR 0000200426 #define UNIX_R_USR 0000400427 #define UNIX_STICKY 0001000428 #define UNIX_SET_GID 0002000429 #define UNIX_SET_UID 0004000430 431 /* Masks for the above */432 #define UNIX_OTH_MASK 0000007433 #define UNIX_GRP_MASK 0000070434 #define UNIX_USR_MASK 0000700435 #define UNIX_PERM_MASK 0000777436 #define UNIX_EXTRA_MASK 0007000437 #define UNIX_ALL_MASK 0007777438 439 /* Flags for the file_flags field in UNIX_INFO2: */440 #define EXT_SECURE_DELETE 0x00000001441 #define EXT_ENABLE_UNDELETE 0x00000002442 #define EXT_SYNCHRONOUS 0x00000004443 #define EXT_IMMUTABLE 0x00000008444 #define EXT_OPEN_APPEND_ONLY 0x00000010445 #define EXT_DO_NOT_BACKUP 0x00000020446 #define EXT_NO_UPDATE_ATIME 0x00000040447 #define EXT_HIDDEN 0x00000080448 449 #define SMB_QFILEINFO_UNIX_LINK 0x201450 #define SMB_SFILEINFO_UNIX_LINK 0x201451 #define SMB_SFILEINFO_UNIX_HLINK 0x203452 453 /*454 Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus455 64-bits worth of capability fun :-).456 */457 458 #define SMB_QUERY_CIFS_UNIX_INFO 0x200459 460 /* Returns the following.461 462 UINT16 major version number463 UINT16 minor version number464 LARGE_INTEGER capability bitfield465 466 */467 468 #define CIFS_UNIX_MAJOR_VERSION 1469 #define CIFS_UNIX_MINOR_VERSION 0470 471 #define CIFS_UNIX_FCNTL_LOCKS_CAP 0x1472 #define CIFS_UNIX_POSIX_ACLS_CAP 0x2473 474 /* ... more as we think of them :-). */475 476 308 #endif -
vendor/current/source4/libcli/resolve/bcast.c
r740 r988 48 48 struct resolve_bcast_data *data = talloc_get_type(userdata, struct resolve_bcast_data); 49 49 50 num_interfaces = iface_ count(data->ifaces);50 num_interfaces = iface_list_count(data->ifaces); 51 51 52 52 address_list = talloc_array(mem_ctx, const char *, num_interfaces+1); … … 54 54 55 55 for (i=0;i<num_interfaces;i++) { 56 const char *bcast = iface_n_bcast(data->ifaces, i); 57 if (bcast == NULL) continue; 56 bool ipv4 = iface_list_n_is_v4(data->ifaces, i); 57 const char *bcast; 58 59 if (!ipv4) { 60 continue; 61 } 62 63 bcast = iface_list_n_bcast(data->ifaces, i); 64 if (bcast == NULL) { 65 continue; 66 } 67 58 68 address_list[count] = talloc_strdup(address_list, bcast); 59 69 if (address_list[count] == NULL) { … … 102 112 { 103 113 struct interface *ifaces; 104 load_interface s(ctx, lpcfg_interfaces(lp_ctx), &ifaces);114 load_interface_list(ctx, lp_ctx, &ifaces); 105 115 return resolve_context_add_bcast_method(ctx, ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1)); 106 116 } -
vendor/current/source4/libcli/resolve/dns_ex.c
r740 r988 6 6 Copyright (C) Andrew Tridgell 2005 7 7 Copyright (C) Stefan Metzmacher 2008 8 Copyright (C) Matthieu Patou 2011 8 9 9 10 This program is free software; you can redistribute it and/or modify … … 38 39 #include "librpc/gen_ndr/ndr_nbt.h" 39 40 #include "libcli/resolve/resolve.h" 40 41 #ifdef class 42 #undef class 43 #endif 44 45 #include "heimdal/lib/roken/resolve.h" 41 #include "lib/util/util_net.h" 42 #include "lib/addns/dnsquery.h" 43 #include "lib/addns/dns.h" 44 #include <arpa/nameser.h> 45 #include <resolv.h> 46 46 47 47 struct dns_ex_state { … … 76 76 } 77 77 78 struct dns_records_container { 79 char **list; 80 uint32_t count; 81 }; 82 83 static int reply_to_addrs(TALLOC_CTX *mem_ctx, uint32_t *a_num, 84 char ***cur_addrs, uint32_t total, 85 struct dns_request *reply, int port) 86 { 87 char addrstr[INET6_ADDRSTRLEN]; 88 struct dns_rrec *rr; 89 char **addrs; 90 uint32_t i; 91 const char *addr; 92 93 /* at most we over-allocate here, but not by much */ 94 addrs = talloc_realloc(mem_ctx, *cur_addrs, char *, 95 total + reply->num_answers); 96 if (!addrs) { 97 return 0; 98 } 99 *cur_addrs = addrs; 100 101 for (i = 0; i < reply->num_answers; i++) { 102 rr = reply->answers[i]; 103 104 /* we are only interested in the IN class */ 105 if (rr->r_class != DNS_CLASS_IN) { 106 continue; 107 } 108 109 if (rr->type == QTYPE_NS) { 110 /* 111 * After the record for NS will come the A or AAAA 112 * record of the NS. 113 */ 114 break; 115 } 116 117 /* verify we actually have a record here */ 118 if (!rr->data) { 119 continue; 120 } 121 122 /* we are only interested in A and AAAA records */ 123 switch (rr->type) { 124 case QTYPE_A: 125 addr = inet_ntop(AF_INET, 126 (struct in_addr *)rr->data, 127 addrstr, sizeof(addrstr)); 128 if (addr == NULL) { 129 continue; 130 } 131 break; 132 case QTYPE_AAAA: 133 #ifdef HAVE_IPV6 134 addr = inet_ntop(AF_INET6, 135 (struct in6_addr *)rr->data, 136 addrstr, sizeof(addrstr)); 137 #else 138 addr = NULL; 139 #endif 140 if (addr == NULL) { 141 continue; 142 } 143 break; 144 default: 145 continue; 146 } 147 148 addrs[total] = talloc_asprintf(addrs, "%s@%u/%s", 149 addrstr, port, 150 rr->name->pLabelList->label); 151 if (addrs[total]) { 152 total++; 153 if (rr->type == QTYPE_A) { 154 (*a_num)++; 155 } 156 } 157 } 158 159 return total; 160 } 161 162 static DNS_ERROR dns_lookup(TALLOC_CTX *mem_ctx, const char* name, 163 uint16_t q_type, struct dns_request **reply) 164 { 165 int len, rlen; 166 uint8_t *answer; 167 bool loop; 168 struct dns_buffer buf; 169 DNS_ERROR err; 170 171 /* give space for a good sized answer by default */ 172 answer = NULL; 173 len = 1500; 174 do { 175 answer = talloc_realloc(mem_ctx, answer, uint8_t, len); 176 if (!answer) { 177 return ERROR_DNS_NO_MEMORY; 178 } 179 rlen = res_search(name, DNS_CLASS_IN, q_type, answer, len); 180 if (rlen == -1) { 181 if (len >= 65535) { 182 return ERROR_DNS_SOCKET_ERROR; 183 } 184 /* retry once with max packet size */ 185 len = 65535; 186 loop = true; 187 } else if (rlen > len) { 188 len = rlen; 189 loop = true; 190 } else { 191 loop = false; 192 } 193 } while(loop); 194 195 buf.data = answer; 196 buf.size = rlen; 197 buf.offset = 0; 198 buf.error = ERROR_DNS_SUCCESS; 199 200 err = dns_unmarshall_request(mem_ctx, &buf, reply); 201 202 TALLOC_FREE(answer); 203 return err; 204 } 205 206 static struct dns_records_container get_a_aaaa_records(TALLOC_CTX *mem_ctx, 207 const char* name, 208 int port) 209 { 210 struct dns_request *reply; 211 struct dns_records_container ret; 212 char **addrs = NULL; 213 uint32_t a_num, total; 214 uint16_t qtype; 215 TALLOC_CTX *tmp_ctx; 216 DNS_ERROR err; 217 218 memset(&ret, 0, sizeof(struct dns_records_container)); 219 220 tmp_ctx = talloc_new(mem_ctx); 221 if (!tmp_ctx) { 222 return ret; 223 } 224 225 qtype = QTYPE_AAAA; 226 227 /* this is the blocking call we are going to lots of trouble 228 to avoid them in the parent */ 229 err = dns_lookup(tmp_ctx, name, qtype, &reply); 230 if (!ERR_DNS_IS_OK(err)) { 231 qtype = QTYPE_A; 232 err = dns_lookup(tmp_ctx, name, qtype, &reply); 233 if (!ERR_DNS_IS_OK(err)) { 234 goto done; 235 } 236 } 237 238 a_num = total = 0; 239 total = reply_to_addrs(tmp_ctx, &a_num, &addrs, total, reply, port); 240 241 if (qtype == QTYPE_AAAA && a_num == 0) { 242 /* 243 * DNS server didn't returned A when asked for AAAA records. 244 * Most of the server do it, let's ask for A specificaly. 245 */ 246 err = dns_lookup(tmp_ctx, name, QTYPE_A, &reply); 247 if (!ERR_DNS_IS_OK(err)) { 248 goto done; 249 } 250 251 total = reply_to_addrs(tmp_ctx, &a_num, &addrs, total, 252 reply, port); 253 254 } 255 256 if (total) { 257 talloc_steal(mem_ctx, addrs); 258 ret.count = total; 259 ret.list = addrs; 260 } 261 262 done: 263 TALLOC_FREE(tmp_ctx); 264 return ret; 265 } 266 267 static struct dns_records_container get_srv_records(TALLOC_CTX *mem_ctx, 268 const char* name) 269 { 270 struct dns_records_container ret; 271 char **addrs = NULL; 272 struct dns_rr_srv *dclist; 273 NTSTATUS status; 274 uint32_t total; 275 unsigned i; 276 int count; 277 278 memset(&ret, 0, sizeof(struct dns_records_container)); 279 /* this is the blocking call we are going to lots of trouble 280 to avoid them in the parent */ 281 status = ads_dns_lookup_srv(mem_ctx, name, &dclist, &count); 282 if (!NT_STATUS_IS_OK(status)) { 283 return ret; 284 } 285 total = 0; 286 if (count == 0) { 287 return ret; 288 } 289 290 /* Loop over all returned records and pick the records */ 291 for (i = 0; i < count; i++) { 292 struct dns_records_container c; 293 const char* tmp_str; 294 295 tmp_str = dclist[i].hostname; 296 if (strchr(tmp_str, '.') && tmp_str[strlen(tmp_str)-1] != '.') { 297 /* we are asking for a fully qualified name, but the 298 name doesn't end in a '.'. We need to prevent the 299 DNS library trying the search domains configured in 300 resolv.conf */ 301 tmp_str = talloc_asprintf(mem_ctx, "%s.", tmp_str); 302 } 303 304 c = get_a_aaaa_records(mem_ctx, tmp_str, dclist[i].port); 305 total += c.count; 306 if (addrs == NULL) { 307 addrs = c.list; 308 } else { 309 unsigned j; 310 311 addrs = talloc_realloc(mem_ctx, addrs, char*, total); 312 for (j=0; j < c.count; j++) { 313 addrs[total - j - 1] = talloc_steal(addrs, c.list[j]); 314 } 315 } 316 } 317 318 if (total) { 319 ret.count = total; 320 ret.list = addrs; 321 } 322 323 return ret; 324 } 78 325 /* 79 326 the blocking child … … 81 328 static void run_child_dns_lookup(struct dns_ex_state *state, int fd) 82 329 { 83 struct rk_dns_reply *reply;84 struct rk_resource_record *rr;85 uint32_t count = 0;86 uint32_t srv_valid = 0;87 struct rk_resource_record **srv_rr;88 uint32_t addrs_valid = 0;89 struct rk_resource_record **addrs_rr;90 char *addrs;91 330 bool first; 92 uint32_t i;93 331 bool do_srv = (state->flags & RESOLVE_NAME_FLAG_DNS_SRV); 332 struct dns_records_container c; 333 char* addrs = NULL; 334 unsigned int i; 94 335 95 336 if (strchr(state->name.name, '.') && state->name.name[strlen(state->name.name)-1] != '.') { … … 102 343 } 103 344 104 /* this is the blocking call we are going to lots of trouble105 to avoid in the parent */106 reply = rk_dns_lookup(state->name.name, do_srv?"SRV":"A");107 if (!reply) {108 goto done;109 }110 345 111 346 if (do_srv) { 112 rk_dns_srv_order(reply); 113 } 114 115 /* Loop over all returned records and pick the "srv" records */ 116 for (rr=reply->head; rr; rr=rr->next) { 117 /* we are only interested in the IN class */ 118 if (rr->class != rk_ns_c_in) { 119 continue; 120 } 121 122 if (do_srv) { 123 /* we are only interested in SRV records */ 124 if (rr->type != rk_ns_t_srv) { 125 continue; 126 } 127 128 /* verify we actually have a SRV record here */ 129 if (!rr->u.srv) { 130 continue; 131 } 132 133 /* Verify we got a port */ 134 if (rr->u.srv->port == 0) { 135 continue; 136 } 137 } else { 138 /* we are only interested in A records */ 139 /* TODO: add AAAA support */ 140 if (rr->type != rk_ns_t_a) { 141 continue; 142 } 143 144 /* verify we actually have a A record here */ 145 if (!rr->u.a) { 146 continue; 147 } 148 } 149 count++; 150 } 151 152 if (count == 0) { 153 goto done; 154 } 155 156 srv_rr = talloc_zero_array(state, 157 struct rk_resource_record *, 158 count); 159 if (!srv_rr) { 160 goto done; 161 } 162 163 addrs_rr = talloc_zero_array(state, 164 struct rk_resource_record *, 165 count); 166 if (!addrs_rr) { 167 goto done; 168 } 169 170 /* Loop over all returned records and pick the records */ 171 for (rr=reply->head;rr;rr=rr->next) { 172 /* we are only interested in the IN class */ 173 if (rr->class != rk_ns_c_in) { 174 continue; 175 } 176 177 if (do_srv) { 178 /* we are only interested in SRV records */ 179 if (rr->type != rk_ns_t_srv) { 180 continue; 181 } 182 183 /* verify we actually have a srv record here */ 184 if (!rr->u.srv) { 185 continue; 186 } 187 188 /* Verify we got a port */ 189 if (rr->u.srv->port == 0) { 190 continue; 191 } 192 193 srv_rr[srv_valid] = rr; 194 srv_valid++; 195 } else { 196 /* we are only interested in A records */ 197 /* TODO: add AAAA support */ 198 if (rr->type != rk_ns_t_a) { 199 continue; 200 } 201 202 /* verify we actually have a A record here */ 203 if (!rr->u.a) { 204 continue; 205 } 206 207 addrs_rr[addrs_valid] = rr; 208 addrs_valid++; 209 } 210 } 211 212 for (i=0; i < srv_valid; i++) { 213 for (rr=reply->head;rr;rr=rr->next) { 214 215 if (rr->class != rk_ns_c_in) { 216 continue; 217 } 218 219 /* we are only interested in A records */ 220 if (rr->type != rk_ns_t_a) { 221 continue; 222 } 223 224 /* verify we actually have a srv record here */ 225 if (strcmp(&srv_rr[i]->u.srv->target[0], rr->domain) != 0) { 226 continue; 227 } 228 229 addrs_rr[i] = rr; 230 addrs_valid++; 231 break; 232 } 233 } 234 235 if (addrs_valid == 0) { 347 c = get_srv_records(state, state->name.name); 348 } else { 349 c = get_a_aaaa_records(state, state->name.name, state->port); 350 } 351 352 /* This line in critical - if we return without writing to the 353 * pipe, this is the signal that the name did not exist */ 354 if (c.count == 0) { 236 355 goto done; 237 356 } … … 242 361 } 243 362 first = true; 244 for (i=0; i < count; i++) { 245 uint16_t port; 246 if (!addrs_rr[i]) { 247 continue; 248 } 249 250 if (srv_rr[i] && 251 (state->flags & RESOLVE_NAME_FLAG_OVERWRITE_PORT)) { 252 port = srv_rr[i]->u.srv->port; 253 } else { 254 port = state->port; 255 } 256 257 addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s", 258 first?"":",", 259 inet_ntoa(*addrs_rr[i]->u.a), 260 port, 261 addrs_rr[i]->domain); 262 if (!addrs) { 263 goto done; 264 } 363 364 for (i=0; i < c.count; i++) { 365 addrs = talloc_asprintf_append_buffer(addrs, "%s%s", 366 first?"":",", 367 c.list[i]); 265 368 first = false; 266 369 } 267 370 268 371 if (addrs) { 372 DEBUG(11, ("Addrs = %s\n", addrs)); 269 373 write(fd, addrs, talloc_get_size(addrs)); 270 374 } … … 288 392 ZERO_STRUCT(hints); 289 393 hints.ai_socktype = SOCK_STREAM; 290 hints.ai_family = AF_INET;/* TODO: add AF_INET6 support */291 394 hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; 292 395 … … 298 401 case EAI_NODATA: 299 402 #endif 403 case EAI_FAIL: 404 /* Linux returns EAI_NODATA on non-RFC1034-compliant names. FreeBSD returns EAI_FAIL */ 300 405 case EAI_NONAME: 301 /* getaddrinfo() doesn't handle CNAME records */406 /* getaddrinfo() doesn't handle CNAME or non-RFC1034 compatible records */ 302 407 run_child_dns_lookup(state, fd); 303 408 return; … … 316 421 first = true; 317 422 for (res = res_list; res; res = res->ai_next) { 318 struct sockaddr_in *in; 319 320 if (res->ai_family != AF_INET) { 423 char addrstr[INET6_ADDRSTRLEN]; 424 if (!print_sockaddr_len(addrstr, sizeof(addrstr), (struct sockaddr *)res->ai_addr, res->ai_addrlen)) { 321 425 continue; 322 426 } 323 in = (struct sockaddr_in *)res->ai_addr; 324 325 addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s", 427 addrs = talloc_asprintf_append_buffer(addrs, "%s%s@%u/%s", 326 428 first?"":",", 327 inet_ntoa(in->sin_addr),429 addrstr, 328 430 state->port, 329 431 state->name.name); … … 384 486 385 487 if (ret <= 0) { 488 /* The check for ret == 0 here is important, if the 489 * name does not exist, then no bytes are written to 490 * the pipe */ 386 491 DEBUG(3,("dns child failed to find name '%s' of type %s\n", 387 492 state->name.name, (state->flags & RESOLVE_NAME_FLAG_DNS_SRV)?"SRV":"A")); … … 390 495 } 391 496 392 /* en usre the address looks good */497 /* ensure the address looks good */ 393 498 address[ret] = 0; 394 499 … … 407 512 for (i=0; i < num_addrs; i++) { 408 513 uint32_t port = 0; 409 char *p = strrchr(addrs[i], ' :');514 char *p = strrchr(addrs[i], '@'); 410 515 char *n; 411 516 … … 427 532 n++; 428 533 429 if (strcmp(addrs[i], "0.0.0.0") == 0 || 430 inet_addr(addrs[i]) == INADDR_NONE) { 534 if (strcmp(addrs[i], "0.0.0.0") == 0) { 431 535 composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); 432 536 return; … … 438 542 } 439 543 state->addrs[i] = socket_address_from_strings(state->addrs, 440 "ip v4",544 "ip", 441 545 addrs[i], 442 546 port); … … 486 590 ret = pipe(fd); 487 591 if (ret == -1) { 488 composite_error(c, map_nt_error_from_unix (errno));592 composite_error(c, map_nt_error_from_unix_common(errno)); 489 593 return c; 490 594 } … … 499 603 /* we need to put the child in our event context so 500 604 we know when the dns_lookup() has finished */ 501 state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ,605 state->fde = tevent_add_fd(c->event_ctx, c, state->child_fd, TEVENT_FD_READ, 502 606 pipe_handler, c); 503 607 if (composite_nomem(state->fde, c)) { … … 510 614 state->child = fork(); 511 615 if (state->child == (pid_t)-1) { 512 composite_error(c, map_nt_error_from_unix (errno));616 composite_error(c, map_nt_error_from_unix_common(errno)); 513 617 return c; 514 618 } -
vendor/current/source4/libcli/resolve/nbtlist.c
r740 r988 112 112 uint16_t port, 113 113 struct nbt_name *name, 114 const char * *address_list,114 const char * const *address_list, 115 115 struct interface *ifaces, 116 116 uint16_t nbt_port, -
vendor/current/source4/libcli/resolve/resolve.c
r740 r988 76 76 method->recv_fn = recv_fn; 77 77 method->privdata = userdata; 78 DLIST_ADD_END(ctx->methods, method , struct resolve_method *);78 DLIST_ADD_END(ctx->methods, method); 79 79 return true; 80 80 } … … 172 172 if (is_ipaddress(state->name.name) || 173 173 strcasecmp(state->name.name, "localhost") == 0) { 174 struct in_addr ip = interpret_addr2(state->name.name);175 176 174 state->addrs = talloc_array(state, struct socket_address *, 2); 177 175 if (composite_nomem(state->addrs, c)) return c; 178 state->addrs[0] = socket_address_from_strings(state->addrs, "ip v4",179 inet_ntoa(ip), 0);176 state->addrs[0] = socket_address_from_strings(state->addrs, "ip", 177 state->name.name, 0); 180 178 if (composite_nomem(state->addrs[0], c)) return c; 181 179 state->addrs[1] = NULL; … … 317 315 318 316 319 /*320 general name resolution - sync call321 */322 NTSTATUS resolve_name(struct resolve_context *ctx,323 struct nbt_name *name,324 TALLOC_CTX *mem_ctx,325 const char **reply_addr,326 struct tevent_context *ev)327 {328 return resolve_name_ex(ctx, 0, 0, name, mem_ctx, reply_addr, ev);329 }330 331 317 /* Initialise a struct nbt_name with a NULL scope */ 332 318 -
vendor/current/source4/libcli/resolve/resolve_lp.c
r740 r988 33 33 for (i = 0; methods != NULL && methods[i] != NULL; i++) { 34 34 if (!strcmp(methods[i], "wins")) { 35 resolve_context_add_wins_method_lp(ret, lp_ctx); 35 if (lpcfg_disable_netbios(lp_ctx) == false) { 36 resolve_context_add_wins_method_lp(ret, lp_ctx); 37 } 36 38 } else if (!strcmp(methods[i], "bcast")) { 37 resolve_context_add_bcast_method_lp(ret, lp_ctx); 38 } else if (!strcmp(methods[i], "file")) { 39 resolve_context_add_file_method_lp(ret, lp_ctx); 39 if (lpcfg_disable_netbios(lp_ctx) == false) { 40 resolve_context_add_bcast_method_lp(ret, lp_ctx); 41 } 42 } else if (!strcmp(methods[i], "lmhosts")) { 43 resolve_context_add_lmhosts_method(ret); 40 44 } else if (!strcmp(methods[i], "host")) { 41 45 resolve_context_add_host_method(ret); -
vendor/current/source4/libcli/resolve/testsuite.c
r740 r988 24 24 #include "libcli/resolve/resolve.h" 25 25 #include "torture/torture.h" 26 #include "torture/local/proto.h" 26 27 #include "system/network.h" 27 28 #include "lib/util/util_net.h" -
vendor/current/source4/libcli/resolve/wins.c
r740 r988 28 28 29 29 struct resolve_wins_data { 30 c onst char **address_list;30 char **address_list; 31 31 struct interface *ifaces; 32 32 uint16_t nbt_port; … … 48 48 if (wins_data->address_list == NULL) return NULL; 49 49 return resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, port, name, 50 wins_data->address_list, wins_data->ifaces, 50 (const char * const *)wins_data->address_list, 51 wins_data->ifaces, 51 52 wins_data->nbt_port, wins_data->nbt_timeout, 52 53 false, true); … … 67 68 { 68 69 struct resolve_wins_data *wins_data = talloc(ctx, struct resolve_wins_data); 69 wins_data->address_list = (const char **)str_list_copy(wins_data, address_list);70 wins_data->address_list = str_list_copy(wins_data, address_list); 70 71 wins_data->ifaces = talloc_reference(wins_data, ifaces); 71 72 wins_data->nbt_port = nbt_port; … … 78 79 { 79 80 struct interface *ifaces; 80 load_interface s(ctx, lpcfg_interfaces(lp_ctx), &ifaces);81 load_interface_list(ctx, lp_ctx, &ifaces); 81 82 return resolve_context_add_wins_method(ctx, lpcfg_wins_server_list(lp_ctx), ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1)); 82 83 } -
vendor/current/source4/libcli/security/tests/sddl.c
r740 r988 23 23 #include "libcli/security/security.h" 24 24 #include "torture/torture.h" 25 #include "torture/local/proto.h" 25 26 #include "librpc/gen_ndr/ndr_security.h" 26 27 -
vendor/current/source4/libcli/smb2/cancel.c
r740 r988 21 21 22 22 #include "includes.h" 23 #include <tevent.h> 23 24 #include "libcli/raw/libcliraw.h" 24 25 #include "libcli/smb2/smb2.h" … … 30 31 NTSTATUS smb2_cancel(struct smb2_request *r) 31 32 { 32 NTSTATUS status; 33 struct smb2_request *c; 34 uint32_t old_timeout; 35 uint64_t old_seqnum; 33 bool ok; 36 34 37 /* 38 * if we don't get a pending id yet, we just 39 * mark the request for pending, so that we directly 40 * send the cancel after getting the pending id 41 */ 42 if (!r->cancel.can_cancel) { 43 r->cancel.do_cancel++; 35 if (r->subreq == NULL) { 44 36 return NT_STATUS_OK; 45 37 } 46 38 47 /* we don't want a seqmun for a SMB2 Cancel */ 48 old_seqnum = r->transport->seqnum; 49 c = smb2_request_init(r->transport, SMB2_OP_CANCEL, 0x04, false, 0); 50 r->transport->seqnum = old_seqnum; 51 NT_STATUS_HAVE_NO_MEMORY(c); 52 c->seqnum = 0; 53 54 SIVAL(c->out.hdr, SMB2_HDR_FLAGS, 0x00000002); 55 SSVAL(c->out.hdr, SMB2_HDR_CREDIT, 0x0030); 56 SBVAL(c->out.hdr, SMB2_HDR_ASYNC_ID, r->cancel.async_id); 57 SBVAL(c->out.hdr, SMB2_HDR_MESSAGE_ID, c->seqnum); 58 if (r->session) { 59 SBVAL(c->out.hdr, SMB2_HDR_SESSION_ID, r->session->uid); 39 ok = tevent_req_cancel(r->subreq); 40 if (!ok) { 41 return NT_STATUS_INTERNAL_ERROR; 60 42 } 61 43 62 SSVAL(c->out.body, 0x02, 0); 63 64 old_timeout = c->transport->options.request_timeout; 65 c->transport->options.request_timeout = 0; 66 smb2_transport_send(c); 67 c->transport->options.request_timeout = old_timeout; 68 69 if (c->state == SMB2_REQUEST_ERROR) { 70 status = c->status; 71 } else { 72 status = NT_STATUS_OK; 73 } 74 75 talloc_free(c); 76 return status; 44 return NT_STATUS_OK; 77 45 } -
vendor/current/source4/libcli/smb2/connect.c
r414 r988 21 21 22 22 #include "includes.h" 23 #include <tevent.h> 24 #include "lib/util/tevent_ntstatus.h" 23 25 #include "libcli/raw/libcliraw.h" 24 26 #include "libcli/raw/raw_proto.h" … … 28 30 #include "libcli/resolve/resolve.h" 29 31 #include "param/param.h" 32 #include "auth/credentials/credentials.h" 33 #include "../libcli/smb/smbXcli_base.h" 30 34 31 35 struct smb2_connect_state { 36 struct tevent_context *ev; 32 37 struct cli_credentials *credentials; 38 uint64_t previous_session_id; 33 39 struct resolve_context *resolve_ctx; 34 40 const char *host; 35 41 const char *share; 42 const char *unc; 36 43 const char **ports; 37 44 const char *socket_options; 45 struct nbt_name calling, called; 38 46 struct gensec_settings *gensec_settings; 39 47 struct smbcli_options options; 40 struct smb2_negprot negprot; 41 struct smb2_tree_connect tcon; 48 struct smb2_transport *transport; 42 49 struct smb2_session *session; 43 50 struct smb2_tree *tree; 44 51 }; 45 52 46 /* 47 continue after tcon reply 48 */ 49 static void continue_tcon(struct smb2_request *req) 50 { 51 struct composite_context *c = talloc_get_type(req->async.private_data, 52 struct composite_context); 53 struct smb2_connect_state *state = talloc_get_type(c->private_data, 54 struct smb2_connect_state); 55 56 c->status = smb2_tree_connect_recv(req, &state->tcon); 57 if (!composite_is_ok(c)) return; 58 59 state->tree->tid = state->tcon.out.tid; 60 61 composite_done(c); 62 } 63 64 /* 65 continue after a session setup 66 */ 67 static void continue_session(struct composite_context *creq) 68 { 69 struct composite_context *c = talloc_get_type(creq->async.private_data, 70 struct composite_context); 71 struct smb2_connect_state *state = talloc_get_type(c->private_data, 72 struct smb2_connect_state); 73 struct smb2_request *req; 74 75 c->status = smb2_session_setup_spnego_recv(creq); 76 if (!composite_is_ok(c)) return; 77 78 state->tree = smb2_tree_init(state->session, state, true); 79 if (composite_nomem(state->tree, c)) return; 80 81 state->tcon.in.reserved = 0; 82 state->tcon.in.path = talloc_asprintf(state, "\\\\%s\\%s", 83 state->host, state->share); 84 if (composite_nomem(state->tcon.in.path, c)) return; 85 86 req = smb2_tree_connect_send(state->tree, &state->tcon); 87 if (composite_nomem(req, c)) return; 88 89 req->async.fn = continue_tcon; 90 req->async.private_data = c; 91 } 92 93 /* 94 continue after negprot reply 95 */ 96 static void continue_negprot(struct smb2_request *req) 97 { 98 struct composite_context *c = talloc_get_type(req->async.private_data, 99 struct composite_context); 100 struct smb2_connect_state *state = talloc_get_type(c->private_data, 101 struct smb2_connect_state); 102 struct smb2_transport *transport = req->transport; 103 struct composite_context *creq; 104 105 c->status = smb2_negprot_recv(req, c, &state->negprot); 106 if (!composite_is_ok(c)) return; 107 108 transport->negotiate.secblob = state->negprot.out.secblob; 109 talloc_steal(transport, transport->negotiate.secblob.data); 110 transport->negotiate.system_time = state->negprot.out.system_time; 111 transport->negotiate.server_start_time = state->negprot.out.server_start_time; 112 transport->negotiate.security_mode = state->negprot.out.security_mode; 113 transport->negotiate.dialect_revision = state->negprot.out.dialect_revision; 114 115 switch (transport->options.signing) { 116 case SMB_SIGNING_OFF: 117 if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { 118 composite_error(c, NT_STATUS_ACCESS_DENIED); 119 return; 120 } 121 transport->signing_required = false; 122 break; 123 case SMB_SIGNING_SUPPORTED: 124 if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { 125 transport->signing_required = true; 126 } else { 127 transport->signing_required = false; 128 } 129 break; 130 case SMB_SIGNING_AUTO: 131 if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) { 132 transport->signing_required = true; 133 } else { 134 transport->signing_required = false; 135 } 136 break; 137 case SMB_SIGNING_REQUIRED: 138 if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) { 139 transport->signing_required = true; 140 } else { 141 composite_error(c, NT_STATUS_ACCESS_DENIED); 142 return; 143 } 144 break; 145 } 146 147 state->session = smb2_session_init(transport, state->gensec_settings, state, true); 148 if (composite_nomem(state->session, c)) return; 149 150 creq = smb2_session_setup_spnego_send(state->session, state->credentials); 151 152 composite_continue(c, creq, continue_session, c); 153 } 154 155 /* 156 continue after a socket connect completes 157 */ 158 static void continue_socket(struct composite_context *creq) 159 { 160 struct composite_context *c = talloc_get_type(creq->async.private_data, 161 struct composite_context); 162 struct smb2_connect_state *state = talloc_get_type(c->private_data, 163 struct smb2_connect_state); 164 struct smbcli_socket *sock; 165 struct smb2_transport *transport; 166 struct smb2_request *req; 167 uint16_t dialects[3] = { 168 SMB2_DIALECT_REVISION_000, 169 SMB2_DIALECT_REVISION_202, 170 SMB2_DIALECT_REVISION_210 171 }; 172 173 c->status = smbcli_sock_connect_recv(creq, state, &sock); 174 if (!composite_is_ok(c)) return; 175 176 transport = smb2_transport_init(sock, state, &state->options); 177 if (composite_nomem(transport, c)) return; 178 179 ZERO_STRUCT(state->negprot); 180 state->negprot.in.dialect_count = sizeof(dialects) / sizeof(dialects[0]); 181 switch (transport->options.signing) { 182 case SMB_SIGNING_OFF: 183 state->negprot.in.security_mode = 0; 184 break; 185 case SMB_SIGNING_SUPPORTED: 186 case SMB_SIGNING_AUTO: 187 state->negprot.in.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; 188 break; 189 case SMB_SIGNING_REQUIRED: 190 state->negprot.in.security_mode = 191 SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; 192 break; 193 } 194 state->negprot.in.capabilities = 0; 195 unix_to_nt_time(&state->negprot.in.start_time, time(NULL)); 196 state->negprot.in.dialects = dialects; 197 198 req = smb2_negprot_send(transport, &state->negprot); 199 if (composite_nomem(req, c)) return; 200 201 req->async.fn = continue_negprot; 202 req->async.private_data = c; 203 } 204 205 206 /* 207 continue after a resolve finishes 208 */ 209 static void continue_resolve(struct composite_context *creq) 210 { 211 struct composite_context *c = talloc_get_type(creq->async.private_data, 212 struct composite_context); 213 struct smb2_connect_state *state = talloc_get_type(c->private_data, 214 struct smb2_connect_state); 215 const char *addr; 216 const char **ports; 217 const char *default_ports[] = { "445", NULL }; 218 219 c->status = resolve_name_recv(creq, state, &addr); 220 if (!composite_is_ok(c)) return; 221 222 if (state->ports == NULL) { 223 ports = default_ports; 224 } else { 225 ports = state->ports; 226 } 227 228 creq = smbcli_sock_connect_send(state, addr, ports, state->host, state->resolve_ctx, c->event_ctx, state->socket_options); 229 230 composite_continue(c, creq, continue_socket, c); 231 } 53 static void smb2_connect_socket_done(struct composite_context *creq); 232 54 233 55 /* … … 235 57 a connected smb2_tree 236 58 */ 237 struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, 238 const char *host, 239 const char **ports, 240 const char *share, 241 struct resolve_context *resolve_ctx, 242 struct cli_credentials *credentials, 243 struct tevent_context *ev, 244 struct smbcli_options *options, 245 const char *socket_options, 246 struct gensec_settings *gensec_settings) 247 { 248 struct composite_context *c; 59 struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx, 60 struct tevent_context *ev, 61 const char *host, 62 const char **ports, 63 const char *share, 64 struct resolve_context *resolve_ctx, 65 struct cli_credentials *credentials, 66 uint64_t previous_session_id, 67 const struct smbcli_options *options, 68 const char *socket_options, 69 struct gensec_settings *gensec_settings) 70 { 71 struct tevent_req *req; 249 72 struct smb2_connect_state *state; 250 struct nbt_name name;251 73 struct composite_context *creq; 252 253 c = composite_create(mem_ctx, ev); 254 if (c == NULL) return NULL; 255 256 state = talloc(c, struct smb2_connect_state); 257 if (composite_nomem(state, c)) return c; 258 c->private_data = state; 259 74 static const char *default_ports[] = { "445", "139", NULL }; 75 76 req = tevent_req_create(mem_ctx, &state, 77 struct smb2_connect_state); 78 if (req == NULL) { 79 return NULL; 80 } 81 82 state->ev = ev; 260 83 state->credentials = credentials; 84 state->previous_session_id = previous_session_id; 261 85 state->options = *options; 262 state->host = talloc_strdup(c, host); 263 if (composite_nomem(state->host, c)) return c; 264 state->ports = talloc_reference(state, ports); 265 state->share = talloc_strdup(c, share); 266 if (composite_nomem(state->share, c)) return c; 267 state->resolve_ctx = talloc_reference(state, resolve_ctx); 268 state->socket_options = talloc_reference(state, socket_options); 269 state->gensec_settings = talloc_reference(state, gensec_settings); 270 271 ZERO_STRUCT(name); 272 name.name = host; 273 274 creq = resolve_name_send(resolve_ctx, state, &name, c->event_ctx); 275 composite_continue(c, creq, continue_resolve, c); 276 return c; 277 } 278 279 /* 280 receive a connect reply 281 */ 282 NTSTATUS smb2_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, 86 state->host = host; 87 state->ports = ports; 88 state->share = share; 89 state->resolve_ctx = resolve_ctx; 90 state->socket_options = socket_options; 91 state->gensec_settings = gensec_settings; 92 93 if (state->ports == NULL) { 94 state->ports = default_ports; 95 } 96 97 make_nbt_name_client(&state->calling, 98 cli_credentials_get_workstation(credentials)); 99 100 nbt_choose_called_name(state, &state->called, 101 host, NBT_NAME_SERVER); 102 103 state->unc = talloc_asprintf(state, "\\\\%s\\%s", 104 state->host, state->share); 105 if (tevent_req_nomem(state->unc, req)) { 106 return tevent_req_post(req, ev); 107 } 108 109 creq = smbcli_sock_connect_send(state, NULL, state->ports, 110 state->host, state->resolve_ctx, 111 state->ev, state->socket_options, 112 &state->calling, 113 &state->called); 114 if (tevent_req_nomem(creq, req)) { 115 return tevent_req_post(req, ev); 116 } 117 creq->async.fn = smb2_connect_socket_done; 118 creq->async.private_data = req; 119 120 return req; 121 } 122 123 static void smb2_connect_negprot_done(struct tevent_req *subreq); 124 125 static void smb2_connect_socket_done(struct composite_context *creq) 126 { 127 struct tevent_req *req = 128 talloc_get_type_abort(creq->async.private_data, 129 struct tevent_req); 130 struct smb2_connect_state *state = 131 tevent_req_data(req, 132 struct smb2_connect_state); 133 struct smbcli_socket *sock; 134 struct tevent_req *subreq; 135 NTSTATUS status; 136 uint32_t timeout_msec; 137 enum protocol_types min_protocol; 138 139 status = smbcli_sock_connect_recv(creq, state, &sock); 140 if (tevent_req_nterror(req, status)) { 141 return; 142 } 143 144 state->transport = smb2_transport_init(sock, state, &state->options); 145 if (tevent_req_nomem(state->transport, req)) { 146 return; 147 } 148 149 timeout_msec = state->transport->options.request_timeout * 1000; 150 min_protocol = state->transport->options.min_protocol; 151 if (min_protocol < PROTOCOL_SMB2_02) { 152 min_protocol = PROTOCOL_SMB2_02; 153 } 154 155 subreq = smbXcli_negprot_send(state, state->ev, 156 state->transport->conn, timeout_msec, 157 min_protocol, 158 state->transport->options.max_protocol); 159 if (tevent_req_nomem(subreq, req)) { 160 return; 161 } 162 tevent_req_set_callback(subreq, smb2_connect_negprot_done, req); 163 } 164 165 static void smb2_connect_session_done(struct tevent_req *subreq); 166 167 static void smb2_connect_negprot_done(struct tevent_req *subreq) 168 { 169 struct tevent_req *req = 170 tevent_req_callback_data(subreq, 171 struct tevent_req); 172 struct smb2_connect_state *state = 173 tevent_req_data(req, 174 struct smb2_connect_state); 175 struct smb2_transport *transport = state->transport; 176 NTSTATUS status; 177 178 status = smbXcli_negprot_recv(subreq); 179 TALLOC_FREE(subreq); 180 if (tevent_req_nterror(req, status)) { 181 return; 182 } 183 184 /* This is a hack... */ 185 smb2cli_conn_set_max_credits(transport->conn, 30); 186 187 state->session = smb2_session_init(transport, state->gensec_settings, state); 188 if (tevent_req_nomem(state->session, req)) { 189 return; 190 } 191 192 subreq = smb2_session_setup_spnego_send(state, state->ev, 193 state->session, 194 state->credentials, 195 state->previous_session_id); 196 if (tevent_req_nomem(subreq, req)) { 197 return; 198 } 199 tevent_req_set_callback(subreq, smb2_connect_session_done, req); 200 } 201 202 static void smb2_connect_tcon_done(struct tevent_req *subreq); 203 204 static void smb2_connect_session_done(struct tevent_req *subreq) 205 { 206 struct tevent_req *req = 207 tevent_req_callback_data(subreq, 208 struct tevent_req); 209 struct smb2_connect_state *state = 210 tevent_req_data(req, 211 struct smb2_connect_state); 212 NTSTATUS status; 213 uint32_t timeout_msec; 214 215 status = smb2_session_setup_spnego_recv(subreq); 216 TALLOC_FREE(subreq); 217 if (tevent_req_nterror(req, status)) { 218 return; 219 } 220 221 state->tree = smb2_tree_init(state->session, state, true); 222 if (tevent_req_nomem(state->tree, req)) { 223 return; 224 } 225 226 timeout_msec = state->transport->options.request_timeout * 1000; 227 228 subreq = smb2cli_tcon_send(state, state->ev, 229 state->transport->conn, 230 timeout_msec, 231 state->session->smbXcli, 232 state->tree->smbXcli, 233 0, /* flags */ 234 state->unc); 235 if (tevent_req_nomem(subreq, req)) { 236 return; 237 } 238 tevent_req_set_callback(subreq, smb2_connect_tcon_done, req); 239 } 240 241 static void smb2_connect_tcon_done(struct tevent_req *subreq) 242 { 243 struct tevent_req *req = 244 tevent_req_callback_data(subreq, 245 struct tevent_req); 246 NTSTATUS status; 247 248 status = smb2cli_tcon_recv(subreq); 249 if (tevent_req_nterror(req, status)) { 250 return; 251 } 252 253 tevent_req_done(req); 254 } 255 256 NTSTATUS smb2_connect_recv(struct tevent_req *req, 257 TALLOC_CTX *mem_ctx, 283 258 struct smb2_tree **tree) 284 259 { 285 NTSTATUS status; 286 struct smb2_connect_state *state = talloc_get_type(c->private_data, 287 struct smb2_connect_state); 288 status = composite_wait(c); 289 if (NT_STATUS_IS_OK(status)) { 290 *tree = talloc_steal(mem_ctx, state->tree); 291 } 292 talloc_free(c); 293 return status; 260 struct smb2_connect_state *state = 261 tevent_req_data(req, 262 struct smb2_connect_state); 263 NTSTATUS status; 264 265 if (tevent_req_is_nterror(req, &status)) { 266 tevent_req_received(req); 267 return status; 268 } 269 270 *tree = talloc_move(mem_ctx, &state->tree); 271 272 tevent_req_received(req); 273 return NT_STATUS_OK; 294 274 } 295 275 … … 297 277 sync version of smb2_connect 298 278 */ 299 NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, 300 const char *host, const char **ports, 279 NTSTATUS smb2_connect_ext(TALLOC_CTX *mem_ctx, 280 const char *host, 281 const char **ports, 301 282 const char *share, 283 struct resolve_context *resolve_ctx, 284 struct cli_credentials *credentials, 285 uint64_t previous_session_id, 286 struct smb2_tree **tree, 287 struct tevent_context *ev, 288 const struct smbcli_options *options, 289 const char *socket_options, 290 struct gensec_settings *gensec_settings) 291 { 292 struct tevent_req *subreq; 293 NTSTATUS status; 294 bool ok; 295 TALLOC_CTX *frame = talloc_stackframe(); 296 297 if (frame == NULL) { 298 return NT_STATUS_NO_MEMORY; 299 } 300 301 subreq = smb2_connect_send(frame, 302 ev, 303 host, 304 ports, 305 share, 306 resolve_ctx, 307 credentials, 308 previous_session_id, 309 options, 310 socket_options, 311 gensec_settings); 312 if (subreq == NULL) { 313 TALLOC_FREE(frame); 314 return NT_STATUS_NO_MEMORY; 315 } 316 317 ok = tevent_req_poll(subreq, ev); 318 if (!ok) { 319 status = map_nt_error_from_unix_common(errno); 320 TALLOC_FREE(frame); 321 return status; 322 } 323 324 status = smb2_connect_recv(subreq, mem_ctx, tree); 325 TALLOC_FREE(subreq); 326 if (!NT_STATUS_IS_OK(status)) { 327 TALLOC_FREE(frame); 328 return status; 329 } 330 331 TALLOC_FREE(frame); 332 return NT_STATUS_OK; 333 } 334 335 NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, 336 const char *host, 337 const char **ports, 338 const char *share, 302 339 struct resolve_context *resolve_ctx, 303 340 struct cli_credentials *credentials, … … 305 342 struct tevent_context *ev, 306 343 struct smbcli_options *options, 307 const char *socket_options, 308 struct gensec_settings *gensec_settings) 309 { 310 struct composite_context *c = smb2_connect_send(mem_ctx, host, ports, 311 share, resolve_ctx, 312 credentials, ev, options, 313 socket_options, 314 gensec_settings); 315 return smb2_connect_recv(c, mem_ctx, tree); 316 } 344 const char *socket_options, 345 struct gensec_settings *gensec_settings) 346 { 347 NTSTATUS status; 348 349 status = smb2_connect_ext(mem_ctx, host, ports, share, resolve_ctx, 350 credentials, 351 0, /* previous_session_id */ 352 tree, ev, options, socket_options, 353 gensec_settings); 354 355 return status; 356 } -
vendor/current/source4/libcli/smb2/create.c
r740 r988 107 107 } 108 108 109 if (io->in.durable_open_v2) { 110 uint8_t data[32]; 111 uint32_t flags = 0; 112 DATA_BLOB guid_blob; 113 114 SIVAL(data, 0, io->in.timeout); 115 if (io->in.persistent_open) { 116 flags = SMB2_DHANDLE_FLAG_PERSISTENT; 117 } 118 SIVAL(data, 4, flags); 119 SBVAL(data, 8, 0x0); /* reserved */ 120 status = GUID_to_ndr_blob(&io->in.create_guid, req, /* TALLOC_CTX */ 121 &guid_blob); 122 if (!NT_STATUS_IS_OK(status)) { 123 talloc_free(req); 124 return NULL; 125 } 126 memcpy(data+16, guid_blob.data, 16); 127 128 status = smb2_create_blob_add(req, &blobs, 129 SMB2_CREATE_TAG_DH2Q, 130 data_blob_const(data, 32)); 131 if (!NT_STATUS_IS_OK(status)) { 132 talloc_free(req); 133 return NULL; 134 } 135 } 136 109 137 if (io->in.durable_handle) { 110 138 uint8_t data[16]; … … 112 140 status = smb2_create_blob_add(req, &blobs, 113 141 SMB2_CREATE_TAG_DHNC, data_blob_const(data, 16)); 142 if (!NT_STATUS_IS_OK(status)) { 143 talloc_free(req); 144 return NULL; 145 } 146 } 147 148 if (io->in.durable_handle_v2) { 149 uint8_t data[36]; 150 DATA_BLOB guid_blob; 151 uint32_t flags = 0; 152 153 smb2_push_handle(data, io->in.durable_handle_v2); 154 status = GUID_to_ndr_blob(&io->in.create_guid, req, /* TALLOC_CTX */ 155 &guid_blob); 156 if (!NT_STATUS_IS_OK(status)) { 157 talloc_free(req); 158 return NULL; 159 } 160 memcpy(data+16, guid_blob.data, 16); 161 if (io->in.persistent_open) { 162 flags = SMB2_DHANDLE_FLAG_PERSISTENT; 163 } 164 SIVAL(data, 32, flags); 165 166 status = smb2_create_blob_add(req, &blobs, 167 SMB2_CREATE_TAG_DH2C, 168 data_blob_const(data, 36)); 114 169 if (!NT_STATUS_IS_OK(status)) { 115 170 talloc_free(req); … … 158 213 uint8_t data[32]; 159 214 160 memcpy(&data[0], &io->in.lease_request->lease_key, 16); 161 SIVAL(data, 16, io->in.lease_request->lease_state); 162 SIVAL(data, 20, io->in.lease_request->lease_flags); 163 SBVAL(data, 24, io->in.lease_request->lease_duration); 164 165 status = smb2_create_blob_add(req, &blobs, 166 SMB2_CREATE_TAG_RQLS, 167 data_blob_const(data, 32)); 215 if (!smb2_lease_push(io->in.lease_request, data, 216 sizeof(data))) { 217 TALLOC_FREE(req); 218 return NULL; 219 } 220 221 status = smb2_create_blob_add( 222 req, &blobs, SMB2_CREATE_TAG_RQLS, 223 data_blob_const(data, sizeof(data))); 224 if (!NT_STATUS_IS_OK(status)) { 225 talloc_free(req); 226 return NULL; 227 } 228 } 229 230 if (io->in.lease_request_v2) { 231 uint8_t data[52]; 232 233 if (!smb2_lease_push(io->in.lease_request_v2, data, 234 sizeof(data))) { 235 TALLOC_FREE(req); 236 return NULL; 237 } 238 239 status = smb2_create_blob_add( 240 req, &blobs, SMB2_CREATE_TAG_RQLS, 241 data_blob_const(data, sizeof(data))); 242 if (!NT_STATUS_IS_OK(status)) { 243 talloc_free(req); 244 return NULL; 245 } 246 } 247 248 if (io->in.app_instance_id) { 249 uint8_t data[20]; 250 DATA_BLOB guid_blob; 251 252 SSVAL(data, 0, 20); /* structure size */ 253 SSVAL(data, 2, 0); /* reserved */ 254 255 status = GUID_to_ndr_blob(io->in.app_instance_id, 256 req, /* TALLOC_CTX */ 257 &guid_blob); 258 if (!NT_STATUS_IS_OK(status)) { 259 talloc_free(req); 260 return NULL; 261 } 262 memcpy(data+4, guid_blob.data, 16); 263 264 status = smb2_create_blob_add(req, &blobs, 265 SMB2_CREATE_TAG_APP_INSTANCE_ID, 266 data_blob_const(data, 20)); 168 267 if (!NT_STATUS_IS_OK(status)) { 169 268 talloc_free(req); … … 194 293 talloc_free(req); 195 294 return NULL; 295 } 296 297 if (((io->in.fname == NULL) || (strlen(io->in.fname) == 0)) && 298 (blob.length == 0)) { 299 struct smb2_request_buffer *buf = &req->out; 300 301 status = smb2_grow_buffer(buf, 1); 302 if (!NT_STATUS_IS_OK(status)) { 303 talloc_free(req); 304 return NULL; 305 } 306 buf->dynamic[0] = 0; 307 buf->dynamic += 1; 308 buf->body_size += 1; 309 buf->size += 1; 196 310 } 197 311 … … 263 377 } 264 378 if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_RQLS) == 0) { 379 struct smb2_lease *ls = NULL; 265 380 uint8_t *data; 266 if (io->out.blobs.blobs[i].data.length != 32) { 381 382 ZERO_STRUCT(io->out.lease_response); 383 ZERO_STRUCT(io->out.lease_response_v2); 384 385 switch (io->out.blobs.blobs[i].data.length) { 386 case 32: 387 ls = &io->out.lease_response; 388 ls->lease_version = 1; 389 break; 390 case 52: 391 ls = &io->out.lease_response_v2; 392 ls->lease_version = 2; 393 break; 394 default: 267 395 smb2_request_destroy(req); 268 396 return NT_STATUS_INVALID_NETWORK_RESPONSE; … … 270 398 271 399 data = io->out.blobs.blobs[i].data.data; 272 memcpy(&io->out.lease_response.lease_key, data, 16); 273 io->out.lease_response.lease_state = IVAL(data, 16); 274 io->out.lease_response.lease_flags = IVAL(data, 20); 275 io->out.lease_response.lease_duration = BVAL(data, 24); 400 memcpy(&ls->lease_key, data, 16); 401 ls->lease_state = IVAL(data, 16); 402 ls->lease_flags = IVAL(data, 20); 403 ls->lease_duration = BVAL(data, 24); 404 405 if (io->out.blobs.blobs[i].data.length == 52) { 406 memcpy(&ls->parent_lease_key, data+32, 16); 407 ls->lease_epoch = SVAL(data, 48); 408 } 409 } 410 if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_DHNQ) == 0) { 411 if (io->out.blobs.blobs[i].data.length != 8) { 412 smb2_request_destroy(req); 413 return NT_STATUS_INVALID_NETWORK_RESPONSE; 414 } 415 io->out.durable_open = true; 416 } 417 if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_DH2Q) == 0) { 418 uint32_t flags; 419 uint8_t *data; 420 421 if (io->out.blobs.blobs[i].data.length != 8) { 422 smb2_request_destroy(req); 423 return NT_STATUS_INVALID_NETWORK_RESPONSE; 424 } 425 426 io->out.durable_open = false; 427 io->out.durable_open_v2 = true; 428 429 data = io->out.blobs.blobs[i].data.data; 430 io->out.timeout = IVAL(data, 0); 431 flags = IVAL(data, 4); 432 if ((flags & SMB2_DHANDLE_FLAG_PERSISTENT) != 0) { 433 io->out.persistent_open = true; 434 } 276 435 } 277 436 } -
vendor/current/source4/libcli/smb2/find.c
r740 r988 34 34 NTSTATUS status; 35 35 36 req = smb2_request_init_tree(tree, SMB2_OP_ FIND, 0x20, true, 0);36 req = smb2_request_init_tree(tree, SMB2_OP_QUERY_DIRECTORY, 0x20, true, 0); 37 37 if (req == NULL) return NULL; 38 38 -
vendor/current/source4/libcli/smb2/ioctl.c
r414 r988 23 23 #include "libcli/smb2/smb2.h" 24 24 #include "libcli/smb2/smb2_calls.h" 25 #include "librpc/gen_ndr/ioctl.h" 25 26 26 27 /* … … 62 63 } 63 64 65 /* 66 * 3.3.4.4 Sending an Error Response 67 */ 68 static bool smb2_ioctl_is_failure(uint32_t ctl_code, NTSTATUS status, 69 size_t data_size) 70 { 71 if (NT_STATUS_IS_OK(status)) { 72 return false; 73 } 74 75 if (NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW) 76 && ((ctl_code == FSCTL_PIPE_TRANSCEIVE) 77 || (ctl_code == FSCTL_PIPE_PEEK) 78 || (ctl_code == FSCTL_DFS_GET_REFERRALS))) { 79 return false; 80 } 81 82 if (((ctl_code == FSCTL_SRV_COPYCHUNK) 83 || (ctl_code == FSCTL_SRV_COPYCHUNK_WRITE)) 84 && (data_size == sizeof(struct srv_copychunk_rsp))) { 85 /* 86 * copychunk responses may come with copychunk data or error 87 * response data, independent of status. 88 */ 89 return false; 90 } 91 92 return true; 93 } 64 94 65 95 /* 66 96 recv a ioctl reply 67 97 */ 68 NTSTATUS smb2_ioctl_recv(struct smb2_request *req, 98 NTSTATUS smb2_ioctl_recv(struct smb2_request *req, 69 99 TALLOC_CTX *mem_ctx, struct smb2_ioctl *io) 70 100 { 71 101 NTSTATUS status; 72 102 73 if (!smb2_request_receive(req) || 74 smb2_request_is_error(req)) { 103 if (!smb2_request_receive(req) || 104 smb2_ioctl_is_failure(io->in.function, req->status, 105 req->in.bufinfo.data_size)) { 75 106 return smb2_request_destroy(req); 76 107 } -
vendor/current/source4/libcli/smb2/logoff.c
r414 r988 36 36 req->session = session; 37 37 38 SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, session->uid);39 40 38 SSVAL(req->out.body, 0x02, 0); 41 39 -
vendor/current/source4/libcli/smb2/read.c
r414 r988 45 45 SSVAL(req->out.body, 0x2E, io->in.channel_length); 46 46 47 req->credit_charge = (MAX(io->in.length, 1) - 1)/ 65536 + 1; 48 47 49 smb2_transport_send(req); 48 50 -
vendor/current/source4/libcli/smb2/request.c
r740 r988 43 43 } 44 44 45 46 /* destroy a request structure */47 static int smb2_request_destructor(struct smb2_request *req)48 {49 if (req->transport) {50 /* remove it from the list of pending requests (a null op if51 its not in the list) */52 DLIST_REMOVE(req->transport->pending_recv, req);53 }54 return 0;55 }56 57 45 /* 58 46 initialise a smb2 request … … 63 51 { 64 52 struct smb2_request *req; 65 uint64_t seqnum;66 53 uint32_t hdr_offset; 67 uint32_t flags = 0;68 54 bool compound = false; 69 55 … … 76 62 } 77 63 78 req = talloc (transport, struct smb2_request);64 req = talloc_zero(transport, struct smb2_request); 79 65 if (req == NULL) return NULL; 80 81 seqnum = transport->seqnum;82 if (transport->credits.charge > 0) {83 transport->seqnum += transport->credits.charge;84 } else {85 transport->seqnum += 1;86 }87 66 88 67 req->state = SMB2_REQUEST_INIT; 89 68 req->transport = transport; 90 req->session = NULL; 91 req->tree = NULL; 92 req->seqnum = seqnum; 93 req->status = NT_STATUS_OK; 94 req->async.fn = NULL; 95 req->next = req->prev = NULL; 96 97 ZERO_STRUCT(req->cancel); 98 ZERO_STRUCT(req->in); 99 100 if (transport->compound.missing > 0) { 101 compound = true; 102 transport->compound.missing -= 1; 103 req->out = transport->compound.buffer; 104 ZERO_STRUCT(transport->compound.buffer); 105 if (transport->compound.related) { 106 flags |= SMB2_HDR_FLAG_CHAINED; 107 } 108 } else { 109 ZERO_STRUCT(req->out); 110 } 111 112 if (req->out.size > 0) { 113 hdr_offset = req->out.size; 114 } else { 115 hdr_offset = NBT_HDR_SIZE; 116 } 69 70 hdr_offset = NBT_HDR_SIZE; 117 71 118 72 req->out.size = hdr_offset + SMB2_HDR_BODY + body_fixed_size; … … 134 88 SIVAL(req->out.hdr, 0, SMB2_MAGIC); 135 89 SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); 136 SSVAL(req->out.hdr, SMB2_HDR_ EPOCH, transport->credits.charge);90 SSVAL(req->out.hdr, SMB2_HDR_CREDIT_CHARGE, 0); 137 91 SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); 138 92 SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); 139 SSVAL(req->out.hdr, SMB2_HDR_CREDIT, transport->credits.ask_num);140 SIVAL(req->out.hdr, SMB2_HDR_FLAGS, flags);93 SSVAL(req->out.hdr, SMB2_HDR_CREDIT, 0); 94 SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); 141 95 SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND, 0); 142 SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID, req->seqnum);96 SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID, 0); 143 97 SIVAL(req->out.hdr, SMB2_HDR_PID, 0); 144 98 SIVAL(req->out.hdr, SMB2_HDR_TID, 0); … … 158 112 } 159 113 160 talloc_set_destructor(req, smb2_request_destructor);161 162 114 return req; 163 115 } … … 175 127 if (req == NULL) return NULL; 176 128 177 SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, tree->session->uid);178 SIVAL(req->out.hdr, SMB2_HDR_PID, tree->session->pid);179 SIVAL(req->out.hdr, SMB2_HDR_TID, tree->tid);180 129 req->session = tree->session; 181 130 req->tree = tree; … … 215 164 /* keep receiving packets until this one is replied to */ 216 165 while (req->state <= SMB2_REQUEST_RECV) { 217 if ( event_loop_once(req->transport->socket->event.ctx) != 0) {166 if (tevent_loop_once(req->transport->ev) != 0) { 218 167 return false; 219 168 } … … 687 636 NTSTATUS status; 688 637 void *vstr; 638 size_t converted_size = 0; 689 639 bool ret; 690 640 … … 706 656 707 657 ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, 708 blob.data, blob.length, &vstr, NULL, false);658 blob.data, blob.length, &vstr, &converted_size); 709 659 data_blob_free(&blob); 710 660 (*str) = (char *)vstr; … … 725 675 NTSTATUS status; 726 676 bool ret; 677 void *ptr = NULL; 727 678 728 679 if (str == NULL) { … … 737 688 738 689 ret = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, 739 str, strlen(str), (void **)&blob.data, &blob.length, 740 false); 690 str, strlen(str), &ptr, &blob.length); 741 691 if (!ret) { 742 692 return NT_STATUS_ILLEGAL_CHARACTER; 743 693 } 694 blob.data = (uint8_t *)ptr; 744 695 745 696 status = smb2_push_o16s16_blob(buf, ofs, blob); -
vendor/current/source4/libcli/smb2/session.c
r740 r988 21 21 22 22 #include "includes.h" 23 #include "system/network.h" 24 #include <tevent.h> 25 #include "lib/util/tevent_ntstatus.h" 23 26 #include "libcli/raw/libcliraw.h" 24 27 #include "libcli/smb2/smb2.h" 25 28 #include "libcli/smb2/smb2_calls.h" 26 #include "libcli/composite/composite.h"27 29 #include "auth/gensec/gensec.h" 28 29 #include <unistd.h>30 #include "auth/credentials/credentials.h" 31 #include "../libcli/smb/smbXcli_base.h" 30 32 31 33 /** … … 34 36 struct smb2_session *smb2_session_init(struct smb2_transport *transport, 35 37 struct gensec_settings *settings, 36 TALLOC_CTX *parent_ctx , bool primary)38 TALLOC_CTX *parent_ctx) 37 39 { 38 40 struct smb2_session *session; … … 43 45 return NULL; 44 46 } 45 if (primary) {46 session->transport = talloc_steal(session, transport); 47 } else {48 session->transport = talloc_reference(session, transport);49 }50 51 session->pid = getpid();47 session->transport = talloc_steal(session, transport); 48 49 session->smbXcli = smbXcli_session_create(session, transport->conn); 50 if (session->smbXcli == NULL) { 51 talloc_free(session); 52 return NULL; 53 } 52 54 53 55 /* prepare a gensec context for later use */ 54 status = gensec_client_start(session, &session->gensec, 55 session->transport->socket->event.ctx, 56 status = gensec_client_start(session, &session->gensec, 56 57 settings); 57 58 if (!NT_STATUS_IS_OK(status)) { … … 65 66 } 66 67 67 /** 68 send a session setup request 69 */ 70 struct smb2_request *smb2_session_setup_send(struct smb2_session *session, 71 struct smb2_session_setup *io) 72 { 73 struct smb2_request *req; 74 NTSTATUS status; 75 76 req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, 77 0x18, true, io->in.secblob.length); 78 if (req == NULL) return NULL; 79 80 SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, session->uid); 81 SCVAL(req->out.body, 0x02, io->in.vc_number); 82 SCVAL(req->out.body, 0x03, io->in.security_mode); 83 SIVAL(req->out.body, 0x04, io->in.capabilities); 84 SIVAL(req->out.body, 0x08, io->in.channel); 85 SBVAL(req->out.body, 0x10, io->in.previous_sessionid); 86 87 req->session = session; 88 89 status = smb2_push_o16s16_blob(&req->out, 0x0C, io->in.secblob); 68 /* 69 * Note: that the caller needs to keep 'transport' around as 70 * long as the returned session is active! 71 */ 72 struct smb2_session *smb2_session_channel(struct smb2_transport *transport, 73 struct gensec_settings *settings, 74 TALLOC_CTX *parent_ctx, 75 struct smb2_session *base_session) 76 { 77 struct smb2_session *session; 78 NTSTATUS status; 79 80 session = talloc_zero(parent_ctx, struct smb2_session); 81 if (!session) { 82 return NULL; 83 } 84 session->transport = transport; 85 86 status = smb2cli_session_create_channel(session, 87 base_session->smbXcli, 88 transport->conn, 89 &session->smbXcli); 90 90 if (!NT_STATUS_IS_OK(status)) { 91 talloc_free(req); 92 return NULL; 93 } 94 95 smb2_transport_send(req); 96 97 return req; 98 } 99 100 101 /** 102 recv a session setup reply 103 */ 104 NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, 105 struct smb2_session_setup *io) 106 { 107 NTSTATUS status; 108 109 if (!smb2_request_receive(req) || 110 (smb2_request_is_error(req) && 111 !NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED))) { 112 return smb2_request_destroy(req); 113 } 114 115 SMB2_CHECK_PACKET_RECV(req, 0x08, true); 116 117 io->out.session_flags = SVAL(req->in.body, 0x02); 118 io->out.uid = BVAL(req->in.hdr, SMB2_HDR_SESSION_ID); 119 120 status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob); 91 talloc_free(session); 92 return NULL; 93 } 94 95 session->needs_bind = true; 96 97 /* prepare a gensec context for later use */ 98 status = gensec_client_start(session, &session->gensec, 99 settings); 121 100 if (!NT_STATUS_IS_OK(status)) { 122 smb2_request_destroy(req); 123 return status; 124 } 125 126 return smb2_request_destroy(req); 127 } 128 129 /* 130 sync session setup request 131 */ 132 NTSTATUS smb2_session_setup(struct smb2_session *session, 133 TALLOC_CTX *mem_ctx, struct smb2_session_setup *io) 134 { 135 struct smb2_request *req = smb2_session_setup_send(session, io); 136 return smb2_session_setup_recv(req, mem_ctx, io); 137 } 138 139 140 struct smb2_session_state { 141 struct smb2_session_setup io; 142 struct smb2_request *req; 101 talloc_free(session); 102 return NULL; 103 } 104 105 gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY); 106 107 return session; 108 } 109 110 struct smb2_session_setup_spnego_state { 111 struct tevent_context *ev; 112 struct smb2_session *session; 113 struct cli_credentials *credentials; 114 uint64_t previous_session_id; 115 bool session_bind; 116 bool reauth; 143 117 NTSTATUS gensec_status; 118 DATA_BLOB in_secblob; 119 DATA_BLOB out_secblob; 144 120 }; 145 121 146 /* 147 handle continuations of the spnego session setup 148 */ 149 static void session_request_handler(struct smb2_request *req) 150 { 151 struct composite_context *c = talloc_get_type(req->async.private_data, 152 struct composite_context); 153 struct smb2_session_state *state = talloc_get_type(c->private_data, 154 struct smb2_session_state); 155 struct smb2_session *session = req->session; 156 NTSTATUS session_key_err; 157 DATA_BLOB session_key; 158 NTSTATUS peer_status; 159 160 c->status = smb2_session_setup_recv(req, c, &state->io); 161 peer_status = c->status; 162 163 if (NT_STATUS_EQUAL(peer_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || 164 (NT_STATUS_IS_OK(peer_status) && 165 NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED))) { 166 c->status = gensec_update(session->gensec, c, 167 state->io.out.secblob, 168 &state->io.in.secblob); 169 state->gensec_status = c->status; 170 171 session->uid = state->io.out.uid; 172 } 173 174 if (!NT_STATUS_IS_OK(c->status) && 175 !NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 176 composite_error(c, c->status); 177 return; 178 } 179 180 if (NT_STATUS_EQUAL(peer_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 181 state->req = smb2_session_setup_send(session, &state->io); 182 if (state->req == NULL) { 183 composite_error(c, NT_STATUS_NO_MEMORY); 184 return; 185 } 186 187 state->req->async.fn = session_request_handler; 188 state->req->async.private_data = c; 189 return; 190 } 191 192 session_key_err = gensec_session_key(session->gensec, &session_key); 193 if (NT_STATUS_IS_OK(session_key_err)) { 194 session->session_key = session_key; 195 } 196 197 if (session->transport->signing_required) { 198 if (session->session_key.length == 0) { 199 DEBUG(0,("Wrong session key length %u for SMB2 signing\n", 200 (unsigned)session->session_key.length)); 201 composite_error(c, NT_STATUS_ACCESS_DENIED); 202 return; 203 } 204 session->signing_active = true; 205 } 206 207 composite_done(c); 208 } 122 static void smb2_session_setup_spnego_done(struct tevent_req *subreq); 209 123 210 124 /* 211 125 a composite function that does a full SPNEGO session setup 212 126 */ 213 struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *session, 214 struct cli_credentials *credentials) 215 { 216 struct composite_context *c; 217 struct smb2_session_state *state; 127 struct tevent_req *smb2_session_setup_spnego_send( 128 TALLOC_CTX *mem_ctx, 129 struct tevent_context *ev, 130 struct smb2_session *session, 131 struct cli_credentials *credentials, 132 uint64_t previous_session_id) 133 { 134 struct tevent_req *req; 135 struct smb2_session_setup_spnego_state *state; 136 uint64_t current_session_id; 218 137 const char *chosen_oid; 219 220 c = composite_create(session, session->transport->socket->event.ctx); 221 if (c == NULL) return NULL; 222 223 state = talloc(c, struct smb2_session_state); 224 if (composite_nomem(state, c)) return c; 225 c->private_data = state; 226 227 ZERO_STRUCT(state->io); 228 state->io.in.vc_number = 0; 229 if (session->transport->signing_required) { 230 state->io.in.security_mode = 231 SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED; 232 } 233 state->io.in.capabilities = 0; 234 state->io.in.channel = 0; 235 state->io.in.previous_sessionid = 0; 236 237 c->status = gensec_set_credentials(session->gensec, credentials); 238 if (!composite_is_ok(c)) return c; 239 240 c->status = gensec_set_target_hostname(session->gensec, 241 session->transport->socket->hostname); 242 if (!composite_is_ok(c)) return c; 243 244 c->status = gensec_set_target_service(session->gensec, "cifs"); 245 if (!composite_is_ok(c)) return c; 246 247 if (session->transport->negotiate.secblob.length > 0) { 138 struct tevent_req *subreq; 139 NTSTATUS status; 140 const DATA_BLOB *server_gss_blob; 141 DATA_BLOB negprot_secblob = data_blob_null; 142 uint32_t timeout_msec; 143 uint8_t in_flags = 0; 144 145 timeout_msec = session->transport->options.request_timeout * 1000; 146 147 req = tevent_req_create(mem_ctx, &state, 148 struct smb2_session_setup_spnego_state); 149 if (req == NULL) { 150 return NULL; 151 } 152 state->ev = ev; 153 state->session = session; 154 state->credentials = credentials; 155 state->previous_session_id = previous_session_id; 156 157 current_session_id = smb2cli_session_current_id(state->session->smbXcli); 158 if (state->session->needs_bind) { 159 state->session_bind = true; 160 } else if (current_session_id != 0) { 161 state->reauth = true; 162 } 163 server_gss_blob = smbXcli_conn_server_gss_blob(session->transport->conn); 164 if (server_gss_blob) { 165 negprot_secblob = *server_gss_blob; 166 } 167 168 status = gensec_set_credentials(session->gensec, credentials); 169 if (tevent_req_nterror(req, status)) { 170 return tevent_req_post(req, ev); 171 } 172 173 status = gensec_set_target_hostname(session->gensec, 174 smbXcli_conn_remote_name(session->transport->conn)); 175 if (tevent_req_nterror(req, status)) { 176 return tevent_req_post(req, ev); 177 } 178 179 status = gensec_set_target_service(session->gensec, "cifs"); 180 if (tevent_req_nterror(req, status)) { 181 return tevent_req_post(req, ev); 182 } 183 184 if (negprot_secblob.length > 0) { 248 185 chosen_oid = GENSEC_OID_SPNEGO; 249 186 } else { … … 251 188 } 252 189 253 c->status = gensec_start_mech_by_oid(session->gensec, chosen_oid); 254 if (!composite_is_ok(c)) return c; 255 256 c->status = gensec_update(session->gensec, c, 257 session->transport->negotiate.secblob, 258 &state->io.in.secblob); 259 if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 260 composite_error(c, c->status); 261 return c; 262 } 263 state->gensec_status = c->status; 264 265 state->req = smb2_session_setup_send(session, &state->io); 266 composite_continue_smb2(c, state->req, session_request_handler, c); 267 return c; 190 status = gensec_start_mech_by_oid(session->gensec, chosen_oid); 191 if (tevent_req_nterror(req, status)) { 192 return tevent_req_post(req, ev); 193 } 194 195 status = gensec_update_ev(session->gensec, state, 196 state->ev, 197 negprot_secblob, 198 &state->in_secblob); 199 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 200 tevent_req_nterror(req, status); 201 return tevent_req_post(req, ev); 202 } 203 state->gensec_status = status; 204 205 if (state->session_bind) { 206 in_flags |= SMB2_SESSION_FLAG_BINDING; 207 } 208 209 subreq = smb2cli_session_setup_send(state, state->ev, 210 session->transport->conn, 211 timeout_msec, 212 session->smbXcli, 213 in_flags, 214 0, /* in_capabilities */ 215 0, /* in_channel */ 216 state->previous_session_id, 217 &state->in_secblob); 218 if (tevent_req_nomem(subreq, req)) { 219 return tevent_req_post(req, ev); 220 } 221 tevent_req_set_callback(subreq, smb2_session_setup_spnego_done, req); 222 223 return req; 224 } 225 226 /* 227 handle continuations of the spnego session setup 228 */ 229 static void smb2_session_setup_spnego_done(struct tevent_req *subreq) 230 { 231 struct tevent_req *req = 232 tevent_req_callback_data(subreq, 233 struct tevent_req); 234 struct smb2_session_setup_spnego_state *state = 235 tevent_req_data(req, 236 struct smb2_session_setup_spnego_state); 237 struct smb2_session *session = state->session; 238 NTSTATUS peer_status; 239 NTSTATUS status; 240 struct iovec *recv_iov; 241 uint32_t timeout_msec; 242 uint8_t in_flags = 0; 243 244 timeout_msec = session->transport->options.request_timeout * 1000; 245 246 status = smb2cli_session_setup_recv(subreq, state, 247 &recv_iov, 248 &state->out_secblob); 249 if (!NT_STATUS_IS_OK(status) && 250 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 251 tevent_req_nterror(req, status); 252 return; 253 } 254 peer_status = status; 255 256 if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 257 status = gensec_update_ev(session->gensec, state, 258 state->ev, 259 state->out_secblob, 260 &state->in_secblob); 261 state->gensec_status = status; 262 } 263 264 if (!NT_STATUS_IS_OK(status) && 265 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 266 tevent_req_nterror(req, status); 267 return; 268 } 269 270 if (NT_STATUS_IS_OK(peer_status) && NT_STATUS_IS_OK(state->gensec_status)) { 271 DATA_BLOB session_key; 272 273 if (state->reauth) { 274 tevent_req_done(req); 275 return; 276 } 277 278 if (cli_credentials_is_anonymous(state->credentials)) { 279 /* 280 * Windows server does not set the 281 * SMB2_SESSION_FLAG_IS_GUEST nor 282 * SMB2_SESSION_FLAG_IS_NULL flag. 283 * 284 * This fix makes sure we do not try 285 * to verify a signature on the final 286 * session setup response. 287 */ 288 tevent_req_done(req); 289 return; 290 } 291 292 status = gensec_session_key(session->gensec, state, 293 &session_key); 294 if (tevent_req_nterror(req, status)) { 295 return; 296 } 297 298 if (state->session_bind) { 299 status = smb2cli_session_set_channel_key(session->smbXcli, 300 session_key, 301 recv_iov); 302 if (tevent_req_nterror(req, status)) { 303 return; 304 } 305 session->needs_bind = false; 306 } else { 307 status = smb2cli_session_set_session_key(session->smbXcli, 308 session_key, 309 recv_iov); 310 if (tevent_req_nterror(req, status)) { 311 return; 312 } 313 } 314 tevent_req_done(req); 315 return; 316 } 317 318 if (state->session_bind) { 319 in_flags |= SMB2_SESSION_FLAG_BINDING; 320 } 321 322 subreq = smb2cli_session_setup_send(state, state->ev, 323 session->transport->conn, 324 timeout_msec, 325 session->smbXcli, 326 in_flags, 327 0, /* in_capabilities */ 328 0, /* in_channel */ 329 state->previous_session_id, 330 &state->in_secblob); 331 if (tevent_req_nomem(subreq, req)) { 332 return; 333 } 334 tevent_req_set_callback(subreq, smb2_session_setup_spnego_done, req); 268 335 } 269 336 … … 271 338 receive a composite session setup reply 272 339 */ 273 NTSTATUS smb2_session_setup_spnego_recv(struct composite_context *c) 274 { 275 NTSTATUS status; 276 status = composite_wait(c); 277 talloc_free(c); 278 return status; 340 NTSTATUS smb2_session_setup_spnego_recv(struct tevent_req *req) 341 { 342 return tevent_req_simple_recv_ntstatus(req); 279 343 } 280 344 … … 283 347 */ 284 348 NTSTATUS smb2_session_setup_spnego(struct smb2_session *session, 285 struct cli_credentials *credentials) 286 { 287 struct composite_context *c = smb2_session_setup_spnego_send(session, credentials); 288 return smb2_session_setup_spnego_recv(c); 289 } 349 struct cli_credentials *credentials, 350 uint64_t previous_session_id) 351 { 352 struct tevent_req *subreq; 353 NTSTATUS status; 354 bool ok; 355 TALLOC_CTX *frame = talloc_stackframe(); 356 struct tevent_context *ev = session->transport->ev; 357 358 if (frame == NULL) { 359 return NT_STATUS_NO_MEMORY; 360 } 361 362 subreq = smb2_session_setup_spnego_send(frame, ev, 363 session, credentials, 364 previous_session_id); 365 if (subreq == NULL) { 366 TALLOC_FREE(frame); 367 return NT_STATUS_NO_MEMORY; 368 } 369 370 ok = tevent_req_poll(subreq, ev); 371 if (!ok) { 372 status = map_nt_error_from_unix_common(errno); 373 TALLOC_FREE(frame); 374 return status; 375 } 376 377 status = smb2_session_setup_spnego_recv(subreq); 378 TALLOC_FREE(subreq); 379 if (!NT_STATUS_IS_OK(status)) { 380 TALLOC_FREE(frame); 381 return status; 382 } 383 384 TALLOC_FREE(frame); 385 return NT_STATUS_OK; 386 } -
vendor/current/source4/libcli/smb2/smb2.h
r740 r988 28 28 struct smb2_handle; 29 29 struct smb2_lease_break; 30 31 /*32 information returned from the negotiate process33 */34 struct smb2_negotiate {35 DATA_BLOB secblob;36 NTTIME system_time;37 NTTIME server_start_time;38 uint16_t security_mode;39 uint16_t dialect_revision;40 };41 30 42 31 struct smb2_request_buffer { … … 71 60 /* this is the context for the smb2 transport layer */ 72 61 struct smb2_transport { 73 /* socket level info */ 74 struct smbcli_socket *socket; 75 76 struct smb2_negotiate negotiate; 77 78 /* next seqnum to allocate */ 79 uint64_t seqnum; 62 struct tevent_context *ev; /* TODO: remove this !!! */ 63 struct smbXcli_conn *conn; 80 64 81 65 /* the details for coumpounded requests */ 82 66 struct { 83 uint32_t missing;84 67 bool related; 85 struct smb2_request_buffer buffer;68 struct tevent_req **reqs; 86 69 } compound; 87 88 struct {89 uint16_t charge;90 uint16_t ask_num;91 } credits;92 93 /* a list of requests that are pending for receive on this94 connection */95 struct smb2_request *pending_recv;96 97 /* context of the stream -> packet parser */98 struct packet_context *packet;99 70 100 71 /* an idle function - if this is defined then it will be … … 105 76 void *private_data; 106 77 unsigned int period; 78 struct tevent_timer *te; 107 79 } idle; 108 80 … … 124 96 void *private_data; 125 97 } lease; 98 struct tevent_req *break_subreq; 126 99 127 100 struct smbcli_options options; 128 129 bool signing_required;130 101 }; 131 102 … … 136 107 struct smb2_tree { 137 108 struct smb2_session *session; 138 uint32_t tid;109 struct smbXcli_tcon *smbXcli; 139 110 }; 140 111 … … 145 116 struct smb2_transport *transport; 146 117 struct gensec_security *gensec; 147 uint64_t uid; 148 uint32_t pid; 149 DATA_BLOB session_key; 150 bool signing_active; 118 struct smbXcli_session *smbXcli; 119 bool needs_bind; 151 120 }; 152 121 … … 163 132 /* the context for a single SMB2 request */ 164 133 struct smb2_request { 165 /* allow a request to be part of a list of requests */166 struct smb2_request *next, *prev;167 168 134 /* each request is in one of 3 possible states */ 169 135 enum smb2_request_state state; 136 137 struct tevent_req *subreq; 170 138 171 139 struct smb2_transport *transport; … … 173 141 struct smb2_tree *tree; 174 142 175 uint64_t seqnum;176 177 143 struct { 178 bool do_cancel;179 144 bool can_cancel; 180 uint64_t async_id;181 145 } cancel; 182 146 … … 187 151 struct smb2_request_buffer in; 188 152 struct smb2_request_buffer out; 153 struct iovec *recv_iov; 154 155 uint16_t credit_charge; 189 156 190 157 /* information on what to do with a reply when it is received -
vendor/current/source4/libcli/smb2/tcon.c
r414 r988 23 23 #include "libcli/smb2/smb2.h" 24 24 #include "libcli/smb2/smb2_calls.h" 25 #include "../libcli/smb/smbXcli_base.h" 25 26 26 27 /* … … 41 42 tree->session = talloc_reference(tree, session); 42 43 } 43 return tree;44 }45 44 46 /* 47 send a tree connect 48 */ 49 struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree, 50 struct smb2_tree_connect *io) 51 { 52 struct smb2_request *req; 53 NTSTATUS status; 54 55 req = smb2_request_init(tree->session->transport, SMB2_OP_TCON, 56 0x08, true, 0); 57 if (req == NULL) return NULL; 58 59 SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, tree->session->uid); 60 req->session = tree->session; 61 62 SSVAL(req->out.body, 0x02, io->in.reserved); 63 status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path); 64 if (!NT_STATUS_IS_OK(status)) { 65 talloc_free(req); 45 tree->smbXcli = smbXcli_tcon_create(tree); 46 if (tree->smbXcli == NULL) { 47 talloc_free(tree); 66 48 return NULL; 67 49 } 68 50 69 smb2_transport_send(req); 70 71 return req; 51 return tree; 72 52 } 73 74 75 /*76 recv a tree connect reply77 */78 NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_connect *io)79 {80 if (!smb2_request_receive(req) ||81 smb2_request_is_error(req)) {82 return smb2_request_destroy(req);83 }84 85 SMB2_CHECK_PACKET_RECV(req, 0x10, false);86 87 io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID);88 89 io->out.share_type = CVAL(req->in.body, 0x02);90 io->out.reserved = CVAL(req->in.body, 0x03);91 io->out.flags = IVAL(req->in.body, 0x04);92 io->out.capabilities= IVAL(req->in.body, 0x08);93 io->out.access_mask = IVAL(req->in.body, 0x0C);94 95 if (io->out.capabilities & ~SMB2_CAP_ALL) {96 DEBUG(0,("Unknown capabilities mask 0x%x\n", io->out.capabilities));97 }98 if (io->out.flags & ~SMB2_SHAREFLAG_ALL) {99 DEBUG(0,("Unknown tcon shareflag 0x%x\n", io->out.flags));100 }101 102 return smb2_request_destroy(req);103 }104 105 /*106 sync tree connect request107 */108 NTSTATUS smb2_tree_connect(struct smb2_tree *tree, struct smb2_tree_connect *io)109 {110 struct smb2_request *req = smb2_tree_connect_send(tree, io);111 return smb2_tree_connect_recv(req, io);112 } -
vendor/current/source4/libcli/smb2/transport.c
r740 r988 21 21 22 22 #include "includes.h" 23 #include "system/network.h" 23 24 #include "libcli/raw/libcliraw.h" 24 25 #include "libcli/raw/raw_proto.h" … … 27 28 #include "lib/socket/socket.h" 28 29 #include "lib/events/events.h" 29 #include "lib/stream/packet.h"30 30 #include "../lib/util/dlinklist.h" 31 32 33 /* 34 an event has happened on the socket 35 */ 36 static void smb2_transport_event_handler(struct tevent_context *ev, 37 struct tevent_fd *fde, 38 uint16_t flags, void *private_data) 39 { 40 struct smb2_transport *transport = talloc_get_type(private_data, 41 struct smb2_transport); 42 if (flags & EVENT_FD_READ) { 43 packet_recv(transport->packet); 44 return; 45 } 46 if (flags & EVENT_FD_WRITE) { 47 packet_queue_run(transport->packet); 48 } 49 } 31 #include "../libcli/smb/smbXcli_base.h" 32 #include "librpc/ndr/libndr.h" 50 33 51 34 /* … … 57 40 return 0; 58 41 } 59 60 61 /*62 handle receive errors63 */64 static void smb2_transport_error(void *private_data, NTSTATUS status)65 {66 struct smb2_transport *transport = talloc_get_type(private_data,67 struct smb2_transport);68 smb2_transport_dead(transport, status);69 }70 71 static NTSTATUS smb2_transport_finish_recv(void *private_data, DATA_BLOB blob);72 42 73 43 /* … … 83 53 if (!transport) return NULL; 84 54 85 transport-> socket = talloc_steal(transport, sock);55 transport->ev = sock->event.ctx; 86 56 transport->options = *options; 87 transport->credits.charge = 0; 88 transport->credits.ask_num = 1; 89 90 /* setup the stream -> packet parser */ 91 transport->packet = packet_init(transport); 92 if (transport->packet == NULL) { 57 58 if (transport->options.max_protocol == PROTOCOL_DEFAULT) { 59 transport->options.max_protocol = PROTOCOL_LATEST; 60 } 61 62 if (transport->options.max_protocol < PROTOCOL_SMB2_02) { 63 transport->options.max_protocol = PROTOCOL_LATEST; 64 } 65 66 TALLOC_FREE(sock->event.fde); 67 TALLOC_FREE(sock->event.te); 68 69 transport->conn = smbXcli_conn_create(transport, 70 sock->sock->fd, 71 sock->hostname, 72 options->signing, 73 0, /* smb1_capabilities */ 74 &options->client_guid, 75 options->smb2_capabilities); 76 if (transport->conn == NULL) { 93 77 talloc_free(transport); 94 78 return NULL; 95 79 } 96 packet_set_private(transport->packet, transport); 97 packet_set_socket(transport->packet, transport->socket->sock); 98 packet_set_callback(transport->packet, smb2_transport_finish_recv); 99 packet_set_full_request(transport->packet, packet_full_request_nbt); 100 packet_set_error_handler(transport->packet, smb2_transport_error); 101 packet_set_event_context(transport->packet, transport->socket->event.ctx); 102 packet_set_nofree(transport->packet); 103 104 /* take over event handling from the socket layer - it only 105 handles events up until we are connected */ 106 talloc_free(transport->socket->event.fde); 107 transport->socket->event.fde = event_add_fd(transport->socket->event.ctx, 108 transport->socket, 109 socket_get_fd(transport->socket->sock), 110 EVENT_FD_READ, 111 smb2_transport_event_handler, 112 transport); 113 114 packet_set_fde(transport->packet, transport->socket->event.fde); 115 packet_set_serialise(transport->packet); 80 sock->sock->fd = -1; 81 TALLOC_FREE(sock); 116 82 117 83 talloc_set_destructor(transport, transport_destructor); … … 125 91 void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status) 126 92 { 127 smbcli_sock_dead(transport->socket);128 129 93 if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) { 130 94 status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; 131 95 } 132 133 /* kill all pending receives */ 134 while (transport->pending_recv) { 135 struct smb2_request *req = transport->pending_recv; 96 if (NT_STATUS_IS_OK(status)) { 97 status = NT_STATUS_LOCAL_DISCONNECT; 98 } 99 100 smbXcli_conn_disconnect(transport->conn, status); 101 } 102 103 static void smb2_request_done(struct tevent_req *subreq); 104 static void smb2_transport_break_handler(struct tevent_req *subreq); 105 106 /* 107 put a request into the send queue 108 */ 109 void smb2_transport_send(struct smb2_request *req) 110 { 111 NTSTATUS status; 112 struct smb2_transport *transport = req->transport; 113 struct tevent_req **reqs = transport->compound.reqs; 114 size_t num_reqs = talloc_array_length(reqs); 115 size_t i; 116 uint16_t cmd = SVAL(req->out.hdr, SMB2_HDR_OPCODE); 117 uint32_t additional_flags = IVAL(req->out.hdr, SMB2_HDR_FLAGS); 118 uint32_t clear_flags = 0; 119 struct smbXcli_tcon *tcon = NULL; 120 struct smbXcli_session *session = NULL; 121 bool need_pending_break = false; 122 size_t hdr_ofs; 123 size_t pdu_len; 124 DATA_BLOB body = data_blob_null; 125 DATA_BLOB dyn = data_blob_null; 126 uint32_t timeout_msec = transport->options.request_timeout * 1000; 127 128 if (transport->oplock.handler) { 129 need_pending_break = true; 130 } 131 132 if (transport->lease.handler) { 133 need_pending_break = true; 134 } 135 136 if (transport->break_subreq) { 137 need_pending_break = false; 138 } 139 140 if (need_pending_break) { 141 struct tevent_req *subreq; 142 143 subreq = smb2cli_req_create(transport, 144 transport->ev, 145 transport->conn, 146 SMB2_OP_BREAK, 147 0, /* additional_flags */ 148 0, /*clear_flags */ 149 0, /* timeout_msec */ 150 NULL, /* tcon */ 151 NULL, /* session */ 152 NULL, /* body */ 153 0, /* body_fixed */ 154 NULL, /* dyn */ 155 0, /* dyn_len */ 156 0); /* max_dyn_len */ 157 if (subreq != NULL) { 158 smbXcli_req_set_pending(subreq); 159 tevent_req_set_callback(subreq, 160 smb2_transport_break_handler, 161 transport); 162 transport->break_subreq = subreq; 163 } 164 } 165 166 if (req->session) { 167 session = req->session->smbXcli; 168 } 169 170 if (req->tree) { 171 tcon = req->tree->smbXcli; 172 } 173 174 if (transport->compound.related) { 175 additional_flags |= SMB2_HDR_FLAG_CHAINED; 176 } 177 178 hdr_ofs = PTR_DIFF(req->out.hdr, req->out.buffer); 179 pdu_len = req->out.size - hdr_ofs; 180 body.data = req->out.body; 181 body.length = req->out.body_fixed; 182 dyn.data = req->out.body + req->out.body_fixed; 183 dyn.length = pdu_len - (SMB2_HDR_BODY + req->out.body_fixed); 184 185 req->subreq = smb2cli_req_create(req, 186 transport->ev, 187 transport->conn, 188 cmd, 189 additional_flags, 190 clear_flags, 191 timeout_msec, 192 tcon, 193 session, 194 body.data, body.length, 195 dyn.data, dyn.length, 196 0); /* max_dyn_len */ 197 if (req->subreq == NULL) { 136 198 req->state = SMB2_REQUEST_ERROR; 199 req->status = NT_STATUS_NO_MEMORY; 200 return; 201 } 202 203 if (!tevent_req_is_in_progress(req->subreq)) { 204 req->state = SMB2_REQUEST_ERROR; 205 req->status = NT_STATUS_INTERNAL_ERROR;/* TODO */ 206 return; 207 } 208 209 tevent_req_set_callback(req->subreq, smb2_request_done, req); 210 211 smb2cli_req_set_notify_async(req->subreq); 212 if (req->credit_charge) { 213 smb2cli_req_set_credit_charge(req->subreq, req->credit_charge); 214 } 215 216 ZERO_STRUCT(req->out); 217 req->state = SMB2_REQUEST_RECV; 218 219 if (num_reqs > 0) { 220 for (i=0; i < num_reqs; i++) { 221 if (reqs[i] != NULL) { 222 continue; 223 } 224 225 reqs[i] = req->subreq; 226 i++; 227 break; 228 } 229 230 if (i < num_reqs) { 231 return; 232 } 233 } else { 234 reqs = &req->subreq; 235 num_reqs = 1; 236 } 237 status = smb2cli_req_compound_submit(reqs, num_reqs); 238 239 TALLOC_FREE(transport->compound.reqs); 240 transport->compound.related = false; 241 242 if (!NT_STATUS_IS_OK(status)) { 137 243 req->status = status; 138 DLIST_REMOVE(transport->pending_recv, req); 139 if (req->async.fn) { 140 req->async.fn(req); 141 } 142 } 143 } 144 145 static NTSTATUS smb2_handle_oplock_break(struct smb2_transport *transport, 146 const DATA_BLOB *blob) 147 { 148 uint8_t *hdr; 244 req->state = SMB2_REQUEST_ERROR; 245 smbXcli_conn_disconnect(transport->conn, status); 246 } 247 } 248 249 static void smb2_request_done(struct tevent_req *subreq) 250 { 251 struct smb2_request *req = 252 tevent_req_callback_data(subreq, 253 struct smb2_request); 254 ssize_t len; 255 size_t i; 256 257 req->recv_iov = NULL; 258 259 req->status = smb2cli_req_recv(req->subreq, req, &req->recv_iov, NULL, 0); 260 if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { 261 req->cancel.can_cancel = true; 262 return; 263 } 264 TALLOC_FREE(req->subreq); 265 if (!NT_STATUS_IS_OK(req->status)) { 266 if (req->recv_iov == NULL) { 267 req->state = SMB2_REQUEST_ERROR; 268 if (req->async.fn) { 269 req->async.fn(req); 270 } 271 return; 272 } 273 } 274 275 len = req->recv_iov[0].iov_len; 276 for (i=1; i < 3; i++) { 277 uint8_t *p = req->recv_iov[i-1].iov_base; 278 uint8_t *c1 = req->recv_iov[i].iov_base; 279 uint8_t *c2 = p + req->recv_iov[i-1].iov_len; 280 281 len += req->recv_iov[i].iov_len; 282 283 if (req->recv_iov[i].iov_len == 0) { 284 continue; 285 } 286 287 if (c1 != c2) { 288 req->status = NT_STATUS_INTERNAL_ERROR; 289 req->state = SMB2_REQUEST_ERROR; 290 if (req->async.fn) { 291 req->async.fn(req); 292 } 293 return; 294 } 295 } 296 297 req->in.buffer = req->recv_iov[0].iov_base; 298 req->in.size = len; 299 req->in.allocated = req->in.size; 300 301 req->in.hdr = req->recv_iov[0].iov_base; 302 req->in.body = req->recv_iov[1].iov_base; 303 req->in.dynamic = req->recv_iov[2].iov_base; 304 req->in.body_fixed = req->recv_iov[1].iov_len; 305 req->in.body_size = req->in.body_fixed; 306 req->in.body_size += req->recv_iov[2].iov_len; 307 308 smb2_setup_bufinfo(req); 309 310 req->state = SMB2_REQUEST_DONE; 311 if (req->async.fn) { 312 req->async.fn(req); 313 } 314 } 315 316 static void smb2_transport_break_handler(struct tevent_req *subreq) 317 { 318 struct smb2_transport *transport = 319 tevent_req_callback_data(subreq, 320 struct smb2_transport); 321 NTSTATUS status; 149 322 uint8_t *body; 150 uint16_t len , bloblen;323 uint16_t len = 0; 151 324 bool lease; 152 153 hdr = blob->data+NBT_HDR_SIZE; 154 body = hdr+SMB2_HDR_BODY; 155 bloblen = blob->length - SMB2_HDR_BODY; 156 157 if (bloblen < 2) { 158 DEBUG(1,("Discarding smb2 oplock reply of size %u\n", 159 (unsigned)blob->length)); 160 return NT_STATUS_INVALID_NETWORK_RESPONSE; 161 } 162 163 len = CVAL(body, 0x00); 164 if (len > bloblen) { 165 DEBUG(1,("Discarding smb2 oplock reply," 166 "packet claims %u byte body, only %u bytes seen\n", 167 len, bloblen)); 168 return NT_STATUS_INVALID_NETWORK_RESPONSE; 325 struct iovec *recv_iov = NULL; 326 327 transport->break_subreq = NULL; 328 329 status = smb2cli_req_recv(subreq, transport, &recv_iov, NULL, 0); 330 TALLOC_FREE(subreq); 331 if (!NT_STATUS_IS_OK(status)) { 332 TALLOC_FREE(recv_iov); 333 smb2_transport_dead(transport, status); 334 return; 335 } 336 337 /* 338 * Setup the subreq to handle the 339 * next incoming SMB2 Break. 340 */ 341 subreq = smb2cli_req_create(transport, 342 transport->ev, 343 transport->conn, 344 SMB2_OP_BREAK, 345 0, /* additional_flags */ 346 0, /*clear_flags */ 347 0, /* timeout_msec */ 348 NULL, /* tcon */ 349 NULL, /* session */ 350 NULL, /* body */ 351 0, /* body_fixed */ 352 NULL, /* dyn */ 353 0, /* dyn_len */ 354 0); /* max_dyn_len */ 355 if (subreq != NULL) { 356 smbXcli_req_set_pending(subreq); 357 tevent_req_set_callback(subreq, 358 smb2_transport_break_handler, 359 transport); 360 transport->break_subreq = subreq; 361 } 362 363 body = recv_iov[1].iov_base; 364 365 len = recv_iov[1].iov_len; 366 if (recv_iov[1].iov_len >= 2) { 367 len = CVAL(body, 0x00); 368 if (len != recv_iov[1].iov_len) { 369 len = recv_iov[1].iov_len; 370 } 169 371 } 170 372 … … 175 377 } else { 176 378 DEBUG(1,("Discarding smb2 oplock reply of invalid size %u\n", 177 (unsigned)blob->length)); 178 return NT_STATUS_INVALID_NETWORK_RESPONSE; 379 (unsigned)len)); 380 TALLOC_FREE(recv_iov); 381 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 382 smb2_transport_dead(transport, status); 383 return; 179 384 } 180 385 … … 185 390 level = CVAL(body, 0x02); 186 391 smb2_pull_handle(body+0x08, &h); 392 393 TALLOC_FREE(recv_iov); 187 394 188 395 transport->oplock.handler(transport, &h, level, … … 192 399 193 400 ZERO_STRUCT(lb); 401 lb.new_epoch = SVAL(body, 0x2); 194 402 lb.break_flags = SVAL(body, 0x4); 195 403 memcpy(&lb.current_lease.lease_key, body+0x8, … … 201 409 lb.share_mask_hint = SVAL(body, 0x28); 202 410 411 TALLOC_FREE(recv_iov); 412 203 413 transport->lease.handler(transport, &lb, 204 414 transport->lease.private_data); … … 207 417 lease ? "lease" : "oplock")); 208 418 } 209 210 return NT_STATUS_OK; 211 } 212 213 struct smb2_transport_compount_response_state { 214 struct smb2_transport *transport; 215 DATA_BLOB blob; 216 }; 217 218 static void smb2_transport_compound_response_handler(struct tevent_context *ctx, 219 struct tevent_immediate *im, 220 void *private_data) 221 { 222 struct smb2_transport_compount_response_state *state = 223 talloc_get_type_abort(private_data, 224 struct smb2_transport_compount_response_state); 225 struct smb2_transport *transport = state->transport; 226 NTSTATUS status; 227 228 status = smb2_transport_finish_recv(transport, state->blob); 229 TALLOC_FREE(state); 230 if (!NT_STATUS_IS_OK(status)) { 231 smb2_transport_error(transport, status); 232 } 233 } 234 235 /* 236 we have a full request in our receive buffer - match it to a pending request 237 and process 238 */ 239 static NTSTATUS smb2_transport_finish_recv(void *private_data, DATA_BLOB blob) 240 { 241 struct smb2_transport *transport = talloc_get_type(private_data, 242 struct smb2_transport); 243 uint8_t *buffer, *hdr; 244 int len; 245 struct smb2_request *req = NULL; 246 uint64_t seqnum; 247 uint32_t flags; 248 uint16_t buffer_code; 249 uint32_t dynamic_size; 250 uint32_t i; 251 uint16_t opcode; 252 NTSTATUS status; 253 uint32_t next_ofs; 254 255 buffer = blob.data; 256 len = blob.length; 257 258 hdr = buffer+NBT_HDR_SIZE; 259 260 if (len < SMB2_MIN_SIZE) { 261 DEBUG(1,("Discarding smb2 reply of size %d\n", len)); 262 goto error; 263 } 264 265 flags = IVAL(hdr, SMB2_HDR_FLAGS); 266 seqnum = BVAL(hdr, SMB2_HDR_MESSAGE_ID); 267 opcode = SVAL(hdr, SMB2_HDR_OPCODE); 268 269 /* see MS-SMB2 3.2.5.19 */ 270 if (seqnum == UINT64_MAX) { 271 if (opcode != SMB2_OP_BREAK) { 272 DEBUG(1,("Discarding packet with invalid seqnum, " 273 "opcode %u\n", opcode)); 274 return NT_STATUS_INVALID_NETWORK_RESPONSE; 275 } 276 277 return smb2_handle_oplock_break(transport, &blob); 278 } 279 280 /* match the incoming request against the list of pending requests */ 281 for (req=transport->pending_recv; req; req=req->next) { 282 if (req->seqnum == seqnum) break; 283 } 284 285 if (!req) { 286 DEBUG(1,("Discarding unmatched reply with seqnum 0x%llx op %d\n", 287 (long long)seqnum, SVAL(hdr, SMB2_HDR_OPCODE))); 288 goto error; 289 } 290 291 /* fill in the 'in' portion of the matching request */ 292 req->in.buffer = buffer; 293 talloc_steal(req, buffer); 294 req->in.size = len; 295 req->in.allocated = req->in.size; 296 297 req->in.hdr = hdr; 298 req->in.body = hdr+SMB2_HDR_BODY; 299 req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); 300 req->status = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS)); 301 302 if ((flags & SMB2_HDR_FLAG_ASYNC) && 303 NT_STATUS_EQUAL(req->status, STATUS_PENDING)) { 304 req->cancel.can_cancel = true; 305 req->cancel.async_id = BVAL(hdr, SMB2_HDR_ASYNC_ID); 306 for (i=0; i< req->cancel.do_cancel; i++) { 307 smb2_cancel(req); 308 } 309 talloc_free(buffer); 310 return NT_STATUS_OK; 311 } 312 313 next_ofs = IVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND); 314 if (next_ofs > 0) { 315 if (smb2_oob(&req->in, req->in.hdr + next_ofs, SMB2_HDR_BODY + 2)) { 316 DEBUG(1,("SMB2 request invalid next offset 0x%x\n", 317 next_ofs)); 318 goto error; 319 } 320 321 req->in.size = NBT_HDR_SIZE + next_ofs; 322 req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); 323 } 324 325 if (req->session && req->session->signing_active) { 326 status = smb2_check_signature(&req->in, 327 req->session->session_key); 328 if (!NT_STATUS_IS_OK(status)) { 329 /* the spec says to ignore packets with a bad signature */ 330 talloc_free(buffer); 331 return status; 332 } 333 } 334 335 buffer_code = SVAL(req->in.body, 0); 336 req->in.body_fixed = (buffer_code & ~1); 337 req->in.dynamic = NULL; 338 dynamic_size = req->in.body_size - req->in.body_fixed; 339 if (dynamic_size != 0 && (buffer_code & 1)) { 340 req->in.dynamic = req->in.body + req->in.body_fixed; 341 if (smb2_oob(&req->in, req->in.dynamic, dynamic_size)) { 342 DEBUG(1,("SMB2 request invalid dynamic size 0x%x\n", 343 dynamic_size)); 344 goto error; 345 } 346 } 347 348 smb2_setup_bufinfo(req); 349 350 DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", (long long)req->seqnum)); 351 dump_data(5, req->in.body, req->in.body_size); 352 353 if (next_ofs > 0) { 354 struct tevent_immediate *im; 355 struct smb2_transport_compount_response_state *state; 356 357 state = talloc(transport, 358 struct smb2_transport_compount_response_state); 359 if (!state) { 360 goto error; 361 } 362 state->transport = transport; 363 364 state->blob = data_blob_talloc(state, NULL, 365 blob.length - next_ofs); 366 if (!state->blob.data) { 367 goto error; 368 } 369 im = tevent_create_immediate(state); 370 if (!im) { 371 TALLOC_FREE(state); 372 goto error; 373 } 374 _smb2_setlen(state->blob.data, state->blob.length - NBT_HDR_SIZE); 375 memcpy(state->blob.data + NBT_HDR_SIZE, 376 req->in.hdr + next_ofs, 377 req->in.allocated - req->in.size); 378 tevent_schedule_immediate(im, transport->socket->event.ctx, 379 smb2_transport_compound_response_handler, 380 state); 381 } 382 383 /* if this request has an async handler then call that to 384 notify that the reply has been received. This might destroy 385 the request so it must happen last */ 386 DLIST_REMOVE(transport->pending_recv, req); 387 req->state = SMB2_REQUEST_DONE; 388 if (req->async.fn) { 389 req->async.fn(req); 390 } 391 return NT_STATUS_OK; 392 393 error: 394 dump_data(5, buffer, len); 395 if (req) { 396 DLIST_REMOVE(transport->pending_recv, req); 397 req->state = SMB2_REQUEST_ERROR; 398 if (req->async.fn) { 399 req->async.fn(req); 400 } 401 } else { 402 talloc_free(buffer); 403 } 404 return NT_STATUS_UNSUCCESSFUL; 405 } 406 407 /* 408 handle timeouts of individual smb requests 409 */ 410 static void smb2_timeout_handler(struct tevent_context *ev, struct tevent_timer *te, 411 struct timeval t, void *private_data) 412 { 413 struct smb2_request *req = talloc_get_type(private_data, struct smb2_request); 414 415 if (req->state == SMB2_REQUEST_RECV) { 416 DLIST_REMOVE(req->transport->pending_recv, req); 417 } 418 req->status = NT_STATUS_IO_TIMEOUT; 419 req->state = SMB2_REQUEST_ERROR; 420 if (req->async.fn) { 421 req->async.fn(req); 422 } 423 } 424 425 426 /* 427 destroy a request 428 */ 429 static int smb2_request_destructor(struct smb2_request *req) 430 { 431 if (req->state == SMB2_REQUEST_RECV) { 432 DLIST_REMOVE(req->transport->pending_recv, req); 433 } 434 return 0; 435 } 436 437 static NTSTATUS smb2_transport_raw_send(struct smb2_transport *transport, 438 struct smb2_request_buffer *buffer) 439 { 440 DATA_BLOB blob; 441 NTSTATUS status; 442 443 /* check if the transport is dead */ 444 if (transport->socket->sock == NULL) { 445 return NT_STATUS_NET_WRITE_FAULT; 446 } 447 448 _smb2_setlen(buffer->buffer, buffer->size - NBT_HDR_SIZE); 449 blob = data_blob_const(buffer->buffer, buffer->size); 450 status = packet_send(transport->packet, blob); 451 if (!NT_STATUS_IS_OK(status)) { 452 return status; 453 } 454 455 return NT_STATUS_OK; 456 } 457 458 /* 459 put a request into the send queue 460 */ 461 void smb2_transport_send(struct smb2_request *req) 462 { 463 NTSTATUS status; 464 465 DEBUG(2, ("SMB2 send seqnum=0x%llx\n", (long long)req->seqnum)); 466 dump_data(5, req->out.body, req->out.body_size); 467 468 if (req->transport->compound.missing > 0) { 469 off_t next_ofs; 470 size_t pad = 0; 471 uint8_t *end; 472 473 end = req->out.buffer + req->out.size; 474 475 /* 476 * we need to set dynamic otherwise 477 * smb2_grow_buffer segfaults 478 */ 479 if (req->out.dynamic == NULL) { 480 req->out.dynamic = end; 481 } 482 483 next_ofs = end - req->out.hdr; 484 if ((next_ofs % 8) > 0) { 485 pad = 8 - (next_ofs % 8); 486 } 487 next_ofs += pad; 488 489 status = smb2_grow_buffer(&req->out, pad); 490 if (!NT_STATUS_IS_OK(status)) { 491 req->state = SMB2_REQUEST_ERROR; 492 req->status = status; 493 return; 494 } 495 req->out.size += pad; 496 497 SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND, next_ofs); 498 } 499 500 /* possibly sign the message */ 501 if (req->session && req->session->signing_active) { 502 status = smb2_sign_message(&req->out, req->session->session_key); 503 if (!NT_STATUS_IS_OK(status)) { 504 req->state = SMB2_REQUEST_ERROR; 505 req->status = status; 506 return; 507 } 508 } 509 510 if (req->transport->compound.missing > 0) { 511 req->transport->compound.buffer = req->out; 512 } else { 513 status = smb2_transport_raw_send(req->transport, 514 &req->out); 515 if (!NT_STATUS_IS_OK(status)) { 516 req->state = SMB2_REQUEST_ERROR; 517 req->status = status; 518 return; 519 } 520 } 521 ZERO_STRUCT(req->out); 522 523 req->state = SMB2_REQUEST_RECV; 524 DLIST_ADD(req->transport->pending_recv, req); 525 526 /* add a timeout */ 527 if (req->transport->options.request_timeout) { 528 event_add_timed(req->transport->socket->event.ctx, req, 529 timeval_current_ofs(req->transport->options.request_timeout, 0), 530 smb2_timeout_handler, req); 531 } 532 533 talloc_set_destructor(req, smb2_request_destructor); 419 TALLOC_FREE(recv_iov); 534 420 } 535 421 … … 537 423 uint32_t num) 538 424 { 425 TALLOC_FREE(transport->compound.reqs); 539 426 ZERO_STRUCT(transport->compound); 540 transport->compound.missing = num; 427 428 transport->compound.reqs = talloc_zero_array(transport, 429 struct tevent_req *, 430 num); 431 if (transport->compound.reqs == NULL) { 432 return NT_STATUS_NO_MEMORY; 433 } 434 541 435 return NT_STATUS_OK; 542 436 } … … 551 445 uint16_t ask_num) 552 446 { 553 transport->credits.ask_num = ask_num; 554 } 555 556 void smb2_transport_credits_set_charge(struct smb2_transport *transport, 557 uint16_t charge) 558 { 559 transport->credits.charge = charge; 447 smb2cli_conn_set_max_credits(transport->conn, ask_num); 560 448 } 561 449 … … 565 453 struct smb2_transport *transport = talloc_get_type(private_data, 566 454 struct smb2_transport); 567 struct timeval next = timeval_add(&t, 0, transport->idle.period); 568 transport->socket->event.te = event_add_timed(transport->socket->event.ctx, 569 transport, 570 next, 571 idle_handler, transport); 455 struct timeval next; 456 572 457 transport->idle.func(transport, transport->idle.private_data); 458 459 next = timeval_current_ofs_usec(transport->idle.period); 460 transport->idle.te = tevent_add_timer(transport->ev, 461 transport, 462 next, 463 idle_handler, 464 transport); 573 465 } 574 466 … … 582 474 void *private_data) 583 475 { 476 TALLOC_FREE(transport->idle.te); 477 584 478 transport->idle.func = idle_func; 585 479 transport->idle.private_data = private_data; 586 480 transport->idle.period = period; 587 481 588 if (transport->socket->event.te != NULL) { 589 talloc_free(transport->socket->event.te); 590 } 591 592 transport->socket->event.te = event_add_timed(transport->socket->event.ctx, 593 transport, 594 timeval_current_ofs(0, period), 595 idle_handler, transport); 596 } 482 transport->idle.te = tevent_add_timer(transport->ev, 483 transport, 484 timeval_current_ofs_usec(period), 485 idle_handler, 486 transport); 487 } -
vendor/current/source4/libcli/smb2/util.c
r740 r988 231 231 return (h1.data[0] == h2.data[0]) && (h1.data[1] == h2.data[1]); 232 232 } 233 234 bool smb2_util_handle_empty(const struct smb2_handle h) 235 { 236 struct smb2_handle empty; 237 238 ZERO_STRUCT(empty); 239 240 return smb2_util_handle_equal(h, empty); 241 } -
vendor/current/source4/libcli/smb2/write.c
r414 r988 59 59 { 60 60 if (!smb2_request_receive(req) || 61 smb2_request_is_error(req)) {61 !smb2_request_is_ok(req)) { 62 62 return smb2_request_destroy(req); 63 63 } -
vendor/current/source4/libcli/smb2/wscript_build
r740 r988 2 2 3 3 bld.SAMBA_SUBSYSTEM('LIBCLI_SMB2', 4 source='transport.c request.c negprot.csession.c tcon.c create.c close.c connect.c getinfo.c write.c read.c setinfo.c find.c ioctl.c logoff.c tdis.c flush.c lock.c notify.c cancel.c keepalive.c break.c util.c signing.c lease_break.c',4 source='transport.c request.c session.c tcon.c create.c close.c connect.c getinfo.c write.c read.c setinfo.c find.c ioctl.c logoff.c tdis.c flush.c lock.c notify.c cancel.c keepalive.c break.c util.c signing.c lease_break.c', 5 5 autoproto='smb2_proto.h', 6 public_deps='LIBCLI_RAW LIBPACKET gensec' 6 deps='tevent-util cli_smb_common', 7 public_deps='smbclient-raw gensec samba-credentials tevent', 8 private_headers='smb2.h', 7 9 ) 8 10 -
vendor/current/source4/libcli/smb_composite/appendacl.c
r740 r988 248 248 c->private_data = state; 249 249 c->state = COMPOSITE_STATE_IN_PROGRESS; 250 c->event_ctx = tree->session->transport-> socket->event.ctx;250 c->event_ctx = tree->session->transport->ev; 251 251 252 252 /* setup structures for opening file */ -
vendor/current/source4/libcli/smb_composite/connect.c
r740 r988 32 32 #include "param/param.h" 33 33 #include "lib/util/util_net.h" 34 #include "libcli/smb/smbXcli_base.h" 34 35 35 36 /* the stages of this call */ 36 37 enum connect_stage {CONNECT_SOCKET, 37 CONNECT_SESSION_REQUEST,38 38 CONNECT_NEGPROT, 39 39 CONNECT_SESSION_SETUP, … … 53 53 struct smbcli_request *req; 54 54 struct composite_context *creq; 55 struct tevent_req *subreq; 56 struct nbt_name calling, called; 55 57 }; 56 58 … … 58 60 static void request_handler(struct smbcli_request *); 59 61 static void composite_handler(struct composite_context *); 62 static void subreq_handler(struct tevent_req *subreq); 60 63 61 64 /* … … 70 73 status = smb_raw_tcon_recv(state->req, c, state->io_tcon); 71 74 NT_STATUS_NOT_OK_RETURN(status); 75 76 if (state->io_tcon->tconx.out.options & SMB_EXTENDED_SIGNATURES) { 77 smb1cli_session_protect_session_key(io->out.tree->session->smbXcli); 78 } 72 79 73 80 io->out.tree->tid = state->io_tcon->tconx.out.tid; … … 109 116 /* connect to a share using a tree connect */ 110 117 state->io_tcon->generic.level = RAW_TCON_TCONX; 111 state->io_tcon->tconx.in.flags = 0;118 state->io_tcon->tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE; 112 119 state->io_tcon->tconx.in.password = data_blob(NULL, 0); 113 120 … … 162 169 * would lead to an invalid uid in the anonymous fallback */ 163 170 state->session->vuid = 0; 164 data_blob_free(&state->session->user_session_key);165 171 talloc_free(state->session->gensec); 166 172 state->session->gensec = NULL; … … 195 201 /* connect to a share using a tree connect */ 196 202 state->io_tcon->generic.level = RAW_TCON_TCONX; 197 state->io_tcon->tconx.in.flags = 0; 203 state->io_tcon->tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE; 204 state->io_tcon->tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES; 198 205 state->io_tcon->tconx.in.password = data_blob(NULL, 0); 199 206 … … 231 238 NTSTATUS status; 232 239 233 status = smb_raw_negotiate_recv(state->req); 240 status = smb_raw_negotiate_recv(state->subreq); 241 TALLOC_FREE(state->subreq); 234 242 NT_STATUS_NOT_OK_RETURN(status); 235 243 … … 282 290 struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); 283 291 284 state->req = smb_raw_negotiate_send(state->transport, io->in.options.unicode, io->in.options.max_protocol); 285 NT_STATUS_HAVE_NO_MEMORY(state->req); 286 287 state->req->async.fn = request_handler; 288 state->req->async.private_data = c; 292 /* the socket is up - we can initialise the smbcli transport layer */ 293 state->transport = smbcli_transport_init(state->sock, state, true, 294 &io->in.options); 295 NT_STATUS_HAVE_NO_MEMORY(state->transport); 296 297 state->subreq = smb_raw_negotiate_send(state, 298 state->transport->ev, 299 state->transport, 300 state->transport->options.min_protocol, 301 state->transport->options.max_protocol); 302 NT_STATUS_HAVE_NO_MEMORY(state->subreq); 303 tevent_req_set_callback(state->subreq, subreq_handler, c); 289 304 state->stage = CONNECT_NEGPROT; 290 305 291 306 return NT_STATUS_OK; 292 }293 294 295 /*296 a session request operation has completed297 */298 static NTSTATUS connect_session_request(struct composite_context *c,299 struct smb_composite_connect *io)300 {301 struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);302 NTSTATUS status;303 304 status = smbcli_transport_connect_recv(state->req);305 NT_STATUS_NOT_OK_RETURN(status);306 307 /* next step is a negprot */308 return connect_send_negprot(c, io);309 307 } 310 308 … … 317 315 struct connect_state *state = talloc_get_type(c->private_data, struct connect_state); 318 316 NTSTATUS status; 319 struct nbt_name calling, called;320 317 321 318 status = smbcli_sock_connect_recv(state->creq, state, &state->sock); 322 319 NT_STATUS_NOT_OK_RETURN(status); 323 324 /* the socket is up - we can initialise the smbcli transport layer */325 state->transport = smbcli_transport_init(state->sock, state, true,326 &io->in.options);327 NT_STATUS_HAVE_NO_MEMORY(state->transport);328 320 329 321 if (is_ipaddress(state->sock->hostname) && … … 337 329 } 338 330 339 make_nbt_name_client(&calling, cli_credentials_get_workstation(io->in.credentials)); 340 341 nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER); 342 343 /* we have a connected socket - next step is a session 344 request, if needed. Port 445 doesn't need it, so it goes 345 straight to the negprot */ 346 if (state->sock->port == 445) { 347 status = nbt_name_dup(state->transport, &called, 348 &state->transport->called); 349 NT_STATUS_NOT_OK_RETURN(status); 350 return connect_send_negprot(c, io); 351 } 352 353 state->req = smbcli_transport_connect_send(state->transport, &calling, &called); 354 NT_STATUS_HAVE_NO_MEMORY(state->req); 355 356 state->req->async.fn = request_handler; 357 state->req->async.private_data = c; 358 state->stage = CONNECT_SESSION_REQUEST; 359 360 return NT_STATUS_OK; 331 /* next step is a negprot */ 332 return connect_send_negprot(c, io); 361 333 } 362 334 … … 372 344 case CONNECT_SOCKET: 373 345 c->status = connect_socket(c, state->io); 374 break;375 case CONNECT_SESSION_REQUEST:376 c->status = connect_session_request(c, state->io);377 346 break; 378 347 case CONNECT_NEGPROT: … … 422 391 423 392 /* 393 handler for completion of a tevent_req sub-request 394 */ 395 static void subreq_handler(struct tevent_req *subreq) 396 { 397 struct composite_context *c = 398 tevent_req_callback_data(subreq, 399 struct composite_context); 400 state_handler(c); 401 } 402 403 /* 424 404 a function to establish a smbcli_tree from scratch 425 405 */ … … 446 426 c->state = COMPOSITE_STATE_IN_PROGRESS; 447 427 c->private_data = state; 428 429 make_nbt_name_client(&state->calling, 430 cli_credentials_get_workstation(io->in.credentials)); 431 432 nbt_choose_called_name(state, &state->called, 433 io->in.called_name, NBT_NAME_SERVER); 448 434 449 435 state->creq = smbcli_sock_connect_send(state, … … 452 438 io->in.dest_host, 453 439 resolve_ctx, c->event_ctx, 454 io->in.socket_options); 440 io->in.socket_options, 441 &state->calling, 442 &state->called); 455 443 if (state->creq == NULL) goto failed; 456 444 -
vendor/current/source4/libcli/smb_composite/fsinfo.c
r740 r988 128 128 struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, 129 129 struct smb_composite_fsinfo *io, 130 struct resolve_context *resolve_ctx) 130 struct resolve_context *resolve_ctx, 131 struct tevent_context *event_ctx) 131 132 { 132 133 struct composite_context *c; … … 136 137 if (c == NULL) goto failed; 137 138 139 c->event_ctx = event_ctx; 140 if (c->event_ctx == NULL) goto failed; 141 138 142 state = talloc(c, struct fsinfo_state); 139 143 if (state == NULL) goto failed; … … 141 145 state->io = io; 142 146 143 state->connect = talloc (state, struct smb_composite_connect);147 state->connect = talloc_zero(state, struct smb_composite_connect); 144 148 145 149 if (state->connect == NULL) goto failed; … … 202 206 TALLOC_CTX *mem_ctx, 203 207 struct smb_composite_fsinfo *io, 204 struct resolve_context *resolve_ctx) 205 { 206 struct composite_context *c = smb_composite_fsinfo_send(tree, io, resolve_ctx); 208 struct resolve_context *resolve_ctx, 209 struct tevent_context *ev) 210 { 211 struct composite_context *c = smb_composite_fsinfo_send(tree, io, resolve_ctx, ev); 207 212 return smb_composite_fsinfo_recv(c, mem_ctx); 208 213 } -
vendor/current/source4/libcli/smb_composite/loadfile.c
r414 r988 230 230 c->private_data = state; 231 231 c->state = COMPOSITE_STATE_IN_PROGRESS; 232 c->event_ctx = tree->session->transport-> socket->event.ctx;232 c->event_ctx = tree->session->transport->ev; 233 233 234 234 /* setup for the open */ -
vendor/current/source4/libcli/smb_composite/savefile.c
r414 r988 226 226 227 227 c->state = COMPOSITE_STATE_IN_PROGRESS; 228 c->event_ctx = tree->session->transport-> socket->event.ctx;228 c->event_ctx = tree->session->transport->ev; 229 229 230 230 state = talloc(c, struct savefile_state); -
vendor/current/source4/libcli/smb_composite/sesssetup.c
r414 r988 26 26 #include "libcli/composite/composite.h" 27 27 #include "libcli/smb_composite/smb_composite.h" 28 #include "libcli/smb_composite/proto.h"29 28 #include "libcli/auth/libcli_auth.h" 30 29 #include "auth/auth.h" … … 33 32 #include "version.h" 34 33 #include "param/param.h" 34 #include "libcli/smb/smbXcli_base.h" 35 35 36 36 struct sesssetup_state { … … 40 40 struct smb_composite_sesssetup *io; 41 41 struct smbcli_request *req; 42 unsigned int logon_retries; 42 43 }; 43 44 … … 66 67 67 68 /* 68 store the user session key for a transport69 */70 static void set_user_session_key(struct smbcli_session *session,71 const DATA_BLOB *session_key)72 {73 session->user_session_key = data_blob_talloc(session,74 session_key->data,75 session_key->length);76 }77 78 /*79 69 handler for completion of a smbcli_request sub-request 80 70 */ … … 84 74 struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); 85 75 struct smbcli_session *session = req->session; 86 DATA_BLOB session_key = data_blob(NULL, 0);87 76 DATA_BLOB null_data_blob = data_blob(NULL, 0); 88 77 NTSTATUS session_key_err, nt_status; … … 136 125 state->io->out.vuid = state->setup.nt1.out.vuid; 137 126 if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { 138 /* we nee tto reset the vuid for a new try */127 /* we need to reset the vuid for a new try */ 139 128 session->vuid = 0; 140 129 if (cli_credentials_wrong_password(state->io->in.credentials)) { … … 157 146 state->io->out.vuid = state->setup.spnego.out.vuid; 158 147 if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { 148 const char *principal; 149 159 150 /* we need to reset the vuid for a new try */ 160 151 session->vuid = 0; 161 if (cli_credentials_wrong_password(state->io->in.credentials)) { 152 153 principal = gensec_get_target_principal(session->gensec); 154 if (principal == NULL) { 155 const char *hostname = gensec_get_target_hostname(session->gensec); 156 const char *service = gensec_get_target_service(session->gensec); 157 if (hostname != NULL && service != NULL) { 158 principal = talloc_asprintf(state, "%s/%s", service, hostname); 159 } 160 } 161 if (cli_credentials_failed_kerberos_login(state->io->in.credentials, principal, &state->logon_retries) || 162 cli_credentials_wrong_password(state->io->in.credentials)) { 162 163 nt_status = session_setup_spnego(c, session, 163 164 state->io, … … 184 185 * requirements */ 185 186 186 state->gensec_status = gensec_update (session->gensec, state,187 state->gensec_status = gensec_update_ev(session->gensec, state, c->event_ctx, 187 188 state->setup.spnego.out.secblob, 188 189 &state->setup.spnego.in.secblob); … … 196 197 } 197 198 198 if (NT_STATUS_IS_OK(state->remote_status)) { 199 if (cli_credentials_is_anonymous(state->io->in.credentials)) { 200 /* 201 * anonymous => no signing 202 */ 203 } else if (NT_STATUS_IS_OK(state->remote_status)) { 204 DATA_BLOB session_key; 205 199 206 if (state->setup.spnego.in.secblob.length) { 200 207 c->status = NT_STATUS_INTERNAL_ERROR; 201 208 break; 202 209 } 203 session_key_err = gensec_session_key(session->gensec, &session_key);210 session_key_err = gensec_session_key(session->gensec, session, &session_key); 204 211 if (NT_STATUS_IS_OK(session_key_err)) { 205 set_user_session_key(session, &session_key); 206 smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob); 212 smb1cli_conn_activate_signing(session->transport->conn, 213 session_key, 214 null_data_blob); 215 } 216 217 c->status = smb1cli_session_set_session_key(session->smbXcli, 218 session_key); 219 data_blob_free(&session_key); 220 if (!NT_STATUS_IS_OK(c->status)) { 221 break; 207 222 } 208 223 } … … 217 232 state->req = smb_raw_sesssetup_send(session, &state->setup); 218 233 session->vuid = vuid; 219 if (state->req) { 234 if (state->req && 235 !smb1cli_conn_signing_is_active(state->req->transport->conn)) { 220 236 state->req->sign_caller_checks = true; 221 237 } … … 233 249 234 250 if (check_req) { 251 bool ok; 252 235 253 check_req->sign_caller_checks = false; 236 if (!smbcli_request_check_sign_mac(check_req)) { 254 255 ok = smb1cli_conn_check_signing(check_req->transport->conn, 256 check_req->in.buffer, 1); 257 if (!ok) { 237 258 c->status = NT_STATUS_ACCESS_DENIED; 238 259 } 239 260 talloc_free(check_req); 240 261 check_req = NULL; 241 }242 243 /* enforce the local signing required flag */244 if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) {245 if (!session->transport->negotiate.sign_info.doing_signing246 && session->transport->negotiate.sign_info.mandatory_signing) {247 DEBUG(0, ("SMB signing required, but server does not support it\n"));248 c->status = NT_STATUS_ACCESS_DENIED;249 }250 262 } 251 263 … … 281 293 { 282 294 NTSTATUS nt_status = NT_STATUS_INTERNAL_ERROR; 283 struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); 284 DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, cli_credentials_get_domain(io->in.credentials)); 295 struct sesssetup_state *state = talloc_get_type(c->private_data, 296 struct sesssetup_state); 297 const char *domain = cli_credentials_get_domain(io->in.credentials); 298 299 /* 300 * domain controllers tend to reject the NTLM v2 blob 301 * if the netbiosname is not valid (e.g. IP address or FQDN) 302 * so just leave it away (as Windows client do) 303 */ 304 DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, NULL, domain); 305 285 306 DATA_BLOB session_key = data_blob(NULL, 0); 286 307 int flags = CLI_CRED_NTLM_AUTH; 287 288 smbcli_temp_set_signing(session->transport);289 308 290 309 if (session->options.lanman_auth) { … … 311 330 312 331 if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { 332 if (!cli_credentials_is_anonymous(io->in.credentials) && 333 session->options.ntlmv2_auth && 334 session->transport->options.use_spnego) 335 { 336 /* 337 * Don't send an NTLMv2_RESPONSE without NTLMSSP 338 * if we want to use spnego 339 */ 340 return NT_STATUS_INVALID_PARAMETER; 341 } 342 313 343 nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, 314 344 &flags, 315 345 session->transport->negotiate.secblob, 346 NULL, /* server_timestamp */ 316 347 names_blob, 317 348 &state->setup.nt1.in.password1, … … 333 364 } 334 365 335 if (NT_STATUS_IS_OK(nt_status)) { 336 smbcli_transport_simple_set_signing(session->transport, session_key, 337 state->setup.nt1.in.password2); 338 set_user_session_key(session, &session_key); 339 340 data_blob_free(&session_key); 366 if (!NT_STATUS_IS_OK(nt_status)) { 367 /* 368 * plain text => no signing 369 */ 370 return (*req)->status; 371 } 372 373 if (cli_credentials_is_anonymous(io->in.credentials)) { 374 /* 375 * anonymous => no signing 376 */ 377 return (*req)->status; 378 } 379 380 smb1cli_conn_activate_signing(session->transport->conn, 381 session_key, 382 state->setup.nt1.in.password2); 383 384 nt_status = smb1cli_session_set_session_key(session->smbXcli, 385 session_key); 386 data_blob_free(&session_key); 387 if (!NT_STATUS_IS_OK(nt_status)) { 388 return nt_status; 341 389 } 342 390 … … 354 402 { 355 403 NTSTATUS nt_status; 356 struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); 404 struct sesssetup_state *state = talloc_get_type(c->private_data, 405 struct sesssetup_state); 357 406 const char *password = cli_credentials_get_password(io->in.credentials); 358 DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, cli_credentials_get_domain(io->in.credentials)); 407 408 /* 409 * domain controllers tend to reject the NTLM v2 blob 410 * if the netbiosname is not valid (e.g. IP address or FQDN) 411 * so just leave it away (as Windows client do) 412 */ 359 413 DATA_BLOB session_key; 360 int flags = 0;361 if (session->options.lanman_auth) {362 flags |= CLI_CRED_LANMAN_AUTH;363 }364 365 if (session->options.ntlmv2_auth) {366 flags |= CLI_CRED_NTLMv2_AUTH;367 }368 414 369 415 state->setup.old.level = RAW_SESSSETUP_OLD; … … 379 425 380 426 if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) { 427 DATA_BLOB names_blob = data_blob_null; 428 int flags = 0; 429 430 if (!cli_credentials_is_anonymous(io->in.credentials) && 431 !session->options.lanman_auth) 432 { 433 return NT_STATUS_INVALID_PARAMETER; 434 } 435 436 flags |= CLI_CRED_LANMAN_AUTH; 437 381 438 nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, 382 439 &flags, 383 440 session->transport->negotiate.secblob, 441 NULL, /* server_timestamp */ 384 442 names_blob, 385 443 &state->setup.old.in.password, … … 387 445 NULL, &session_key); 388 446 NT_STATUS_NOT_OK_RETURN(nt_status); 389 set_user_session_key(session, &session_key); 390 447 448 nt_status = smb1cli_session_set_session_key(session->smbXcli, 449 session_key); 391 450 data_blob_free(&session_key); 451 if (!NT_STATUS_IS_OK(nt_status)) { 452 return nt_status; 453 } 392 454 } else if (session->options.plaintext_auth) { 393 455 state->setup.old.in.password = data_blob_talloc(state, password, strlen(password)); … … 427 489 state->setup.spnego.in.workgroup = io->in.workgroup; 428 490 429 smbcli_temp_set_signing(session->transport); 430 431 status = gensec_client_start(session, &session->gensec, c->event_ctx, 491 status = gensec_client_start(session, &session->gensec, 432 492 io->in.gensec_settings); 433 493 if (!NT_STATUS_IS_OK(status)) { … … 445 505 } 446 506 447 status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname); 507 status = gensec_set_target_hostname(session->gensec, 508 smbXcli_conn_remote_name(session->transport->conn)); 448 509 if (!NT_STATUS_IS_OK(status)) { 449 510 DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", … … 484 545 } 485 546 486 if ((const void *)chosen_oid == (const void *)GENSEC_OID_SPNEGO) { 487 status = gensec_update(session->gensec, state, 547 if (strequal(chosen_oid, GENSEC_OID_SPNEGO)) { 548 status = gensec_update_ev(session->gensec, state, 549 c->event_ctx, 488 550 session->transport->negotiate.secblob, 489 551 &state->setup.spnego.in.secblob); 490 552 } else { 491 status = gensec_update(session->gensec, state, 553 status = gensec_update_ev(session->gensec, state, 554 c->event_ctx, 492 555 data_blob(NULL, 0), 493 556 &state->setup.spnego.in.secblob); … … 514 577 * which comes within the response itself 515 578 */ 516 (*req)->sign_caller_checks = true; 579 if (!smb1cli_conn_signing_is_active((*req)->transport->conn)) { 580 (*req)->sign_caller_checks = true; 581 } 517 582 518 583 return (*req)->status; … … 532 597 NTSTATUS status; 533 598 534 c = composite_create(session, session->transport-> socket->event.ctx);599 c = composite_create(session, session->transport->ev); 535 600 if (c == NULL) return NULL; 536 601 -
vendor/current/source4/libcli/smb_composite/smb2.c
r414 r988 26 26 27 27 #include "includes.h" 28 #include <tevent.h> 29 #include "lib/util/tevent_ntstatus.h" 28 30 #include "libcli/raw/libcliraw.h" 29 31 #include "libcli/raw/raw_proto.h" … … 81 83 struct smb2_request *req; 82 84 83 ctx = composite_create(tree, tree->session->transport-> socket->event.ctx);85 ctx = composite_create(tree, tree->session->transport->ev); 84 86 if (ctx == NULL) return NULL; 85 87 … … 160 162 struct smb2_request *req; 161 163 162 ctx = composite_create(tree, tree->session->transport-> socket->event.ctx);164 ctx = composite_create(tree, tree->session->transport->ev); 163 165 if (ctx == NULL) return NULL; 164 166 … … 231 233 struct smb2_request *req; 232 234 233 ctx = composite_create(tree, tree->session->transport-> socket->event.ctx);235 ctx = composite_create(tree, tree->session->transport->ev); 234 236 if (ctx == NULL) return NULL; 235 237 … … 265 267 } 266 268 267 268 /* 269 continue after the setfileinfo in a composite setpathinfo 270 */ 271 static void continue_setpathinfo_close(struct smb2_request *req) 272 { 273 struct composite_context *ctx = talloc_get_type(req->async.private_data, 274 struct composite_context); 275 struct smb2_tree *tree = req->tree; 276 struct smb2_close close_parm; 277 NTSTATUS status; 278 union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, 279 union smb_setfileinfo); 280 281 status = smb2_setinfo_recv(req); 282 if (!NT_STATUS_IS_OK(status)) { 283 composite_error(ctx, status); 284 return; 285 } 286 287 ZERO_STRUCT(close_parm); 288 close_parm.in.file.handle = io2->generic.in.file.handle; 289 290 req = smb2_close_send(tree, &close_parm); 291 composite_continue_smb2(ctx, req, continue_close, ctx); 292 } 293 294 295 /* 296 continue after the create in a composite setpathinfo 297 */ 298 static void continue_setpathinfo(struct smb2_request *req) 299 { 300 struct composite_context *ctx = talloc_get_type(req->async.private_data, 301 struct composite_context); 302 struct smb2_tree *tree = req->tree; 303 struct smb2_create create_parm; 304 NTSTATUS status; 305 union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, 306 union smb_setfileinfo); 307 308 status = smb2_create_recv(req, ctx, &create_parm); 309 if (!NT_STATUS_IS_OK(status)) { 310 composite_error(ctx, status); 311 return; 312 } 313 314 io2->generic.in.file.handle = create_parm.out.file.handle; 315 316 req = smb2_setinfo_file_send(tree, io2); 317 composite_continue_smb2(ctx, req, continue_setpathinfo_close, ctx); 318 } 319 269 struct smb2_composite_setpathinfo_state { 270 struct smb2_tree *tree; 271 union smb_setfileinfo io; 272 NTSTATUS set_status; 273 struct smb2_create cr; 274 struct smb2_close cl; 275 }; 276 277 static void smb2_composite_setpathinfo_create_done(struct smb2_request *smb2req); 320 278 321 279 /* 322 280 composite SMB2 setpathinfo call 323 281 */ 324 struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree, 325 union smb_setfileinfo *io) 326 { 327 struct composite_context *ctx; 328 struct smb2_create create_parm; 329 struct smb2_request *req; 330 union smb_setfileinfo *io2; 331 332 ctx = composite_create(tree, tree->session->transport->socket->event.ctx); 333 if (ctx == NULL) return NULL; 334 335 ZERO_STRUCT(create_parm); 336 create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; 337 create_parm.in.create_disposition = NTCREATEX_DISP_OPEN; 338 create_parm.in.share_access = 282 struct tevent_req *smb2_composite_setpathinfo_send(TALLOC_CTX *mem_ctx, 283 struct tevent_context *ev, 284 struct smb2_tree *tree, 285 const union smb_setfileinfo *io) 286 { 287 struct tevent_req *req; 288 struct smb2_composite_setpathinfo_state *state; 289 struct smb2_request *smb2req; 290 291 req = tevent_req_create(mem_ctx, &state, 292 struct smb2_composite_setpathinfo_state); 293 if (req == NULL) { 294 return NULL; 295 } 296 297 state->tree = tree; 298 state->io = *io; 299 300 state->cr.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; 301 state->cr.in.create_disposition = NTCREATEX_DISP_OPEN; 302 state->cr.in.share_access = 339 303 NTCREATEX_SHARE_ACCESS_DELETE| 340 304 NTCREATEX_SHARE_ACCESS_READ| 341 305 NTCREATEX_SHARE_ACCESS_WRITE; 342 create_parm.in.create_options = 0; 343 create_parm.in.fname = io->generic.in.file.path; 344 if (create_parm.in.fname[0] == '\\') { 345 create_parm.in.fname++; 346 } 347 348 req = smb2_create_send(tree, &create_parm); 349 350 io2 = talloc(ctx, union smb_setfileinfo); 351 if (composite_nomem(io2, ctx)) { 352 return ctx; 353 } 354 *io2 = *io; 355 356 ctx->private_data = io2; 357 358 composite_continue_smb2(ctx, req, continue_setpathinfo, ctx); 359 return ctx; 360 } 361 306 state->cr.in.create_options = 0; 307 state->cr.in.fname = state->io.generic.in.file.path; 308 if (state->cr.in.fname[0] == '\\') { 309 state->cr.in.fname++; 310 } 311 312 smb2req = smb2_create_send(tree, &state->cr); 313 if (tevent_req_nomem(smb2req, req)) { 314 return tevent_req_post(req, ev); 315 } 316 smb2req->async.fn = smb2_composite_setpathinfo_create_done; 317 smb2req->async.private_data = req; 318 319 return req; 320 } 321 322 static void smb2_composite_setpathinfo_setinfo_done(struct smb2_request *smb2req); 323 324 static void smb2_composite_setpathinfo_create_done(struct smb2_request *smb2req) 325 { 326 struct tevent_req *req = 327 talloc_get_type_abort(smb2req->async.private_data, 328 struct tevent_req); 329 struct smb2_composite_setpathinfo_state *state = 330 tevent_req_data(req, 331 struct smb2_composite_setpathinfo_state); 332 NTSTATUS status; 333 334 status = smb2_create_recv(smb2req, state, &state->cr); 335 if (tevent_req_nterror(req, status)) { 336 return; 337 } 338 339 state->io.generic.in.file.handle = state->cr.out.file.handle; 340 341 smb2req = smb2_setinfo_file_send(state->tree, &state->io); 342 if (tevent_req_nomem(smb2req, req)) { 343 return; 344 } 345 smb2req->async.fn = smb2_composite_setpathinfo_setinfo_done; 346 smb2req->async.private_data = req; 347 } 348 349 static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req); 350 351 static void smb2_composite_setpathinfo_setinfo_done(struct smb2_request *smb2req) 352 { 353 struct tevent_req *req = 354 talloc_get_type_abort(smb2req->async.private_data, 355 struct tevent_req); 356 struct smb2_composite_setpathinfo_state *state = 357 tevent_req_data(req, 358 struct smb2_composite_setpathinfo_state); 359 NTSTATUS status; 360 361 status = smb2_setinfo_recv(smb2req); 362 state->set_status = status; 363 364 state->cl.in.file.handle = state->io.generic.in.file.handle; 365 366 smb2req = smb2_close_send(state->tree, &state->cl); 367 if (tevent_req_nomem(smb2req, req)) { 368 return; 369 } 370 smb2req->async.fn = smb2_composite_setpathinfo_close_done; 371 smb2req->async.private_data = req; 372 } 373 374 static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req) 375 { 376 struct tevent_req *req = 377 talloc_get_type_abort(smb2req->async.private_data, 378 struct tevent_req); 379 struct smb2_composite_setpathinfo_state *state = 380 tevent_req_data(req, 381 struct smb2_composite_setpathinfo_state); 382 NTSTATUS status; 383 384 status = smb2_close_recv(smb2req, &state->cl); 385 386 if (tevent_req_nterror(req, state->set_status)) { 387 return; 388 } 389 390 if (tevent_req_nterror(req, status)) { 391 return; 392 } 393 394 tevent_req_done(req); 395 } 396 397 NTSTATUS smb2_composite_setpathinfo_recv(struct tevent_req *req) 398 { 399 NTSTATUS status; 400 401 if (tevent_req_is_nterror(req, &status)) { 402 tevent_req_received(req); 403 return status; 404 } 405 406 tevent_req_received(req); 407 return NT_STATUS_OK; 408 } 362 409 363 410 /* … … 366 413 NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io) 367 414 { 368 struct composite_context *c = smb2_composite_setpathinfo_send(tree, io); 369 return composite_wait_free(c); 370 } 415 struct tevent_req *subreq; 416 NTSTATUS status; 417 bool ok; 418 TALLOC_CTX *frame = talloc_stackframe(); 419 struct tevent_context *ev = tree->session->transport->ev; 420 421 if (frame == NULL) { 422 return NT_STATUS_NO_MEMORY; 423 } 424 425 subreq = smb2_composite_setpathinfo_send(frame, ev, tree, io); 426 if (subreq == NULL) { 427 TALLOC_FREE(frame); 428 return NT_STATUS_NO_MEMORY; 429 } 430 431 ok = tevent_req_poll(subreq, ev); 432 if (!ok) { 433 status = map_nt_error_from_unix_common(errno); 434 TALLOC_FREE(frame); 435 return status; 436 } 437 438 status = smb2_composite_setpathinfo_recv(subreq); 439 TALLOC_FREE(subreq); 440 if (!NT_STATUS_IS_OK(status)) { 441 TALLOC_FREE(frame); 442 return status; 443 } 444 445 TALLOC_FREE(frame); 446 return NT_STATUS_OK; 447 } -
vendor/current/source4/libcli/smb_composite/smb_composite.h
r740 r988 28 28 */ 29 29 30 #include "libcli/raw/signing.h" 30 #ifndef __SMB_COMPOSITE_H__ 31 #define __SMB_COMPOSITE_H__ 32 31 33 #include "libcli/raw/libcliraw.h" 32 34 #include "libcli/smb2/smb2.h" 33 35 34 35 36 /* 36 37 a composite open/read(s)/close request that loads a whole file … … 46 47 } out; 47 48 }; 49 50 struct composite_context *smb_composite_loadfile_send(struct smbcli_tree *tree, 51 struct smb_composite_loadfile *io); 52 NTSTATUS smb_composite_loadfile_recv(struct composite_context *c, TALLOC_CTX *mem_ctx); 53 NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree, 54 TALLOC_CTX *mem_ctx, 55 struct smb_composite_loadfile *io); 48 56 49 57 struct smb_composite_fetchfile { … … 69 77 }; 70 78 79 struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io, 80 struct tevent_context *event_ctx); 81 NTSTATUS smb_composite_fetchfile_recv(struct composite_context *c, 82 TALLOC_CTX *mem_ctx); 83 NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io, 84 TALLOC_CTX *mem_ctx); 85 71 86 /* 72 87 a composite open/write(s)/close request that saves a whole file from … … 81 96 }; 82 97 98 struct composite_context *smb_composite_savefile_send(struct smbcli_tree *tree, 99 struct smb_composite_savefile *io); 100 NTSTATUS smb_composite_savefile_recv(struct composite_context *c); 101 NTSTATUS smb_composite_savefile(struct smbcli_tree *tree, 102 struct smb_composite_savefile *io); 83 103 84 104 /* … … 112 132 }; 113 133 134 struct composite_context *smb_composite_connect_send(struct smb_composite_connect *io, 135 TALLOC_CTX *mem_ctx, 136 struct resolve_context *resolve_ctx, 137 struct tevent_context *event_ctx); 138 NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx); 139 NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx, 140 struct resolve_context *resolve_ctx, 141 struct tevent_context *ev); 142 114 143 115 144 /* … … 129 158 } out; 130 159 }; 160 161 struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *session, 162 struct smb_composite_sesssetup *io); 163 NTSTATUS smb_composite_sesssetup_recv(struct composite_context *c); 164 NTSTATUS smb_composite_sesssetup(struct smbcli_session *session, struct smb_composite_sesssetup *io); 131 165 132 166 /* … … 152 186 }; 153 187 188 struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, 189 struct smb_composite_fsinfo *io, 190 struct resolve_context *resolve_ctx, 191 struct tevent_context *event_ctx); 192 NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx); 193 NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree, 194 TALLOC_CTX *mem_ctx, 195 struct smb_composite_fsinfo *io, 196 struct resolve_context *resolve_ctx, 197 struct tevent_context *ev); 198 154 199 /* 155 200 composite call for appending new acl to the file's security descriptor and get … … 168 213 } out; 169 214 }; 215 216 struct composite_context *smb_composite_appendacl_send(struct smbcli_tree *tree, 217 struct smb_composite_appendacl *io); 218 NTSTATUS smb_composite_appendacl_recv(struct composite_context *c, TALLOC_CTX *mem_ctx); 219 NTSTATUS smb_composite_appendacl(struct smbcli_tree *tree, 220 TALLOC_CTX *mem_ctx, 221 struct smb_composite_appendacl *io); 170 222 171 223 /* … … 190 242 struct resolve_context; 191 243 192 #include "libcli/smb_composite/proto.h" 244 struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree, 245 union smb_unlink *io); 246 NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io); 247 struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree, 248 union smb_mkdir *io); 249 NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io); 250 struct composite_context *smb2_composite_rmdir_send(struct smb2_tree *tree, 251 struct smb_rmdir *io); 252 NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io); 253 struct tevent_req *smb2_composite_setpathinfo_send(TALLOC_CTX *mem_ctx, 254 struct tevent_context *ev, 255 struct smb2_tree *tree, 256 const union smb_setfileinfo *io); 257 NTSTATUS smb2_composite_setpathinfo_recv(struct tevent_req *req); 258 NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io); 259 260 #endif /* __SMB_COMPOSITE_H__ */ -
vendor/current/source4/libcli/util/clilsa.c
r860 r988 33 33 #include "librpc/gen_ndr/ndr_lsa_c.h" 34 34 #include "libcli/util/clilsa.h" 35 #include "libcli/smb/smbXcli_base.h" 35 36 36 37 struct smblsa_state { 37 struct dcerpc_ pipe *pipe;38 struct dcerpc_binding_handle *binding_handle; 38 39 struct smbcli_tree *ipc_tree; 39 40 struct policy_handle handle; … … 46 47 { 47 48 struct smblsa_state *lsa; 49 struct dcerpc_pipe *lsa_pipe; 48 50 NTSTATUS status; 49 51 struct lsa_OpenPolicy r; … … 69 71 /* connect to IPC$ */ 70 72 tcon.generic.level = RAW_TCON_TCONX; 71 tcon.tconx.in.flags = 0; 73 tcon.tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE; 74 tcon.tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES; 72 75 tcon.tconx.in.password = data_blob(NULL, 0); 73 76 tcon.tconx.in.path = "ipc$"; … … 80 83 lsa->ipc_tree->tid = tcon.tconx.out.tid; 81 84 82 lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx); 83 if (lsa->pipe == NULL) { 85 if (tcon.tconx.out.options & SMB_EXTENDED_SIGNATURES) { 86 smb1cli_session_protect_session_key(cli->session->smbXcli); 87 } 88 89 lsa_pipe = dcerpc_pipe_init(lsa, cli->transport->ev); 90 if (lsa_pipe == NULL) { 84 91 talloc_free(lsa); 85 92 return NT_STATUS_NO_MEMORY; … … 87 94 88 95 /* open the LSA pipe */ 89 status = dcerpc_pipe_open_smb(lsa ->pipe, lsa->ipc_tree, NDR_LSARPC_NAME);96 status = dcerpc_pipe_open_smb(lsa_pipe, lsa->ipc_tree, NDR_LSARPC_NAME); 90 97 if (!NT_STATUS_IS_OK(status)) { 91 98 talloc_free(lsa); … … 94 101 95 102 /* bind to the LSA pipe */ 96 status = dcerpc_bind_auth_none(lsa ->pipe, &ndr_table_lsarpc);103 status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc); 97 104 if (!NT_STATUS_IS_OK(status)) { 98 105 talloc_free(lsa); 99 106 return status; 100 107 } 101 108 lsa->binding_handle = lsa_pipe->binding_handle; 102 109 103 110 /* open a lsa policy handle */ … … 119 126 r.out.handle = &lsa->handle; 120 127 121 status = dcerpc_lsa_OpenPolicy_r(lsa-> pipe->binding_handle, lsa, &r);128 status = dcerpc_lsa_OpenPolicy_r(lsa->binding_handle, lsa, &r); 122 129 if (!NT_STATUS_IS_OK(status)) { 123 130 talloc_free(lsa); … … 155 162 r.out.rights = rights; 156 163 157 status = dcerpc_lsa_EnumAccountRights_r(cli->lsa-> pipe->binding_handle, mem_ctx, &r);164 status = dcerpc_lsa_EnumAccountRights_r(cli->lsa->binding_handle, mem_ctx, &r); 158 165 if (!NT_STATUS_IS_OK(status)) { 159 166 return status; … … 244 251 r.out.domains = &domains; 245 252 246 status = dcerpc_lsa_LookupSids_r(cli->lsa-> pipe->binding_handle, mem_ctx2, &r);253 status = dcerpc_lsa_LookupSids_r(cli->lsa->binding_handle, mem_ctx2, &r); 247 254 if (!NT_STATUS_IS_OK(status)) { 248 255 talloc_free(mem_ctx2); … … 319 326 r.out.domains = &domains; 320 327 321 status = dcerpc_lsa_LookupNames_r(cli->lsa-> pipe->binding_handle, mem_ctx2, &r);328 status = dcerpc_lsa_LookupNames_r(cli->lsa->binding_handle, mem_ctx2, &r); 322 329 if (!NT_STATUS_IS_OK(status)) { 323 330 talloc_free(mem_ctx2); … … 368 375 r.in.rights = rights; 369 376 370 status = dcerpc_lsa_AddAccountRights_r(cli->lsa-> pipe->binding_handle, mem_ctx, &r);377 status = dcerpc_lsa_AddAccountRights_r(cli->lsa->binding_handle, mem_ctx, &r); 371 378 if (!NT_STATUS_IS_OK(status)) { 372 379 return status; … … 396 403 r.in.rights = rights; 397 404 398 status = dcerpc_lsa_RemoveAccountRights_r(cli->lsa-> pipe->binding_handle, mem_ctx, &r);405 status = dcerpc_lsa_RemoveAccountRights_r(cli->lsa->binding_handle, mem_ctx, &r); 399 406 if (!NT_STATUS_IS_OK(status)) { 400 407 return status; -
vendor/current/source4/libcli/util/pyerrors.h
r740 r988 23 23 #define PyErr_FromWERROR(err) Py_BuildValue("(i,s)", W_ERROR_V(err), discard_const_p(char, win_errstr(err))) 24 24 25 #define PyErr_FromHRESULT(err) Py_BuildValue("(i,s)", HRES_ERROR_V(err), discard_const_p(char, hresult_errstr_const(err))) 26 25 27 #define PyErr_FromNTSTATUS(status) Py_BuildValue("(i,s)", NT_STATUS_V(status), discard_const_p(char, get_friendly_nt_error_msg(status))) 26 28 … … 39 41 } 40 42 41 #define PyErr_WERROR_IS_ERR_RAISE(status) \ 43 #define PyErr_NTSTATUS_NOT_OK_RAISE(status) \ 44 if (!NT_STATUS_IS_OK(status)) { \ 45 PyErr_SetNTSTATUS(status); \ 46 return NULL; \ 47 } 48 49 #define PyErr_WERROR_NOT_OK_RAISE(status) \ 42 50 if (!W_ERROR_IS_OK(status)) { \ 43 51 PyErr_SetWERROR(status); \ -
vendor/current/source4/libcli/wbclient/wbclient.c
r740 r988 22 22 #include "includes.h" 23 23 #include <tevent.h> 24 #include "lib/util/tevent_unix.h" 24 25 #include "libcli/wbclient/wbclient.h" 25 26 /** 27 * Initialize the wbclient context, talloc_free() when done. 28 * 29 * \param mem_ctx talloc context to allocate memory from 30 * \param msg_ctx message context to use 31 * \param 32 */ 33 struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx, 34 struct messaging_context *msg_ctx, 35 struct tevent_context *event_ctx) 36 { 37 struct wbc_context *ctx; 38 39 ctx = talloc(mem_ctx, struct wbc_context); 40 if (ctx == NULL) return NULL; 41 42 ctx->event_ctx = event_ctx; 43 44 ctx->irpc_handle = irpc_binding_handle_by_name(ctx, msg_ctx, 45 "winbind_server", 46 &ndr_table_winbind); 47 if (ctx->irpc_handle == NULL) { 48 talloc_free(ctx); 26 #include "nsswitch/wb_reqtrans.h" 27 #include "system/network.h" 28 #include "libcli/util/error.h" 29 #include "libcli/security/dom_sid.h" 30 31 static int wb_simple_trans(struct tevent_context *ev, int fd, 32 struct winbindd_request *wb_req, 33 TALLOC_CTX *mem_ctx, 34 struct winbindd_response **resp, int *err) 35 { 36 struct tevent_req *req; 37 bool polled; 38 int ret; 39 40 req = wb_simple_trans_send(ev, ev, NULL, fd, wb_req); 41 if (req == NULL) { 42 *err = ENOMEM; 43 return -1; 44 } 45 46 polled = tevent_req_poll(req, ev); 47 if (!polled) { 48 *err = errno; 49 DEBUG(10, ("tevent_req_poll returned %s\n", 50 strerror(*err))); 51 return -1; 52 } 53 54 ret = wb_simple_trans_recv(req, mem_ctx, resp, err); 55 TALLOC_FREE(req); 56 return ret; 57 } 58 59 static const char *winbindd_socket_dir(void) 60 { 61 #ifdef SOCKET_WRAPPER 62 const char *env_dir; 63 64 env_dir = getenv("SELFTEST_WINBINDD_SOCKET_DIR"); 65 if (env_dir) { 66 return env_dir; 67 } 68 #endif 69 70 return WINBINDD_SOCKET_DIR; 71 } 72 73 static int winbindd_pipe_sock(void) 74 { 75 struct sockaddr_un sunaddr = {}; 76 int ret, fd; 77 char *path; 78 79 ret = asprintf(&path, "%s/%s", winbindd_socket_dir(), 80 WINBINDD_SOCKET_NAME); 81 if (ret == -1) { 82 errno = ENOMEM; 83 return -1; 84 } 85 sunaddr.sun_family = AF_UNIX; 86 strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)); 87 free(path); 88 89 fd = socket(AF_UNIX, SOCK_STREAM, 0); 90 if (fd == -1) { 91 return -1; 92 } 93 94 ret = connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); 95 if (ret == -1) { 96 int err = errno; 97 close(fd); 98 errno = err; 99 return -1; 100 } 101 102 return fd; 103 } 104 105 NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids, 106 uint32_t count) 107 { 108 TALLOC_CTX *mem_ctx; 109 struct winbindd_request req = {}; 110 struct winbindd_response *resp; 111 uint32_t i; 112 int fd, ret, err; 113 char *sids, *p; 114 size_t sidslen; 115 116 fd = winbindd_pipe_sock(); 117 if (fd == -1) { 118 return map_nt_error_from_unix_common(errno); 119 } 120 121 mem_ctx = talloc_new(NULL); 122 if (mem_ctx == NULL) { 123 close(fd); 124 return NT_STATUS_NO_MEMORY; 125 } 126 127 sidslen = count * (DOM_SID_STR_BUFLEN + 1); 128 129 sids = talloc_array(mem_ctx, char, sidslen); 130 if (sids == NULL) { 131 close(fd); 132 TALLOC_FREE(mem_ctx); 133 return NT_STATUS_NO_MEMORY; 134 } 135 136 p = sids; 137 for (i=0; i<count; i++) { 138 p += dom_sid_string_buf(ids[i].sid, p, sidslen - (p - sids)); 139 *p++ = '\n'; 140 } 141 *p++ = '\0'; 142 143 DEBUG(10, ("sids=\n%s", sids)); 144 145 req.length = sizeof(struct winbindd_request); 146 req.cmd = WINBINDD_SIDS_TO_XIDS; 147 req.pid = getpid(); 148 req.extra_data.data = sids; 149 req.extra_len = (p - sids); 150 151 ret = wb_simple_trans(ev, fd, &req, mem_ctx, &resp, &err); 152 if (ret == -1) { 153 return map_nt_error_from_unix_common(err); 154 } 155 156 close(fd); 157 158 if (resp->result != WINBINDD_OK || p == NULL) { 159 return NT_STATUS_INTERNAL_ERROR; 160 } 161 162 p = resp->extra_data.data; 163 164 for (i=0; i<count; i++) { 165 struct unixid *id = &ids[i].xid; 166 char *q; 167 168 switch (p[0]) { 169 case 'U': 170 id->type = ID_TYPE_UID; 171 id->id = strtoul(p+1, &q, 10); 172 break; 173 case 'G': 174 id->type = ID_TYPE_GID; 175 id->id = strtoul(p+1, &q, 10); 176 break; 177 case 'B': 178 id->type = ID_TYPE_BOTH; 179 id->id = strtoul(p+1, &q, 10); 180 break; 181 default: 182 id->type = ID_TYPE_NOT_SPECIFIED; 183 id->id = UINT32_MAX; 184 q = strchr(p, '\n'); 185 break; 186 }; 187 ids[i].status = ID_MAPPED; 188 189 if (q == NULL || q[0] != '\n') { 190 TALLOC_FREE(mem_ctx); 191 return NT_STATUS_INTERNAL_ERROR; 192 } 193 p = q+1; 194 } 195 196 return NT_STATUS_OK; 197 } 198 199 struct wbc_id_to_sid_state { 200 struct winbindd_request wbreq; 201 struct dom_sid sid; 202 }; 203 204 static void wbc_id_to_sid_done(struct tevent_req *subreq); 205 206 static struct tevent_req *wbc_id_to_sid_send(TALLOC_CTX *mem_ctx, 207 struct tevent_context *ev, 208 int fd, const struct unixid *id) 209 { 210 struct tevent_req *req, *subreq; 211 struct wbc_id_to_sid_state *state; 212 213 req = tevent_req_create(mem_ctx, &state, struct wbc_id_to_sid_state); 214 if (req == NULL) { 49 215 return NULL; 50 216 } 51 217 52 return ctx; 53 } 54 55 struct wbc_idmap_state { 56 struct composite_context *ctx; 57 struct winbind_get_idmap *req; 218 switch(id->type) { 219 case ID_TYPE_UID: 220 state->wbreq.cmd = WINBINDD_UID_TO_SID; 221 state->wbreq.data.uid = id->id; 222 break; 223 case ID_TYPE_GID: 224 state->wbreq.cmd = WINBINDD_GID_TO_SID; 225 state->wbreq.data.gid = id->id; 226 break; 227 default: 228 tevent_req_error(req, ENOENT); 229 return tevent_req_post(req, ev); 230 } 231 232 subreq = wb_simple_trans_send(state, ev, NULL, fd, &state->wbreq); 233 if (tevent_req_nomem(subreq, req)) { 234 return tevent_req_post(req, ev); 235 } 236 tevent_req_set_callback(subreq, wbc_id_to_sid_done, req); 237 return req; 238 } 239 240 static void wbc_id_to_sid_done(struct tevent_req *subreq) 241 { 242 struct tevent_req *req = tevent_req_callback_data( 243 subreq, struct tevent_req); 244 struct wbc_id_to_sid_state *state = tevent_req_data( 245 req, struct wbc_id_to_sid_state); 246 struct winbindd_response *wbresp; 247 int ret, err; 248 249 ret = wb_simple_trans_recv(subreq, state, &wbresp, &err); 250 TALLOC_FREE(subreq); 251 if (ret == -1) { 252 tevent_req_error(req, err); 253 return; 254 } 255 if ((wbresp->result != WINBINDD_OK) || 256 !dom_sid_parse(wbresp->data.sid.sid, &state->sid)) { 257 tevent_req_error(req, ENOENT); 258 return; 259 } 260 tevent_req_done(req); 261 } 262 263 static int wbc_id_to_sid_recv(struct tevent_req *req, struct dom_sid *sid) 264 { 265 struct wbc_id_to_sid_state *state = tevent_req_data( 266 req, struct wbc_id_to_sid_state); 267 int err; 268 269 if (tevent_req_is_unix_error(req, &err)) { 270 return err; 271 } 272 sid_copy(sid, &state->sid); 273 return 0; 274 } 275 276 struct wbc_ids_to_sids_state { 277 struct tevent_context *ev; 278 int fd; 58 279 struct id_map *ids; 280 uint32_t count; 281 uint32_t idx; 59 282 }; 60 283 61 static void sids_to_xids_recv_ids(struct tevent_req *subreq); 62 63 struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx, 64 TALLOC_CTX *mem_ctx, 65 uint32_t count, 66 struct id_map *ids) 67 { 68 struct composite_context *ctx; 69 struct wbc_idmap_state *state; 70 struct tevent_req *subreq; 71 72 DEBUG(5, ("wbc_sids_to_xids called\n")); 73 74 ctx = composite_create(mem_ctx, wbc_ctx->event_ctx); 75 if (ctx == NULL) return NULL; 76 77 state = talloc(ctx, struct wbc_idmap_state); 78 if (composite_nomem(state, ctx)) return ctx; 79 ctx->private_data = state; 80 81 state->req = talloc(state, struct winbind_get_idmap); 82 if (composite_nomem(state->req, ctx)) return ctx; 83 84 state->req->in.count = count; 85 state->req->in.level = WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS; 86 state->req->in.ids = ids; 87 state->ctx = ctx; 88 89 subreq = dcerpc_winbind_get_idmap_r_send(state, 90 wbc_ctx->event_ctx, 91 wbc_ctx->irpc_handle, 92 state->req); 93 if (composite_nomem(subreq, ctx)) return ctx; 94 95 tevent_req_set_callback(subreq, sids_to_xids_recv_ids, state); 96 97 return ctx; 98 } 99 100 static void sids_to_xids_recv_ids(struct tevent_req *subreq) 101 { 102 struct wbc_idmap_state *state = 103 tevent_req_callback_data(subreq, 104 struct wbc_idmap_state); 105 106 state->ctx->status = dcerpc_winbind_get_idmap_r_recv(subreq, state); 284 static void wbc_ids_to_sids_done(struct tevent_req *subreq); 285 286 static struct tevent_req *wbc_ids_to_sids_send( 287 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 288 int fd, struct id_map *ids, uint32_t count) 289 { 290 struct tevent_req *req, *subreq; 291 struct wbc_ids_to_sids_state *state; 292 293 req = tevent_req_create(mem_ctx, &state, 294 struct wbc_ids_to_sids_state); 295 if (req == NULL) { 296 return NULL; 297 } 298 state->ev = ev; 299 state->fd = fd; 300 state->ids = ids; 301 state->count = count; 302 303 if (count == 0) { 304 tevent_req_done(req); 305 return tevent_req_post(req, ev); 306 } 307 308 subreq = wbc_id_to_sid_send(state, state->ev, state->fd, 309 &state->ids[state->idx].xid); 310 if (tevent_req_nomem(subreq, req)) { 311 return tevent_req_post(req, ev); 312 } 313 tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req); 314 return req; 315 } 316 317 static void wbc_ids_to_sids_done(struct tevent_req *subreq) 318 { 319 struct tevent_req *req = tevent_req_callback_data( 320 subreq, struct tevent_req); 321 struct wbc_ids_to_sids_state *state = tevent_req_data( 322 req, struct wbc_ids_to_sids_state); 323 struct id_map *id; 324 struct dom_sid sid; 325 int ret; 326 327 ret = wbc_id_to_sid_recv(subreq, &sid); 107 328 TALLOC_FREE(subreq); 108 if (!composite_is_ok(state->ctx)) return; 109 110 state->ids = state->req->out.ids; 111 composite_done(state->ctx); 112 } 113 114 NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx, 115 struct id_map **ids) 116 { 117 NTSTATUS status = composite_wait(ctx); 118 DEBUG(5, ("wbc_sids_to_xids_recv called\n")); 119 if (NT_STATUS_IS_OK(status)) { 120 struct wbc_idmap_state *state = talloc_get_type_abort( 121 ctx->private_data, 122 struct wbc_idmap_state); 123 *ids = state->ids; 124 } 125 329 330 id = &state->ids[state->idx]; 331 if (ret == 0) { 332 id->status = ID_MAPPED; 333 id->sid = dom_sid_dup(state->ids, &sid); 334 if (id->sid == NULL) { 335 tevent_req_error(req, ENOMEM); 336 return; 337 } 338 } else { 339 id->status = ID_UNMAPPED; 340 id->sid = NULL; 341 } 342 343 state->idx += 1; 344 if (state->idx == state->count) { 345 tevent_req_done(req); 346 return; 347 } 348 349 subreq = wbc_id_to_sid_send(state, state->ev, state->fd, 350 &state->ids[state->idx].xid); 351 if (tevent_req_nomem(subreq, req)) { 352 return; 353 } 354 tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req); 355 } 356 357 static int wbc_ids_to_sids_recv(struct tevent_req *req) 358 { 359 int err; 360 if (tevent_req_is_unix_error(req, &err)) { 361 return err; 362 } 363 return 0; 364 } 365 366 NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids, 367 uint32_t count) 368 { 369 struct tevent_req *req; 370 NTSTATUS status; 371 bool polled; 372 int ret, fd; 373 374 DEBUG(5, ("wbc_xids_to_sids called: %u ids\n", (unsigned)count)); 375 376 fd = winbindd_pipe_sock(); 377 if (fd == -1) { 378 status = map_nt_error_from_unix_common(errno); 379 DEBUG(10, ("winbindd_pipe_sock returned %s\n", 380 strerror(errno))); 381 return status; 382 } 383 384 req = wbc_ids_to_sids_send(ev, ev, fd, ids, count); 385 if (req == NULL) { 386 status = NT_STATUS_NO_MEMORY; 387 goto done; 388 } 389 390 polled = tevent_req_poll(req, ev); 391 if (!polled) { 392 status = map_nt_error_from_unix_common(errno); 393 DEBUG(10, ("tevent_req_poll returned %s\n", 394 strerror(errno))); 395 goto done; 396 } 397 398 ret = wbc_ids_to_sids_recv(req); 399 TALLOC_FREE(req); 400 if (ret != 0) { 401 status = map_nt_error_from_unix_common(ret); 402 DEBUG(10, ("tevent_req_poll returned %s\n", 403 strerror(ret))); 404 } else { 405 status = NT_STATUS_OK; 406 } 407 408 done: 409 close(fd); 126 410 return status; 127 411 } 128 129 static void xids_to_sids_recv_ids(struct tevent_req *subreq);130 131 struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,132 TALLOC_CTX *mem_ctx,133 uint32_t count,134 struct id_map *ids)135 {136 struct composite_context *ctx;137 struct wbc_idmap_state *state;138 struct tevent_req *subreq;139 140 DEBUG(5, ("wbc_xids_to_sids called\n"));141 142 ctx = composite_create(mem_ctx, wbc_ctx->event_ctx);143 if (ctx == NULL) return NULL;144 145 state = talloc(ctx, struct wbc_idmap_state);146 if (composite_nomem(state, ctx)) return ctx;147 ctx->private_data = state;148 149 state->req = talloc(state, struct winbind_get_idmap);150 if (composite_nomem(state->req, ctx)) return ctx;151 152 state->req->in.count = count;153 state->req->in.level = WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS;154 state->req->in.ids = ids;155 state->ctx = ctx;156 157 subreq = dcerpc_winbind_get_idmap_r_send(state,158 wbc_ctx->event_ctx,159 wbc_ctx->irpc_handle,160 state->req);161 if (composite_nomem(subreq, ctx)) return ctx;162 163 tevent_req_set_callback(subreq, xids_to_sids_recv_ids, state);164 165 return ctx;166 }167 168 static void xids_to_sids_recv_ids(struct tevent_req *subreq)169 {170 struct wbc_idmap_state *state =171 tevent_req_callback_data(subreq,172 struct wbc_idmap_state);173 174 state->ctx->status = dcerpc_winbind_get_idmap_r_recv(subreq, state);175 TALLOC_FREE(subreq);176 if (!composite_is_ok(state->ctx)) return;177 178 state->ids = state->req->out.ids;179 composite_done(state->ctx);180 }181 182 NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,183 struct id_map **ids)184 {185 NTSTATUS status = composite_wait(ctx);186 DEBUG(5, ("wbc_xids_to_sids_recv called\n"));187 if (NT_STATUS_IS_OK(status)) {188 struct wbc_idmap_state *state = talloc_get_type_abort(189 ctx->private_data,190 struct wbc_idmap_state);191 *ids = state->ids;192 }193 194 return status;195 }196 -
vendor/current/source4/libcli/wbclient/wbclient.h
r740 r988 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 20 */ 21 #include "lib/messaging/irpc.h" 22 #include "libcli/composite/composite.h" 23 #include "librpc/gen_ndr/ndr_winbind_c.h" 21 #include "librpc/gen_ndr/idmap.h" 24 22 25 struct wbc_context { 26 struct tevent_context *event_ctx; 27 struct dcerpc_binding_handle *irpc_handle; 28 }; 23 NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids, 24 uint32_t count); 29 25 30 struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx, 31 struct messaging_context *msg_ctx, 32 struct tevent_context *event_ctx); 33 34 struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx, 35 TALLOC_CTX *mem_ctx, 36 uint32_t count, 37 struct id_map *ids); 38 39 NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx, 40 struct id_map **ids); 41 42 struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx, 43 TALLOC_CTX *mem_ctx, 44 uint32_t count, 45 struct id_map *ids); 46 47 NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx, 48 struct id_map **ids); 49 26 NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids, 27 uint32_t count); -
vendor/current/source4/libcli/wbclient/wscript_build
r740 r988 1 1 #!/usr/bin/env python 2 2 3 bld.SAMBA_SUBSYSTEM('LIBWBCLIENT_OLD', 4 source='wbclient.c', 5 public_deps='errors events', 6 deps='NDR_WINBIND MESSAGING RPC_NDR_WINBIND' 3 bld.SAMBA_LIBRARY('LIBWBCLIENT_OLD', 4 source='wbclient.c', 5 public_deps='samba-errors events', 6 cflags='-DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR, 7 deps='WB_REQTRANS NDR_WINBIND MESSAGING RPC_NDR_WINBIND', 8 private_library=True 7 9 ) 8 10 -
vendor/current/source4/libcli/wrepl/winsrepl.c
r740 r988 137 137 { 138 138 struct interface *ifaces; 139 load_interface s(lp_ctx, lpcfg_interfaces(lp_ctx), &ifaces);140 return iface_ best_ip(ifaces, peer_ip);139 load_interface_list(lp_ctx, lp_ctx, &ifaces); 140 return iface_list_best_ip(ifaces, peer_ip); 141 141 } 142 142 … … 182 182 &state->local_address); 183 183 if (ret != 0) { 184 NTSTATUS status = map_nt_error_from_unix (errno);184 NTSTATUS status = map_nt_error_from_unix_common(errno); 185 185 tevent_req_nterror(req, status); 186 186 return tevent_req_post(req, ev); … … 191 191 &state->remote_address); 192 192 if (ret != 0) { 193 NTSTATUS status = map_nt_error_from_unix (errno);193 NTSTATUS status = map_nt_error_from_unix_common(errno); 194 194 tevent_req_nterror(req, status); 195 195 return tevent_req_post(req, ev); … … 202 202 NULL); 203 203 if (!ok) { 204 tevent_req_ nomem(NULL,req);204 tevent_req_oom(req); 205 205 return tevent_req_post(req, ev); 206 206 } … … 251 251 state, &state->stream, NULL); 252 252 if (ret != 0) { 253 NTSTATUS status = map_nt_error_from_unix (sys_errno);253 NTSTATUS status = map_nt_error_from_unix_common(sys_errno); 254 254 tevent_req_nterror(req, status); 255 255 return; … … 360 360 361 361 if (wrepl_socket->stream == NULL) { 362 tevent_req_nterror(req, NT_STATUS_ INVALID_CONNECTION);362 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); 363 363 return tevent_req_post(req, ev); 364 364 } … … 383 383 NULL); 384 384 if (!ok) { 385 tevent_req_ nomem(NULL,req);385 tevent_req_oom(req); 386 386 return tevent_req_post(req, ev); 387 387 } … … 409 409 410 410 if (state->caller.wrepl_socket->stream == NULL) { 411 tevent_req_nterror(req, NT_STATUS_ INVALID_CONNECTION);411 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); 412 412 return; 413 413 } … … 444 444 TALLOC_FREE(subreq); 445 445 if (ret == -1) { 446 NTSTATUS status = map_nt_error_from_unix (sys_errno);446 NTSTATUS status = map_nt_error_from_unix_common(sys_errno); 447 447 TALLOC_FREE(state->caller.wrepl_socket->stream); 448 448 tevent_req_nterror(req, status); … … 451 451 452 452 if (state->caller.wrepl_socket->stream == NULL) { 453 tevent_req_nterror(req, NT_STATUS_ INVALID_CONNECTION);453 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); 454 454 return; 455 455 } … … 495 495 TALLOC_FREE(subreq); 496 496 if (ret == -1) { 497 NTSTATUS status = map_nt_error_from_unix (sys_errno);497 NTSTATUS status = map_nt_error_from_unix_common(sys_errno); 498 498 TALLOC_FREE(state->caller.wrepl_socket->stream); 499 499 tevent_req_nterror(req, status); -
vendor/current/source4/libcli/wscript_build
r740 r988 4 4 bld.RECURSE('wbclient') 5 5 6 bld.SAMBA_LIBRARY('errors',7 source='../../libcli/util/doserr.c util/errormap.c util/nterr.c',8 public_headers='../../libcli/util/error.h ../../libcli/util/ntstatus.h ../../libcli/util/doserr.h ../../libcli/util/werror.h',9 header_path='core',10 deps='talloc',11 private_library=True12 )13 14 15 6 bld.SAMBA_SUBSYSTEM('LIBSAMBA_TSOCKET', 16 7 source='../../libcli/util/tstream.c', 17 public_deps='LIBTSOCKET UTIL_TEVENT'8 public_deps='LIBTSOCKET tevent-util' 18 9 ) 19 10 … … 22 13 source='util/clilsa.c', 23 14 autoproto='util/clilsa.h', 24 public_deps='RPC_NDR_LSA ',25 deps='s ecurity'15 public_deps='RPC_NDR_LSA dcerpc', 16 deps='samba-security' 26 17 ) 27 18 28 19 29 bld.SAMBA_SUBSYSTEM(' LIBCLI_COMPOSITE',20 bld.SAMBA_SUBSYSTEM('cli_composite', 30 21 source='composite/composite.c', 31 22 autoproto='composite/proto.h', … … 36 27 bld.SAMBA_SUBSYSTEM('LIBCLI_SMB_COMPOSITE', 37 28 source='smb_composite/loadfile.c smb_composite/savefile.c smb_composite/connect.c smb_composite/sesssetup.c smb_composite/fetchfile.c smb_composite/appendacl.c smb_composite/fsinfo.c smb_composite/smb2.c', 38 autoproto='smb_composite/proto.h',39 deps='LIBCLI_SMB2',40 p ublic_deps='LIBCLI_COMPOSITE credentials gensec LIBCLI_RESOLVE'29 deps='LIBCLI_SMB2 tevent-util', 30 public_deps='cli_composite samba-credentials gensec LIBCLI_RESOLVE tevent', 31 private_headers='smb_composite/smb_composite.h', 41 32 ) 42 33 34 bld.SAMBA_PYTHON('pysmb', 35 source='pysmb.c', 36 deps='LIBCLI_SMB_COMPOSITE LIBCLI_SMB2 tevent-util pyparam_util pytalloc-util', 37 public_deps='cli_composite samba-credentials gensec LIBCLI_RESOLVE tevent param_options', 38 realname='samba/smb.so' 39 ) 43 40 44 41 bld.SAMBA_SUBSYSTEM('LIBCLI_DGRAM', … … 59 56 autoproto='resolve/proto.h', 60 57 deps='roken', 61 public_deps=' NDR_NBTLIBTSOCKET'58 public_deps='ndr_nbt LIBTSOCKET' 62 59 ) 63 60 64 61 65 62 bld.SAMBA_SUBSYSTEM('LP_RESOLVE', 66 source='resolve/bcast.c resolve/nbtlist.c resolve/wins.c resolve/dns_ex.c resolve/ file.c resolve/host.c resolve/resolve_lp.c',63 source='resolve/bcast.c resolve/nbtlist.c resolve/wins.c resolve/dns_ex.c resolve/host.c resolve/lmhosts.c resolve/resolve_lp.c', 67 64 autoproto='resolve/lp_proto.h', 68 deps='cli-nbt samba-hostconfig netif '65 deps='cli-nbt samba-hostconfig netif addns' 69 66 ) 70 67 71 68 72 69 bld.SAMBA_SUBSYSTEM('LIBCLI_FINDDCS', 73 source='finddcs_ nbt.c finddcs_cldap.c',70 source='finddcs_cldap.c', 74 71 autoproto='finddcs_proto.h', 75 public_deps='cli -nbt MESSAGING RPC_NDR_IRPC LIBCLI_CLDAP'72 public_deps='cli_cldap' 76 73 ) 77 74 … … 79 76 bld.SAMBA_SUBSYSTEM('LIBCLI_SMB', 80 77 source='clireadwrite.c cliconnect.c clifile.c clilist.c clitrans2.c climessage.c clideltree.c', 81 autoproto='libcli_proto.h',82 public_deps=' LIBCLI_RAW errors LIBCLI_AUTH LIBCLI_SMB_COMPOSITE cli-nbtsecurity LIBCLI_RESOLVE LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba_socket'78 private_headers='libcli.h:smb_cli.h', 79 public_deps='smbclient-raw samba-errors LIBCLI_AUTH LIBCLI_SMB_COMPOSITE cli-nbt samba-security LIBCLI_RESOLVE LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba_socket' 83 80 ) 84 81 85 82 86 bld.SAMBA_ SUBSYSTEM('LIBCLI_RAW',83 bld.SAMBA_LIBRARY('smbclient-raw', 87 84 source='raw/rawfile.c raw/smb_signing.c raw/clisocket.c raw/clitransport.c raw/clisession.c raw/clitree.c raw/clierror.c raw/rawrequest.c raw/rawreadwrite.c raw/rawsearch.c raw/rawsetfileinfo.c raw/raweas.c raw/rawtrans.c raw/clioplock.c raw/rawnegotiate.c raw/rawfsinfo.c raw/rawfileinfo.c raw/rawnotify.c raw/rawioctl.c raw/rawacl.c raw/rawdate.c raw/rawlpq.c raw/rawshadow.c', 88 85 autoproto='raw/raw_proto.h', 89 86 public_deps='samba_socket LIBPACKET LIBCRYPTO', 90 deps='LIBCLI_COMPOSITE LIBCLI_RESOLVE security ndr samba-util errors CHARSET talloc LIBCLI_SMB_COMPOSITE tevent NDR_NBT_BUF LIBCLI_SMB_COMMON' 87 deps='cli_composite LIBCLI_RESOLVE samba-security ndr samba-util samba-errors charset talloc LIBCLI_SMB_COMPOSITE tevent cli_smb_common', 88 private_headers='raw/request.h:smb_request.h raw/signing.h:smb_raw_signing.h raw/libcliraw.h:smb_cliraw.h raw/interfaces.h:smb_raw_interfaces.h raw/smb.h:smb_raw.h raw/trans2.h:smb_raw_trans2.h', 89 private_library=True, 91 90 ) 92 91
Note:
See TracChangeset
for help on using the changeset viewer.