Changeset 988 for vendor/current/source4/libcli/raw
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/libcli/raw
- Files:
-
- 1 deleted
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.