Changeset 745 for trunk/server/source3/smbd/smb2_getinfo.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/smbd/smb2_getinfo.c
r414 r745 4 4 5 5 Copyright (C) Stefan Metzmacher 2009 6 Copyright (C) Jeremy Allison 2010 6 7 7 8 This program is free software; you can redistribute it and/or modify … … 20 21 21 22 #include "includes.h" 23 #include "smbd/smbd.h" 22 24 #include "smbd/globals.h" 23 25 #include "../libcli/smb/smb_common.h" 26 #include "trans2.h" 27 #include "../lib/util/tevent_ntstatus.h" 24 28 25 29 static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, … … 35 39 static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req, 36 40 TALLOC_CTX *mem_ctx, 37 DATA_BLOB *out_output_buffer); 41 DATA_BLOB *out_output_buffer, 42 NTSTATUS *p_call_status); 38 43 39 44 static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq); … … 96 101 if (req->compat_chain_fsp) { 97 102 /* skip check */ 98 } else if (in_file_id_persistent != 0) {103 } else if (in_file_id_persistent != in_file_id_volatile) { 99 104 return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); 100 105 } … … 129 134 DATA_BLOB out_output_buffer = data_blob_null; 130 135 NTSTATUS status; 136 NTSTATUS call_status = NT_STATUS_OK; 131 137 NTSTATUS error; /* transport error */ 132 138 133 139 status = smbd_smb2_getinfo_recv(subreq, 134 140 req, 135 &out_output_buffer); 141 &out_output_buffer, 142 &call_status); 136 143 TALLOC_FREE(subreq); 137 144 if (!NT_STATUS_IS_OK(status)) { … … 145 152 } 146 153 154 if (!NT_STATUS_IS_OK(call_status)) { 155 /* Return a specific error with data. */ 156 error = smbd_smb2_request_error_ex(req, 157 call_status, 158 &out_output_buffer, 159 __location__); 160 if (!NT_STATUS_IS_OK(error)) { 161 smbd_server_connection_terminate(req->sconn, 162 nt_errstr(error)); 163 return; 164 } 165 return; 166 } 167 147 168 out_output_buffer_offset = SMB2_HDR_BODY + 0x08; 148 169 … … 181 202 DATA_BLOB out_output_buffer; 182 203 }; 204 205 static void smb2_ipc_getinfo(struct tevent_req *req, 206 struct smbd_smb2_getinfo_state *state, 207 struct tevent_context *ev, 208 uint8_t in_info_type, 209 uint8_t in_file_info_class) 210 { 211 /* We want to reply to SMB2_GETINFO_FILE 212 with a class of SMB2_FILE_STANDARD_INFO as 213 otherwise a Win7 client issues this request 214 twice (2xroundtrips) if we return NOT_SUPPORTED. 215 NB. We do the same for SMB1 in call_trans2qpipeinfo() */ 216 217 if (in_info_type == 0x01 && /* SMB2_GETINFO_FILE */ 218 in_file_info_class == 0x05) { /* SMB2_FILE_STANDARD_INFO */ 219 state->out_output_buffer = data_blob_talloc(state, 220 NULL, 24); 221 if (tevent_req_nomem(state->out_output_buffer.data, req)) { 222 return; 223 } 224 225 memset(state->out_output_buffer.data,0,24); 226 SOFF_T(state->out_output_buffer.data,0,4096LL); 227 SIVAL(state->out_output_buffer.data,16,1); 228 SIVAL(state->out_output_buffer.data,20,1); 229 tevent_req_done(req); 230 } else { 231 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); 232 } 233 } 183 234 184 235 static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, … … 198 249 connection_struct *conn = smb2req->tcon->compat_conn; 199 250 files_struct *fsp; 251 NTSTATUS status; 200 252 201 253 req = tevent_req_create(mem_ctx, &state, … … 205 257 } 206 258 state->smb2req = smb2req; 207 state->status = NT_STATUS_ INTERNAL_ERROR;259 state->status = NT_STATUS_OK; 208 260 state->out_output_buffer = data_blob_null; 209 261 … … 231 283 232 284 if (IS_IPC(conn)) { 233 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); 285 smb2_ipc_getinfo(req, state, ev, 286 in_info_type, in_file_info_class); 234 287 return tevent_req_post(req, ev); 235 288 } … … 247 300 int lock_data_count = 0; 248 301 char *lock_data = NULL; 249 bool ms_dfs_link = false;250 NTSTATUS status;251 302 252 303 ZERO_STRUCT(write_time_ts); … … 274 325 /* We know this name is ok, it's already passed the checks. */ 275 326 276 } else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) {327 } else if (fsp && fsp->fh->fd == -1) { 277 328 /* 278 329 * This is actually a QFILEINFO on a directory … … 304 355 fileid = vfs_file_id_from_sbuf(conn, 305 356 &fsp->fsp_name->st); 306 get_file_infos(fileid, &delete_pending, &write_time_ts); 357 get_file_infos(fileid, fsp->name_hash, 358 &delete_pending, &write_time_ts); 307 359 } else { 308 360 /* … … 320 372 fileid = vfs_file_id_from_sbuf(conn, 321 373 &fsp->fsp_name->st); 322 get_file_infos(fileid, &delete_pending, &write_time_ts); 374 get_file_infos(fileid, fsp->name_hash, 375 &delete_pending, &write_time_ts); 323 376 } 324 377 … … 329 382 delete_pending, 330 383 write_time_ts, 331 ms_dfs_link,332 384 ea_list, 333 385 lock_data_count, … … 363 415 char *data = NULL; 364 416 int data_size = 0; 365 NTSTATUS status;366 417 367 418 /* the levels directly map to the passthru levels */ … … 395 446 } 396 447 448 case 0x03:/* SMB2_GETINFO_SEC */ 449 { 450 uint8_t *p_marshalled_sd = NULL; 451 size_t sd_size = 0; 452 453 status = smbd_do_query_security_desc(conn, 454 state, 455 fsp, 456 /* Security info wanted. */ 457 in_additional_information, 458 in_output_buffer_length, 459 &p_marshalled_sd, 460 &sd_size); 461 462 if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) { 463 /* Return needed size. */ 464 state->out_output_buffer = data_blob_talloc(state, 465 NULL, 466 4); 467 if (tevent_req_nomem(state->out_output_buffer.data, req)) { 468 return tevent_req_post(req, ev); 469 } 470 SIVAL(state->out_output_buffer.data,0,(uint32_t)sd_size); 471 state->status = NT_STATUS_BUFFER_TOO_SMALL; 472 break; 473 } 474 if (!NT_STATUS_IS_OK(status)) { 475 DEBUG(10,("smbd_smb2_getinfo_send: " 476 "smbd_do_query_security_desc of %s failed " 477 "(%s)\n", fsp_str_dbg(fsp), 478 nt_errstr(status))); 479 tevent_req_nterror(req, status); 480 return tevent_req_post(req, ev); 481 } 482 483 if (sd_size > 0) { 484 state->out_output_buffer = data_blob_talloc(state, 485 p_marshalled_sd, 486 sd_size); 487 if (tevent_req_nomem(state->out_output_buffer.data, req)) { 488 return tevent_req_post(req, ev); 489 } 490 } 491 break; 492 } 493 397 494 default: 495 DEBUG(10,("smbd_smb2_getinfo_send: " 496 "unknown in_info_type of %u " 497 " for file %s\n", 498 (unsigned int)in_info_type, 499 fsp_str_dbg(fsp) )); 500 398 501 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 399 502 return tevent_req_post(req, ev); … … 406 509 static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req, 407 510 TALLOC_CTX *mem_ctx, 408 DATA_BLOB *out_output_buffer) 511 DATA_BLOB *out_output_buffer, 512 NTSTATUS *pstatus) 409 513 { 410 514 NTSTATUS status; … … 419 523 *out_output_buffer = state->out_output_buffer; 420 524 talloc_steal(mem_ctx, out_output_buffer->data); 525 *pstatus = state->status; 421 526 422 527 tevent_req_received(req);
Note:
See TracChangeset
for help on using the changeset viewer.